FileProvider throws exception on GetUriForFile
Asked Answered
T

3

26

I followed the example code on the android developer reference on FileProviders but it won't work.

I have setup the path files/exports/ in the file provider definition in my Manifest and the referenced files does exist at that path.

In my Manifest:

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

And in xml/file_paths.xml

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

Then I try to get the content-uri with the following code:

Java.IO.File exportFile = 
    new Java.IO.File ("/data/data/com.company.app/files/exports/file.pdf"); 
Android.Net.Uri exportUri = 
    Android.Support.V4.Content.FileProvider.GetUriForFile (this, "com.company.app.fileprovider", exportFile);

However I get this error:

Exception of type 'Java.Lang.NullPointerException' was thrown.
  at Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00064] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.2-branch/4b53fbd0/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1160 
  at Android.Support.V4.Content.FileProvider.GetUriForFile (Android.Content.Context context, System.String authority, Java.IO.File file) [0x00000] in <filename unknown>:0 
  at com.company.App.ImageAndSubtitle.cloudStorageDidDownloadFile (System.Object sender, com.company.App.CloudStorageEventArgs args) [0x001f7] in /app_path/Screens/ImageAndSubtitle.cs:187 
  --- End of managed exception stack trace ---
java.lang.NullPointerException
    at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243)
    at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:217)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:130)
    at mono.java.lang.RunnableImplementor.n_run(Native Method)
    at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:29)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4838)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:642)
    at dalvik.system.NativeStart.main(Native Method)

Update

From the Android source code I could hunt that down so far as I now know that this command in android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243) will fail and return null:

final ProviderInfo info = context.getPackageManager().resolveContentProvider(authority, PackageManager.GET_META_DATA);

But I have no idea why...

Tradition answered 21/2, 2014 at 10:6 Comment(0)
T
38

I finally found good example code on how to create ContentProviders and FileProviders on https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider

The actual error in my code was that in the Manifest file I had the provider tag outside of the application tag, but it must be inside. The Manifest must look like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.company.app">
<uses-sdk android:minSdkVersion="13" />

<permission
    android:name="com.company.app.fileprovider.READ"
    android:description="@string/perm_read"
    android:label="@string/perm_read_label"/>
<uses-permission android:name="com.company.app.fileprovider.READ"/>

<application android:label="MyApp">

    <provider 
    android:name="android.support.v4.content.FileProvider" 
    android:authorities="com.company.app.fileprovider" 
    android:exported="false" 
    android:grantUriPermissions="true"
    android:readPermission="com.company.app.fileprovider.READ">
                <meta-data 
                android:name="android.support.FILE_PROVIDER_PATHS" 
                android:resource="@xml/file_paths" />
    </provider>

</application>
<uses-permission android:name="android.permission.INTERNET" />

</manifest>
Tradition answered 24/2, 2014 at 13:25 Comment(7)
@ codingFriend1 i too have the same error can u plz help me posted a question in stackoverflow here is the link:#26398755Alluvium
Thank you for pointing this. It was a silly mistake. Sometimes my brain behaves weirdly, I see something while I do something else..Liebowitz
It happened to me using cordova-plugin-x-socialsharing after changing the name of the application in cordova's config.xml. I had to remove and reinstall the plugin to make it workAntechoir
this is gold. I haven't noticed it anywhere, thanks for pointing it out.Tonjatonjes
saved my day. Also <root-path name="root" path="." /> in file_paths.xml was required for meNepil
This is a partial answer. Please complete it by adding Java side code (which you write to interact with this XML from your Activity or Fragment).Bowl
@Alluvium That could be a duplicate question. This is discouraged at SOW.Bowl
D
10

In trying to set up a FileProvider for getting a PDF file that is on the device and being able to email it out, I ran into this exception as well. Reading the different answers out there - it seems a bit complicated to get the FileProvider set up correctly by hand (at least this first time around).

Finally what worked for me was to copy the components from this example into an empty new project: https://github.com/IanDarwin/Android-Cookbook-Examples/tree/master/PdfShare

Once I see it working in the standalone, then I'm able to bring in the changes to my actual project.

Specifically, here are the files to replicate:

1. AndroidManifest.xml - where all the tricky FileProvider config is

2. file_paths.xml - This is a small but important component. Looking on SO there are a variety of answers for what to put there, however only from this project did the set up work for me

3. MainActivity.java - the corresponding Java setup to work with what's configured in the manifest; and of course don't forget the associated layout file

Daugava answered 4/1, 2018 at 21:5 Comment(1)
I also ran into a bunch of answers out there but this compilation was the closest set I found. I had to make some minor adjustments to adapt it for Xamarin.Android. Thanks!Eniwetok
C
2

This error occurred in my case because I had passed an incorrect package name to the second parameter of GetUriForFile. I used BuildConfig.PACKAGE_NAME which resolved to android.support.multidex which is incorrect.

Cordwain answered 14/9, 2017 at 13:30 Comment(4)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewPlaster
its just another mistake to get same exceptionCordwain
for example first time i use BuildConfig.PACKAGE_NAME that was "android.support.multidex" by defaultCordwain
Thanks for this answer, this helped me. My fault, I changed my package name mid way through development and forgot to also go back and update the manifest file. AHHH!!!!!!Klement

© 2022 - 2024 — McMap. All rights reserved.