Android 11:内容不允许的主目录(无效)://media/external/file 允许的目录是 [下载,文档]
Android 11: Primary directory (invalid) not allowed for content://media/external/file allowed directories are [Download, Documents]
我正在尝试从 base64 字符串创建 PDF 文件。由于 Storage Update in Android 11,我必须更改我的代码,但在 Android 11 台设备中出现以下错误:
java.lang.IllegalArgumentException: Primary directory (invalid) not allowed for content://media/external/file; allowed directories are [Download, Documents]
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:549)
at android.content.ContentResolver.insert(ContentResolver.java:2149)
at android.content.ContentResolver.insert(ContentResolver.java:2111)
此代码创建一个 PDF 文件并将其保存到文件夹中。
public static void createPDF(Context mContext, String fileName, String base64) {
try {
String folderPath;
File dwldsPath;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
dwldsPath = new File(folderPath + "/" + fileName);
File folder = new File(folderPath);
folder.mkdirs();
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); // file name
values.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf"); // file extension, will automatically add to file
values.put(MediaStore.DownloadColumns.RELATIVE_PATH, folderPath); // end "/" is not mandatory
Uri uriFile = mContext.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); // important!
OutputStream outputStream = mContext.getContentResolver().openOutputStream(uriFile);
outputStream.write(Base64.decode(base64, 0));
outputStream.close();
} else {
folderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
dwldsPath = new File(folderPath + "/" + fileName);
File folder = new File(folderPath);
folder.mkdirs();
FileOutputStream os = new FileOutputStream(dwldsPath, false);
os.write(Base64.decode(base64, 0));
os.flush();
os.close();
}
openPDF(mContext, dwldsPath);
} catch (IOException e) {
e.printStackTrace();
} catch (ActivityNotFoundException e) {
Toast.makeText(mContext, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}
}
此代码可用于打开文件
public static void openPDF(Context mContext, File dwldsPath) {
Intent intentUrl = new Intent(Intent.ACTION_VIEW);
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", dwldsPath);
intentUrl.setDataAndType(uri, "application/pdf");
intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentUrl.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(intentUrl);
}
除此错误外,folder.mkdirs() returns false in Android 11。这里是provider_paths.xml和在 AndroidManifest.xml
中定义
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
</paths>
我 google 它,但我找不到任何有效的解决方案来解决问题。提前致谢。
我终于找到了解决办法。我不能说这是最好的解决方案,但效果很好。
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
至
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + File.separator + "appFolderName";
我想在 Android 11 中,他们 允许在 DOWNLOADS 文件夹中创建 folder/file 但 不允许创建 DOCUMENTS .最好的问候。
华为开发者注意:你只需要保持当前的文件写入策略即可。现在不需要 Android 11 特殊代码。我尝试了新的文件写入方法,它崩溃了。显然,他们没有完全实施 Android 11.
我正在尝试从 base64 字符串创建 PDF 文件。由于 Storage Update in Android 11,我必须更改我的代码,但在 Android 11 台设备中出现以下错误:
java.lang.IllegalArgumentException: Primary directory (invalid) not allowed for content://media/external/file; allowed directories are [Download, Documents]
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:549)
at android.content.ContentResolver.insert(ContentResolver.java:2149)
at android.content.ContentResolver.insert(ContentResolver.java:2111)
此代码创建一个 PDF 文件并将其保存到文件夹中。
public static void createPDF(Context mContext, String fileName, String base64) {
try {
String folderPath;
File dwldsPath;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
dwldsPath = new File(folderPath + "/" + fileName);
File folder = new File(folderPath);
folder.mkdirs();
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); // file name
values.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf"); // file extension, will automatically add to file
values.put(MediaStore.DownloadColumns.RELATIVE_PATH, folderPath); // end "/" is not mandatory
Uri uriFile = mContext.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); // important!
OutputStream outputStream = mContext.getContentResolver().openOutputStream(uriFile);
outputStream.write(Base64.decode(base64, 0));
outputStream.close();
} else {
folderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
dwldsPath = new File(folderPath + "/" + fileName);
File folder = new File(folderPath);
folder.mkdirs();
FileOutputStream os = new FileOutputStream(dwldsPath, false);
os.write(Base64.decode(base64, 0));
os.flush();
os.close();
}
openPDF(mContext, dwldsPath);
} catch (IOException e) {
e.printStackTrace();
} catch (ActivityNotFoundException e) {
Toast.makeText(mContext, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}
}
此代码可用于打开文件
public static void openPDF(Context mContext, File dwldsPath) {
Intent intentUrl = new Intent(Intent.ACTION_VIEW);
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", dwldsPath);
intentUrl.setDataAndType(uri, "application/pdf");
intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentUrl.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(intentUrl);
}
除此错误外,folder.mkdirs() returns false in Android 11。这里是provider_paths.xml和在 AndroidManifest.xml
中定义<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
</paths>
我 google 它,但我找不到任何有效的解决方案来解决问题。提前致谢。
我终于找到了解决办法。我不能说这是最好的解决方案,但效果很好。
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
至
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + File.separator + "appFolderName";
我想在 Android 11 中,他们 允许在 DOWNLOADS 文件夹中创建 folder/file 但 不允许创建 DOCUMENTS .最好的问候。
华为开发者注意:你只需要保持当前的文件写入策略即可。现在不需要 Android 11 特殊代码。我尝试了新的文件写入方法,它崩溃了。显然,他们没有完全实施 Android 11.