所以我正在编写一个应用程序,它可以通过其他应用程序的共享菜单接收文件。我有一个ShareActivity
,它有一个用于接收文件的intent过滤器。
收到文件后ShareActivity
启动,在该活动中,用户必须选择将上传收到的文件的文件夹。当用户选择该文件夹时,将启动一个服务,该服务将上载该文件。
问题在于,收到的文件URI(来自Google相册)传递给UploadService
,Finish()
调用ShareActivity
以及ShareActivity
完成时,抛出异常:
[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?
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 :(得分: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