1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.musicplayer; 18 19 import android.content.ContentResolver; 20 import android.content.ContentUris; 21 import android.database.Cursor; 22 import android.net.Uri; 23 import android.provider.MediaStore; 24 import android.util.Log; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 import java.util.Random; 29 30 /** 31 * Retrieves and organizes media to play. Before being used, you must call {@link #prepare()}, 32 * which will retrieve all of the music on the user's device (by performing a query on a content 33 * resolver). After that, it's ready to retrieve a random song, with its title and URI, upon 34 * request. 35 */ 36 public class MusicRetriever { 37 final String TAG = "MusicRetriever"; 38 39 ContentResolver mContentResolver; 40 41 // the items (songs) we have queried 42 List<Item> mItems = new ArrayList<Item>(); 43 44 Random mRandom = new Random(); 45 MusicRetriever(ContentResolver cr)46 public MusicRetriever(ContentResolver cr) { 47 mContentResolver = cr; 48 } 49 50 /** 51 * Loads music data. This method may take long, so be sure to call it asynchronously without 52 * blocking the main thread. 53 */ prepare()54 public void prepare() { 55 Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 56 Log.i(TAG, "Querying media..."); 57 Log.i(TAG, "URI: " + uri.toString()); 58 59 // Perform a query on the content resolver. The URI we're passing specifies that we 60 // want to query for all audio media on external storage (e.g. SD card) 61 Cursor cur = mContentResolver.query(uri, null, 62 MediaStore.Audio.Media.IS_MUSIC + " = 1", null, null); 63 Log.i(TAG, "Query finished. " + (cur == null ? "Returned NULL." : "Returned a cursor.")); 64 65 if (cur == null) { 66 // Query failed... 67 Log.e(TAG, "Failed to retrieve music: cursor is null :-("); 68 return; 69 } 70 if (!cur.moveToFirst()) { 71 // Nothing to query. There is no music on the device. How boring. 72 Log.e(TAG, "Failed to move cursor to first row (no query results)."); 73 return; 74 } 75 76 Log.i(TAG, "Listing..."); 77 78 // retrieve the indices of the columns where the ID, title, etc. of the song are 79 int artistColumn = cur.getColumnIndex(MediaStore.Audio.Media.ARTIST); 80 int titleColumn = cur.getColumnIndex(MediaStore.Audio.Media.TITLE); 81 int albumColumn = cur.getColumnIndex(MediaStore.Audio.Media.ALBUM); 82 int durationColumn = cur.getColumnIndex(MediaStore.Audio.Media.DURATION); 83 int idColumn = cur.getColumnIndex(MediaStore.Audio.Media._ID); 84 85 Log.i(TAG, "Title column index: " + String.valueOf(titleColumn)); 86 Log.i(TAG, "ID column index: " + String.valueOf(titleColumn)); 87 88 // add each song to mItems 89 do { 90 Log.i(TAG, "ID: " + cur.getString(idColumn) + " Title: " + cur.getString(titleColumn)); 91 mItems.add(new Item( 92 cur.getLong(idColumn), 93 cur.getString(artistColumn), 94 cur.getString(titleColumn), 95 cur.getString(albumColumn), 96 cur.getLong(durationColumn))); 97 } while (cur.moveToNext()); 98 99 Log.i(TAG, "Done querying media. MusicRetriever is ready."); 100 } 101 getContentResolver()102 public ContentResolver getContentResolver() { 103 return mContentResolver; 104 } 105 106 /** Returns a random Item. If there are no items available, returns null. */ getRandomItem()107 public Item getRandomItem() { 108 if (mItems.size() <= 0) return null; 109 return mItems.get(mRandom.nextInt(mItems.size())); 110 } 111 112 public static class Item { 113 long id; 114 String artist; 115 String title; 116 String album; 117 long duration; 118 Item(long id, String artist, String title, String album, long duration)119 public Item(long id, String artist, String title, String album, long duration) { 120 this.id = id; 121 this.artist = artist; 122 this.title = title; 123 this.album = album; 124 this.duration = duration; 125 } 126 getId()127 public long getId() { 128 return id; 129 } 130 getArtist()131 public String getArtist() { 132 return artist; 133 } 134 getTitle()135 public String getTitle() { 136 return title; 137 } 138 getAlbum()139 public String getAlbum() { 140 return album; 141 } 142 getDuration()143 public long getDuration() { 144 return duration; 145 } 146 getURI()147 public Uri getURI() { 148 return ContentUris.withAppendedId( 149 android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); 150 } 151 } 152 } 153