Android 11下创建PDF提示成功但无法保存到内部存储问题求助
1. 核心原因:文件存储在应用专属目录,普通文件管理器默认不可见
你代码中调用getExternalFilesDir("/")获取的是应用专属外部存储目录,路径格式为:内部存储/Android/data/[你的应用包名]/files/
Android 11及以上系统对Android/data目录有访问限制,普通文件管理器默认无法直接访问该路径,所以你找不到生成的PDF文件,但文件实际上是存在的,你可以通过以下方式验证:
- 用Android Studio的Device File Explorer工具,进入上述路径查看
- 给系统自带文件管理器授权访问
Android/data目录后进入对应包名路径查找
2. 现有代码的其他问题
2.1 权限申请写法错误
你调用ActivityCompat.requestPermissions时,第三个参数传了PackageManager.PERMISSION_GRANTED,这是错误的:该参数应为自定义的整数请求码,用于后续权限申请结果的回调,你现在的写法等于权限申请逻辑完全没有正确执行。
不过由于getExternalFilesDir目录本身不需要申请任何存储权限即可访问,所以这个错误没有影响到PDF生成逻辑。
2.2 存储权限配置已失效
Android 11及以上系统中,WRITE_EXTERNAL_STORAGE权限已经完全废弃,android:requestLegacyExternalStorage="true"属性仅在Android 10系统上生效,对Android 11及更高版本没有作用,你现有配置的权限规则其实不生效。
2.3 提示文案拼写错误
你的成功提示Toast中"Sucessfull"拼写错误,正确拼写为"Successful",该问题不影响功能,仅属于显示细节问题。
3. 解决方案:生成公共可见的PDF文件
如果想要生成的PDF可以在普通文件管理器的公共目录(如下载、文档目录)直接查看,可以改用MediaStore API将文件写入公共外部存储,示例代码如下:
private void createPublicPDF() { PdfDocument myPdfDocument = new PdfDocument(); Paint myPaint = new Paint(); PdfDocument.PageInfo myPageInfo1 = new PdfDocument.PageInfo.Builder(250, 400, 1).create(); PdfDocument.Page myPage1 = myPdfDocument.startPage(myPageInfo1); Canvas canvas = myPage1.getCanvas(); canvas.drawText("Expert Laptops", 40, 50, myPaint); myPdfDocument.finishPage(myPage1); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ContentResolver resolver = getContentResolver(); ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "firstPDF.pdf"); contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf"); contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); Uri uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues); if (uri != null) { try { OutputStream outputStream = resolver.openOutputStream(uri); myPdfDocument.writeTo(outputStream); if (outputStream != null) { outputStream.close(); } Toast.makeText(MainActivity.this, "创建成功,文件在下载目录", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "创建失败", Toast.LENGTH_SHORT).show(); } } } myPdfDocument.close(); }
上述代码不需要申请任何存储权限,生成的PDF会直接保存在系统下载目录,普通文件管理器可以直接查看。
内容的提问来源于stack exchange,提问作者Salman Kadwani

