FileProvider.getUriForFile returns NullPointerException

12,493

First, this:

android:authorities="${applicationId}.fileprovider"

does not match this:

private static final String AUTHORITY = "org.broadinstitute.jsnap.provider";

Use the same algorithm in both places. So, replace the second line with:

private static final String AUTHORITY = BuildConfig.APPLICATION_ID+".fileprovider";

That will get you past the NullPointerException.

Second, this:

File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FILENAME);

does not match this:

<external-path name="jsnap_images" path="Android/data/org.broadinstitute.jsnap/files/Pictures" />

Since I don't know which of those is what you really want, I cannot suggest a fix.

Share:
12,493
A.A.
Author by

A.A.

Updated on July 15, 2022

Comments

  • A.A.
    A.A. almost 2 years

    I'm trying to write my first android app, which will involve taking a picture and doing stuff with it.

    I've put together some code after looking at several tutorials online but am getting the following NullPointerException whenever the button is clicked:

    10-03 14:48:00.284 26310-26310/org.broadinstitute.jsnap E/MainActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
    10-03 14:48:00.293 26310-26310/org.broadinstitute.jsnap E/MYAPP: exception
                                                                     java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
                                                                         at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:583)
                                                                         at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:557)
                                                                         at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:399)
                                                                         at org.broadinstitute.jsnap.MainActivity.takePhoto(MainActivity.java:54)
                                                                         at org.broadinstitute.jsnap.MainActivity.access$000(MainActivity.java:24)
                                                                         at org.broadinstitute.jsnap.MainActivity$1.onClick(MainActivity.java:43)
                                                                         at android.view.View.performClick(View.java:6205)
                                                                         at android.widget.TextView.performClick(TextView.java:11103)
                                                                         at android.view.View$PerformClick.run(View.java:23653)
                                                                         at android.os.Handler.handleCallback(Handler.java:751)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6682)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
    

    I'm not quite sure how to resolve. Here's my relevant code:

    manifest:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="org.broadinstitute.jsnap">
    
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" android:required="true"/>
        <uses-feature android:name="android.hardware.camera.autofocus" />
        <uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            >
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <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/file_paths"></meta-data>
            </provider>
        </application>
    
    </manifest>
    

    file_paths.xml

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="jsnap_images" path="Android/data/org.broadinstitute.jsnap/files/Pictures" />
    </paths>
    

    And MainActivity:

    package org.broadinstitute.jsnap;
    
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.support.v4.content.FileProvider;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.Toast;
    import java.io.File;
    import java.io.IOException;
    import java.util.jar.Manifest;
    
    
    public class MainActivity extends Activity {
        private static String logtag = "MainActivity";
        private static int TAKE_PICTURE = 1;
        private static final String AUTHORITY = "org.broadinstitute.jsnap.provider";
        private static final String PHOTOS="photos";
        private static final String FILENAME="jsnap_test.jpeg";
        Uri imageURI;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button cameraButton = (Button)(findViewById(R.id.cam_button));
            cameraButton.setOnClickListener(cameraListener);
    
        }
        private View.OnClickListener cameraListener = new View.OnClickListener() {
            public void onClick(View v) {
                try {
                    takePhoto(v);
                } catch (Exception e) {
                    Log.e(logtag, e.toString());
                }
            }
        };
        private void takePhoto(View v){
            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
            File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FILENAME);
            imageURI=FileProvider.getUriForFile(this, AUTHORITY, photo);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageURI);
            // TAKE_PICTURE is a request code saying we want to use the rear-facing camera.
            startActivityForResult(intent, TAKE_PICTURE);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
            super.onActivityResult(requestCode, resultCode, intent);
    
            if(resultCode == Activity.RESULT_OK) {
                Uri selectedImage = imageURI;
                getContentResolver().notifyChange(selectedImage, null);
    
                ImageView imageView = (ImageView)findViewById(R.id.image_camera);
                ContentResolver cr = getContentResolver();
                Bitmap bitmap;
    
                try {
                    bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
                    imageView.setImageBitmap(bitmap);
                    Toast.makeText(MainActivity.this, selectedImage.toString(), Toast.LENGTH_SHORT).show();
                } catch(Exception e) {
                    Log.e(logtag, e.toString());
                }
            }
        }
    }
    

    Any help is greatly appreciated.

  • A.A.
    A.A. over 6 years
    Thanks! For the second issue, I had copied the code from a Google tutorial that suggested it be done that way if you want other apps to be able to access the photo. That would be nice but not essential for the app I'm trying to create. Mostly I'd like to just get a first iteration of the app working either way. So, do I need to make external-path point to an actual external directory in the android system?
  • A.A.
    A.A. over 6 years
    Also, I fixed the first issue you mentioned, and get a new error: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Pictures/jsnap_test.jpeg. This suggests as you said that file location in code and in xml aren't matching, but I'm not sure exactly what I should put in external-path...
  • CommonsWare
    CommonsWare over 6 years
    @AmrA.: If you want to keep the existing File, then <external-path name="jsnap_images" path="Pictures" /> should work.
  • A.A.
    A.A. over 6 years
    thanks, that change did work! Encountering another error now but it looks more familiar and I will try to figure it out before asking for more help!