首页 > 解决方案 > Runtime permission was granted but still getting the error java.io.FileNotFoundException: /storage/emulated/0/... .jpg (Permission denied)

问题描述

my program needs to share screenshots. However I have some problems with Runtime permissions. I'm giving the grant but still getting the error (Permission denied). Program works perfectly for the older versions and it works for Oreo when I delete the runtime permission part and give permission manually.

I used these links while I was creating the takeScreenshot() and shareImage() functions:

How to programmatically take a screenshot?

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

and creating the runtime permission part: https://www.youtube.com/watch?v=SMrB97JuIoM

public class MainActivity extends AppCompatActivity {

private int STORAGE_PERMISSION_CODE = 1;

private void requestStoragePermission(){
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)){
        new AlertDialog.Builder(this).setTitle("Permission Needed").setMessage("Permission needed to share screenshot").setPositiveButton("Okay", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

                ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
            }
        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        }).create().show();
    } else {
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode == STORAGE_PERMISSION_CODE){
        if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(this, "Not Granted", Toast.LENGTH_SHORT).show();
        }
    }
}

private void takeScreenshot() {
    Date now = new Date();
    android.text.format.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() + "/" + now + ".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);

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

        //openScreenshot(imageFile);
        shareImage(imageFile);
    } catch (Throwable e) {
        // Several error may come out with file handling or DOM
        e.printStackTrace();
    }
}

private void shareImage(File imageFile){
    Uri uri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".my.package.name.provider", imageFile);

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.setType("image/*");

    intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
    intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    try {
        startActivity(Intent.createChooser(intent, "Share Screenshot"));
    } catch (ActivityNotFoundException e) {
        Toast.makeText(this, "No App Available", Toast.LENGTH_SHORT).show();
    }
}

Button share;

Main:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED);

    else
        requestStoragePermission();

    share = (Button)findViewById(R.id.share);
    share.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            takeScreenshot();
        }
    });

}

}

Manifest.xml

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

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

</application>

Error when I press the share button

java.io.FileNotFoundException: /storage/emulated/0/Thu Nov 29 19:10:39 

GMT+03:00 2018.jpg (Permission denied)
11-29 19:10:39.827 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at java.io.FileOutputStream.open0(Native Method)
11-29 19:10:39.827 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at java.io.FileOutputStream.open(FileOutputStream.java:287)
11-29 19:10:39.827 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
11-29 19:10:39.827 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at com.example.serkan.oylesinedenemeler.MainActivity.takeScreenshot(MainActivity.java:78)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at com.example.serkan.oylesinedenemeler.MainActivity.access$100(MainActivity.java:27)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at com.example.serkan.oylesinedenemeler.MainActivity$3.onClick(MainActivity.java:128)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.view.View.performClick(View.java:6256)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.view.View$PerformClick.run(View.java:24710)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.os.Handler.handleCallback(Handler.java:789)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:98)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.os.Looper.loop(Looper.java:251)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6589)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
11-29 19:10:39.828 21814-21814/com.example.serkan.oylesinedenemeler W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

标签: javaandroidruntime-permissions

解决方案


您可能需要 WRITE_EXTERNAL_STORAGE(而不是 READ)?

另外,考虑使用getExternalStoragePublicDirectory


推荐阅读