首页 > 解决方案 > 将手机更新到 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();

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

标签: androidpermissionspdf-generationstorage

解决方案


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

按照这个链接

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


推荐阅读