2016-04-15 49 views
0

所以我正在写一个应用程序,可以通过从其他应用程序的共享菜单接收文件。我有一个ShareActivity,它具有接收文件的意图过滤器。Android“权限拒绝”,当收到共享文件

一旦收到文件ShareActivity已启动,并且在该活动中,用户必须选择一个文件夹,在该文件夹中将接收文件上传。当用户选择该文件夹时,会启动一个服务来上传文件。

的问题是,接收的文件URI(从谷歌组图)传递给UploadServiceFinish()被调用ShareActivityShareActivity完成后,抛出一个异常:

[Xamarin.Insights] Warning: Unhandled exception: Java.Lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{cf1e0da 8268:lv.new_failiem/u0a247} (pid=8268, uid=10247) that is not exported from uid 10124 
[Xamarin.Insights] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
[Xamarin.Insights] at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue* parms) [0x00064] in /Users/builder/data/lanes/3053/a94a03b5/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:195 
[Xamarin.Insights] at Android.Content.ContentResolver.OpenInputStream (Android.Net.Uri uri) [0x00044] in /Users/builder/data/lanes/3053/a94a03b5/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Android.Content.ContentResolver.cs:926 
[Xamarin.Insights] at lv.failiem.android.UploadService+<UploadFiles>c__async0.MoveNext() [0x0031a] in /Projects/Android/UploadService.cs:116 

这样做在一些研究中,我发现内容提供者仅在当前接收活动存在的时候才为该特定文件颁发许可。当该活动关闭时,权限将被丢弃,并抛出此异常。事实上,如果我不打Finish()在我的ShareActivity,一切工作正常(但我需要上传发生在后台)。

有没有办法将该权限传递给我的服务?我不想上传发生在独立于任何活动的背景中。

我阅读这些StackOveflow帖子: Using data from context providers or requesting Google Photos read permission?

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.content.GooglePhotosImageProvider

Permission denial: opening provider

一个答案毫无遗漏了我的眼睛(https://stackoverflow.com/a/30909105/5884133),它说要

使用临时文件路径

有关如何解决此问题的任何想法?如何获取临时文件路径?

编辑: 当用户选择的文件夹中ShareActivity,这种方法被调用:

void AddUploadFiles(Folder folder) { 
    switch (Intent.Action) { 

    //For receiving one file 
    case Intent.ActionSend: 
     var result = Intent.GetParcelableExtra (Intent.ExtraStream); 
     var uri = Android.Net.Uri.Parse (result.ToString()); 
     UploadService.AddFile (Android.Net.Uri.Parse (result.ToString()), folder); 
     StartService (new Intent(this, typeof(UploadService))); 
     break; 

    //For receiving multiple files 
    case Intent.ActionSendMultiple: 
     var imageUris = Intent.GetParcelableArrayListExtra (Intent.ExtraStream); 
     foreach (var item in imageUris) 
      UploadService.AddFile (Android.Net.Uri.Parse (item.ToString()), folder); 
     StartService (new Intent(this, typeof(UploadService))); 
     break; 
    } 
} 

然后将文件获取排队在UploadService和上传一个接一个。

+0

您可以发布您的代码? – Giorgi

回答

0

我找到了解决办法 - 我可以通过发行许可的UploadService这样的:

var result = Intent.GetParcelableExtra (Intent.ExtraStream); 
UploadService.AddFile (Android.Net.Uri.Parse (result.ToString()), parentFolder); 
var i = new Intent (this, typeof(UploadService)); 
i.AddFlags (ActivityFlags.GrantReadUriPermission); //Pass permission from content provider 
i.SetData (Android.Net.Uri.Parse (result.ToString())); 
StartService (i); 

参考:http://developer.android.com/guide/topics/providers/content-provider-basics.html#Intents