Permission Denied but permission is set in manifes

2019-07-29 14:24发布

问题:

I receive this error:

remove failed: ENOENT (No such file or directory) : /storage/emulated/0/screenShot.jpg
FileNotFoundException: /storage/emulated/0/screenShot.jpg: open failed: EACCES (Permission denied)

while running this screenshot method (the error points at the FileOutputStream creation from the imageFile, after "else"):

public void shareScreenshot(View v){
    Date now = new Date();
    android.text.format.DateFormat.format("yyyy-MM-dd_hh-mm-ss", now);

    CharSequence nowStr = DateFormat.format("yyyy-MM-dd_hh-mm-ss", now);

    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = Environment.getExternalStorageDirectory().toString() + "/" + "screenShot" + ".jpg";

        // create bitmap screen capture
        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);

        File imageFile = new File(mPath);
        if(imageFile.delete()){

            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();

            startShareIntent(imageFile);

        }else{

            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();

            startShareIntent(imageFile);
        }


    } catch (Throwable e) {
        // Several error may come out with file handling or OOM
        e.printStackTrace();
        Toast.makeText(this,"Something went wrong, try again.", Toast.LENGTH_SHORT).show();

    }
}

And here's my manifest:

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

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.android.vending.BILLING" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

回答1:

To request permission at runtime use this function which checks for version's 23 above as well as below

public  boolean isPermissionGrantedForStorage() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {

            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { 
         //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
}

Make sure your Activity implements OnRequestPermissionResult

Now callback for this will be

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
        Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
        //resume tasks needing this permission
    }
}

More over you are not writing anything to FileOutputStream. Without writing how can you expect to get the image stored !

Ideally it should be this way

ByteArrayOutputStream bytearrayoutputstream;
File file;
FileOutputStream fileoutputstream;

@Override
 protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      bytearrayoutputstream = new ByteArrayOutputStream();
      // you code to access image and other logic ...
      Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
      bitmap.compress(Bitmap.CompressFormat.PNG, 60, bytearrayoutputstream);
      file = new File( Environment.getExternalStorageDirectory() + "/SampleImage.png");
     try 
      {
      file.createNewFile();
      fileoutputstream = new FileOutputStream(file);
      fileoutputstream.write(bytearrayoutputstream.toByteArray()); 
      fileoutputstream.close();
      } 
      catch (Exception e) 
      {
           e.printStackTrace();
      } 
}

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



回答2:

As of API level 23 and higher camera permission needs to be requested at runtime

Change your onCreate code to:

if (PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)) { // asks primission to use the devices camera

 //what ever you want to do ..

} else {
    requestWritePermission(MainActivity.this);
}

and add the function

private static void requestWritePermission(final Context context) {
    if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.CAMERA)) {
        new AlertDialog.Builder(context)
                .setMessage("This app needs permission to use The phone Camera in order to activate the Scanner")
                .setPositiveButton("Allow", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, 1);
                    }
                }).show();

    } else {
        ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, 1);
    }
}

add these lines and try again. Also for more input read the flowing articale:

https://developer.android.com/training/permissions/requesting.html



回答3:

it showing this error because there is no such file in that folder as you specified in this code. may be something wrong with your filename specified by you. while taking screenshot it save with its app name.