documentfilehuawei-mobile-servicessaf

DocumentFile.createFile() failed on some Android 10 devices


DocumentFile.createFile() returns null ( java.lang.IllegalArgumentException ) on some Android 10 devices.
Most of them are HUAWEI devices: VOG-L29, MAR-LX1A, ...

Some users have reported this, but I can't figure out why. I don't have a device with this problem, so I can't test it.
It works without problems on most devices.
Has anyone solved this problem?

Uri treeUri = <from ACTION_OPEN_DOCUMENT_TREE result> ( content://com.android.externalstorage.documents/tree/4A21-0000:Photos )
DocumentFile docFile = DocumentFile.fromTreeUri( context, treeUri );
DocumentFile resultFile = docFile.createFile( "image/jpeg", "IMG_20200327_144048.jpg" );

resultFile is null !!!

Log received from user:

onActivityResult: requestCode=1,resultCode=-1,data=Intent { dat=content://com.android.externalstorage.documents/tree/4A21-0000:Photos flg=0xc3 }

DocumentsContract: Failed to create document
DocumentsContract: java.lang.IllegalArgumentException: Requested path /mnt/media_rw/4A21-0000/Photos/IMG_20200327_144048.jpg doesn't appear under [/system/media, /hw_product/hw_oem/VOG-L29/media, /system/product/media]
DocumentsContract:  at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
DocumentsContract:  at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
DocumentsContract:  at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
DocumentsContract:  at android.content.ContentResolver.call(ContentResolver.java:2080)
DocumentsContract:  at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1327)
...

Solution

  • Context: As many Huawei users have noticed, the update from EMUI 9 to EMUI 10 has broken a number of apps that rely on write access to the SD card. The problem has been reported to Huawei, who shifted the blame onto Google and does not seem to be taking any further action. The developer of the app Total Commander, which was affected by the problem, found out that

    On Huawei devices with Android 10, DocumentsContract.createDocument successfully creates the file, but then causes an exception

    and suspects that

    apparently Huawei hardcoded some paths where the user should be allowed to create files, but made a mistake.

    Hypothesis: Your users try to save files on their SD card via your app. You didn't mention that in your question, but based on the issue and the tree URI shown by the log, I assume this is the case.

    Solution: Even though createFile() returns null, the file has been properly created. You can use findFile() to get it:

    DocumentFile docFile = DocumentFile.fromTreeUri(context, treeUri);
    String filename = "IMG_20200327_144048"
    DocumentFile resultFile = docFile.createFile("image/jpeg", filename);
    
    if (resultFile == null) {
        resultFile = docFile.findFile(filename + ".jpg");
    }
    

    If at that point resultFile is still null, then I think it's another issue.

    Caveat: If there is already a file called "IMG_20200327_144048.jpg" in this directory, then createFile() will most likely create a file called "IMG_20200327_144048 (1).jpg", and calling findFile() as in the solution above will give you the old file, not the newly created one. You can handle that however you want, but I think it's beyond the scope of this question.