It is possible to recognize whether the file obtained using "Media file access" is stored on the SD card or in the Internal Memory ? For example, is it possible to find out the information from a media URI? In my opinion, it is only possible to find out the name of a subdirectory, but then it is no longer possible to find out the name of parent subdirectory.
Thanks, Michal
class Video {
private final Uri uri;
private final String name;
private final int duration;
private final int size;
public Video(Uri uri, String name, int duration, int size) {
this.uri = uri;
this.name = name;
this.duration = duration;
this.size = size;
}
}
List<Video> videoList = new ArrayList<Video>();
String[] projection = new String[] {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.SIZE
};
String selection = MediaStore.Video.Media.DURATION +
" >= ?";
String[] selectionArgs = new String[] {
String.valueOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
};
String sortOrder = MediaStore.Video.Media.DISPLAY_NAME + " ASC";
try (Cursor cursor = getApplicationContext().getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
sortOrder
)) {
// Cache column indices.
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
int durationColumn =
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
while (cursor.moveToNext()) {
// Get values of columns for a given video.
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
int duration = cursor.getInt(durationColumn);
int size = cursor.getInt(sizeColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
// Stores column values and the contentUri in a local object
// that represents the media file.
videoList.add(new Video(contentUri, name, duration, size));
}
}
it is possible to somehow find out that the video is on the SD card or in the memory.
Related
I'm a beginner in android. According to following the document 'Access media files from shared storage'. I want to display name all audio in the list, but it only shows one audio. Could someone help me to solve this? Thanks. Here my code.`
ArrayList<audio> arrayList = new ArrayList<audio>();
String[] projection = new String[]{
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.SIZE
};
String selection = MediaStore.Audio.Media.DURATION +
" >= ?";
String[] selectionArgs = new String[]{
String.valueOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES))};
String sortOrder = MediaStore.Audio.Media.DISPLAY_NAME + " ASC";
try (Cursor cursor = v.getContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
sortOrder
)) {
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
int durationColumn =
cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE);
while (cursor.moveToNext()) {
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
int duration = cursor.getInt(durationColumn);
int size = cursor.getInt(sizeColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
// Stores column values and the contentUri in a local object
// that represents the media file.
arrayList.add(new audio(name));
}
}
`
I have a simple question.
It's possible to access to DCIM folder (internal storage) from an app and retrieve an image?
I've found solutions that use something like Enviroment.getExternalStoragePublicDirectory but I don't understand why.
Environment.getExternalStorageDirectory().toString()+ "/DCIM/Camera";
or
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()
Will give you a path for the public directory. This path is required to fetch all files including image. getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() is public so you can access them from any installed app.
The following code snippet can be used to list all image file path from "DCIM" folder:
public static List<String> getCameraImages(Context context) {
public final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString()+ "/DCIM/Camera";
public final String CAMERA_IMAGE_BUCKET_ID = String.valueOf(CAMERA_IMAGE_BUCKET_NAME.toLowerCase().hashCode());
final String[] projection = { MediaStore.Images.Media.DATA };
final String selection = MediaStore.Images.Media.BUCKET_ID + " = ?";
final String[] selectionArgs = { CAMERA_IMAGE_BUCKET_ID };
final Cursor cursor = context.getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null);
ArrayList<String> result = new ArrayList<String>(cursor.getCount());
if (cursor.moveToFirst()) {
final int dataColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
do {
final String data = cursor.getString(dataColumn);
result.add(data);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
When I launch my application after upgrading from android 7 to 8.1 I noticed that it lost a lot of responsiveness.
When I'm trying to get songs from device memory I get a lot of errors like:
E/SEC_DRM_PLUGIN_Omafl: OmaPlugin::onOpenDecryptSession(fd)::Drm2IsDrmFileByExtFd::file is NOT DRM by extension
That works much slower than on the Android 7.
Code:
public ArrayList<Song> getSongList() {
MediaMetadataRetriever metaRetriver = new MediaMetadataRetriever();
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
ArrayList<Song> songList = new ArrayList<>();
ContentResolver musicResolver = context.getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, selection, null, null);
if (musicCursor != null && musicCursor.moveToFirst()) {
int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int durationColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION);
int column_index = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
do {
long id = musicCursor.getLong(idColumn);
String path = musicCursor.getString(column_index);
String title = musicCursor.getString(titleColumn);
String artist = musicCursor.getString(artistColumn);
String duration = musicCursor.getString(durationColumn);
try {
metaRetriver.setDataSource(path);
songList.add(new Song(id, title, artist, path, duration));
}catch (Exception exc){}
} while (musicCursor.moveToNext());
}
return songList;
}
I had to delete the one line of code that was causing the error when trying to get every single song from memory:
mediaMetadataRetriver.setDataSource(pathOfSong);
Hope it will help you.
I have this function from developer.android but it can't find all songs, only few. Please give me some clue.
public void getAllSongs() {
ContentResolver contentResolver = getContentResolver();
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
do {
long thisId = cursor.getLong(idColumn);
String thisTitle = cursor.getString(titleColumn);
songs.add(thisId + "||"+thisTitle);// ...process entry...
} while (cursor.moveToNext());
}
}
I use the following to get all tracks:
private final String track_id = MediaStore.Audio.Media._ID;
private final String track_no = MediaStore.Audio.Media.TRACK;
private final String track_name = MediaStore.Audio.Media.TITLE;
private final String artist = MediaStore.Audio.Media.ARTIST;
private final String artist_id = MediaStore.Audio.Media.ARTIST_ID;
private final String duration = MediaStore.Audio.Media.DURATION;
private final String album = MediaStore.Audio.Media.ALBUM;
private final String composer = MediaStore.Audio.Media.COMPOSER;
private final String year = MediaStore.Audio.Media.YEAR;
private final String path = MediaStore.Audio.Media.DATA;
private final String date_added = MediaStore.Audio.Media.DATE_ADDED;
private final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
public Cursor getAllTracks(Context context) {
// gets all tracks
ContentResolver cr = context.getContentResolver();
final String[] columns = {track_id ,track_no, artist, track_name,
album, duration, path, year, composer};
return cr.query(uri, columns, null, null, null);
}
I try to get all tracks from MediaStore.
Cursor cursor = managedQuery(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, null, null, null, null);
while (cursor.moveToNext())
{
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.AudioColumns._ID));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST));
int duration = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION));
}
cursor.close();
But I can't read values from cursor. When I run this code
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.ARTIST and
MediaStore.Audio.AudioColumns.DURATION
constants is null.
Which constants I must use to get values in result above?
set up columns and uri to return:
final String track_id = MediaStore.Audio.Media._ID;
final String track_no = MediaStore.Audio.Media.TRACK;
final String track_name = MediaStore.Audio.Media.TITLE;
final String artist = MediaStore.Audio.Media.ARTIST;
final String duration = MediaStore.Audio.Media.DURATION;
final String album = MediaStore.Audio.Media.ALBUM;
final String composer = MediaStore.Audio.Media.COMPOSER;
final String year = MediaStore.Audio.Media.YEAR;
final String path = MediaStore.Audio.Media.DATA;
final String date_added = MediaStore.Audio.Media.DATE_ADDED;
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
To get all tracks:
public Cursor getTrackTrackcursor(Context context, Cursor cursor) {
// gets all tracks
ContentResolver cr = context.getContentResolver();
final String[] columns = { track_id, track_no, artist, track_name,
album, duration, path, year, composer };
cursor = cr.query(uri, columns, null, null, null);
return cursor;
}
now loop through the cursor and extract the string values according to the columns returned.
You can only extract columns which have been returned by the cursor so an error would occur as I did not return NUMBER_OF_SONGS. You would have to ensure this is also returned by the cursor
For example:
String stralbum = (c.getString(cursor
.getColumnIndex(MediaStore.Audio.Albums.ALBUM)));
String strartist = (cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Albums.ARTIST)));
String stryear = (cursor.getString(cusrsor
.getColumnIndex(MediaStore.Audio.Albums.FIRST_YEAR)));
String strnosongs = (cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS)));
You are 99% correct but your uri needs the column layout. Hope this helps