将手机更新到 Android 11 后无法保存 pdf 文件

问题描述

在我的一项活动中,我将图像保存在我的应用程序目录子文件夹中,在下一个活动中,我读取了 .png 文件并将其包含在带有其他一些数据的 pdf 文件中,然后将其保存在我的应用程序目录中,一切正常很好,直到我将手机从 Android 10 更新到 11。现在我收到此错误

E/main: error java.io.FileNotFoundException: /storage/emulated/0/IranianMasonryBuildings/sjdnnd -- Fri Feb 12 11:49:36 GMT+03:30 2021.pdf: open Failed: EPERM (Operation not permitted)

我在网上尝试了许多修复程序,但似乎都不起作用。

我的清单包括这些权限以及 requestLegacyExternalStorage = true

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

    android:requestLegacyExternalStorage="true"

compileSdkVersion 和 targetSdkVersion 设置为 29,我尝试将 API 级别更改为 28,如其他问题的一些答案中所述,但没有奏效。

这是我尝试创建 pdf 文件的方式:

private boolean isExternalStorageWritable(){
    if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
        Log.i("State","Yes,it is writable");
        return true;
    }else{
        return false;
    }
}

public boolean checkPermission(String permission){
    int check = ContextCompat.checkSelfPermission(this,permission);
    return (check == PackageManager.PERMISSION_GRANTED);
}

public void checkPermission(String permission,int requestCode)
{
    if (ContextCompat.checkSelfPermission(Results.this,permission)
            == PackageManager.PERMISSION_DENIED) {

        // Requesting the permission
        ActivityCompat.requestPermissions(Results.this,new String[] { permission },requestCode);
    }
    else {
        /*Toast.makeText(Results.this,"Permission already granted",Toast.LENGTH_SHORT)
                .show();*/
    }
}
@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode,permissions,grantResults);

    if (requestCode == STORAGE_PERMISSION_CODE){
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            /*Toast.makeText(Results.this,"Storage Permission Granted",Toast.LENGTH_SHORT)
                    .show();*/
        }
        else {
            Toast.makeText(Results.this,"Please grant access",Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE
};

public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity,Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE
        );
    }
}

public void writeExternalStorage (){
String state;
        state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) && 
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        try {
                //File storageDir2 = new File(Environment.getExternalStorageDirectory().toString(),"/IranianMasonryBuildings/BluePrints");
                File storageDir2 = new File(Environment.getExternalStorageDirectory().toString(),"/IranianMasonryBuildings");
                File f = new File(storageDir2,"BluePrint213.png");
                Bitmap blueprint2 = BitmapFactory.decodeStream(new FileInputStream(f));
         } catch (FileNotFoundException e) {
                e.printstacktrace();
            }

         PdfDocument myPdfDocument = new PdfDocument();
            Paint myPaint = new Paint();

            // Create a page description
            PdfDocument.PageInfo myPageInfo1 = new PdfDocument.PageInfo.Builder(PageWidth,PageHeight,PageNumber).create();

            // start a page
            PdfDocument.Page myPage1 = myPdfDocument.startPage(myPageInfo1);
            Canvas canvas = myPage1.getCanvas();
            myPaint = new Paint();

            myPaint.setStyle(Paint.Style.stroke);
            myPaint.setstrokeWidth(3);
            canvas.drawRect(200,250,1900,2600,myPaint);


            myPdfDocument.finishPage(myPage1);

            File storageDir = new File(Environment.getExternalStorageDirectory().toString(),"/IranianMasonryBuildings");
            storageDir.mkdirs(); // make sure you call mkdirs() and not mkdir()
            boolean wasSuccessful = storageDir.mkdirs();
            if (!wasSuccessful) {
                //Toast.makeText(getApplicationContext(),"mkdirs was not Successful  ",Toast.LENGTH_LONG).show();
            }


            File file2 = new File(storageDir,ProjectName + " -- " + Today + ".pdf");
            try {
                myPdfDocument.writeto(new FileOutputStream(file2));
                Toast.makeText(this,"The results are saved in" + "IranianMasonryBuildings",Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                Log.e("main","error " + e.toString());
                Toast.makeText(this,"Error!" + e.toString(),Toast.LENGTH_LONG).show();
            }

            // close the document
            myPdfDocument.close();

任何想法是什么导致了问题以及如何解决

解决方法

Android 11(API 级别 30)进一步增强了平台,为外部存储上的应用和用户数据提供更好的保护。此版本引入了多项增强功能,例如选择加入媒体的原始文件路径访问、媒体的批量编辑操作以及更新的存储访问框架用户界面。

点击此链接

https://developer.android.com/about/versions/11/privacy/storage