Getting IllegalArgumentException while capturing p

2019-08-31 14:53发布

问题:

In my project I am using FileProvider.getUriForFile with given provider_paths.xml file:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-files-path name="StrengGeheim" path="/" />
</paths>

This I added in my AndroidManifest.xml inside tag:

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

This is my camera Intent code:

private void cameraIntent() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    fileUri = getOutputMediaFileUri();
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, CAMERA);
}

private Uri getOutputMediaFileUri() {
    try {
        return FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider",getOutputMediaFile());
    }
    catch (IOException ex){
        ex.printStackTrace();
        Toast.makeText(getContext(), MESSAGE_FAILED, Toast.LENGTH_SHORT).show();
    }
    return null;
}

In file Uri the path is something like this /storage/emulated/0/StrengGeheim/06673da7-876f-4a53-9a3d-288ae033f7ac and the path of storing image from gallery is also same. But still I am getting below error while capturing photo and app is closing.

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.stegano.strenggeheim, PID: 19189
              java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/StrengGeheim/8bb91a47-d33f-428d-a6ee-1f974e61e63e.png
                  at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:712)
                  at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:401)
                  at com.stegano.strenggeheim.fragment.FragmentEncode.getOutputMediaFileUri(FragmentEncode.java:68)
                  at com.stegano.strenggeheim.fragment.FragmentEncode.cameraIntent(FragmentEncode.java:61)
                  at com.stegano.strenggeheim.fragment.FragmentEncode.access$100(FragmentEncode.java:35)
                  at com.stegano.strenggeheim.fragment.FragmentEncode$2.onClick(FragmentEncode.java:111)
                  at android.support.v7.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1044)
                  at android.widget.AdapterView.performItemClick(AdapterView.java:318)
                  at android.widget.AbsListView.performItemClick(AbsListView.java:1165)
                  at android.widget.AbsListView$PerformClick.run(AbsListView.java:3134)
                  at android.widget.AbsListView$3.run(AbsListView.java:4049)
                  at android.os.Handler.handleCallback(Handler.java:789)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6541)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

This is how I am handling OnActivityResult:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == getActivity().RESULT_CANCELED) {
        return;
    }
    try {
        if (requestCode == GALLERY && data != null) {

                    Bitmap bitmap = getBitmapFromData(data, getContext());
                    File mediaFile = getOutputMediaFile();
                    String path = saveImage(bitmap, mediaFile);
                    Log.println(Log.INFO, "Message", path);
                    Toast.makeText(getContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_SHORT).show();
                    loadImage.setImageBitmap(bitmap);
                    imageTextMessage.setVisibility(View.INVISIBLE);

        } else if (requestCode == CAMERA) {
                File file =  new File(fileUri.getPath());
                final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath());
                loadImage.setImageBitmap(bitmap);
                saveImage(bitmap, file);
                Toast.makeText(getContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_SHORT).show();
                imageTextMessage.setVisibility(View.INVISIBLE);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
        Toast.makeText(getContext(), MESSAGE_FAILED, Toast.LENGTH_SHORT).show();
    }
}

private Bitmap getBitmapFromData(Intent intent, Context context){
    Uri selectedImage = intent.getData();
    String[] filePathColumn = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver().query(selectedImage,filePathColumn, null, null, null);
    cursor.moveToFirst();
    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String picturePath = cursor.getString(columnIndex);
    cursor.close();
    return BitmapFactory.decodeFile(picturePath);
}

private String saveImage(Bitmap bmpImage, File mediaFile) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bmpImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
    try {
        FileOutputStream fo = new FileOutputStream(mediaFile);
        fo.write(bytes.toByteArray());
        MediaScannerConnection.scanFile(getContext(),
                new String[]{mediaFile.getPath()},
                new String[]{"image/png"}, null);
        fo.close();

        return mediaFile.getAbsolutePath();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return "";
}

Can someone help, please?

回答1:

<paths>
  <external-files-path name="StrengGeheim" path="/" />
</paths>

This configuration is for files stored under getExternalFilesDir(). That is not where your files are stored, based on your error. Change this to:

<paths>
  <external-path name="StrengGeheim" path="."/>
</paths>