java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED on KitKat only

匿名 (未验证) 提交于 2019-12-03 02:49:01

问题:

I am using the DownloadManager to download images off our server and I am placing the files in the externalFilesDir.

I am send out a broadcast intent because I don't want these downloaded images to appear in the gallery.

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + context.getExternalFilesDir(null)))); 

I only tested this on my Galaxy S3 Jelly Bean 4.3 prior and it was working, but when I tested it on KitKat 4.4 it crashes the app.

Is there a better way to not have the files downloaded from the DownloadManager not appear in the phone gallery?

Stack Trace

06-05 17:34:41.940: E/AndroidRuntime(15410): FATAL EXCEPTION: main 06-05 17:34:41.940: E/AndroidRuntime(15410): Process: com.walintukai.lfdate, PID: 15410 06-05 17:34:41.940: E/AndroidRuntime(15410): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.walintukai.lfdate (has extras) } in com.walintukai.lfdate.SocketIOService$1@42359f40 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:778) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.os.Handler.handleCallback(Handler.java:733) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.os.Handler.dispatchMessage(Handler.java:95) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.os.Looper.loop(Looper.java:136) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.app.ActivityThread.main(ActivityThread.java:5057) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at java.lang.reflect.Method.invokeNative(Native Method) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at java.lang.reflect.Method.invoke(Method.java:515) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at dalvik.system.NativeStart.main(Native Method) 06-05 17:34:41.940: E/AndroidRuntime(15410): Caused by: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED from pid=15410, uid=10135 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.os.Parcel.readException(Parcel.java:1465) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.os.Parcel.readException(Parcel.java:1419) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2390) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1127) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:365) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at com.walintukai.lfdate.SocketIOService$1.onReceive(SocketIOService.java:111) 06-05 17:34:41.940: E/AndroidRuntime(15410):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768) 06-05 17:34:41.940: E/AndroidRuntime(15410):    ... 9 more 

回答1:

It seems that google is trying to prevent this from KITKAT.
Looking at core/rest/AndroidManifest.xml you will notice that broadcast android.intent.action.MEDIA_MOUNTED is protected now. Which means it is a broadcast that only the system can send.

The following should work for all versions:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {     final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);     final Uri contentUri = Uri.fromFile(outputFile);      scanIntent.setData(contentUri);     sendBroadcast(scanIntent); } else {     final Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()));     sendBroadcast(intent); } 

If the above is not working try the following:

According to this post you need another way to fix it.
Like using MediaScannerConnection or ACTION_MEDIA_SCANNER_SCAN_FILE.

MediaScannerConnection.scanFile(this, new String[] {  file.getAbsolutePath()},  null, new MediaScannerConnection.OnScanCompletedListener() {  public void onScanCompleted(String path, Uri uri)  {   }  }); 


回答2:

I know its late but try this can working in all versions:

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                     Intent mediaScanIntent = new Intent(                             Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);                     Uri contentUri = Uri.fromFile(out); \\out is your output file                     mediaScanIntent.setData(contentUri);                     this.sendBroadcast(mediaScanIntent);                 } else {                     sendBroadcast(new Intent(                             Intent.ACTION_MEDIA_MOUNTED,                             Uri.parse("file://"                                     + Environment.getExternalStorageDirectory())));                 } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!