I used this answer to get the duration,but it's not working for me.Can anybody tell me what's the problem?
Any help is appreciated.
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] columns = {MediaStore.Video.VideoColumns.DURATION};
String selection = MediaStore.Video.VideoColumns.DATA + "=?";
String selectionArgs[] = {"/data/data/com.test.test/files/video1.mp4"};
Cursor cursor = context.getContentResolver().query(uri, columns, selection, selectionArgs, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.DURATION));
}
cursor.close();
}
If you've already got the Uri or the file path to the video, it might be easier to use the MediaMetadataRetriever class. It would look something like this:
MediaMetadataRetriever r = new MediaMetadataRetriever();
r.setDataSource(filePath);
String durString = r.extractMetadata( MediaMetadataRetriever.METADATA_KEY_DURATION );
int duration = Integer.parseInt(durString);
The MediaStore is a Media provider that contains meta data for all available media on both internal and external storage devices.I am not sure,but the path you are using maybe is not visible for MediaStore.If you are using MediaPlayer do like this...
MediaPlayer mp = MediaPlayer.create(this, Uri.parse(uriOfYourFile));
int duration = mp.getDuration();
Related
I'm building a music player app. I'm trying to populate a recyclerView with album arts of songs. I successfully did that with the code that is given below. But some of the songs do not have embedded album art not any album art in the folder. So, I'm trying to check if the album art is null or not before adding it to the recyclerView. If the album art is null, the app will automatically fetch it from the internet. I tried checking if the album art is null or not, but everytime it gives me a uri whether the album art is available or not.
Code for fetching album art from mediastore:
String[] projection = {MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.ALBUM_ID};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, selection, whereVal, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));
String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
Long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
Long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
String albumArtUri = String.valueOf(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"),albumId));
SongInfoModel s = new SongInfoModel(id, name, artist, null, album, null, duration, data, albumId,albumArtUri);
SongList.add(s);
} while (cursor.moveToNext());
}
The value for albumArtUri is never null.
It always gives the following uri(s):
content://media/external/audio/albumart/12
content://media/external/audio/albumart/5
content://media/external/audio/albumart/6
content://media/external/audio/albumart/3
content://media/external/audio/albumart/8
content://media/external/audio/albumart/9
But among these uri(s), content://media/external/audio/albumart/9 has no album art. It always displays the placeholder I said using Glide
So my question, how to check if album art is available(as embedded art or in song folder) before populating the recyclerView? I know I can use Glide placeholder and I'm using it. But I also want to fetch album art from the internet if album art is not available offline, that is why I need to check, so that I can add the internet links into the arraylist. Hope you guys get what I'm trying to say.
Thank you!
EDIT:
I found that the below given code snippet returns if album art exists or not but it consumes a lot of time.
public String fetchAlbumArt(long albumID){
String art;
Cursor cur = getActivity().getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[]
{MediaStore.Audio.Albums.ALBUM_ART}, MediaStore.Audio.Albums._ID + "=?", new String[] {String.valueOf(albumID)}, null);
cur.moveToFirst();
art = cur.getString(cur.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
cur.close();
return art;
}
The easiest way:
// loading album cover using Glide library
String stralbumId = c.getString(c
.getColumnIndex(BaseColumns._ID));
Uri ImageUrl = getAlbumUri(mContext, stralbumId);
if (ImageUrl != null) {
Glide.with(mContext)
.asBitmap()
.load(ImageUrl)
.into(image);
}
and
public Uri getAlbumUri(Context mContext,String album_id){
if(mContext!=null) {
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri imageUri = Uri.withAppendedPath(sArtworkUri, String.valueOf(album_id));
return imageUri;
}
return null;
}
you can check for album cover by using the MediaMetadataRetriever
try the code below and also read the MediaMetadataRetriever Documentation
MediaMetadataRetriever retriver = new MediaMetadataRetriever();
retriver.setDataSource(musicFile.getAbsolutePath());
byte[] cover = retriver.getEmbeddedPicture();
if(cover == null){
// get cover from the internet
}else{
// use glide to load the album art
}
Try to use the code below
var albumArtExists = true
try {
val contentUri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId)
context.contentResolver.loadThumbnail(contentUri, Size(64, 64), null)
} catch(e: FileNotFoundException) {
albumArtExists = false
}
This works for sdk 29 and higher
I'm able to get the paths of all videos in the filesystem using MediaStore. is there any way to get a specific duration (or less than that) video using MediaStore. like video duration less than 15min.
These are my code to get the video paths
public void getVideoPaths(Context context) {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Video.VideoColumns.DATA};
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
if (c != null) {
while (c.moveToNext()) {
filesNames.add(c.getString(0));
}
c.close();
}
}
String duration = Integer.toString(15*60*1000);
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Video.VideoColumns.DURATION + " < ?", new String[] {duration}, null);
This will query for only files shorter than 15 minutes
The MediaStore is a Media provider that contains meta data for all available media on both internal and external storage devices. You just need to have a uri of that video file than use below code for duration purpose
MediaPlayer mp = MediaPlayer.create(this, Uri.parse(uriOfYourFile));
int duration = mp.getDuration();
And after that check for specific duration. You can use one more option as well as mentioned below
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//use one of overloaded setDataSource() functions to set your data source
retriever.setDataSource(context, Uri.fromFile(videoFile));
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMillisec = Long.parseLong(time );
retriever.release()
Hope that helps you.
I have gone through a lot of stackoverflow questions but I couldn't find an answer to this. There is an answer for Image files but that doesn't work in my case.
So I have the absolute path of the file using file.getAbsolutePath(). But I need to convert it to contentUri so that below query works fine.
Cursor tempCursor = context.getContentResolver().query(uri,
proj, null, null, null);
It is not working. I tried Uri.parse(contentUri) but that doesn't give the content uri I guess. Please help me, I am stuck since a long time. Thanks !!
You do not use the get.absolute etc. Simply query the Medfiastore.Audio etc and bring back _id and _DATA. _id is the song id and _DATA has the full path and track
below a piece of code which you could use. Just feed it the track name
public String getThisTrackId(Context context, String trackName) {
ContentResolver cr = context.getContentResolver();
final String _id = MediaStore.Audio.Media._ID;
final String path = MediaStore.Audio.Media.DATA;
final String[] columns = { _id };
final String[] trackname = { "%"+ trackName +"%" };
String where = path + " LIKE ?";
String strtrack_id = null;
Cursor crs =cr.query(uri, columns, where, trackname, null);
if(crs!= null && crs.moveToFirst()){
strtrack_id = crs.getString(crs.getColumnIndexOrThrow(_id));
crs.close();
}
return strtrack_id;
}
I am using the Storage Access Framework for android 4.4 and opening the file picker.
Everything works except when choosing a file from Google Drive, I can only figure out how to open it as an input stream, but I would like to get a java File object.
The content uri that's being returned looks something like this: content://com.google.android.apps.docs.storage/document/acc%3D4%3Bdoc%3D2279
Other questions that are similar but do not have a working solution which allows me to get the filename, filesize and contents:
Get real path from URI, Android KitKat new storage access framework
Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
I've also looked into Paul Burke's FileChooser ( https://github.com/iPaulPro/aFileChooser) and this is the most common question on the issue's list.
How can I get a file from that content uri?
My current workaround is to write out a temporary file from an inputstream.
Thanks!
Ok. I found that the right way is to use the input stream from the other posts in conjunction with some data from the contentresolver.
For reference here are the hard to find android docs: https://developer.android.com/training/secure-file-sharing/retrieve-info.html
The relevant code to get mimetype, filename, and filesize:
Uri returnUri = returnIntent.getData();
String mimeType = getContentResolver().getType(returnUri);
Cursor returnCursor =
getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
TextView nameView = (TextView) findViewById(R.id.filename_text);
TextView sizeView = (TextView) findViewById(R.id.filesize_text);
nameView.setText(returnCursor.getString(nameIndex));
sizeView.setText(Long.toString(returnCursor.getLong(sizeIndex)));
And to get the file contents:
getContentResolver().openInputStream(uri)
Hope this helps someone else.
Adding to #Keith Entzeroth answer , after getting fileName, fileSize and Input Stream , this is way to get the file
public static File getFile(final Context context, final Uri uri) {
Log.e(TAG,"inside getFile==");
ContentResolver contentResolver = context.getContentResolver();
try {
String mimeType = contentResolver.getType(uri);
Cursor returnCursor =
contentResolver.query(uri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String fileName = returnCursor.getString(nameIndex);
String fileSize = Long.toString(returnCursor.getLong(sizeIndex));
InputStream inputStream = contentResolver.openInputStream(uri);
File tempFile = File.createTempFile(fileName, "");
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copyStream(inputStream,out);
return tempFile;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
this code solved my problem, when i tried to select image from google drive ,app get crashed ,
private void setImagePath(Intent data) throws Exception {
String wholeID="";
Uri selectedImage = data.getData();
if(Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN_MR2){
wholeID=getUriPreKitkat(selectedImage);
}else {
wholeID = DocumentsContract.getDocumentId(selectedImage);
}
// Split at colon, use second item in the array
Log.i("debug","uri google drive "+wholeID);
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
}
i am traversing in the phone's memory with the following code.
ContentResolver contentResolver = getContentResolver();
String[] columns = {
MediaColumns._ID,
MediaColumns.TITLE,
AudioColumns.DURATION,
};
final String where = MediaStore.Audio.Media.IS_MUSIC + "=1";
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,columns, where, null, null);
while(cursor.moveToNext()) {
String urp = cursor.getString(cursor.getColumnIndex(MediaColumns._ID));
String title = cursor.getString(cursor.getColumnIndex(MediaColumns.TITLE));
Long duration = cursor.getLong(cursor.getColumnIndex(AudioColumns.DURATION));
}
so now my question is, how to get the uri of the cursor items traveresed, like
for first while run i have stored id,title,duration etc metadata and i would also like to
store that tracks URI, also i would like to convert that URI from content// scheme to file scheme.
Any help will be greatful
thankyou
String.valueOf(cur.getColumnIndex(android.provider.MediaStore.MediaColumns.DATA)));
http://android-er.blogspot.fr/2011/04/convert-uri-to-real-path-format.html