How delete image by Uri using scoped storage android 10? - android

How I can delete image by Uri using scoped storage android 10?
I saved my images to this scoped
final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + "myApp" + File.separator + constants.PhotoDirName;
ContentResolver resolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
I need to delete an image using Uri using this code
String[] projection;
projection = new String[]{MediaStore.MediaColumns._ID};
Uri externalUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = context.getContentResolver().query(externalUri, projection,
MediaStore.MediaColumns.DISPLAY_NAME + " LIKE ?", new String[]{displayName}, null);
assert cursor != null;
cursor.moveToFirst();
if (cursor.getCount() > 0) {
int columnIndex = cursor.getColumnIndex(projection[0]);
long fileId = cursor.getLong(columnIndex);
cursor.close();
Uri uri= Uri.parse(externalUri.toString() + "/" + fileId);
if (uri != null) {
final ContentResolver resolver = context.getContentResolver();
String[] selectionArgsPdf = new String[]{displayName};
try {
resolver.delete(uri, MediaStore.MediaColumns.DISPLAY_NAME + "=?", selectionArgsPdf);
} catch (Exception ex) {
ex.printStackTrace();
// show some alert message
}
}
}
But the image did not deleted!!
this error appears
android.app.RecoverableSecurityException: com.xxxx.xxxx has no access to content://media/external/images/media/11774

Related

How to access files created by other apps with mediastore on Android?

I am able to read the file i created with mediastore in android 10
But I can't read files created by other apps
'java.io.IOException: setDataSource failed.: status=0x80000000' error occurs when trying to access mediaPlayer from other apps
How can I read files created by other apps?
Below is the code to get the list of files in the MUSIC folder
public void getFileListInFolderApiQ(String path) {
mDataSet.clear();
Uri externalUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=?";
String[] selectionArgs = new String[]{Environment.DIRECTORY_MUSIC + "/" + "tts" + "/"};
String[] projection = new String[]{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.MIME_TYPE
};
Cursor cursor = getContentResolver().query(externalUri, projection, selection, selectionArgs, null);
Uri testUri = null;
if (cursor == null || !cursor.moveToFirst()) {
return;
}
do {
String contentUrl = externalUri.toString() + "/" + cursor.getString(0);
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
Uri uri = ContentUris.withAppendedId(externalUri, id);
String tmpFilename = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME));
testUri = uri;
mDataSet.add(new CustomTTSListData(tmpFilename, getPathFromUri(testUri), 1, 1, uri));
} while (cursor.moveToNext());
}

How to get URI from filename which is saved in the external Storage using Scoped Storage in android 10 and above?

Before SDK 29 this is the correct way to find the Uri but now it won't work anymore for sdk greater than 28. Let's assume I save the BITMAP using scoped-storage like:
#RequiresApi(api = Build.VERSION_CODES.Q)
#NonNull
private Uri saveBitmap(#NonNull final Context context, #NonNull final Bitmap bitmap,
#NonNull final Bitmap.CompressFormat format, #NonNull final String mimeType,
#NonNull final String displayName, #Nullable final String subFolder) throws IOException {
String relativeLocation = Environment.DIRECTORY_PICTURES;
if (!TextUtils.isEmpty(subFolder)) {
relativeLocation += File.separator + subFolder;
}
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
final ContentResolver resolver = context.getContentResolver();
OutputStream stream = null;
Uri uri = null;
try {
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
uri = resolver.insert(contentUri, contentValues);
if (uri == null) {
throw new IOException("Failed to create new MediaStore record.");
}
stream = resolver.openOutputStream(uri);
if (stream == null) {
throw new IOException("Failed to get output stream.");
}
if (!bitmap.compress(format, 95, stream)) {
throw new IOException("Failed to save bitmap.");
}
return uri;
} catch (IOException e) {
if (uri != null) {
// Don't leave an orphan entry in the MediaStore
resolver.delete(uri, null, null);
}
throw e;
} finally {
if (stream != null) {
stream.close();
}
}
}
This code works for SDK <= 28. But, How to get URI using fileName which is saved in the external storage for SDK version 29 and above?
private String getFilePathUri(String enteredFileName) {
String file_uri_string = Environment.getExternalStorageDirectory() + "/"
+ AppConstants.APP_FOLDER + "/" + enteredFileName + ".jpg";
AppUtils.showLog(TAG, file_uri_string + "");
return file_uri_string;
}
Android 10 and above: Here the uri gives the file_id based you the given displayName.
/**
* Returns the Uri which can be used to delete/work with images in the photo gallery.
* #param displayName Path to IMAGE on SD card
* #return Uri in the format of... content://media/external/images/media/[NUMBER]
*/
private Uri getUriFromPath(String displayName) {
long photoId;
Uri photoUri = MediaStore.Images.Media.getContentUri("external");
String[] projection = {MediaStore.Images.ImageColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = getContentResolver().query(photoUri, projection, MediaStore.Images.ImageColumns.DISPLAY_NAME + " LIKE ?", new String[] { displayName }, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
photoId = cursor.getLong(columnIndex);
cursor.close();
return Uri.parse(photoUri.toString() + "/" + photoId);
}

How can I list all the files in directory using Medistore (Android 10/Q)?

I want to query all of the files in a folder called as memories through the Mediastore API. I have tried looking at these questions but didn't get an appropriate answer.
https://android.jlelse.eu/handling-files-in-code-after-the-android-10-released-2bea0e16d35
https://developer.android.com/training/data-storage/shared/media#query-collection
How to I read and write a txt file from android 10 and above from internal storage
How to get the path of a specific folder in Android Q
How do I list all file in a directory in android 10 using Android Studio?
EDIT: Abs Path: imageUri: content://media/external/images/media/31
EDIT: How I save the image:
private void saveImage(Bitmap bitmap, #NonNull String name) throws IOException {
boolean saved;
OutputStream fos;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentResolver resolver = getContext().getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/" + IMAGES_FOLDER_NAME);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
Log.d(TAG, "imageUri: " + imageUri);
fos = resolver.openOutputStream(imageUri);
} else {
String imagesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).toString() + File.separator + IMAGES_FOLDER_NAME;
File file = new File(imagesDir);
if (!file.exists()) {
file.mkdir();
}
File image = new File(imagesDir, name + ".png");
Log.d(TAG, "File file: " + image);
fos = new FileOutputStream(image);
}
saved = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
Log.d(TAG, "Bitmap Image AndroidQ: " + saved);
fos.flush();
fos.close();
}
EDIT:
I looked up many questions with the tag Mediastore and formed this solution but I am not able to write SQLite Placeholder syntax so can anyone help me with that. #blackapps
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "/DCIM/" + IMAGES_FOLDER_NAME;
String[] selectionArgs = new String[] {"%memories%"};
try (Cursor cursor = requireContext().getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null
)) {
assert cursor != null;
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
Log.d(TAG, "name column: " + nameColumn);
while (cursor.moveToNext()) {
String name = cursor.getString(nameColumn);
byte[] bytes = name.getBytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Log.d(TAG, "file name: " + name);
imageList.add(bitmap);
}
}
You can do like this
fun getFiles(var directory_name){
var selection: String
selection = MediaStore.Files.FileColumns.RELATIVE_PATH+ " =? "
var selectionArgs = arrayOf(directory_name)
val cursor: Cursor? = contentResolver.query(
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY),
null,
selection,
selectionArgs,
null
)
}
you need to iterate cursor with do while loop or any other
function call:
getFiles(Lyrics/) //folder name from internal meomery if you want to use sd card then use MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL). I have tested this and its working fine for me

How to get albums from mediastore in Android Q?

I am trying to get Images and videos from Media store (album wise).It is working properly in devices having OS version < 10. In Android Q i am getting an syntax error.
System.err: android.database.sqlite.SQLiteException: near "GROUP": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT _id, _data, date_modified, bucket_display_name, media_type FROM files WHERE ((is_pending=0) AND (is_trashed=0) AND (volume_name IN ( 'external_primary' ))) AND ((media_type=1 OR media_type=3) GROUP BY (bucket_display_name)) ORDER BY bucket_display_name ASC
I am using below code to get data.
Uri queryUri = MediaStore.Files.getContentUri("external");
Uri intqueryUri = MediaStore.Files.getContentUri("internal");
String[] projection = {MediaStore.Images.Media._ID,
MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.DATE_MODIFIED,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Files.FileColumns.MEDIA_TYPE};
// Return only video and image metadata.
String selection;
selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
Cursor cursorExternal,cursorInternal;
cursorExternal = getContentResolver().query(queryUri, projection, selection+") GROUP BY (bucket_display_name",
null, MediaStore.Images.Media.BUCKET_DISPLAY_NAME+" ASC");
cursorInternal = getContentResolver().query(intqueryUri, projection, selection+") GROUP BY (bucket_display_name",
null, MediaStore.Images.Media.BUCKET_DISPLAY_NAME+" ASC");
Cursor cursor = new MergeCursor(new Cursor[]{cursorExternal, cursorInternal});
while (cursor.moveToNext()) {
path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
Log.w( "album:** ",album+"" );
HashMap<String, String> listData = Function.mappingInboxAlbum(album, path, countPhoto);
if (!albumList.contains(listData)) {
albumList.add(listData);
}
}
cursor.close();
I googled it but not getting any solution.
Please help...
Add this line in AndroidManifest :
android:requestLegacyExternalStorage="true"
Here is my approach:
first you will need the album_id
Uri path = Uri
.parse("content://media/external/audio/albumart");
Bitmap bmp = Album.getAlbumart(getActivity(), Long.parseLong(album_id), path);
then
public Bitmap getAlbumart(Context context, long album_id, Uri sArtworkUri) {
Bitmap bm = null;
try {
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
}
} catch (Exception e) {
}
return bm;
}
finally to display use Glide library
try {
Glide.with(mContext)
.load(uri)
.asbitmap
.error(Glide.with(ivcircle).load(R.drawable.playlist))
.into(ivcircle);
} catch (Exception e) {
e.printStackTrace();
}
you can use this method
public static ArrayList<Album> loadAlbum(Context context) {
ContentResolver contentResolver = context.getContentResolver();
ArrayList<Album> albumList = new ArrayList<>();
Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String[] projection = new String[]
{
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ARTIST,
MediaStore.Audio.Albums.NUMBER_OF_SONGS
};
//String sortOrder = MediaStore.Audio.Albums.ALBUM + " ASC";
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ARTIST));
int numberOfSongs = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS));
// Save to albumList
albumList.add(new Album(title, artist, numberOfSongs));
}
}
assert cursor != null;
cursor.close();
return albumList;
}

Converting android image URI

i am getting below type of uri:
/mnt/sdcard/Pictures/WW/ww_1360248819300.jpg
how to convert above type of URI to below URI:
content://media/external/images/media/12
please help
Thanks
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}

Categories

Resources