uygur
uygur

Reputation: 11

android-writing to a file denied in sd card

i'm trying to develop a simple file encrypter-decrypter app. on android devices.user picks whichever file he/she wants and encrypt or decrypt it using aes.this process is allowed for internal storage but when i choose a file in sd card it causes an error i can't find a solution for a long time.

i have permissions in manifest.xml:

<uses-permission 
    android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission 
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

also i ask user for runtime permissions(despite user allows permissions the result is "permission denied" error).

the error generated in th log is:

W/System.err: java.io.FileNotFoundException: storage/3962-3235/Download/dummyFileEncrypted.txt: open failed: EACCES (Permission denied)

where the error occurs in the encrypt function while the output file is being created, with line:

FileOutputStream outputStream=new FileOutputStream(outputFile);

as i said process works perfectly when i pick a file from internal storage.

any advice would be welcome. thanks in advance.

as of 22.04.22 here is my trial to delete a file in sd card: this is my file picker:

btnFileCh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //TODO buraya ipaul file chooser shower
            // Create the ACTION_GET_CONTENT Intent
            Intent getContentIntent = FileUtils.createGetContentIntent();
            Intent intent = Intent.createChooser(getContentIntent, "Select a file");
            startActivityForResult(intent, REQUEST_CHOOSER);
                       }
    });

public static Intent createGetContentIntent() {
    // Implicitly allow the user to select a particular kind of data
    final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    // The MIME data type filter
    intent.setType("*/*");
    // Only return URIs that can be opened with ContentResolver
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    return intent;
}

public static final int READ_WRITE_PERMISSIONS = Intent.FLAG_GRANT_READ_URI_PERMISSION
        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
public static void grantFileReadWritePermissions(Context targetUi, Intent intent, Uri uri) {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        List<ResolveInfo> resInfoList = targetUi.getApplicationContext()
                .getPackageManager()
                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            targetUi.getApplicationContext().grantUriPermission(packageName, uri, READ_WRITE_PERMISSIONS);
        }
    }
}

and onActivityResult event:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //TODO buraya ipaul file chooserdan dönen değerler ile işlemler
    switch (requestCode) {
        case REQUEST_CHOOSER:
            if (resultCode == RESULT_OK) {//
                if (data != null) {
                    final Uri uri = data.getData();// Get the URI of the selected file
                    try {//trial deletion
                        
                        FileUtils.grantFileReadWritePermissions(getApplicationContext(),data,uri);
                        DocumentsContract.deleteDocument(getApplicationContext().getContentResolver(),uri);
                        return;
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
        ...

but no deletion occurs and causes error:

2022-04-22 11:29:37.636 8288-8341/? E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: writing com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/3962-3235%3ADownload%2FdummyFile.txt from pid=8960, uid=10256 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
    at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:824)
    at com.android.externalstorage.ExternalStorageProvider.enforceWritePermissionInner(ExternalStorageProvider.java:149)
    at android.provider.DocumentsProvider.callUnchecked(DocumentsProvider.java:1163)
    at android.provider.DocumentsProvider.call(DocumentsProvider.java:1067)
    at com.android.externalstorage.ExternalStorageProvider.call(ExternalStorageProvider.java:611)
    at android.content.ContentProvider.call(ContentProvider.java:2173)
    at android.content.ContentProvider$Transport.call(ContentProvider.java:477)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:277)
    at android.os.Binder.execTransactInternal(Binder.java:1056)
    at android.os.Binder.execTransact(Binder.java:1029)

2022-04-22 11:29:37.646 8960-8960/com.example.basiccryptor E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.basiccryptor, PID: 8960
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1234, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/document/3962-3235:Download/dummyFile.txt flg=0x1 }} to activity {com.example.basiccryptor/com.example.basiccryptor.ActivityFilePicker}: java.lang.SecurityException: Permission Denial: writing com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/3962-3235%3ADownload%2FdummyFile.txt from pid=8960, uid=10256 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5230)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5271)
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2216)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:7948)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
 Caused by: java.lang.SecurityException: Permission Denial: writing com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/3962-3235%3ADownload%2FdummyFile.txt from pid=8960, uid=10256 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
    at android.os.Parcel.createException(Parcel.java:2088)
    at android.os.Parcel.readException(Parcel.java:2056)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
    at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
    at android.content.ContentResolver.call(ContentResolver.java:2049)
    at android.provider.DocumentsContract.deleteDocument(DocumentsContract.java:1422)
    at com.example.basiccryptor.ActivityFilePicker.onActivityResult(ActivityFilePicker.java:247)
    at android.app.Activity.dispatchActivityResult(Activity.java:8292)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5223)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5271) 
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2216) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:237) 
    at android.app.ActivityThread.main(ActivityThread.java:7948) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 

i guess i miss something in this mechanism but what?any suggestion?

Upvotes: 0

Views: 871

Answers (2)

blackapps
blackapps

Reputation: 9282

Yes, micro sd cards are read only since Android KitKat.

Only one app specific directory is writable for your app.

Have a look at the second item returned by getExternalFilesDirs() for writable location.

Or use Storage Access Framework if you wanna write at other locations.

Upvotes: 1

Related Questions