1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/* 2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 4792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * you may not use this file except in compliance with the License. 6792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * You may obtain a copy of the License at 7792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 8792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 10792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * See the License for the specific language governing permissions and 14792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * limitations under the License. 15792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 16792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 17792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpackage com.android.music; 18792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 19792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.app.ListActivity; 20792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.AsyncQueryHandler; 21792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentUris; 22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Context; 23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Intent; 24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.database.CharArrayBuffer; 25792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.database.Cursor; 26792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.AudioManager; 27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.MediaPlayer; 28792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.RingtoneManager; 29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.net.Uri; 30792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Bundle; 31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Parcelable; 32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.provider.MediaStore; 3389f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissenimport android.text.TextUtils; 34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.util.Log; 35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.Menu; 36792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.MenuItem; 37792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.View; 38792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.ViewGroup; 39792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.Window; 40792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.animation.AnimationUtils; 41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.ImageView; 42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.ListView; 43792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.RadioButton; 44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.SectionIndexer; 45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.SimpleCursorAdapter; 46792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.TextView; 47792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 48792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.io.IOException; 49792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.text.Collator; 50792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.util.Formatter; 51792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.util.Locale; 52792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 53792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/** 54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Activity allowing the user to select a music track on the device, and 55792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * return it to its caller. The music picker user interface is fairly 56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * extensive, providing information about each track like the music 57792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * application (title, author, album, duration), as well as the ability to 58792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * previous tracks and sort them in different orders. 59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * <p>This class also illustrates how you can load data from a content 61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * provider asynchronously, providing a good UI while doing so, perform 62792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * indexing of the content for use inside of a {@link FastScrollView}, and 63792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * perform filtering of the data as the user presses keys. 64792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 65792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpublic class MusicPicker extends ListActivity 66792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project implements View.OnClickListener, MediaPlayer.OnCompletionListener, 67792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MusicUtils.Defs { 68792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final boolean DBG = false; 69792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final String TAG = "MusicPicker"; 70792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 71792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Holds the previous state of the list, to restore after the async 72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * query has completed. */ 73792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final String LIST_STATE_KEY = "liststate"; 74792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Remember whether the list last had focus for restoring its state. */ 75792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final String FOCUS_KEY = "focused"; 76792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Remember the last ordering mode for restoring state. */ 77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final String SORT_MODE_KEY = "sortMode"; 78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Arbitrary number, doesn't matter since we only do one query type. */ 80756c3f57f11a7bb3bf1cf1333ee8ffbc51039748Marco Nelissen static final int MY_QUERY_TOKEN = 42; 81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Menu item to sort the music list by track title. */ 83792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final int TRACK_MENU = Menu.FIRST; 84792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Menu item to sort the music list by album title. */ 85792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final int ALBUM_MENU = Menu.FIRST+1; 86792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Menu item to sort the music list by artist name. */ 87792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final int ARTIST_MENU = Menu.FIRST+2; 88792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 89792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** These are the columns in the music cursor that we are interested in. */ 90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final String[] CURSOR_COLS = new String[] { 91792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media._ID, 92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TITLE, 93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TITLE_KEY, 94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, 95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ALBUM, 96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ARTIST, 97792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ARTIST_ID, 98792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DURATION, 99792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TRACK 100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Formatting optimization to avoid creating many temporary objects. */ 103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static StringBuilder sFormatBuilder = new StringBuilder(); 104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Formatting optimization to avoid creating many temporary objects. */ 105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault()); 106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Formatting optimization to avoid creating many temporary objects. */ 107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project static final Object[] sTimeArgs = new Object[5]; 108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Uri to the directory of all music being displayed. */ 110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri mBaseUri; 111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** This is the adapter used to display all of the tracks. */ 113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TrackListAdapter mAdapter; 114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Our instance of QueryHandler used to perform async background queries. */ 115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project QueryHandler mQueryHandler; 116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Used to keep track of the last scroll state of the list. */ 118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Parcelable mListState = null; 119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Used to keep track of whether the list last had focus. */ 120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean mListHasFocus; 121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** The current cursor on the music that is being displayed. */ 123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor mCursor; 124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** The actual sort order the user has selected. */ 125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int mSortMode = -1; 126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** SQL order by string describing the currently selected sort order. */ 127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String mSortOrder; 128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Container of the in-screen progress indicator, to be able to hide it 130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * when done loading the initial cursor. */ 131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View mProgressContainer; 132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Container of the list view hierarchy, to be able to show it when done 133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * loading the initial cursor. */ 134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View mListContainer; 135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Set to true when the list view has been shown for the first time. */ 136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean mListShown; 137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** View holding the okay button. */ 139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View mOkayButton; 140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** View holding the cancel button. */ 141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View mCancelButton; 142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Which track row ID the user has last selected. */ 144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long mSelectedId = -1; 145792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Completel Uri that the user has last selected. */ 146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri mSelectedUri; 147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** If >= 0, we are currently playing a track for preview, and this is its 149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * row ID. */ 150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long mPlayingId = -1; 151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** This is used for playing previews of the music files. */ 153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlayer mMediaPlayer; 154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 156792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * A special implementation of SimpleCursorAdapter that knows how to bind 157792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * our cursor data to our list item structure, and takes care of other 158792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * advanced features such as indexing and filtering. 159792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 160792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project class TrackListAdapter extends SimpleCursorAdapter 161792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project implements SectionIndexer { 162792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final ListView mListView; 163792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final StringBuilder mBuilder = new StringBuilder(); 165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final String mUnknownArtist; 166792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final String mUnknownAlbum; 167792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 168792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mIdIdx; 169792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mTitleIdx; 170792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mArtistIdx; 171792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mAlbumIdx; 172792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mDurationIdx; 173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mLoading = true; 175792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mIndexerSortMode; 176792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private MusicAlphabetIndexer mIndexer; 177792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 178792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project class ViewHolder { 179792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TextView line1; 180792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TextView line2; 181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TextView duration; 182792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project RadioButton radio; 183792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ImageView play_indicator; 184792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project CharArrayBuffer buffer1; 185792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project char [] buffer2; 186792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 187792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 188792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project TrackListAdapter(Context context, ListView listView, int layout, 189792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] from, int[] to) { 190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super(context, layout, null, from, to); 191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListView = listView; 192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mUnknownArtist = context.getString(R.string.unknown_artist_name); 193792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mUnknownAlbum = context.getString(R.string.unknown_album_name); 194792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * The mLoading flag is set while we are performing a background 198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * query, to avoid displaying the "No music" empty view during 199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * this time. 200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setLoading(boolean loading) { 202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mLoading = loading; 203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean isEmpty() { 207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mLoading) { 208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We don't want the empty state to show when loading. 209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return super.isEmpty(); 212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public View newView(Context context, Cursor cursor, ViewGroup parent) { 217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project View v = super.newView(context, cursor, parent); 218792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ViewHolder vh = new ViewHolder(); 219792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.line1 = (TextView) v.findViewById(R.id.line1); 220792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.line2 = (TextView) v.findViewById(R.id.line2); 221792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.duration = (TextView) v.findViewById(R.id.duration); 222792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.radio = (RadioButton) v.findViewById(R.id.radio); 223792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.play_indicator = (ImageView) v.findViewById(R.id.play_indicator); 224792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.buffer1 = new CharArrayBuffer(100); 225792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.buffer2 = new char[200]; 226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project v.setTag(vh); 227792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return v; 228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 231792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void bindView(View view, Context context, Cursor cursor) { 232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ViewHolder vh = (ViewHolder) view.getTag(); 233792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 234792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.copyStringToBuffer(mTitleIdx, vh.buffer1); 235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.line1.setText(vh.buffer1.data, 0, vh.buffer1.sizeCopied); 236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int secs = cursor.getInt(mDurationIdx) / 1000; 238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (secs == 0) { 239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.duration.setText(""); 240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 2411e5a567390e41045cba6abac1d2c94eb8f59fc30Marco Nelissen vh.duration.setText(MusicUtils.makeTimeString(context, secs)); 242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 243792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 244792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final StringBuilder builder = mBuilder; 245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.delete(0, builder.length()); 246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String name = cursor.getString(mAlbumIdx); 248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (name == null || name.equals("<unknown>")) { 249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.append(mUnknownAlbum); 250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 251792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.append(name); 252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.append('\n'); 254792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project name = cursor.getString(mArtistIdx); 255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (name == null || name.equals("<unknown>")) { 256792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.append(mUnknownArtist); 257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.append(name); 259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = builder.length(); 261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (vh.buffer2.length < len) { 262792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.buffer2 = new char[len]; 263792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 264792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.getChars(0, len, vh.buffer2, 0); 265792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.line2.setText(vh.buffer2, 0, len); 266792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 267792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Update the checkbox of the item, based on which the user last 268792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // selected. Note that doing it this way means we must have the 269792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // list view update all of its items when the selected item 270792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // changes. 271792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final long id = cursor.getLong(mIdIdx); 272792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project vh.radio.setChecked(id == mSelectedId); 273792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Binding id=" + id + " sel=" + mSelectedId 274792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + " playing=" + mPlayingId + " cursor=" + cursor); 275792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 276792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Likewise, display the "now playing" icon if this item is 277792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // currently being previewed for the user. 278792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ImageView iv = vh.play_indicator; 279792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (id == mPlayingId) { 280792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iv.setImageResource(R.drawable.indicator_ic_mp_playing_list); 281792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iv.setVisibility(View.VISIBLE); 282792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 283792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iv.setVisibility(View.GONE); 284792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 285792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 286792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 287792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 288792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This method is called whenever we receive a new cursor due to 289792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * an async query, and must take care of plugging the new one in 290792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * to the adapter. 291792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 292792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void changeCursor(Cursor cursor) { 294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.changeCursor(cursor); 295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Setting cursor to: " + cursor 296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + " from: " + MusicPicker.this.mCursor); 297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MusicPicker.this.mCursor = cursor; 299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor != null) { 301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Retrieve indices of the various columns we are interested in. 302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIdIdx = cursor.getColumnIndex(MediaStore.Audio.Media._ID); 303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mTitleIdx = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE); 304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mArtistIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); 305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAlbumIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM); 306792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDurationIdx = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION); 3074c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen 3084c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen // If the sort mode has changed, or we haven't yet created an 3094c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen // indexer one, then create a new one that is indexing the 3104c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen // appropriate column based on the sort mode. 3114c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen if (mIndexerSortMode != mSortMode || mIndexer == null) { 3124c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen mIndexerSortMode = mSortMode; 3134c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen int idx = mTitleIdx; 3144c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen switch (mIndexerSortMode) { 3154c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen case ARTIST_MENU: 3164c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen idx = mArtistIdx; 3174c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen break; 3184c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen case ALBUM_MENU: 3194c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen idx = mAlbumIdx; 3204c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen break; 3214c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen } 3224c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen mIndexer = new MusicAlphabetIndexer(cursor, idx, 3233d4b2625018856a506a203e046550afd2d9d8a92Marco Nelissen getResources().getString(R.string.fast_scroll_alphabet)); 3244c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen 3254c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen // If we have a valid indexer, but the cursor has changed since 3264c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen // its last use, then point it to the current cursor. 3274c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen } else { 3284c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen mIndexer.setCursor(cursor); 3294c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen } 330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Ensure that the list is shown (and initial progress indicator 333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // hidden) in case this is the first cursor we have gotten. 334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project makeListShown(); 335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 337792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 338792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This method is called from a background thread by the list view 339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * when the user has typed a letter that should result in a filtering 340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * of the displayed items. It returns a Cursor, when will then be 341792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * handed to changeCursor. 342792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 343792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 344792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public Cursor runQueryOnBackgroundThread(CharSequence constraint) { 345792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Getting new cursor..."); 346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return doQuery(true, constraint.toString()); 347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 349792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getPositionForSection(int section) { 350792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor cursor = getCursor(); 351792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (cursor == null) { 352792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // No cursor, the section doesn't exist so just return 0 353792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return 0; 354792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 355792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mIndexer.getPositionForSection(section); 357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 358792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 359792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getSectionForPosition(int position) { 360792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return 0; 361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public Object[] getSections() { 3644c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen if (mIndexer != null) { 3654c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen return mIndexer.getSections(); 3664c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen } 3674c7fcfad7fd8000d6cc4d99026e895d06b6b5624Marco Nelissen return null; 368792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 369792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 370792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 372792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * This is our specialization of AsyncQueryHandler applies new cursors 373792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * to our state as they become available. 374792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final class QueryHandler extends AsyncQueryHandler { 376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public QueryHandler(Context context) { 377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super(context.getContentResolver()); 378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 379792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 380792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 381792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 382792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!isFinishing()) { 383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Update the adapter: we are no longer loading, and have 384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // a new cursor for it. 385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter.setLoading(false); 386792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter.changeCursor(cursor); 387792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setProgressBarIndeterminateVisibility(false); 388792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 389792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Now that the cursor is populated again, it's possible to restore the list state 390792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mListState != null) { 391792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getListView().onRestoreInstanceState(mListState); 392792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mListHasFocus) { 393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getListView().requestFocus(); 394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 395792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListHasFocus = false; 396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListState = null; 397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 399792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project cursor.close(); 400792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 401792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 402792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 403792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Called when the activity is first created. */ 405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onCreate(Bundle icicle) { 407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onCreate(icicle); 408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 409792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 410792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 411792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int sortMode = TRACK_MENU; 412792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (icicle == null) { 413792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSelectedUri = getIntent().getParcelableExtra( 414792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); 415792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSelectedUri = (Uri)icicle.getParcelable( 417792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); 418792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Retrieve list state. This will be applied after the 419792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // QueryHandler has run 420792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListState = icicle.getParcelable(LIST_STATE_KEY); 421792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListHasFocus = icicle.getBoolean(FOCUS_KEY); 422792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sortMode = icicle.getInt(SORT_MODE_KEY, sortMode); 423792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 424792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (Intent.ACTION_GET_CONTENT.equals(getIntent().getAction())) { 425792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mBaseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 426792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 427792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mBaseUri = getIntent().getData(); 428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mBaseUri == null) { 429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.w("MusicPicker", "No data URI given to PICK action"); 430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project finish(); 431792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 432792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 433792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 434792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 435792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setContentView(R.layout.music_picker); 436792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 437792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortOrder = MediaStore.Audio.Media.TITLE_KEY; 438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project final ListView listView = getListView(); 440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project listView.setItemsCanFocus(false); 442792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 443792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter = new TrackListAdapter(this, listView, 444792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project R.layout.music_picker_item, new String[] {}, 445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new int[] {}); 446792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 447792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setListAdapter(mAdapter); 448792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 449792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project listView.setTextFilterEnabled(true); 450792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 451792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We manually save/restore the listview state 452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project listView.setSaveEnabled(false); 453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mQueryHandler = new QueryHandler(this); 455792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 456792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mProgressContainer = findViewById(R.id.progressContainer); 457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListContainer = findViewById(R.id.listContainer); 458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOkayButton = findViewById(R.id.okayButton); 460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOkayButton.setOnClickListener(this); 461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCancelButton = findViewById(R.id.cancelButton); 462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCancelButton.setOnClickListener(this); 463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // If there is a currently selected Uri, then try to determine who 465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // it is. 466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mSelectedUri != null) { 467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri.Builder builder = mSelectedUri.buildUpon(); 468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String path = mSelectedUri.getEncodedPath(); 469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int idx = path.lastIndexOf('/'); 470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (idx >= 0) { 471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project path = path.substring(0, idx); 472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project builder.encodedPath(path); 474792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri baseSelectedUri = builder.build(); 475792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Selected Uri: " + mSelectedUri); 476792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Selected base Uri: " + baseSelectedUri); 477792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Base Uri: " + mBaseUri); 478792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (baseSelectedUri.equals(mBaseUri)) { 479792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // If the base Uri of the selected Uri is the same as our 480792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // content's base Uri, then use the selection! 481792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSelectedId = ContentUris.parseId(mSelectedUri); 482792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 483792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 484792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 485792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setSortMode(sortMode); 486792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 487792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 488792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override public void onRestart() { 489792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onRestart(); 490792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doQuery(false, null); 491792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 492792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 493792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override public boolean onOptionsItemSelected(MenuItem item) { 494792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (setSortMode(item.getItemId())) { 495792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 496792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 497792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return super.onOptionsItemSelected(item); 498792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 499792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 500792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override public boolean onCreateOptionsMenu(Menu menu) { 501792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onCreateOptionsMenu(menu); 502792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project menu.add(Menu.NONE, TRACK_MENU, Menu.NONE, R.string.sort_by_track); 503792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project menu.add(Menu.NONE, ALBUM_MENU, Menu.NONE, R.string.sort_by_album); 504792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project menu.add(Menu.NONE, ARTIST_MENU, Menu.NONE, R.string.sort_by_artist); 505792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 506792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 507792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 508792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override protected void onSaveInstanceState(Bundle icicle) { 509792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onSaveInstanceState(icicle); 510792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Save list state in the bundle so we can restore it after the 511792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // QueryHandler has run 512792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project icicle.putParcelable(LIST_STATE_KEY, getListView().onSaveInstanceState()); 513792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project icicle.putBoolean(FOCUS_KEY, getListView().hasFocus()); 514792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project icicle.putInt(SORT_MODE_KEY, mSortMode); 515792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 516792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 517792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override public void onPause() { 518792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onPause(); 519792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stopMediaPlayer(); 520792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 521792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 522792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override public void onStop() { 523792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onStop(); 524792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 525792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We don't want the list to display the empty state, since when we 526792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // resume it will still be there and show up while the new query is 527792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // happening. After the async query finishes in response to onResume() 528792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // setLoading(false) will be called. 529792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter.setLoading(true); 530792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter.changeCursor(null); 531792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 532792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 533792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 534792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Changes the current sort order, building the appropriate query string 535792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * for the selected order. 536792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 537792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean setSortMode(int sortMode) { 538792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sortMode != mSortMode) { 539792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project switch (sortMode) { 540792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case TRACK_MENU: 541792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortMode = sortMode; 542792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortOrder = MediaStore.Audio.Media.TITLE_KEY; 543792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doQuery(false, null); 544792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 545792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case ALBUM_MENU: 546792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortMode = sortMode; 547792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortOrder = MediaStore.Audio.Media.ALBUM_KEY + " ASC, " 548792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + MediaStore.Audio.Media.TRACK + " ASC, " 549792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + MediaStore.Audio.Media.TITLE_KEY + " ASC"; 550792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doQuery(false, null); 551792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 552792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case ARTIST_MENU: 553792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortMode = sortMode; 554792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSortOrder = MediaStore.Audio.Media.ARTIST_KEY + " ASC, " 555792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + MediaStore.Audio.Media.ALBUM_KEY + " ASC, " 556792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + MediaStore.Audio.Media.TRACK + " ASC, " 557792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + MediaStore.Audio.Media.TITLE_KEY + " ASC"; 558792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doQuery(false, null); 559792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 560792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 561792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 562792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 563792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 564792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 565792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 566792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 567792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * The first time this is called, we hide the large progress indicator 568792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * and show the list view, doing fade animations between them. 569792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 570792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project void makeListShown() { 571792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!mListShown) { 572792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListShown = true; 573792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mProgressContainer.startAnimation(AnimationUtils.loadAnimation( 574792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project this, android.R.anim.fade_out)); 575792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mProgressContainer.setVisibility(View.GONE); 576792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListContainer.startAnimation(AnimationUtils.loadAnimation( 577792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project this, android.R.anim.fade_in)); 578792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mListContainer.setVisibility(View.VISIBLE); 579792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 580792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 581792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 582792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 583792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Common method for performing a query of the music database, called for 584792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * both top-level queries and filtering. 585792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 586792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param sync If true, this query should be done synchronously and the 587792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * resulting cursor returned. If false, it will be done asynchronously and 588792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * null returned. 589792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param filterstring If non-null, this is a filter to apply to the query. 590792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 591792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor doQuery(boolean sync, String filterstring) { 592792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Cancel any pending queries 593792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mQueryHandler.cancelOperation(MY_QUERY_TOKEN); 594792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 595792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder where = new StringBuilder(); 596792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where.append(MediaStore.Audio.Media.TITLE + " != ''"); 597792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 598792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We want to show all audio files, even recordings. Enforcing the 599792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // following condition would hide recordings. 600792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //where.append(" AND " + MediaStore.Audio.Media.IS_MUSIC + "=1"); 60189f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen 60289f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen Uri uri = mBaseUri; 60389f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen if (!TextUtils.isEmpty(filterstring)) { 60489f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen uri = uri.buildUpon().appendQueryParameter("filter", Uri.encode(filterstring)).build(); 60589f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen } 60689f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen 607792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (sync) { 608792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 60989f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen return getContentResolver().query(uri, CURSOR_COLS, 61089f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen where.toString(), null, mSortOrder); 611792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 612792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 613792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 614792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAdapter.setLoading(true); 615792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setProgressBarIndeterminateVisibility(true); 61689f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen mQueryHandler.startQuery(MY_QUERY_TOKEN, null, uri, CURSOR_COLS, 61789f6c66505717689d9ea3f3d8e81709616b3e588Marco Nelissen where.toString(), null, mSortOrder); 618792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 619792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 620792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 621792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 622792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override protected void onListItemClick(ListView l, View v, int position, 623792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long id) { 624792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.moveToPosition(position); 625792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (DBG) Log.v(TAG, "Click on " + position + " (id=" + id 626792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + ", cursid=" 627792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media._ID)) 628792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + ") in cursor " + mCursor 629792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project + " adapter=" + l.getAdapter()); 630792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setSelected(mCursor); 631792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 632792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 633792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project void setSelected(Cursor c) { 634792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 635792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long newId = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media._ID)); 636792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSelectedUri = ContentUris.withAppendedId(uri, newId); 637792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 638792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mSelectedId = newId; 639792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (newId != mPlayingId || mMediaPlayer == null) { 640792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stopMediaPlayer(); 641792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer = new MediaPlayer(); 642792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 643792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setDataSource(this, mSelectedUri); 644792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnCompletionListener(this); 645792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING); 646792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.prepare(); 647792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.start(); 648792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayingId = newId; 649792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getListView().invalidateViews(); 650792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException e) { 651792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.w("MusicPicker", "Unable to play track", e); 652792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 653792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mMediaPlayer != null) { 654792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stopMediaPlayer(); 655792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getListView().invalidateViews(); 656792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 657792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 658792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 659792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onCompletion(MediaPlayer mp) { 660792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mMediaPlayer == mp) { 661792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mp.stop(); 662792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mp.release(); 663792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer = null; 664792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayingId = -1; 665792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getListView().invalidateViews(); 666792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 667792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 668792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 669792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project void stopMediaPlayer() { 670792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mMediaPlayer != null) { 671792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.stop(); 672792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.release(); 673792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer = null; 674792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayingId = -1; 675792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 676792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 677792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 678792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onClick(View v) { 679792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project switch (v.getId()) { 680792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case R.id.okayButton: 681792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mSelectedId >= 0) { 682792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setResult(RESULT_OK, new Intent().setData(mSelectedUri)); 683792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project finish(); 684792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 685792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 686792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 687792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case R.id.cancelButton: 688792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project finish(); 689792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 690792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 691792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 692792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 693