Fixed
Status Update
Comments
al...@android.com <al...@android.com>
mm...@commonsware.com <mm...@commonsware.com> #2
No "Me Too!" button so; Me Too!
pl...@gmail.com <pl...@gmail.com> #3
Me too!
mm...@commonsware.com <mm...@commonsware.com> #4
Me too please
pa...@outlook.com <pa...@outlook.com> #5
Me too please
on...@gmail.com <on...@gmail.com> #6
Me too!
ad...@google.com <ad...@google.com> #7
Heat maps are a very useful form of conditional formatting I can see additional functionality being very useful. Me Too!
pa...@outlook.com <pa...@outlook.com> #8
Me too
pa...@outlook.com <pa...@outlook.com> #9
+1
Description
To see this effect in action:
1. UnZIP the attached project somewhere.
2. Set up an Android 6.0 device for testing (e.g., set up for adb access).
3. Upload app/src/main/res/raw/clip.ogg from the project to the Notifications/ directory on the test device.
4. Run the project on the test device. You should see a 2x2 grid of buttons.
5. Click the Resource button. This will play a 14-second audio clip as part of showing a Notification. Feel free to swipe down the notification shade to stop the audio.
6. Click the File Uri button. If you did step #3, you will hear the same audio clip.
7. Click the FileProvider button. You will not hear anything, but you will get messages like these in LogCat:
09-07 12:30:05.568 919-930/? W/ActivityManager: Permission Denial: opening provider com.commonsware.android.notif.sound.LegacyCompatFileProvider from ProcessRecord{ddb9d4e 3051:com.android.systemui/u0a27} (pid=3051, uid=10027) that is not exported from uid 10099
09-07 12:30:05.569 3051-24269/? W/MediaPlayer: Couldn't open file on client side; trying server side: java.lang.SecurityException: Permission Denial: opening provider com.commonsware.android.notif.sound.LegacyCompatFileProvider from ProcessRecord{ddb9d4e 3051:com.android.systemui/u0a27} (pid=3051, uid=10027) that is not exported from uid 10099
09-07 12:30:05.570 919-3108/? W/ActivityManager: Permission Denial: opening provider com.commonsware.android.notif.sound.LegacyCompatFileProvider from (null) (pid=511, uid=1013) that is not exported from uid 10099
[ 09-07 12:30:05.571 511: 511 D/ ]
openContentUri(content://com.commonsware.android.notif.sound.provider/stuff/clip.ogg) caught exception -1
09-07 12:30:05.571 511-511/? E/MediaPlayerService: Couldn't open fd for content://com.commonsware.android.notif.sound.provider/stuff/clip.ogg
09-07 12:30:05.571 3051-24269/? W/RingtonePlayer: error loading sound for content://com.commonsware.android.notif.sound.provider/stuff/clip.ogg
java.io.IOException: setDataSource failed.: status=0x80000000
at android.media.MediaPlayer.nativeSetDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1080)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1069)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1023)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:968)
at com.android.systemui.media.NotificationPlayer$CreationAndCompletionThread.run(NotificationPlayer.java:85)
They indicate that the system does not have read access to the FileProvider-supplied Uri.
8. Set up an Android 7.0 device for testing (e.g., set up for adb access).
9. Upload app/src/main/res/raw/clip.ogg from the project to the Notifications/ directory on the test device.
10. Run the project on the test device. You should see the same 2x2 grid of buttons.
11. Click the Resource button. This will play the audio clip.
12. Click the File Uri button. You will not hear anything, but you will crash with the following stack trace:
09-07 12:38:19.468 3525-3525/com.commonsware.android.notif.sound E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.commonsware.android.notif.sound, PID: 3525
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4697)
at android.view.View.performClick(View.java:5609)
at android.view.View$PerformClick.run(View.java:22259)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4692)
at android.view.View.performClick(View.java:5609)
at android.view.View$PerformClick.run(View.java:22259)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Notifications/clip.ogg exposed beyond app through Notification.sound
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed(Uri.java:2346)
at android.app.NotificationManager.notifyAsUser(NotificationManager.java:300)
at android.app.NotificationManager.notify(NotificationManager.java:284)
at android.app.NotificationManager.notify(NotificationManager.java:268)
at com.commonsware.android.notif.sound.MainActivity.raiseNotification(MainActivity.java:137)
at com.commonsware.android.notif.sound.MainActivity.playFile(MainActivity.java:94)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4692)
at android.view.View.performClick(View.java:5609)
at android.view.View$PerformClick.run(View.java:22259)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
This is the standard file: Uri ban crash.
13. Click the FileProvider button. You will not hear anything, but you will get messages akin to those in step #7 above.
================
What should happen is that the FileProvider scenario should work fine, because NotificationManager should be smart enough to grant read access to our content: Uri, since reading that content **is the entire point of having provided the sound Uri**.
Alternatively, there should be some documented means for developers to be able to use setSound() effectively on Android 7.0+ devices, for apps with a targetSdkVersion of 24+, beyond just the android.resource Uri scheme. A lot of apps allow users to choose custom "ringtones" for the app's notifications, and there is no clean way to offer that now.
Thanks!