I am getting audio files from specific folder and binding them on recyclerview. now i want Uri of each file so i can upload them one-by-one. i am using Cursor to get files. below is my code :
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.SIZE,MediaStore.Audio.AudioColumns.TITLE,android.provider.MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.DURATION,MediaStore.Audio.AudioColumns.TITLE};
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%/storage/emulated/0/Call%"},null);
if (c != null ) {
for (int i = 0; i < 50 && c.moveToNext(); ++i) {
// Create a model object.
POJO audioModel = new POJO();
long id = c.getLong(4);
String SIZE = c.getString(0); // Retrieve path.
String NAME = c.getColumnName(1); // Retrieve name.
String PATH = c.getString(2); // Retrieve album name.
String DURATION = c.getString(3); // Retrieve artist name.
Uri contentUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,id);
audioModel.setSize(SIZE);
audioModel.setName(NAME);
audioModel.setPath(PATH);
audioModel.setDuration(DURATION);
audioModel.setUri(contentUri);
Log.d("#", String.valueOf(contentUri));
arrayListFile.add(audioModel);
}
c.close();
}
return arrayListFile;
in contentUri i am getting this ( content://media/external/audio/media/0 ) . and what i want is
content://com.android.providers.media.documents/document/xyz.mp3. how can i do ??
why do not use MediaStore.Files.FileColumns.DATA ? the path can be also used to upload to server.
Please consider using (MediaStore.Audio.Media.DATA must be part of your projection):
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
Uri yourFileUri = Uri.parse(cursor.getString(column_index));
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?
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.
To query the MediaStore, I simply create an URI with the proper "base URI" and append the IMAGE_ID (which I have from the corresponding thumbnail). Then, I simply invoke the content resolver to get a cursor:
Long IMAGE_ID = 172712; // let's say we have this IMAGE_ID
Uri baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
baseUri = Uri.withAppendedPath(baseUri, ""+ IMAGE_ID);
// let's just get this one field, description
String[] projection = {MediaStore.Images.Media.DESCRIPTION};
Cursor c = getContext().getContentResolver().query(baseUri, projection, null, null, null);
if (!c.moveToFirst()) return -1;
String description = c.getString(0); // and we're done :-)
However, what if I want to set the MediaStore.Images.Media.DESCRIPTION field? Can I, somehow, invoke the update method?
Long IMAGE_ID = 172712; // same image...
Uri baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
baseUri = Uri.withAppendedPath(baseUri, ""+ IMAGE_ID);
// create an object with the value to set
ContentValues test_values = new ContentValues();
test_values.put(MediaStore.Images.Media.DESCRIPTION, "Some image text...");
// i.e., SQL like: UPDATE MEDIASTORE SET DESCRIPTION = "Some image text..." WHERE IMAGE_ID = 172712;
String sIMAGE_ID = "" + IMAGE_ID;
int res = getContext().getContentResolver().update(baseUri, test_values, MediaStore.Images.Media._ID + "= ?", new String[]{sIMAGE_ID }); // works fine!
The above code works fine (at least in the emulator, Nexus 7 device)! update sets the DESCRIPTION "field".
I am displaying all the sd card images in grid view.The thing is I have to display all the images which are there on external storage of the device and at the same time not to display the camera images.I know that for this I need to get either camera bucket id or bucket display name.I am not getting how to do this.So can anyone please help me how to do this..
Try this.You might need to modify this
public static ArrayList<String> getPathOfAllImages(Activity activity) {
ArrayList<String> absolutePathOfImageList = new ArrayList<String>();
String absolutePathOfImage = null;
String nameOfFile = null;
String absolutePathOfFileWithoutFileName = null;
Uri uri;
Cursor cursor;
int column_index;
int column_displayname;
int lastIndex;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaColumns.DATA,
MediaColumns.DISPLAY_NAME };
cursor = activity.managedQuery(uri, projection, null, null, null);
column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
column_displayname = cursor
.getColumnIndexOrThrow(MediaColumns.DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index);
nameOfFile = cursor.getString(column_displayname);
lastIndex = absolutePathOfImage.lastIndexOf(nameOfFile);
lastIndex = lastIndex >= 0 ? lastIndex
: nameOfFile.length() - 1;
absolutePathOfFileWithoutFileName = absolutePathOfImage
.substring(0, lastIndex);
if (absolutePathOfImage != null&& !absolutePathOfImage.equals("/sdcard/DCMI/")) {
absolutePathOfImageList.add(absolutePathOfImage);
}
}
Use absolutePathOfImageList to populate your grid view
Usualy camera images are stored in a particular folder,DCMI folder.Just dont display images that are in the DCMI folder,skip that folder while you search for images in your sd card
I am trying to get imagepath based on thumbail path , i have already tried solution from
android-getting-path-to-image-from-thumbnail, but it is based on gridview position, i am only retrieving specific images. Also i found one sample code from SO, the code is
private String getImagePathFromThumbPath(String thumbPath)
{
String imgPath=null;
// String[] projection = new String[] {MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID};
String[] imagesDataPath={ MediaStore.Images.Media.DATA ,MediaStore.Images.Media._ID};
//mResolver.query() requires android API 16
Cursor thumbnails = mResolver.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, imagesDataPath,MediaStore.Images.Thumbnails.DATA+"=?",new String[]{thumbPath}, null, null);
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor imageCursor = mResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, filePathColumn, MediaStore.Images.Media._ID + "=?", new String[] {thumbId}, null);
if (imageCursor != null && imageCursor.moveToFirst()) {
// Your file-path will be here
imgPath= imageCursor.getString(imageCursor.getColumnIndex(filePathColumn[0]));
}
return imgPath;
}
The above method is bit modified to suit my needs and it returns nothing on Toasting, please tell how to retrieve imagepath using thumbnail path?
After a long time and relentless try, the solution is here
1. You need to find the image id which is image unique id from images table in thumbnail table, query to thumbnail provider (MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI) if you do not understand it, refer here , specifically IMAGE_ID,
Step 1 is to get retrievedImageId.
retrievedImageId = Long.parseLong(cursor.getString(imageIdInImages));
2. Now using the retrievedImageId get the image path, by again querying the content provider, only this time query the Images media provider (MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
String getImagePathFromThumbPath(String thumbPath)
{
String imagePath = null;
if(thumbPath != null )
{
String[] columns_to_return = {MediaStore.Images.Thumbnails.IMAGE_ID};
String where = MediaStore.Images.Thumbnails.DATA+" LIKE ?";
long retrievedImageId = -1;
String valuesAre[] = {"%"+thumbPath};
Cursor cursor = getContentResolver().query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns_to_return, where, valuesAre, null);
if(cursor != null)
{
int imageIdInImages = cursor.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID);
for (cursor.moveToFirst();!cursor.isAfterLast(); cursor.moveToNext())
{
//STEP 1 to retrieve image ID
retrievedImageId = Long.parseLong(cursor.getString(imageIdInImages));
}
if(retrievedImageId != -1)
{
// STEP 2 Now
Log.i(TAG, "imageId-" + retrievedImageId);
String[] columnsReturn = {MediaStore.Images.Media.DATA};
String whereimageId = MediaStore.Images.Media._ID+" LIKE ?";
String valuesIs[] = {"%" + retrievedImageId};
Cursor mCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columnsReturn, whereimageId, valuesIs, null);
int rawDataPath= mCursor.getColumnIndex(MediaStore.Images.Media.DATA);
for (mCursor.moveToFirst();!mCursor.isAfterLast(); mCursor.moveToNext())
{
imagePath = mCursor.getString(rawDataPath);
}
}
}
}
return imagePath;
}
If you still have doubt or error/exception, leave comment!