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
Related
I cannot understand this problem. I have tried to get the solution from other stackoverflow questions but failed to get the solution. I was not getting this error before. However, now I don't know what's wrong with the code stated below. Please help me with this. I'm stuck with this problem.
public void getAlbumsLists() {
final Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
final String _id = MediaStore.Audio.Albums._ID;
final String album = MediaStore.Audio.Media.ALBUM;
final String album_name = MediaStore.Audio.AlbumColumns.ALBUM;
final String artist = MediaStore.Audio.AlbumColumns.ARTIST;
final String tracks = MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS;
// final String data=MediaStore.Audio.Albums.ALBUM_ID; // NO
// final String id1=MediaStore.Audio.Albums.ALBUM_ID;
final String tit = MediaStore.Audio.Albums.ALBUM; //NO
final String nam = MediaStore.Audio.Albums.ALBUM_KEY; // NO
final String typ = MediaStore.Audio.Media.MIME_TYPE; // NO
final String art = MediaStore.Audio.Albums.ALBUM_ART; //<<<< CAN GET
final String artstkey = MediaStore.Audio.Artists.ARTIST_KEY; //<<<< CAN GET
final String frstyr = MediaStore.Audio.AlbumColumns.FIRST_YEAR; //<<<< CAN GET
final String lstyr = MediaStore.Audio.AlbumColumns.LAST_YEAR; //<<<< CAN GET
final String artstid = "artist_id"; //<<<< CAN GET
final String[] columns = {"*"};
Cursor cursor = getActivity().getContentResolver().query(uri, columns, null, null, null);
// Lists the columns in the cursor
for (String s : cursor.getColumnNames()) {
Log.d("COLUMNS", "Column = " + s);
}
while (cursor.moveToNext()) {
String id = (cursor.getString(cursor.getColumnIndex(_id)));
String name = cursor.getString(cursor.getColumnIndex(album_name));
String artist2 = cursor.getString(cursor.getColumnIndex(artist));
String nr = cursor.getString(cursor.getColumnIndex(tracks));
String x = (cursor.getString(cursor.getColumnIndex(album)));
//String data1=cursor.getString(cursor.getColumnIndexOrThrow(data)); //<<<< NOT A COLUMN
// String id2=cursor.getString(cursor.getColumnIndex(data));
//String title=cursor.getString(cursor.getColumnIndex(tit)); //<<<< NOT A COLUMN
//String name1=cursor.getString(cursor.getColumnIndex(nam)); //<<<< NOT A COLUMN
//String type=cursor.getString(cursor.getColumnIndex(typ)); //<<<< NOT A COLUMN
// AVAIALABLE COLUMNS
String artwork = cursor.getString(cursor.getColumnIndex(art)); //<<<< ADDED
String artistkey = cursor.getString(cursor.getColumnIndex(artstkey)); //<<<< ADDED
String artistid = cursor.getString(cursor.getColumnIndex(artstid)); //<<<< ADDED
String minyear = cursor.getString(cursor.getColumnIndex(frstyr));
String maxyear = cursor.getString(cursor.getColumnIndex(lstyr));
s = new albumInfo(id, name, artist2, nr, artwork, x); // EXCLUDED
albumList.add(s);
cursor.close();
recyclerView1.setAdapter(albumAdapter); // EXCLUDED
}
}
Move cursor.close(); outside the while loop.
Edited..
First time after the while loop iterates the cursor is closed so you need to put it outside while.
I can suggest three improvement scenarios.
You need to move the cursor to first before accessing it for fetching data from the cursor.
You need to close the cursor when nothing is returned or the cursor is null.
Move the cursor close outside of your while loop.
So I would like to recommend you to rewrite the code like following.
// After you have fetched the data from cursor
if(cursor == null) return;
if(cursor.size() == 0) {
cursor.close();
return;
}
for (String s : cursor.getColumnNames()) {
Log.d("COLUMNS", "Column = " + s);
}
// Move the cursor to the first position.
cursor.moveToFirst();
do {
String id = (cursor.getString(cursor.getColumnIndex(_id)));
String name = cursor.getString(cursor.getColumnIndex(album_name));
String artist2 = cursor.getString(cursor.getColumnIndex(artist));
String nr = cursor.getString(cursor.getColumnIndex(tracks));
String x = (cursor.getString(cursor.getColumnIndex(album)));
// ... Other code
} while (cursor.moveToNext());
recyclerView1.setAdapter(albumAdapter); // EXCLUDED
// Move the cursor outside of while loop
cursor.close();
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 want to retrieve whole audio_genres_map table from mediastore in one query. I have all the audio info and genre info but the missing piece is the mapping. I am able to do it in multiple queries. I want to achieve it one query
managed to solve this using following query
String[] genresProjection = {
Audio.Genres.Members.AUDIO_ID,
Audio.Genres.Members.GENRE_ID
};
context.getContentResolver().query(Uri.parse("content://media/external/audio/genres/all/members"), genresProjection, null, null, null);
Or to retrieve all genres using MediaStore.Audio
public Cursor getGenrecursor(Context context) {
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Audio.Genres.getContentUri("external");
String genre = MediaStore.Audio.Genres.NAME;
final String[] columns = { "_id", genre };
return cr.query(uri, columns, null, null, null);
}
and to expand your question, using the genre_id to bring back further details
public Cursor getgenre_TrackCursor(Context context, long genreID) {
final String track_id = MediaStore.Audio.Genres.Members._ID;
final String track_no = MediaStore.Audio.Genres.Members.TRACK;
final String track_name = MediaStore.Audio.Genres.Members.TITLE;
final String artist = MediaStore.Audio.Genres.Members.ARTIST;
final String duration = MediaStore.Audio.Genres.Members.DURATION;
final String album = MediaStore.Audio.Genres.Members.ALBUM;
final String composer = MediaStore.Audio.Genres.Members.COMPOSER;
final String year = MediaStore.Audio.Genres.Members.YEAR;
final String path = MediaStore.Audio.Genres.Members.DATA;
final ContentResolver resolve = context.getContentResolver();
Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external",
genreID);
final String[] columns = { track_id, track_no, artist, track_name,
album, duration, year };
return resolve.query(uri, columns, null, null, null);
}
I create an application to get all contact in addressbook (phone book) of Android device like Viper application.
Here is my code:
private void Import_contacts_from_address_book() {
// TODO Auto-generated method stub
String phoneNumber = null;
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PHONECONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String PHONECONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EMAILCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EMAILCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
System.out.println("---------------------->"+cursor.getCount());
if(cursor.getCount() >0){
countContact = cursor.getCount();
while(cursor.moveToNext()){
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
//------------------- Catch phone number, neu phone >0 thi get phone, ko thi lam chuyen khac
//if(hasPhoneNumber > 0 ){
output.append("\nFirst Name: "+name);
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(PHONECONTENT_URI, null, PHONECONTACT_ID + "=?", new String[]{contact_id}, null);
while(phoneCursor.moveToNext()){
phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
output.append("\n Phone number: "+phoneNumber);
}
phoneCursor.close();
// Query and loop for every email of the contact
Cursor emailCurosr = contentResolver.query(EMAILCONTENT_URI, null, EMAILCONTACT_ID+"=?",new String[]{contact_id},null);
while(emailCurosr.moveToNext()){
email = emailCurosr.getString(emailCurosr.getColumnIndex(EMAIL));
output.append("\nEmail: "+email);
}
emailCurosr.close();
//}
output.append("\n");
}
cursor.close();
}
txtViewContactsInfor.setText("Contacts: "+String.valueOf(countContact));
outputText.setText(output.toString());
}
I try to import 1000 contact and it take at least 45 second.
Is there any way to improve speed?
And when I change some information in contact of addressbook (phone book) in Android device. I using onResume() to update new information for my application but It's reload all page so It take a long time. But I see on Viper, the data updating immediately. So, is there any I can update or sync data from my device to my application like Viper application or improve speed updating, reload page ?
Any help would be much appreciated! Thanks!
Query operation is very long operation on android, because each time, when you call query, system opens database file. Opening file is expensive in android. You should call query as rarely as possible. This is my solution:
public class Contact {
public String name;
public List<String> phones;
public List<String> emails;
}
private static final Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
private static final String _ID = ContactsContract.Contacts._ID;
private static final String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
private static final Uri PHONE_CONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
private static final String PHONE_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
private static final String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
private static final Uri EMAIL_CONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
private static final String EMAIL_CONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
private static final String EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
private Collection<Contact> importContactsFromAddressBook() {
Map<String, Contact> contactMap = new HashMap<String, Contact>();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contactId = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
Contact contact = new Contact();
contact.name = name;
contact.phones = new ArrayList<String>();
contact.emails = new ArrayList<String>();
contactMap.put(contactId, contact);
}
}
cursor.close();
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(PHONE_CONTENT_URI, null, null, null, null);
while (phoneCursor.moveToNext()) {
String contactId = phoneCursor.getString(phoneCursor.getColumnIndex(PHONE_CONTACT_ID));
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
Contact contact = contactMap.get(contactId);
contact.phones.add(phoneNumber);
}
phoneCursor.close();
// Query and loop for every email of the contact
Cursor emailCursor = contentResolver.query(EMAIL_CONTENT_URI, null, EMAIL_CONTACT_ID + "=?", new String[]{contactId}, null);
while (emailCursor.moveToNext()) {
String contactId = emailCursor.getString(emailCursor.getColumnIndex(EMAIL_CONTACT_ID));
String email = emailCursor.getString(emailCursor.getColumnIndex(EMAIL));
Contact contact = contactMap.get(contactId);
contact.emails.add(email);
}
emailCursor.close();
return contactMap.values();
}
There are some similar questions have been posted here, I have used those suggestions and tried it in different ways, but still no results for getting out, my codes is like this:
private Cursor getPlaylists(String playlistName) {
Cursor cursor = null;
String[] projection1 = { MediaStore.Audio.Playlists._ID,
MediaStore.Audio.Playlists.NAME };
cursor = this.managedQuery(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, projection1,
MediaStore.Audio.Playlists.NAME + "=\"" + playlistName + "\"", null,
null); // I need to put "" for the string, otherwise sqlite errors for no such table
startManagingCursor(cursor);
cursor.moveToFirst();
String playlist_id = cursor.getString(0);
Long playlist_id2 = cursor.getLong(0);
if (playlist_id2 > 0) {
String[] projection = {
MediaStore.Audio.Playlists.Members.AUDIO_ID,
MediaStore.Audio.Playlists.Members.ARTIST,
MediaStore.Audio.Playlists.Members.TITLE,
MediaStore.Audio.Playlists.Members._ID
};
cursor = getContentResolver().query(MediaStore.Audio.Playlists.Members.getContentUri("external",playlist_id2),
projection,
null,
null,
null);
}
return cursor;
But after these codes, how can I exactly get music list names? does then store in projection, but my projection variable are always no music list information inside. If I need to iterate this cursor again to get music list names, how can I do it, I have tried this way.. but it won't work.
// startManagingCursor(cursor);
for (boolean hasItem = cursor.moveToFirst(); hasItem; hasItem = cursor
.moveToNext()) {
String musicName = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Playlists.Members.TITLE));
Log.i(LOGGING_TAG, musicName);
}
it looks like hasItem is null as always. I am stuck on this for couple of hours, maybe that is a stupid question but any suggestions would be graceful.
If I understand you correctly, you want to list the tracks on a given playlist.
This is how I do it. Once you have your cursor, you just loop around it by getting the values you need.
see examples below :
public Cursor getPlaylistTracks(Context context, Long playlist_id) {
Uri newuri = MediaStore.Audio.Playlists.Members.getContentUri("external",playlist_id);
ContentResolver resolver = context.getContentResolver();
String _id = MediaStore.Audio.Playlists.Members._ID;
String audio_id = MediaStore.Audio.Playlists.Members.AUDIO_ID;
String artist = MediaStore.Audio.Playlists.Members.ARTIST;
String album = MediaStore.Audio.Playlists.Members.ALBUM;
String title = MediaStore.Audio.Playlists.Members.TITLE;
String duration = MediaStore.Audio.Playlists.Members.DURATION;
String location = MediaStore.Audio.Playlists.Members.DATA;
String composer = MediaStore.Audio.Playlists.Members.COMPOSER;
String playorder = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
String date_modified = MediaStore.Audio.Playlists.Members.DATE_MODIFIED;
String[] columns = { _id, audio_id, artist, album, title, duration,
location, date_modified, playorder, composer };
Cursor cursor = resolver.query(newuri, columns, null, null, null);
return cursor;
}
if (cursor!= null){
cursor.moveToFirst();
int artistColumn = cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.ARTIST);
int durationColumn = cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.DURATION);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
{
artist = cursor.getString(artistColumn);
duration = duration + cursor.getLong(durationColumn);
// do something else
}
cursor.close();
}