I am working now on ImageCompressor app.
I need to delete
and write
(update) image file. In Internal storage works perfectly but **SD Card can't give me access to Delete and Write files.
How can my app able to do write
and delete
operation on sd card (removable storage)?
I've already done whole project without this, so I have to must find a way.
Update:
I am already research & discuss about this issue. And understood I have to use storage access framework
But I'm new on SAF.
I used a library to compress photo that need File not Uri. For that I do Uri -> File
and use Intent.ACTION_OPEN_DOCUMENT
and pick image from Removable storage.
But for removable storage I can't find Image Real Path from uri.
I don't know it's the right way or not. If there have any way in SAF where I can Compress my Image using uri, let me know. Or How to get Image real path from uri of Removable Storage Photo.
Update code SAF:
// ----------- Intent -------------
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// ------------ On Activity Result --------------
Uri uri = data.getData();
try {
ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fos = new FileOutputStream(fileDescriptor.getFileDescriptor());
FileInputStream fis = new FileInputStream(getImageFilePath(uri));
FileChannel source = fis.getChannel();
FileChannel destination = fos.getChannel();
destination.transferFrom(source, 0, source.size());
fis.close();
fos.close();
fileDescriptor.close();
Toast.makeText(this, "File save successfully.", Toast.LENGTH_SHORT).show();
}
Uri to File Path, I done where pick image from media apps(like Gallary, Photos) But pick from sd card what will instead of MediaStore.Images.Media.DATA
I don't know. Code:
private File getImageFilePath(Uri uri) throws IOException {
String image_id = null, imagePath = null;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
image_id = cursor.getString(0);
image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
cursor.close();
}
cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
if (cursor!=null) {
cursor.moveToFirst();
imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
}
File file = new File(imagePath);
return new Compressor(this).setQuality(50).compressToFile(file);
}
I digged into an old Android app of mine and retrieved this :
This method convert the root of the sdcard uri, to a File
path.
public File getRootPath(Context context, Uri sdcardRootUri)
{
List<String> pathSegments = sdcardRootUri.getPathSegments();
String[] tokens = pathSegments.get(pathSegments.size()-1).split(":");
for (File f : ContextCompat.getExternalFilesDirs(context, null))
{
String path = f.getAbsolutePath().substring(0, f.getAbsolutePath().indexOf("/Android/"));
if (path.contains(tokens[0]))
{
return new File(path);
}
}
return null;
}
And in order to retrieved the uri of the sdcard root, I used that :
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, SDCARD_ROOT_CODE);
Then the user would choose the root of the sdcard and then, I handled the result like this :
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK && requestCode == SDCARD_ROOT_CODE)
{
// Persist access permissions
Uri sdcdardRootUri = data.getData();
grantUriPermission(getPackageName(), sdcdardRootUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(sdcdardRootUri, takeFlags);
// Do whatever you want with sdcdardRootUri
}
}
I hope it's what you are looking for. With that you can read/write/delete any file you want on the sdcard.