web-dev-qa-db-fra.com

java.lang.SecurityException: refus d'autorisation: pas autorisé à envoyer la diffusion Android.intent.action.MEDIA_MOUNTED sur KitKat uniquement

J'utilise le DownloadManager pour télécharger des images sur notre serveur et je place les fichiers dans le externalFilesDir.

J'envoie une intention de diffusion parce que je ne veux pas que ces images téléchargées apparaissent dans la galerie.

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

Je l'ai testé uniquement sur mon Galaxy S3 Jelly bean 4.3 avant et cela fonctionnait, mais quand je l'ai testé sur KitKat 4.4 il plante l'application.

Existe-t-il une meilleure façon de ne pas faire apparaître les fichiers téléchargés depuis DownloadManager dans la galerie du téléphone?

Trace de pile

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
15
The Nomad

Il semble que Google essaie d'empêcher cela de KitKat.
En regardant core/rest/AndroidManifest.xml vous remarquerez que la diffusion Android.intent.action.MEDIA_MOUNTED est maintenant protégé. Ce qui signifie que c'est une diffusion que seul le système peut envoyer.

<protected-broadcast Android:name="Android.intent.action.MEDIA_MOUNTED" />

Les éléments suivants devraient fonctionner pour toutes les 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);
}

Si ce qui précède ne fonctionne pas, essayez ce qui suit:

Selon cela post vous avez besoin d'un autre moyen de le réparer.
Comme utiliser MediaScannerConnection ou ACTION_MEDIA_SCANNER_SCAN_FILE.

MediaScannerConnection.scanFile(this, new String[] {

file.getAbsolutePath()},

null, new MediaScannerConnection.OnScanCompletedListener() {

public void onScanCompleted(String path, Uri uri)

{


}

});
42
Lazy Ninja

Je sais que c'est tard mais essayez cela peut fonctionner dans toutes les 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())));
                }
28
WonderSoftwares