0

I am facing the below error in case of android version Nougat after capturing the image and showing in imageview but it is working in marshmallow.I have created Fileprovider path which is required for nougat.

below is the code for camera and cropping.

camera.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialogBuilder.dismiss();
                    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                   /* File file = new File(Environment.getExternalStorageDirectory() + File.separator + "img.jpg");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                    startActivityForResult(intent, 100);*/
                    file = new File(UploadIdActivtiy.this.getExternalCacheDir(),
                            String.valueOf(System.currentTimeMillis()) + ".jpg");
                    if (Build.VERSION.SDK_INT >= 24) {
                        uri = FileProvider.getUriForFile(UploadIdActivtiy.this,
                                BuildConfig.APPLICATION_ID + ".provider",
                                file);
                    }else{
                        uri = Uri.fromFile(file);
                    }
                     Log.d("camerapath==", uri.getPath());
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    startActivityForResult(intent, 100);
                }
            });

//cropping the captured image

private void performCrop() {
        try {
            UploadIdActivtiy.this.grantUriPermission("com.activatic.paychek",uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);


            UploadIdActivtiy.this.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

            Intent cropIntent = new Intent("com.android.camera.action.CROP");
            //indicate image type and Uri
            cropIntent.setDataAndType(uri, "image/*");

            cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            //set crop properties
            cropIntent.putExtra("crop", "true");
            //indicate aspect of desired crop
            cropIntent.putExtra("aspectX", 1);
            cropIntent.putExtra("aspectY", 1);
            //indicate output X and Y
            cropIntent.putExtra("outputX", 256);
            cropIntent.putExtra("outputY", 256);

            cropIntent.putExtra("outputFormat", "JPEG");
            cropIntent.putExtra("noFaceDetection", true);
            //retrieve data on return
            cropIntent.putExtra("return-data", true);

            if (Build.VERSION.SDK_INT >= 24) {

                uri = FileProvider.getUriForFile(UploadIdActivtiy.this,
                        BuildConfig.APPLICATION_ID + ".provider", createCropFile());

            } else
                uri = Uri.fromFile(createCropFile());
            //start the activity - we handle returning in onActivityResult
            cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            startActivityForResult(cropIntent, PIC_CROP);
        } catch (ActivityNotFoundException anfe) {
            //display an error message
            String errorMessage = "Whoops - your device doesn't support the crop action!";
            Toast toast = Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_SHORT);
            toast.show();
        }
    }

//createcropfile function

 private File createCropFile() {
        File storageDir = UploadIdActivtiy.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        //  path = path + (timeStamp + "1jpg");

        try {
            file = File.createTempFile(timeStamp, ".jpg", storageDir);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (Build.VERSION.SDK_INT >= 24)
            mCurrentPhotoPath = String.valueOf(FileProvider.getUriForFile(UploadIdActivtiy.this,
                    BuildConfig.APPLICATION_ID + ".provider", file));
        else
            mCurrentPhotoPath = String.valueOf(Uri.fromFile(file));
        return file;
    }

//OnActivtiy result

   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == -1) {

            if (requestCode == 100 ) {
                Log.e("Exception 100","resultCode >> "+resultCode);
                File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");

                Log.d("showimgfile","==="+file);
                Log.d("shosimg","%%=="+Uri.fromFile(file));


                try{
                    Log.d("shosimg","%%=="+file);
                    Log.d("shosimg","%%=="+Uri.fromFile(file));

                    //ImageCropFunction(Uri.fromFile(file));
//                    uri = data.getData();
                    performCrop();
                }catch (ActivityNotFoundException aNEF){
                    String errorMessage = "Sorry - your device doesn't support the crop action!";
                    Toast toast = Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_SHORT);
                    toast.show();
                }
            }

            else if (requestCode == 10) {
                Log.d("Exception 10", "resultCode >> " + resultCode);

                uri = data.getData();
                performCrop();
            }
            else if(requestCode == PIC_CROP){
                Log.d("imavalue==",""+img);
                if(img==200)
                {
                    Bundle extras = data.getExtras();
                    thePic_imgone = extras.getParcelable("data");

                    CheckCount_imgone = 1;
                    BitmapDrawable background = new BitmapDrawable(thePic_imgone);
                    llFront.setBackgroundDrawable(background);

                    iv_front.setVisibility(View.GONE);
                    txt_front.setVisibility(View.GONE);
                    //iv_front.setImageBitmap(thePic_imgone);

                }

                if(img==300)
                {
                    Bundle extras = data.getExtras();
                    thePic_imgtwo = extras.getParcelable("data");

                    CheckCount_imgtwo = 2;
                    BitmapDrawable background = new BitmapDrawable(thePic_imgtwo);
                    llBack.setBackgroundDrawable(background);

                    ivbackimage.setVisibility(View.GONE);
                    txt_back.setVisibility(View.GONE);
                    //ivbackimage.setImageBitmap(thePic_imgtwo);

                }
            }

        }else{
            Log.e("Exception", "resultCode >> " + resultCode);
        }
    }

//error which I am facing

   java.lang.SecurityException: Permission Denial: writing android.support.v4.content.FileProvider uri content://com.activatic.paychek.provider/external_files/Android/data/com.activatic.paychek/files/Pictures/20180323_103545290646785.jpg from pid=16668, uid=10046 requires the provider be exported, or grantUriPermission()
                                                                          at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:682)
                                                                          at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:497)
                                                                          at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:469)
                                                                          at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:384)
                                                                          at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:262)
                                                                          at android.os.Binder.execTransact(Binder.java:565)
sak
  • 1,230
  • 18
  • 37
Sunil P
  • 3,698
  • 3
  • 13
  • 20

2 Answers2

0

Have u added in your manifest? just add this in your manifest file

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

and your provider_path.xmlwill be as like

<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android">

Mohammad Arman
  • 508
  • 4
  • 13
0

It might be a bit late for the answer. I looked carefully in your code, there are something wrong I want to point out,

  1. You grant permission to an uri and then revoke it immediately. ???

  2. The uri which has access to READ WRITE permissions by addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |Intent.FLAG_GRANT_WRITE_URI_PERMISSION) don't need to use grantUriPermission() to it again.

  3. The most important part is that, you generate another uri then give it to putExtra(MediaStore.EXTRA_OUTPUT, uri)

This uri is the one that doesn't have the permission cause java.lang.SecurityException: Permission Denial ---> use grantUriPermission() for this uri will fix the problem!

BobTheCat
  • 470
  • 4
  • 11