2014-02-10 2 views
9

Ich habe ein Problem, bei dem ich versuche, mehrere Dateien aus meinem internen Speicher an eine E-Mail-Absicht anzuhängen, indem ich sie mit einem FileProvider in meinem Manifest deklariert und die Lese-Uri-Berechtigungen gewähre. Hier ist mein Code.Absicht FLAG_GRANT_READ_URI_PERMISSION Verwendung von FileProvider in Gingerbread

Manifest

  <provider 
      android:name="android.support.v4.content.FileProvider" 
      android:authorities="com.company.example.logprovider" 
      android:exported="false" 
      android:grantUriPermissions="true"> 
      <meta-data 
       android:name="android.support.FILE_PROVIDER_PATHS" 
       android:resource="@xml/provider_paths"/> 
     </provider> 

Intent Creation

 emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); 
     emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
     emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] {"randomemailaddress"}); 

    ArrayList<Uri> uris = new ArrayList<Uri>(); 
    File directory = getFilesDir(); 
    File[] list = directory.listFiles(); 
    for (File f : list) { 
     if (f.getName().contains("log") && f.getName().contains(".txt")) 
      uris.add(FileProvider.getUriForFile(this, "com.company.example.logprovider",f)); 
    } 

    emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 

Die Ausgabe

Dies funktioniert auf zwei Geräte mit Jelly Bean jedoch nicht für zwei Geräte funktioniert Lebkuchen laufen.

Die Ausnahme, die ich bekomme, ist wie folgt.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.gm/com.google.android.gm.ComposeActivity}: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{40b2db08 3885:com.google.android.gm/10110} (pid=3885, uid=10110) requires null or null 
E/AndroidRuntime(3885): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1659) 
E/AndroidRuntime(3885): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675) 
E/AndroidRuntime(3885): at android.app.ActivityThread.access$1500(ActivityThread.java:121) 
E/AndroidRuntime(3885): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943) 
E/AndroidRuntime(3885): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime(3885): at android.os.Looper.loop(Looper.java:138) 
E/AndroidRuntime(3885): at android.app.ActivityThread.main(ActivityThread.java:3701) 
E/AndroidRuntime(3885): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(3885): at java.lang.reflect.Method.invoke(Method.java:507) 
E/AndroidRuntime(3885): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878) 
E/AndroidRuntime(3885): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) 
E/AndroidRuntime(3885): at dalvik.system.NativeStart.main(Native Method) 
E/AndroidRuntime(3885): Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{40b2db08 3885:com.google.android.gm/10110} (pid=3885, uid=10110) requires null or null 
E/AndroidRuntime(3885): at android.os.Parcel.readException(Parcel.java:1322) 
E/AndroidRuntime(3885): at android.os.Parcel.readException(Parcel.java:1276) 
E/AndroidRuntime(3885): at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:1882) 
E/AndroidRuntime(3885): at android.app.ActivityThread.getProvider(ActivityThread.java:3365) 
E/AndroidRuntime(3885): at android.app.ActivityThread.acquireProvider(ActivityThread.java:3390) 
E/AndroidRuntime(3885): at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:1728) 
E/AndroidRuntime(3885): at android.content.ContentResolver.acquireProvider(ContentResolver.java:754) 
E/AndroidRuntime(3885): at android.content.ContentResolver.query(ContentResolver.java:262) 
E/AndroidRuntime(3885): at com.google.android.gm.ComposeArea.addAttachment(ComposeArea.java:736) 
E/AndroidRuntime(3885): at com.google.android.gm.ComposeArea.initFromExtras(ComposeArea.java:699) 
E/AndroidRuntime(3885): at com.google.android.gm.ComposeActivity.initFromExtras(ComposeActivity.java:1482) 
E/AndroidRuntime(3885): at com.google.android.gm.ComposeActivity.finishOnCreateAfterAccountSelected(ComposeActivity.java:1020) 
E/AndroidRuntime(3885): at com.google.android.gm.ComposeActivity.onCreate(ComposeActivity.java:259) 
E/AndroidRuntime(3885): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
E/AndroidRuntime(3885): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1623) 
E/AndroidRuntime(3885): ... 11 more 

Meine Gedanken

Also irgendwo auf der ganzen Linie, die FLAG_GRANT_READ_URI_PERMISSION Flag I auf die Absicht bin Hinzufügen funktioniert nicht?

Ich glaube auch, das Problem kann sein, weil ich die Uris an die Absicht als EXTRA_STREAM anfügen und aus irgendeinem Grund ältere Android-Versionen nicht abholen? (habe noch keine Dokumentation dazu gefunden).

Jede Hilfe wird geschätzt.

+0

haben Sie diese http tryed: // Stackoverflow. com/questions/18249007/how-to-use-support-fileprovider-for-sharing-content-to-other-apps – PedroAGSantos

+0

Ja habe ich, aber 'grantUriPermission' nur ermöglicht bestimmte Pakete in der Lage sein, auf die uri zugreifen – StuStirling

+0

Wie wäre es http://stackoverflow.com/questions/21275898/securityexception-with-granturipermission-when-sharing-a-file-with-fileprovider? –

Antwort

10
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 

//revoke permisions 
context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 

Als letztes Mittel, wenn Sie keine Paketnamen angeben können Sie die Berechtigung für alle Anwendungen gewähren können, die bestimmte Absicht umgehen kann:

//grant permisions for all apps that can handle given intent 
Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_SEND); 
... 
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); 
for (ResolveInfo resolveInfo : resInfoList) { 
    String packageName = resolveInfo.activityInfo.packageName; 
    context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 
} 
+2

Sie sollten die ursprüngliche Antwort verknüpfen, anstatt sie zu kopieren: http://stackoverflow.com/a/18332000/3519951 –

Verwandte Themen