简体   繁体   中英

java.io.IOException: Permission denied when using Camera on Andoid?

I have confirmed that the permissions are correct for Camera access, however on the later OS versions (perhaps API 25 and above) the camera does not open, it just gives the errror in debug console;

W/System.err: java.io.IOException: Permission denied

This is the method;

public void cameraClicked(View view) {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File tempFile = new File(Environment.getExternalStorageDirectory().getPath()+ "/photoTemp.png");
    try {
        tempFile.createNewFile();
        Uri uri = Uri.fromFile(tempFile);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        startActivityForResult(takePictureIntent, 2);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

It does work on Android 7 and below.

EDIT - The following code is now opening the camera correctly, however once the photo is taken it progresses to the next screen but does not show the captured image... Just a black image.

public void cameraClicked(View view) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String path=this.getExternalCacheDir()+"file.png";
        File file=new File(path);
    Uri uri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider",file);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            startActivityForResult(takePictureIntent, 2);
    }

W/System.err: java.io.IOException: Permission denied

This happened because you create file to external storage over Android8/9/10.

If your targetSdk is 23 or higher, you should request permissions dynamically. to know more: Requesting Permissions at Run Time

to get File path you can use Context.getExternalFilesDir()/Context.getExternalCacheDir() for example String path=Context.getExternalCacheDir()+"file.text"; File file=new File(path) it doesnt need permission if the filepath is "Android/data/app package/file name"

As in the Android Documentation, you need to write to the external storage, you must request the WRITE_EXTERNAL_STORAGE permission in your manifest file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   ...
</manifest>

If you use API 23 (Marshmallow) and above, you need to Requesting Permissions at Run Time because it's a Dangerous Permission.

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

Reference source link

reference

make file to external

Edit answer

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {        
    switch (requestCode){
        case 0:
            if (resultCode == Activity.RESULT_OK){
                Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
                SaveImage(thumbnail);                    
            }
            break;
    }
}


private static void SaveImage(Bitmap finalBitmap) {

    String root = Environment.getExternalStorageDirectory().getAbsolutePath();
    File myDir = new File(root + "/saved_images");
    myDir.mkdirs();

    String fname = "Image-"+ Math.random() +".jpg";
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete ();
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

I also faced this issue before, seems like adding this inside the Application tag under AndroidManifest.xml file solve the problem for me:

<application
    ...
    android:requestLegacyExternalStorage="true">
</application>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM