0

I was trying to make the camera intent work on higher APIs but its crashing when i try to. I think there is something wrong with some paths but i cant figure out what. Its running fine with API 23.

FATAL EXCEPTION: main
                                                                    Process: ur.mi.android.wgplus05, PID: 22088
                                                                    java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.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 ur.mi.android.wgplus05.Camera.takePicture(Camera.java:50)
                                                                        at ur.mi.android.wgplus05.PictureActivity.takePicture(PictureActivity.java:148)
                                                                        at ur.mi.android.wgplus05.PictureActivity.checkPermission(PictureActivity.java:140)
                                                                        at ur.mi.android.wgplus05.PictureActivity.onOptionsItemSelected(PictureActivity.java:101)
                                                                        at android.app.Activity.onMenuItemSelected(Activity.java:3204)
                                                                        at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:408)
                                                                        at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
                                                                        at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:113)
                                                                        at android.support.v7.app.AppCompatDelegateImplV9.onMenuItemSelected(AppCompatDelegateImplV9.java:679)
                                                                        at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
                                                                        at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:156)
                                                                        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:969)
                                                                        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:959)
                                                                        at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:623)
                                                                        at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:154)
                                                                        at android.view.View.performClick(View.java:5610)
                                                                        at android.view.View$PerformClick.run(View.java:22260)
                                                                        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:6077)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Line 50:

   Uri photoURI = FileProvider.getUriForFile(activityContext,
                    BuildConfig.APPLICATION_ID + ".genericfileprovider",
                    photoFile);


  public class Camera {
PictureActivity activityContext;
private String currentPhotoPath;

public Camera(PictureActivity activityContext) {
    this.activityContext = activityContext;
}

public void takePicture(int requestCode) {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(activityContext.getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            return;
        }
        // Continue only if the File was successfully created

        if (photoFile != null) {
            if(Build.VERSION.SDK_INT < 24){
            Uri photoURI = Uri.fromFile(photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            activityContext.startActivityForResult(takePictureIntent, requestCode);
        }
        else {
            Uri photoURI = FileProvider.getUriForFile(activityContext,
                    BuildConfig.APPLICATION_ID + ".genericfileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            activityContext.startActivityForResult(takePictureIntent, requestCode);
        }
        }
    }
}

public String getCurrentPhotoPath() {
    return currentPhotoPath;
}

public Bitmap getScaledBitmap(String path, Point targetSize) {
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, bmOptions);

    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;


    int scaleFactor = Math.min(photoW / targetSize.x, photoH / targetSize.y);

    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    Bitmap bitmap = BitmapFactory.decodeFile(path, bmOptions);

    return bitmap;
}

private File createImageFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(imageFileName, ".jpg", storageDir);

    currentPhotoPath = image.getAbsolutePath();

    return image;

}

}

Manifest:

  <?xml version="1.0" encoding="utf-8"?>

<uses-feature android:name="android.hardware.camera"
    android:required="true"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_icon_hdx"
    android:label="@string/app_name"
    android:roundIcon="@drawable/ic_icon_hdx"
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
    <activity android:name=".MainActivity">


        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".Finanzen" />
    <activity android:name=".Einkaufsliste" />
    <activity android:name=".Einkaufsliste2" />
    <activity android:name=".toDoList" />
    <activity android:name=".Settings" />
    <activity android:name=".PictureActivity" />
    <activity
        android:name=".Putzplan"
        android:windowSoftInputMode="adjustResize" />
    <activity android:name=".Kalender" />
    <provider
        android:name=".GenericFileProvider"
        android:authorities="${applicationId}.ur.mi.android.wgplus05.genericfileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
</application>
</manifest>

thats path

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

2 Answers2

1
android:authorities="${applicationId}.ur.mi.android.wgplus05.genericfileprovider"

BuildConfig.APPLICATION_ID + ".genericfileprovider"

These do not match. They need to match. Otherwise, FileProvider cannot find the ContentProvider, because you provided an invalid authority name to getUriForFile().

So, for example, you could change the first line to:

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

Then, the two values would match (application ID plus .genericfileprovider).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • okay if i do: android:authorities="${applicationId}.genericfileprovider" it should work? – boom3x Sep 15 '17 at 12:37
  • @boom3x: It should get you past that error, at least. You have other issues (`android.hardware.camera.autofocus` is not a permission, you are not holding onto `currentPhotoPath` in case of configuration changes or your process being terminated when the camera app is in the foreground). [This sample app](https://github.com/commonsguy/cw-omnibus/tree/v8.7/Camera/FileProvider) demonstrates how to use `ACTION_IMAGE_CAPTURE` with `FileProvider`. – CommonsWare Sep 15 '17 at 13:12
0

The second argument in getUriForFile should match the authorities attribute from the xml.

BuildConfig.APPLICATION_ID + ".ur.mi.android.wgplus05.genericfileprovider"