0

My App is creating a PDF and passes it to other Apps to be displayed elsewhere. I create the file in internal storage to have to ask the user for less permissions.

I create my intent via:

Intent viewIntent = new Intent(Intent.ActionView);
Java.IO.File document = new Java.IO.File(filePath);
Android.Net.Uri contentUri = FileProvider.GetUriForFile(
    _context,
    _context.PackageName + ".provider",
    document);

viewIntent.SetDataAndType(contentUri, GetMimeType(document));
viewIntent.SetFlags(ActivityFlags.NewTask);
viewIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
viewIntent.AddFlags(ActivityFlags.ClearTask);
viewIntent.AddFlags(ActivityFlags.GrantPersistableUriPermission);
viewIntent.AddFlags(ActivityFlags.GrantPrefixUriPermission);
viewIntent.AddFlags(ActivityFlags.GrantWriteUriPermission);
Intent chooser = Intent.CreateChooser(viewIntent, "");
chooser.SetFlags(ActivityFlags.NewTask);
chooser.AddFlags(ActivityFlags.GrantReadUriPermission);
chooser.AddFlags(ActivityFlags.ClearTask);
chooser.AddFlags(ActivityFlags.GrantPersistableUriPermission);
chooser.AddFlags(ActivityFlags.GrantPrefixUriPermission);
chooser.AddFlags(ActivityFlags.GrantWriteUriPermission);

_context.StartActivity(viewIntent);

On the Google Pixel 3 XL where I test, I can open a PDF without any issues.

When I do the same on a Huawei tablet with API level 24, sometimes everything works but at other times Adobe Acrobat shows an error: This file could not be accessed. Check the location or the network and try again.

The behavior isn't deterministic, sometimes I get the error but other times everything works fine.

Christian
  • 25,249
  • 40
  • 134
  • 225
  • Didn't you already ask the same here: https://stackoverflow.com/questions/53187894/how-do-i-open-an-internally-created-pdf-in-xamarin-android-via-a-fileprovider-in? – Cheesebaron Feb 28 '19 at 10:06
  • Possible duplicate of [How do I open an internally created pdf in Xamarin.Android via a FileProvider in the default system pdf app?](https://stackoverflow.com/questions/53187894/how-do-i-open-an-internally-created-pdf-in-xamarin-android-via-a-fileprovider-in) – Cheesebaron Feb 28 '19 at 10:06
  • @Cheesebaron : I did follow the example from the other question but I have now a followup question about getting it to work on the Huawei devices. – Christian Feb 28 '19 at 10:17
  • What happened to the WrapFileWithUri? – Cheesebaron Feb 28 '19 at 10:18

1 Answers1

0

In the Application node of your Android Manifest make sure you've added a FileProvider definition:

<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.FileProvider" android:exported="false" android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>

Add a Resources/xml/provider_paths file with the contents:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-path name="external_files" path="."/>
</paths>

You can restrict this later if needed. However, for my use case I put files in external storage, which I share from. You need to adjust this accordingly where you are sharing from.

I.e. if you are sharing the file from internal app storage you will need to add a files-path definition there too.

Then when sharing a file you simply do:

var packageName = context.ApplicationInfo.PackageName;
var fileProviderName = $"{packageName}.FileProvider";

var intent = new Intent(Intent.ActionSend);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
intent.SetType("image/*"); // change mime type if wanting to open in other app
intent.PutExtra(Intent.ExtraStream,
    FileProvider.GetUriForFile(context, fileProviderName, new Java.IO.File(filePath)));

StartActivity(intent);

That should be enough, works fine every time for me for sharing images to another app. I don't think you need the flags for your chooser Intent, only for the inner viewIntent. Also the GrantReadUriPermission should be the only thing needed if you are providing flags.

Cheesebaron
  • 24,131
  • 15
  • 66
  • 118