How to get the Uri from MediaStore via file path?
In my program, I want to save a selected ringtone by it's file path, and then set it as the current ringtone later.
I have got the ringtone uri from RingtonePreference, and get the file path of it from MediaStore database.
e.g.
Uri - content://media/internal/audio/media/29 Path - /system/media/audio/notifications/Ascend.mp3
Now, how to I get the ringtone Ur开发者_JAVA百科i from the file path i saved ?
Since the ringtone already exist in MediaStore, I tried the following functions, but it's not working.
uriRingtone = MediaStore.Audio.Media.getContentUriForPath(szRingtonePath);
The Uri is not the same as the one I got from RingtonePreference.
uriRingtone - content://media/internal/audio/media
How do I query the MediaStore to get the Uri I need?
p.s. the reason that I don't store the ringtone Uri directly is that I found the Uri for the same ringtone might change sometimes in some device.
The way you can recover the ringtone URI stored in the RingtonePreference is (as far as I know) by knowing the title of the song. Then you can query it by using a cursor to obtain the ringtone _id stored and with it you can build an URI:
String ringtoneTitle = "<The desired ringtone title>";
Uri parcialUri = Uri.parse("content://media/external/audio/media"); // also can be "content://media/internal/audio/media", depends on your needs
Uri finalSuccessfulUri;
RingtoneManager rm = new RingtoneManager(getApplicationContext());
Cursor cursor = rm.getCursor();
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
if(ringtoneTitle.compareToIgnoreCase(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.TITLE))) == 0) {
int ringtoneID = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
finalSuccessfulUri = Uri.withAppendedPath(parcialUri, "" + ringtoneID );
break;
}
cursor.moveToNext();
}
where finalSuccessful uri is the uri pointing to the ringtone in the RingtonePreference.
You can also do this in a more generic manner for any content in the MediaStore. I have to get the path from URIs and get the URI from paths. The former:
/**
* Gets the corresponding path to a file from the given content:// URI
* @param selectedVideoUri The content:// URI to find the file path from
* @param contentResolver The content resolver to use to perform the query.
* @return the file path as a string
*/
private String getFilePathFromContentUri(Uri selectedVideoUri,
ContentResolver contentResolver) {
String filePath;
String[] filePathColumn = {MediaColumns.DATA};
Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
The latter (which I do for videos, but can also be used for Audio or Files or other types of stored content by substituting MediaStore.Audio (etc) for MediaStore.Video:
/**
* Gets the MediaStore video ID of a given file on external storage
* @param filePath The path (on external storage) of the file to resolve the ID of
* @param contentResolver The content resolver to use to perform the query.
* @return the video ID as a long
*/
private long getVideoIdFromFilePath(String filePath,
ContentResolver contentResolver) {
long videoId;
Log.d(TAG,"Loading file " + filePath);
// This returns us content://media/external/videos/media (or something like that)
// I pass in "external" because that's the MediaStore's name for the external
// storage on my device (the other possibility is "internal")
Uri videosUri = MediaStore.Video.Media.getContentUri("external");
Log.d(TAG,"videosUri = " + videosUri.toString());
String[] projection = {MediaStore.Video.VideoColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
Log.d(TAG,"Video ID is " + videoId);
cursor.close();
return videoId;
}
Basically, the DATA
column of MediaStore
(or whichever sub-section of it you're querying) stores the file path, so you use that info to look it up.
Following code will return absolute path for content Uri of audio, video and image.
public static String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
int idx;
if(contentUri.getPath().startsWith("/external/image") || contentUri.getPath().startsWith("/internal/image")) {
idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
}
else if(contentUri.getPath().startsWith("/external/video") || contentUri.getPath().startsWith("/internal/video")) {
idx = cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA);
}
else if(contentUri.getPath().startsWith("/external/audio") || contentUri.getPath().startsWith("/internal/audio")) {
idx = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
}
else{
return contentUri.getPath();
}
if(cursor != null && cursor.moveToFirst()) {
return cursor.getString(idx);
}
return null;
}
@dong221: Use Internal URI as a MediaStore.Audio.Media.INTERNAL_CONTENT_URI.
精彩评论