So i am writing an app, that can receive files via the share menu from other apps. I have a ShareActivity
, which has the intent filter for receiving files.
Once file is received ShareActivity
is started and in that activity user must choose a folder in which the received file will be uploaded. When the user has chosen the folder, a service is started, which uploads the file.
The problem is that, the received file URI (from Google Photos) is passed to the UploadService
and Finish()
is called for ShareActivity
and when the ShareActivity
is finished, an exception is thrown:
[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
By doing some research, I found out that content providers issue a permission for that specific file only for the time, when the receiving activity is alive. When that activity is closed, permission is discarded and this exception is thrown. Indeed, if i don't call Finish()
on my ShareActivity
, everything works fine (but i need the upload to happen in background).
Is there a way to pass that permission to my service? I wan't the upload to happen in the background independent from any activity.
I read these StackOveflow posts: Using data from context providers or requesting Google Photos read permission?
Permission denial: opening provider
One answer cought my eye (https://stackoverflow.com/a/30909105/5884133), which says to
use the temporary file path
Any ideas on how to solve this? How to get the temporary file path?
Edit:
When user has selected the folder in ShareActivity
, this method gets called:
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;
}
}
Then the files get enqueued in the UploadService
and are uploaded one by one.