Android 11: Primary directory (invalid) not allowed for content://media/external/file allowed directories are [Download, Documents]
I finally found a solution. I can't say it's a best solution but it works perfectly.
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + File.separator + "appFolderName";
to
folderPath = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + File.separator + "appFolderName";
I suppose in Android 11, they allowed to create folder/file in DOWNLOADS folder but not DOCUMENTS. Best regards.
Note for Huawei Developers: You just keep the current file writing strategy. No need to Android 11 special code for now. I tried the new file writing method and it crashed. Apperantly, they didn't fully implemented Android 11.
Related videos on Youtube
![Aykut Uludağ](https://i.stack.imgur.com/5FP44.jpg?s=256&g=1)
Aykut Uludağ
Education: BSc in Mechanical Engineering in Çankaya University. Current works: Android&System Developer in Turkish State Railways (TCDD). Mainly working on a tablet app which control/manage rail transportation system. Android&Huawei Developer in e-Nabız Project. Official health app in Turkey, has more than 20 million user. I sometimes work with other projects of Ministry of Health of Turkey. --Android App: https://play.google.com/store/apps/details?id=tr.gov.saglik.enabiz --Huawei App: https://appgallery.huawei.com/#/app/C101184181 Some other private/goverment projects. Developing Android apps since 2011. Published many apps/games on GooglePlay/HuaweiAppGallery/AppleAppstore. You can see some of them in Github. I like to work with: Java, XML, Kotlin, Swift Unity, C#, PHP-SQL-HTML-CSS, Wordpress, Arduino etc. I don't like to work with: C++, Objective-C
Updated on June 02, 2022Comments
-
Aykut Uludağ about 2 years
I am trying to create PDF file from base64 string. Because of Storage Update in Android 11, I have to change my code but I'm getting following error in Android 11 devices:
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)
This code create a PDF file and save it into folder.
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(); } }
This code is working for opening file
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); }
In addition to this error, folder.mkdirs() returns false in Android 11. Here is provider_paths.xml and defined in 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>
I google it but I couldn't find any working solution to fix problem. Thanks in advance.
-
Thomas about 3 yearsI'm no expert here but
values.put(MediaStore.DownloadColumns.RELATIVE_PATH, folderPath);
looks like you might have to put a path relative to the downloads directory, i.e."appFolderName"
in your case. Just a guess though. -
Thomas about 3 yearsI can't tell about the new error but on the previous one I'd have a question: what do
Environment.DIRECTORY_DOCUMENTS
andmContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
return? I'd assume the former acutally already describes the "Documents" directory you're working with while the latter might return null or an empty string thus resulting in a path like"/appFolderName"
. -
Aykut Uludağ about 3 yearsI found a solution. Apperantly there is no permission to write in documents in Android 11. But apperantly downloads folder are permissed to write folder/file.
-
-
valerybodak almost 3 yearsBut the function mContext.getExternalFilesDir(...) returns File. Not string.