-2

I have an app that uses camera it works fine when I compile it with targetSdkVersion 23, but when I try to use version 25 I get this error:

android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_1093948364.jpg exposed beyond app through ClipData.Item.getUri()

This is the code that I'm using:

private void showCameraAction() {
    if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED){
        requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
                getString(R.string.mis_permission_rationale_write_storage),
                REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
    }else {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
            try {
                mTmpFile = FileUtils.createTmpFile(getActivity());
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (mTmpFile != null && mTmpFile.exists()) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
                startActivityForResult(intent, REQUEST_CAMERA);
            } else {
                Toast.makeText(getActivity(), R.string.mis_error_image_not_exist, Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(getActivity(), R.string.mis_msg_no_camera, Toast.LENGTH_SHORT).show();
        }
    }
}

private void requestPermission(final String permission, String rationale, final int requestCode){
    if(shouldShowRequestPermissionRationale(permission)){
        new AlertDialog.Builder(getContext())
                .setTitle(R.string.mis_permission_dialog_title)
                .setMessage(rationale)
                .setPositiveButton(R.string.mis_permission_dialog_ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        requestPermissions(new String[]{permission}, requestCode);
                    }
                })
                .setNegativeButton(R.string.mis_permission_dialog_cancel, null)
                .create().show();
    }else{
        requestPermissions(new String[]{permission}, requestCode);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode == REQUEST_STORAGE_WRITE_ACCESS_PERMISSION){
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
            showCameraAction();
        }
    } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

What should I do? Thanks.

ilse2005
  • 11,189
  • 5
  • 51
  • 75
SIMMORSAL
  • 1,402
  • 1
  • 16
  • 32
  • please check this https://medium.com/@ali.muzaffar/what-is-android-os-fileuriexposedexception-and-what-you-can-do-about-it-70b9eb17c6d0 and also refer https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed – rajeshwaran Jun 28 '17 at 11:30
  • Please provide solutions as answers rather than updates to your question. This is to help future visitors and to avoid confusion. Thank you. – Bugs Jun 28 '17 at 12:53

2 Answers2

0

Your FileUtils.createTmpFile(getActivity()); probably uses file:// URI to share file with other app(in your case camera).

Android versions greater then 24 use content:// URIs instead, and will throw this exception when you try to share a file directly using the file:// URI.

A content URI allows you to grant read and write access using temporary access permissions

Take a look at FileProvider.

user3362334
  • 1,980
  • 3
  • 26
  • 58
  • A couple of lines below that i'm making a Uri (which links say is the problem), and i tried to write it like this: `Uri uri = FileProvider.getUriForFile(MultiImageSelectorFragment.this, MultiImageSelectorFragment.this.getApplicationContext().getPackageName() + ".provider" , mTmpFile);` but im getting an error with `getApplicationContext()` which is _Cannot resolve method 'getApplicationContext()'_ . any thought on how to fix it? – SIMMORSAL Jun 28 '17 at 12:05
0

SOLUTION:

Changed this:

            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));

To this:

            //getActivity() because its a fragment
            Uri uri = FileProvider.getUriForFile(getActivity(),
                    getActivity().getPackageName()
                    , mTmpFile);

            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

And it worked.

SIMMORSAL
  • 1,402
  • 1
  • 16
  • 32