Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileProvider throws exception on GetUriForFile

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...

like image 677
codingFriend1 Avatar asked Feb 21 '14 10:02

codingFriend1


3 Answers

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>
like image 152
codingFriend1 Avatar answered Nov 04 '22 12:11

codingFriend1


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

  • https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/AndroidManifest.xml

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

  • https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/res/xml/file_paths.xml

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

  • https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/src/main/java/com/example/pdfshare/MainActivity.java
like image 10
Gene Bo Avatar answered Nov 04 '22 13:11

Gene Bo


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.

like image 1
RasenKoD Avatar answered Nov 04 '22 11:11

RasenKoD