简体   繁体   中英

Xamarin.Forms Android FileProvider: GrantWriteUriPermission not always working

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?

After further investigation I can confirm that this seems to be an issue of the app receiving my intent (eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM