Doing things like attaching files to emails and sharing files with DataTransfer is difficult on android since one must get a URI from a file provider in newer versions of android.
We should add some functionality to help get a proper URI from an existing filename the developer passes to us which we then transfer into a file provider friendly filename.
What's needed
XML Resource
You must specify the paths you intend to use in an xml resource file. Most users would want to use one or both of these paths:
<?xml version="1.0" encoding="UTF-8" ?>
<paths>
<external-path path "caboodle" name="caboodle/" />
<!-- NOT NEEDED: -->
<!-- <external-path path="Android/data/com.some.package/" name="files_root" /> -->
<!-- <external-path path="." name="external_storage_root" /> -->
</paths>
EDIT: We probably only need to do something like <external-path path "caboodle" name="caboodle" /> or similar... We don't need external storage and we don't need the package name in the path it appears.. so this is good.
We can just add this as a resource in the library itself.
Provider declaration in AndroidManifest.xml
The AndroidManifest.xml file needs this declared:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
I don't believe we can accomplish this currently with C# attributes (there doesn't seem to be an [assembly: Provider(..)] attribute.
Also note the @xml/file_paths resource name needs to be known for this declaration.
We could get the user to add this manually (again, not nice). Or we can use a custom build task.
Content URI
Finally we get the actual content uri:
var contentUri = Android.Support.V4.Content.FileProvider.GetUriForFile(context, "com.some.package", new Java.IO.File(filename));
We can use this uri for things like starting an intent chooser:
var intent = new Android.Content.Intent(Android.Content.Intent.ActionSend);
intent.PutExtra(Android.Content.Intent.ExtraStream, contentUri);
intent.SetFlags(Android.Content.ActivityFlags.GrantReadUriPermission);
var intentChooser = Android.Content.Intent.CreateChooser(intent, "Title");
context.StartActivity(intentChooser);
VS bug #732192
Doing things like attaching files to emails and sharing files with DataTransfer is difficult on android since one must get a URI from a file provider in newer versions of android.
We should add some functionality to help get a proper URI from an existing filename the developer passes to us which we then transfer into a file provider friendly filename.
What's needed
XML Resource
You must specify the paths you intend to use in an xml resource file. Most users would want to use one or both of these paths:
EDIT: We probably only need to do something like
<external-path path "caboodle" name="caboodle" />or similar... We don't need external storage and we don't need the package name in the path it appears.. so this is good.We can just add this as a resource in the library itself.
Provider declaration in AndroidManifest.xml
The AndroidManifest.xml file needs this declared:
I don't believe we can accomplish this currently with C# attributes (there doesn't seem to be an
[assembly: Provider(..)]attribute.Also note the
@xml/file_pathsresource name needs to be known for this declaration.We could get the user to add this manually (again, not nice). Or we can use a custom build task.
Content URI
Finally we get the actual content uri:
We can use this uri for things like starting an intent chooser: