android - 将手机更新到 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)进一步增强了平台,为外部存储上的应用和用户数据提供了更好的保护。此版本引入了多项增强功能,例如选择加入媒体的原始文件路径访问、媒体的批量编辑操作以及存储访问框架的更新 UI。
按照这个链接
https://developer.android.com/about/versions/11/privacy/storage
推荐阅读
- javascript - TypeScript - 将一个对象的所有属性分配给另一个对象的简写方式
- python - 将 PyTorch 变量设置为 float64
- php - laravel 将数据从表传递到表
- r - 如何将 dll 导入并使用到 R
- php - PHP - 将图像上传到多个目录
- c# - NLog 配置节处理程序在 Net Standard 中不可用
- jquery - 从 Chrome 扩展到 Wordpress 网站的 AJAX 请求
- mysql - MySql 用取决于其他表的值填充表
- bash - 仅迭代存储在 git 中的文件
- python - 迭代 pandas 系列,if 和 isin 以执行不同的操作