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 🙂