After updating on Android R, my app can't loading albums' art.
Code below working on Android Q
Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId);
Size size = new Size(700, 700);
return contentResolver.loadThumbnail(uri, size, null);
And also code below working on Android P and earlier
private Bitmap getAlbumArt(int albumId) {
try (Cursor cursor = contentResolver.query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.AlbumColumns.ALBUM_ART},
_ID + "=?",
new String[]{String.valueOf(albumId)},
null)) {
if (cursor == null || !cursor.moveToFirst()) {
return null;
}
String artLink = cursor.getString(0);
return BitmapFactory.decodeFile(artLink);
}
}
The problem is that there is no information in documentation about extracting album art.
After updates file storage access policy this is not working.
Seems it was deprecated. Look there
Related
I have a custom folder in the Pictures directory, like this Pictures/MyFolder. It has images in MyFolder. Here is how to share the images using ContentResolver on MyFolder only. Or is any alternative ways to share the image. It is on android 11.
I queried images using the following snippets
String[] projection = new String[]{
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN};
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
Cursor cur = context.getContentResolver().query(images,
projection, // Which
// columns
// to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
orderBy + " DESC" // Ordering
);
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN);
do {
bucket = cur.getString(bucketColumn);
if (bucket.equals(context.getString(R.string.app_name))) {
date = cur.getString(dateColumn);
imagePath = listImageByFolder.get(bucket);
if (imagePath == null) {
imagePath = new ArrayList<String>();
}
imagePath.add(cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA)));
Uri x = Uri.withAppendedPath(MediaStore.Images.Media.INTERNAL_CONTENT_URI, String.valueOf(cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA))));
listImageByFolder.put(bucket, imagePath);
} ;
} while (cur.moveToNext());
While I try to share the image, Getting android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/WhatsTouch/1628090801008.jpg exposed beyond app through ClipData.Item.getUri() exception. Is any way to correct it or is any alternative way?
I am trying to get real path for Picked image in Android 10 but it's not working Iam using the folowing code its work fine in android 9
public static String getRealPathFromURI(Context context, Android.Net.Uri contentUri)
{
ICursor cursor = context.ContentResolver.Query(contentUri, null, null, null, null);
cursor.MoveToFirst();
String document_id = cursor.GetString(0);
document_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
cursor.Close();
cursor = context.ContentResolver.Query(
Android.Provider.MediaStore.Images.Media.ExternalContentUri,
null, MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new string[] { document_id }, null);
cursor.MoveToFirst();
String path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data));
cursor.Close();
return path;
}
Option1
After SDK 29.0 ,DATA is deprecated . Apps may not have filesystem permissions to directly access this path. Instead of trying to open this path directly, apps should use ContentResolver#openFileDescriptor(Uri, String) to gain access.
Here is a similar thread which you can refer .
Option 2
You could install the plugin Xam.Plugin.Media from nuget .
Usage
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
var path = file.Path;
For more details about the plugin you could check https://github.com/jamesmontemagno/MediaPlugin
We are trying to fetch the path of a file that is saved in SD Card, to pass on to a utility. However when we use the URI to open a cursor, only two columns are being fetched, the path (_data column) is missing. Please let me know how to fetch the path. The query works fine for any file that is in internal storage.
Scheme is "content".
Code snippet
cursor = context.getContentResolver().query(uri, null, null, null, null);
if (null != cursor && cursor.moveToFirst())
{
int testcolCount = cursor.getColumnCount();
for (int i = 0; i < testcolCount; i++)
{
String colName = cursor.getColumnName(i);
String colValue = cursor.getString(i);
System.out.println("" + i + ": " + colName + ":" + colValue + "\n");
}
//This prints only two columns, _display_name and _size
}
Don't try and get the path at all, with Android 10 and above file paths outside of your App's private directories are useless because you won't have permission to access them.
See https://developer.android.com/training/data-storage#scoped-storage
Use the contentResolver to get a FileDescriptor to pass on to the Utility
Note From https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA
This constant was deprecated in API level 29.
Apps may not have filesystem permissions to directly access this path. Instead of trying to open this path directly, apps should use ContentResolver#openFileDescriptor(Uri, String) to gain access.
try this code i am using this function to get real path from uri:
private String getRealPathFromURI(Context mContext, Uri contentURI) {
String result = null;
Cursor cursor = null;
try {
String[] proj = {MediaStore.Video.Media.DATA};
ContentResolver mContentResolver = mContext.getContentResolver();
String mime = mContentResolver.getType(contentURI);
cursor = mContentResolver.query(contentURI, proj, null, null, null);
if (cursor == null) {
return null;
} else {
cursor.moveToFirst();
int column_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if (column_index > -1)
result = cursor.getString(column_index);
cursor.close();
}
} catch (Exception e) {
return null;
} finally {
if (cursor != null)
cursor.close();
}
return result;
}
it will return a string which is real path of your file.
hope it will help you.
The default File manager was the one causing this problem - not returning "DATA" column and returning Authority as "com.lenovo.FileBrowser.FileProvider". When I used another file manager, the Authority was "media". Also got the path column using "DATA" while running the ContenResolver. Thanks to all for taking the effort to help out.
i want to get a contact photo (if he has one) from the callLog.
now i know i can get the number and then query the contacts provider for a contact id.
however i want to know if there is a better way one that directly get the photo uri from the callLog.calls table.
what makes me believe it might be possible is the fact that inside the documentation i ran across 2 interesting fields:
1)CACHED_LOOKUP_URI -The cached URI to look up the contact associated with the phone number, if it exists.
2)CACHED_PHOTO_ID - The cached photo id of the picture associated with the phone number, if it exists.
now if it can be done how, and if it cant be done than i would like to know what those fields are used for,
thx
You can get its ID. Then you have to retrieve the actual image from ContactsContract.
imageDataRow = c.getInt(c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_ID));
Cursor c = mContext.getContentResolver().query(ContactsContract.Data.CONTENT_URI, new String[]{
ContactsContract.CommonDataKinds.Photo.PHOTO
}, ContactsContract.Data._ID + "=?", new String[]{
Integer.toString(imageDataRow)
}, null);
byte[] imageBytes = null;
if (c != null) {
if (c.moveToFirst()) {
imageBytes = c.getBlob(0);
}
c.close();
}
Bitmap photo = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
Mostly, I have used Glide to set an image on view.
SDK>=23
c.getString(c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_URI));
SDK<23
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(num));
Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToNext()) {
image_uri = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
//Log.d(TAG, "image_uri "+image_uri);
}
if(cursor !=null)
cursor.close();
The following is my code for obtaining a thumbnail of a given image.
As of now, the exception that I'm getting is 'Cursor out of bounds'
I think that may be because I am not appending the image URL anywhere. I'm a little confused as to where to do that.
So 2 questions:
1. Where do I use the image URL of which I want to obtain a thumbnail
2. The for loop which is supposed to print column names prints nothing except the first statement 'COLUMN NAMES'
//get the corresponding thumbnail
String lastImageTakenPath = MyActivity.this.savedInstanceStateVariable.getString("lastImageTaken");
System.out.println("previous image is "+ lastImageTakenPath);
ContentResolver cr = getContentResolver();
if(cr != null){
String[] projection = { MediaStore.Images.Media._ID };
Cursor cursor = managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,projection,null,null,null);
//Cursor cursor = cr.query(lastImageTakenURI, null, null, null, null);
//Activity.startManagingCursor(cursor);
if(cursor != null){
String[] columnNames = cursor.getColumnNames();
System.out.println("COLUMN NAMES");
for(int i=0;i<columnNames.length; i++){
System.out.println(columnNames[i]);
}
/* 1. get the id of the image
* 2. use this id in the call, getThumbnails on MediaStore.Images.Thumbnails to obtain the
thumbnail
3.set the imageview's src to this thumbnail */
int imageID = cursor.getInt( cursor.getColumnIndex(MediaStore.Images.Media._ID) );
Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID) );
// Get original image ID
String url = uri.toString();
int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
// Get (or create upon demand) the micro thumbnail for the original image.
thumbnailLastImage = MediaStore.Images.Thumbnails.getThumbnail(cr, originalImageId, MediaStore.Images.Thumbnails.MICRO_KIND,null);
thumbnailImage.setImageBitmap(thumbnailLastImage);
}
else{
System.out.println("Cursor is NULL");
}
}
else{
Log.d(TAG,"ContentResolver is NULL");
}
I believe your test of if(cursor != null) is incorrect or at least insufficient. If the result of the query returns no thumbnails then you will still get a cursor where cursor.getCount() == 0 you may want to use that as your test.