Last year I read the blog post Notifications, Sounds, Android 7.0, and Aggravation by the always well-informed Mark Murphy. In it Mark describes how the ban on file: URIs has made things difficult for developers who want to use custom notification sounds. Apparently, the notification subsystem wasn’t really prepared for content: URIs taking over. It’s currently not possible to use Notification.Builder#setSound(Uri) with a content: URI pointing to a ContentProvider that hasn’t been exported. That means FileProvider, the standard solution when it comes to exposing files via content: URIs, won’t work.

Mark lists a couple of options to work around the problem. Personally, I thought the option he named “The Axe”, using a custom ContentProvider without URI permissions, was the cleanest solution. For unrelated reasons I was reading the source code of FileProvider at that time. With the blog post in mind I thought it should be fairly easy to change the class to support that use case. And that’s what I did. The result was PublicFileProvider, a modified version of FileProvider that doesn’t require URI permissions and that takes special care to only expose files read-only.

For the last 7 months the project was gathering dust on GitHub. But the other day I stumbled across this entry in the bug tracker for the Android O Preview where Mark reiterates that the permission issue should be fixed in the platform rather than worked around by app developers. I agree, but I’m not confident this will be fixed in Android O. Even if it is, there’s still Android 7.0/7.1 we have to deal with. So there might still be some demand for something like PublicFileProvider. Which is why I added a bit more documentation and published the library on Maven Central. If you run into permission issues with custom notification sounds give PublicFileProvider a try.

Check out PublicFileProvider on GitHub. Feedback is always welcome. Open an issue on GitHub or reach out via Twitter. I’m @cketti. Please also let me know if you find another use case for this library 🙂