Reputation: 11
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
Reputation: 255
You should check they, I recommend using framework.
Upvotes: 0
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