1

I want to edit files from the internal storage of my Xamarin.Forms Android app in third party apps, for example fill out form elements in a PDF file or edit a .docx file.

With my implementation the file gets correctly opened in the external app, but in certain apps it is opened read-only. Adobe Acrobat and Microsoft Word open the files read-only, while other apps like Google Docs are able to write back into the file. (I am using Microsoft Word with a valid Office365 subscription).

My FileProvider in the AndroidManifest.xml:

<provider android:name="android.support.v4.content.FileProvider" 
          android:authorities="xamarintestapp.xamarintestapp.fileprovider" 
          android:grantUriPermissions="true" 
          android:exported="false">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS"     
               android:resource="@xml/filepaths" />
</provider>

filepaths.xml:

<paths>
        <files-path name="files" path="."/>
</paths>

Via the Xamarin.Forms DependencyService I am starting a Activity and pass the content uri to launch the external app:

public void OpenFile(string fileName)
{
    string auth = "xamarintestapp.xamarintestapp.fileprovider";
    string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(fileName.ToLower()));
    if (mimeType == null)
        mimeType = "*/*";

    var file = new Java.IO.File(Path.Combine(Forms.Context.FilesDir.Path, fileName));
    Android.Net.Uri uri = FileProvider.GetUriForFile(Forms.Context, auth, file);

    Intent intent = new Intent(Intent.ActionView);
    intent.SetDataAndType(uri, mimeType);
    intent.AddFlags(ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission);
    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.NoHistory);

    // Trying to allow writing to the external app ...
    var resInfoList = Forms.Context.PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
    foreach (var resolveInfo in resInfoList)
    {
        var packageName = resolveInfo.ActivityInfo.PackageName;
        Forms.Context.GrantUriPermission(packageName, uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantPrefixUriPermission | ActivityFlags.GrantReadUriPermission);
    }

    Forms.Context.StartActivity(intent);
}

Am I doing something wrong or is this simply not possible?

stefffdev
  • 176
  • 1
  • 9
  • 1
    If one app behaves like expected and two not then why do you think you are to blame? Try other extensions and other apps. Try those two apps without file provider. – greenapps Feb 15 '17 at 17:26
  • I have tried both apps without the FileProvider (copying the files to external storage and opening them from there - the files are opened writable then). I tried ContentProvider and DocumentProvider as well, with the same result, some apps open the files read-only while others don't, I'm curious why... – stefffdev Feb 15 '17 at 18:44
  • Based on your code like `Forms.Context.StartActivity(intent);`, you're actually developing a Xamarin.Forms solution, not the Xamarin.Android, am I right? And your problem is about the write permission on other platforms like UWP, not on Android Platform? – Grace Feng Feb 16 '17 at 07:27
  • Thanks for your reply, you are right, I am developing a Xamarin.Forms app and implement the OpenFile Method in the platform-specific projects via the Xamarin.Forms DependencyService. I updated my question accordingly. My OpenFile implementation under UWP works, but I'm having trouble under Android, haven't tried iOS yet. – stefffdev Feb 16 '17 at 12:05

1 Answers1

0

After further investigation I can confirm that this seems to be an issue of the app receiving my intent (e.g. Microsoft Word).

When I start a EDIT intent instead of a VIEW intent as in

Intent intent = new Intent(Intent.ActionEdit);

the file is opened with write access in certain apps (xodo pdf, google docs) but read-only in other apps (Adobe PDF Reader, Microsoft Word) so I'm assuming these apps do not implement receiving an edit intent correctly.

stefffdev
  • 176
  • 1
  • 9