MediaPlaybackService.java revision 792a2206a4f05f6bd13fce902d3663892d2947af
1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/* 2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Copyright (C) 2007 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.Notification; 20792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.app.NotificationManager; 21792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.app.PendingIntent; 22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.app.Service; 23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentResolver; 24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentUris; 25792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.ContentValues; 26792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Context; 27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Intent; 28792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.IntentFilter; 29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.BroadcastReceiver; 30792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.SharedPreferences; 31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.SharedPreferences.Editor; 32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.database.Cursor; 33792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.database.sqlite.SQLiteException; 34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.gadget.GadgetManager; 35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.AudioManager; 36792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.MediaFile; 37792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.MediaPlayer; 38792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.net.Uri; 39792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Environment; 40792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.FileUtils; 41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Handler; 42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.IBinder; 43792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Message; 44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.PowerManager; 45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.SystemClock; 46792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.PowerManager.WakeLock; 47792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.provider.MediaStore; 48792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.util.Log; 49792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.RemoteViews; 50792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.Toast; 51792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport com.android.internal.telephony.Phone; 52792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport com.android.internal.telephony.PhoneStateIntentReceiver; 53792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.io.IOException; 55792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.util.Random; 56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport java.util.Vector; 57792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 58792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/** 59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Provides "background" audio playback capabilities, allowing the 60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * user to switch between activities without stopping playback. 61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 62792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpublic class MediaPlaybackService extends Service { 63792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** used to specify whether enqueue() should start playing 64792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the new list of files right away, next or once all the currently 65792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * queued files have been played 66792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 67792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int NOW = 1; 68792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int NEXT = 2; 69792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int LAST = 3; 70792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int PLAYBACKSERVICE_STATUS = 1; 71792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int SHUFFLE_NONE = 0; 73792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int SHUFFLE_NORMAL = 1; 74792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int SHUFFLE_AUTO = 2; 75792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 76792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int REPEAT_NONE = 0; 77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int REPEAT_CURRENT = 1; 78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final int REPEAT_ALL = 2; 79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 80792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged"; 81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String META_CHANGED = "com.android.music.metachanged"; 82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String QUEUE_CHANGED = "com.android.music.queuechanged"; 83792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String PLAYBACK_COMPLETE = "com.android.music.playbackcomplete"; 84792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String ASYNC_OPEN_COMPLETE = "com.android.music.asyncopencomplete"; 85792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 86792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String SERVICECMD = "com.android.music.musicservicecommand"; 87792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDNAME = "command"; 88792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDTOGGLEPAUSE = "togglepause"; 89792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDSTOP = "stop"; 90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDPAUSE = "pause"; 91792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDPREVIOUS = "previous"; 92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String CMDNEXT = "next"; 93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String TOGGLEPAUSE_ACTION = "com.android.music.musicservicecommand.togglepause"; 95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String PAUSE_ACTION = "com.android.music.musicservicecommand.pause"; 96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String PREVIOUS_ACTION = "com.android.music.musicservicecommand.previous"; 97792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public static final String NEXT_ACTION = "com.android.music.musicservicecommand.next"; 98792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 99792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int PHONE_CHANGED = 1; 100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int TRACK_ENDED = 1; 101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int RELEASE_WAKELOCK = 2; 102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int SERVER_DIED = 3; 103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int FADEIN = 4; 104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int MAX_HISTORY_SIZE = 10; 105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private MultiPlayer mPlayer; 107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private String mFileToPlay; 108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private PhoneStateIntentReceiver mPsir; 109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mShuffleMode = SHUFFLE_NONE; 110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mRepeatMode = REPEAT_NONE; 111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mMediaMountedCount = 0; 112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int [] mAutoShuffleList = null; 113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mOneShot; 114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int [] mPlayList = null; 115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mPlayListLen = 0; 116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Vector<Integer> mHistory = new Vector<Integer>(MAX_HISTORY_SIZE); 117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Cursor mCursor; 118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mPlayPos = -1; 119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final String LOGTAG = "MediaPlaybackService"; 120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final Shuffler mRand = new Shuffler(); 121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mOpenFailedCounter = 0; 122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String[] mCursorCols = new String[] { 123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project "audio._id AS _id", // index must match IDCOLIDX below 124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ARTIST, 125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ALBUM, 126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.TITLE, 127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.DATA, 128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.MIME_TYPE, 129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ALBUM_ID, 130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.ARTIST_ID, 131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.IS_PODCAST, // index must match PODCASTCOLIDX below 132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.BOOKMARK // index must match BOOKMARKCOLIDX below 133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final static int IDCOLIDX = 0; 135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final static int PODCASTCOLIDX = 8; 136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final static int BOOKMARKCOLIDX = 9; 137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private BroadcastReceiver mUnmountReceiver = null; 138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private WakeLock mWakeLock; 139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mServiceStartId = -1; 140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mServiceInUse = false; 141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mResumeAfterCall = false; 142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mWasPlaying = false; 143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mQuietMode = false; 144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 145792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private SharedPreferences mPreferences; 146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // We use this to distinguish between different cards when saving/restoring playlists. 147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This will have to change if we want to support multiple simultaneous cards. 148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mCardId; 149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private MediaGadgetProvider mGadgetProvider = MediaGadgetProvider.getInstance(); 151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // interval after which we stop the service when idle 153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private static final int IDLE_DELAY = 60000; 154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Handler mPhoneHandler = new Handler() { 156792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 157792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void handleMessage(Message msg) { 158792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project switch (msg.what) { 159792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case PHONE_CHANGED: 160792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Phone.State state = mPsir.getPhoneState(); 161792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (state == Phone.State.RINGING) { 162792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 163792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int ringvolume = audioManager.getStreamVolume(AudioManager.STREAM_RING); 164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (ringvolume > 0) { 165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mResumeAfterCall = (isPlaying() || mResumeAfterCall) && (getAudioId() >= 0); 166792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 167792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 168792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (state == Phone.State.OFFHOOK) { 169792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // pause the music while a conversation is in progress 170792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mResumeAfterCall = (isPlaying() || mResumeAfterCall) && (getAudioId() >= 0); 171792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 172792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (state == Phone.State.IDLE) { 173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // start playing again 174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mResumeAfterCall) { 175792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // resume playback only if music was playing 176792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // when the call was answered 177792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project startAndFadeIn(); 178792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mResumeAfterCall = false; 179792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 180792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 182792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project default: 183792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 184792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 185792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 186792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 187792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 188792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void startAndFadeIn() { 189792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaplayerHandler.sendEmptyMessageDelayed(FADEIN, 10); 190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Handler mMediaplayerHandler = new Handler() { 193792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project float mCurrentVolume = 1.0f; 194792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void handleMessage(Message msg) { 196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project switch (msg.what) { 197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case FADEIN: 198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!isPlaying()) { 199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCurrentVolume = 0f; 200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.setVolume(mCurrentVolume); 201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaplayerHandler.sendEmptyMessageDelayed(FADEIN, 10); 203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCurrentVolume += 0.01f; 205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCurrentVolume < 1.0f) { 206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaplayerHandler.sendEmptyMessageDelayed(FADEIN, 10); 207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCurrentVolume = 1.0f; 209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.setVolume(mCurrentVolume); 211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case SERVER_DIED: 214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mWasPlaying) { 215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project next(true); 216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the server died when we were idle, so just 218792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // reopen the same song (it will start again 219792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // from the beginning though when the user 220792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // restarts) 221792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 222792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 223792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 224792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case TRACK_ENDED: 225792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mRepeatMode == REPEAT_CURRENT) { 226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(0); 227792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (!mOneShot) { 229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project next(false); 230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 231792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(PLAYBACK_COMPLETE); 232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 233792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 234792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case RELEASE_WAKELOCK: 235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWakeLock.release(); 236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project default: 238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 241792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 243792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 244792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onReceive(Context context, Intent intent) { 246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String action = intent.getAction(); 247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String cmd = intent.getStringExtra("command"); 248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (CMDNEXT.equals(cmd) || NEXT_ACTION.equals(action)) { 249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project next(true); 250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDPREVIOUS.equals(cmd) || PREVIOUS_ACTION.equals(action)) { 251792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project prev(); 252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDTOGGLEPAUSE.equals(cmd) || TOGGLEPAUSE_ACTION.equals(action)) { 253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying()) { 254792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 256792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDPAUSE.equals(cmd) || PAUSE_ACTION.equals(action)) { 259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDSTOP.equals(cmd)) { 261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 262792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(0); 263792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (MediaGadgetProvider.CMDGADGETUPDATE.equals(cmd)) { 264792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Someone asked us to refresh a set of specific gadgets, probably 265792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // because they were just added. 266792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int[] gadgetIds = intent.getIntArrayExtra(GadgetManager.EXTRA_GADGET_IDS); 267792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mGadgetProvider.performUpdate(MediaPlaybackService.this, gadgetIds); 268792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 269792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 270792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 271792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 272792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public MediaPlaybackService() { 273792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPsir = new PhoneStateIntentReceiver(this, mPhoneHandler); 274792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPsir.notifyPhoneCallState(PHONE_CHANGED); 275792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 276792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 277792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 278792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onCreate() { 279792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onCreate(); 280792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 281792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPreferences = getSharedPreferences("Music", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE); 282792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCardId = FileUtils.getFatVolumeId(Environment.getExternalStorageDirectory().getPath()); 283792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 284792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project registerExternalStorageListener(); 285792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 286792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Needs to be done in this thread, since otherwise ApplicationContext.getPowerManager() crashes. 287792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer = new MultiPlayer(); 288792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.setHandler(mMediaplayerHandler); 289792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 290792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Clear leftover notification in case this service previously got killed while playing 291792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 292792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nm.cancel(PLAYBACKSERVICE_STATUS); 293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project reloadQueue(); 295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project IntentFilter commandFilter = new IntentFilter(); 297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project commandFilter.addAction(SERVICECMD); 298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project commandFilter.addAction(TOGGLEPAUSE_ACTION); 299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project commandFilter.addAction(PAUSE_ACTION); 300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project commandFilter.addAction(NEXT_ACTION); 301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project commandFilter.addAction(PREVIOUS_ACTION); 302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project registerReceiver(mIntentReceiver, commandFilter); 303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPsir.registerIntent(); 305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 306792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName()); 307792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWakeLock.setReferenceCounted(false); 308792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 309792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // If the service was idle, but got killed before it stopped itself, the 310792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // system will relaunch it. Make sure it gets stopped again in that case. 311792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Message msg = mDelayedStopHandler.obtainMessage(); 312792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY); 313792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 314792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 315792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 316792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onDestroy() { 317792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Check that we're not being destroyed while something is still playing. 318792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying()) { 319792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Log.e("MediaPlaybackService", "Service being destroyed while still playing."); 320792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 321792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and for good measure, call mPlayer.stop(), which calls MediaPlayer.reset(), which 322792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // releases the MediaPlayer's wake lock, if any. 323792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.stop(); 324792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 325792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor != null) { 326792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.close(); 327792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = null; 328792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 329792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project unregisterReceiver(mIntentReceiver); 331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mUnmountReceiver != null) { 332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project unregisterReceiver(mUnmountReceiver); 333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mUnmountReceiver = null; 334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPsir.unregisterIntent(); 336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWakeLock.release(); 337792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project super.onDestroy(); 338792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final char hexdigits [] = new char [] { 341792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project '0', '1', '2', '3', 342792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project '4', '5', '6', '7', 343792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project '8', '9', 'a', 'b', 344792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 'c', 'd', 'e', 'f' 345792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void saveQueue(boolean full) { 348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mOneShot) { 349792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 350792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 351792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Editor ed = mPreferences.edit(); 352792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //long start = System.currentTimeMillis(); 353792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (full) { 354792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project StringBuilder q = new StringBuilder(); 355792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The current playlist is saved as a list of "reverse hexadecimal" 357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // numbers, which we can generate faster than normal decimal or 358792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // hexadecimal numbers, which in turn allows us to save the playlist 359792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // more often without worrying too much about performance. 360792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // (saving the full state takes about 40 ms under no-load conditions 361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // on the phone) 362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = mPlayListLen; 363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int n = mPlayList[i]; 365792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (n == 0) { 366792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project q.append("0;"); 367792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 368792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (n != 0) { 369792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int digit = n & 0xf; 370792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project n >>= 4; 371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project q.append(hexdigits[digit]); 372792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 373792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project q.append(";"); 374792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //Log.i("@@@@ service", "created queue string in " + (System.currentTimeMillis() - start) + " ms"); 377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putString("queue", q.toString()); 378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt("cardid", mCardId); 379792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 380792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt("curpos", mPlayPos); 381792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 382792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putLong("seekpos", mPlayer.position()); 383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt("repeatmode", mRepeatMode); 385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.putInt("shufflemode", mShuffleMode); 386792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ed.commit(); 387792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 388792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //Log.i("@@@@ service", "saved state in " + (System.currentTimeMillis() - start) + " ms"); 389792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 390792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 391792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void reloadQueue() { 392792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String q = null; 393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean newstyle = false; 395792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int id = mCardId; 396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPreferences.contains("cardid")) { 397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project newstyle = true; 398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project id = mPreferences.getInt("cardid", ~mCardId); 399792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 400792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (id == mCardId) { 401792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Only restore the saved playlist if the card is still 402792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the same one as when the playlist was saved 403792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project q = mPreferences.getString("queue", ""); 404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (q != null && q.length() > 1) { 406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //Log.i("@@@@ service", "loaded queue: " + q); 407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String [] entries = q.split(";"); 408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = entries.length; 409792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(len); 410792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 411792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (newstyle) { 412792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String revhex = entries[i]; 413792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int n = 0; 414792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int j = revhex.length() - 1; j >= 0 ; j--) { 415792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project n <<= 4; 416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project char c = revhex.charAt(j); 417792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c >= '0' && c <= '9') { 418792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project n += (c - '0'); 419792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (c >= 'a' && c <= 'f') { 420792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project n += (10 + c - 'a'); 421792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 422792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // bogus playlist data 423792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project len = 0; 424792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 425792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 426792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 427792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[i] = n; 428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[i] = Integer.parseInt(entries[i]); 430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 431792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 432792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = len; 433792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 434792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int pos = mPreferences.getInt("curpos", 0); 435792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (pos < 0 || pos >= len) { 436792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The saved playlist is bogus, discard it 437792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 0; 438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = pos; 441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 442792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // When reloadQueue is called in response to a card-insertion, 443792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we might not be able to query the media provider right away. 444792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // To deal with this, try querying for the current file, and if 445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // that fails, wait a while and try again. If that too fails, 446792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // assume there is a problem and don't restore the state. 447792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = MusicUtils.query(this, 448792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 449792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String [] {"_id"}, "_id=" + mPlayList[mPlayPos] , null, null); 450792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c == null || c.getCount() == 0) { 451792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // wait a bit and try again 452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project SystemClock.sleep(3000); 453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c = getContentResolver().query( 454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 455792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursorCols, "_id=" + mPlayList[mPlayPos] , null, null); 456792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Make sure we don't auto-skip to the next song, since that 462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // also starts playback. What could happen in that case is: 463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // - music is paused 464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // - go to UMS and delete some files, including the currently playing one 465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // - come back from UMS 466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // (time passes) 467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // - music app is killed for some reason (out of memory) 468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // - music service is restarted, service restores state, doesn't find 469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the "current" file, goes to the next and: playback starts on its 470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // own, potentially at some random inconvenient time. 471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOpenFailedCounter = 20; 472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mQuietMode = true; 473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 474792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mQuietMode = false; 475792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!mPlayer.isInitialized()) { 476792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // couldn't restore the saved state 477792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 0; 478792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 479792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 480792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 481792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long seekpos = mPreferences.getLong("seekpos", 0); 482792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(seekpos >= 0 && seekpos < duration() ? seekpos : 0); 483792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 484792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int repmode = mPreferences.getInt("repeatmode", REPEAT_NONE); 485792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (repmode != REPEAT_ALL && repmode != REPEAT_CURRENT) { 486792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project repmode = REPEAT_NONE; 487792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 488792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mRepeatMode = repmode; 489792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 490792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int shufmode = mPreferences.getInt("shufflemode", SHUFFLE_NONE); 491792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (shufmode != SHUFFLE_AUTO && shufmode != SHUFFLE_NORMAL) { 492792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project shufmode = SHUFFLE_NONE; 493792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 494792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (shufmode == SHUFFLE_AUTO) { 495792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (! makeAutoShuffleList()) { 496792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project shufmode = SHUFFLE_NONE; 497792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 498792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 499792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mShuffleMode = shufmode; 500792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 501792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 502792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 503792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 504792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public IBinder onBind(Intent intent) { 505792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.removeCallbacksAndMessages(null); 506792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mServiceInUse = true; 507792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mBinder; 508792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 509792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 510792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 511792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onRebind(Intent intent) { 512792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.removeCallbacksAndMessages(null); 513792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mServiceInUse = true; 514792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 515792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 516792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 517792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onStart(Intent intent, int startId) { 518792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mServiceStartId = startId; 519792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.removeCallbacksAndMessages(null); 520792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 521792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String action = intent.getAction(); 522792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String cmd = intent.getStringExtra("command"); 523792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 524792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (CMDNEXT.equals(cmd) || NEXT_ACTION.equals(action)) { 525792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project next(true); 526792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDPREVIOUS.equals(cmd) || PREVIOUS_ACTION.equals(action)) { 527792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project prev(); 528792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDTOGGLEPAUSE.equals(cmd) || TOGGLEPAUSE_ACTION.equals(action)) { 529792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying()) { 530792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 531792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 532792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 533792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 534792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDPAUSE.equals(cmd) || PAUSE_ACTION.equals(action)) { 535792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 536792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (CMDSTOP.equals(cmd)) { 537792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pause(); 538792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(0); 539792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 540792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 541792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // make sure the service will shut down on its own if it was 542792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // just started but not bound to and nothing is playing 543792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.removeCallbacksAndMessages(null); 544792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Message msg = mDelayedStopHandler.obtainMessage(); 545792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY); 546792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 547792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 548792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 549792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean onUnbind(Intent intent) { 550792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mServiceInUse = false; 551792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 552792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Take a snapshot of the current playlist 553792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(true); 554792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 555792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying() || mResumeAfterCall) { 556792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // something is currently playing, or will be playing once 557792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // an in-progress call ends, so don't stop the service now. 558792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 559792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 560792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 561792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // If there is a playlist but playback is paused, then wait a while 562792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // before stopping the service, so that pause/resume isn't slow. 563792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Also delay stopping the service if we're transitioning between tracks. 564792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayListLen > 0 || mMediaplayerHandler.hasMessages(TRACK_ENDED)) { 565792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Message msg = mDelayedStopHandler.obtainMessage(); 566792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY); 567792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 568792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 569792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 570792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // No active playlist, OK to stop the service right now 571792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stopSelf(mServiceStartId); 572792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 573792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 574792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 575792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Handler mDelayedStopHandler = new Handler() { 576792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 577792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void handleMessage(Message msg) { 578792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Check again to make sure nothing is playing right now 579792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying() || mResumeAfterCall || mServiceInUse 580792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project || mMediaplayerHandler.hasMessages(TRACK_ENDED)) { 581792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 582792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 583792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // save the queue again, because it might have changed 584792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // since the user exited the music app (because of 585792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // party-shuffle or because the play-position changed) 586792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(true); 587792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stopSelf(mServiceStartId); 588792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 589792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 590792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 591792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 592792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Called when we receive a ACTION_MEDIA_EJECT notification. 593792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 594792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param storagePath path to mount point for the removed media 595792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 596792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void closeExternalStorageFiles(String storagePath) { 597792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // stop playback and clean up if the SD card is going to be unmounted. 598792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(true); 599792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 600792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 601792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 602792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 603792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 604792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Registers an intent to listen for ACTION_MEDIA_EJECT notifications. 605792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * The intent will call closeExternalStorageFiles() if the external media 606792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * is going to be ejected, so applications can clean up any files they have open. 607792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 608792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void registerExternalStorageListener() { 609792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mUnmountReceiver == null) { 610792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mUnmountReceiver = new BroadcastReceiver() { 611792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project @Override 612792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onReceive(Context context, Intent intent) { 613792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String action = intent.getAction(); 614792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 615792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(true); 616792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOneShot = true; // This makes us not save the state again later, 617792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // which would be wrong because the song ids and 618792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // card id might not match. 619792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project closeExternalStorageFiles(intent.getData().getPath()); 620792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 621792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaMountedCount++; 622792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCardId = FileUtils.getFatVolumeId(intent.getData().getPath()); 623792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project reloadQueue(); 624792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 625792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 626792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 627792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 628792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 629792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project IntentFilter iFilter = new IntentFilter(); 630792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iFilter.addAction(Intent.ACTION_MEDIA_EJECT); 631792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); 632792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project iFilter.addDataScheme("file"); 633792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project registerReceiver(mUnmountReceiver, iFilter); 634792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 635792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 636792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 637792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 638792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Notify the change-receivers that something has changed. 639792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * The intent that is sent contains the following data 640792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * for the currently playing track: 641792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "id" - Integer: the database row ID 642792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "artist" - String: the name of the artist 643792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "album" - String: the name of the album 644792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "track" - String: the name of the track 645792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * The intent has an action that is one of 646792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "com.android.music.metachanged" 647792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "com.android.music.queuechanged", 648792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "com.android.music.playbackcomplete" 649792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * "com.android.music.playstatechanged" 650792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * respectively indicating that a new track has 651792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * started playing, that the playback queue has 652792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * changed, that playback has stopped because 653792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the last file in the list has been played, 654792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * or that the play-state changed (paused/resumed). 655792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 656792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void notifyChange(String what) { 657792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 658792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent i = new Intent(what); 659792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project i.putExtra("id", Integer.valueOf(getAudioId())); 660792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project i.putExtra("artist", getArtistName()); 661792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project i.putExtra("album",getAlbumName()); 662792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project i.putExtra("track", getTrackName()); 663792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project sendBroadcast(i); 664792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 665792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (what.equals(QUEUE_CHANGED)) { 666792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(true); 667792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 668792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(false); 669792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 670792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 671792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Share this notification directly with our gadgets 672792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mGadgetProvider.notifyChange(this, what); 673792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 674792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 675792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void ensurePlayListCapacity(int size) { 676792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayList == null || size > mPlayList.length) { 677792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // reallocate at 2x requested size so we don't 678792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // need to grow and copy the array for every 679792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // insert 680792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int [] newlist = new int[size * 2]; 681792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = mPlayListLen; 682792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 683792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project newlist[i] = mPlayList[i]; 684792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 685792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList = newlist; 686792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 687792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // FIXME: shrink the array when the needed size is much smaller 688792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // than the allocated size 689792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 690792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 691792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // insert the list of songs at the specified position in the playlist 692792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void addToPlayList(int [] list, int position) { 693792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int addlen = list.length; 694792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position < 0) { // overwrite 695792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 0; 696792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project position = 0; 697792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 698792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(mPlayListLen + addlen); 699792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position > mPlayListLen) { 700792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project position = mPlayListLen; 701792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 702792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 703792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // move part of list after insertion point 704792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int tailsize = mPlayListLen - position; 705792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = tailsize ; i > 0 ; i--) { 706792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[position + i] = mPlayList[position + i - addlen]; 707792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 708792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 709792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // copy list into playlist 710792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < addlen; i++) { 711792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[position + i] = list[i]; 712792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 713792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen += addlen; 714792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 715792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 716792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 717792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Appends a list of tracks to the current playlist. 718792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * If nothing is playing currently, playback will be started at 719792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the first track. 720792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * If the action is NOW, playback will switch to the first of 721792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the new tracks immediately. 722792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param list The list of tracks to append. 723792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param action NOW, NEXT or LAST 724792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 725792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void enqueue(int [] list, int action) { 726792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 727792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (action == NEXT && mPlayPos + 1 < mPlayListLen) { 728792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project addToPlayList(list, mPlayPos + 1); 729792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 730792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 731792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // action == LAST || action == NOW || mPlayPos + 1 == mPlayListLen 732792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project addToPlayList(list, Integer.MAX_VALUE); 733792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 734792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (action == NOW) { 735792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = mPlayListLen - list.length; 736792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 737792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 738792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 739792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 740792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 741792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 742792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos < 0) { 743792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = 0; 744792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 745792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 746792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 747792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 748792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 749792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 750792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 751792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 752792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Replaces the current playlist with a new list, 753792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * and prepares for starting playback at the specified 754792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * position in the list, or a random position if the 755792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * specified position is 0. 756792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param list The new list of tracks. 757792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 758792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void open(int [] list, int position) { 759792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 760792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mShuffleMode == SHUFFLE_AUTO) { 761792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mShuffleMode = SHUFFLE_NORMAL; 762792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 763792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int listlength = list.length; 764792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean newlist = true; 765792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayListLen == listlength) { 766792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // possible fast path: list might be the same 767792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project newlist = false; 768792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < listlength; i++) { 769792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (list[i] != mPlayList[i]) { 770792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project newlist = true; 771792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 772792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 773792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 774792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 775792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (newlist) { 776792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project addToPlayList(list, -1); 777792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 778792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 779792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int oldpos = mPlayPos; 780792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (position >= 0) { 781792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = position; 782792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 783792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = mRand.nextInt(mPlayListLen); 784792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 785792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHistory.clear(); 786792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 787792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveBookmarkIfNeeded(); 788792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 789792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!newlist && mPlayPos != oldpos) { 790792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // the queue didn't change, but the position did 791792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 792792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 793792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 794792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 795792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 796792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 797792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Moves the item at index1 to index2. 798792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param index1 799792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param index2 800792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 801792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void moveQueueItem(int index1, int index2) { 802792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 803792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (index1 >= mPlayListLen) { 804792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project index1 = mPlayListLen - 1; 805792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 806792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (index2 >= mPlayListLen) { 807792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project index2 = mPlayListLen - 1; 808792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 809792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (index1 < index2) { 810792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int tmp = mPlayList[index1]; 811792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = index1; i < index2; i++) { 812792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[i] = mPlayList[i+1]; 813792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 814792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[index2] = tmp; 815792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos == index1) { 816792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = index2; 817792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mPlayPos >= index1 && mPlayPos <= index2) { 818792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos--; 819792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 820792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (index2 < index1) { 821792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int tmp = mPlayList[index1]; 822792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = index1; i > index2; i--) { 823792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[i] = mPlayList[i-1]; 824792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 825792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[index2] = tmp; 826792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos == index1) { 827792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = index2; 828792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mPlayPos >= index2 && mPlayPos <= index1) { 829792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos++; 830792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 831792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 832792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 833792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 834792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 835792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 836792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 837792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the current play list 838792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @return An array of integers containing the IDs of the tracks in the play list 839792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 840792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int [] getQueue() { 841792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 842792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = mPlayListLen; 843792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int [] list = new int[len]; 844792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 845792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project list[i] = mPlayList[i]; 846792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 847792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return list; 848792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 849792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 850792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 851792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void openCurrent() { 852792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 853792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor != null) { 854792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.close(); 855792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = null; 856792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 857792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayListLen == 0) { 858792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 859792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 860792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(false); 861792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 862792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String id = String.valueOf(mPlayList[mPlayPos]); 863792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 864792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = getContentResolver().query( 865792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 866792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursorCols, "_id=" + id , null, null); 867792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor != null) { 868792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.moveToFirst(); 869792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project open(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "/" + id, false); 870792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // go to bookmark if needed 871792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPodcast()) { 872792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long bookmark = getBookmark(); 873792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Start playing a little bit before the bookmark, 874792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // so it's easier to get back in to the narrative. 875792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(bookmark - 5000); 876792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 877792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 878792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 879792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 880792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 881792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void openAsync(String path) { 882792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 883792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (path == null) { 884792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 885792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 886792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 887792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mRepeatMode = REPEAT_NONE; 888792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(1); 889792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 1; 890792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = -1; 891792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 892792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mFileToPlay = path; 893792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = null; 894792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.setDataSourceAsync(mFileToPlay); 895792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOneShot = true; 896792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 897792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 898792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 899792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 900792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Opens the specified file and readies it for playback. 901792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 902792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param path The full path of the file to be opened. 903792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param oneshot when set to true, playback will stop after this file completes, instead 904792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * of moving on to the next track in the list 905792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 906792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void open(String path, boolean oneshot) { 907792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 908792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (path == null) { 909792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 910792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 911792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 912792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (oneshot) { 913792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mRepeatMode = REPEAT_NONE; 914792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(1); 915792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 1; 916792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = -1; 917792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 918792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 919792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // if mCursor is null, try to associate path with a database cursor 920792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 921792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 922792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver resolver = getContentResolver(); 923792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri; 924792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String where; 925792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String selectionArgs[]; 926792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (path.startsWith("content://media/")) { 927792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project uri = Uri.parse(path); 928792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where = null; 929792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project selectionArgs = null; 930792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 931792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project uri = MediaStore.Audio.Media.getContentUriForPath(path); 932792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project where = MediaStore.Audio.Media.DATA + "=?"; 933792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project selectionArgs = new String[] { path }; 934792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 935792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 936792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 937792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = resolver.query(uri, mCursorCols, where, selectionArgs, null); 938792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor != null) { 939792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor.getCount() == 0) { 940792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.close(); 941792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = null; 942792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 943792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.moveToNext(); 944792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(1); 945792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 1; 946792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[0] = mCursor.getInt(IDCOLIDX); 947792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = 0; 948792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 949792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 950792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (UnsupportedOperationException ex) { 951792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 952792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 953792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mFileToPlay = path; 954792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.setDataSource(mFileToPlay); 955792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOneShot = oneshot; 956792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (! mPlayer.isInitialized()) { 957792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(true); 958792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mOpenFailedCounter++ < 10 && mPlayListLen > 1) { 959792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // beware: this ends up being recursive because next() calls open() again. 960792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project next(false); 961792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 962792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (! mPlayer.isInitialized() && mOpenFailedCounter != 0) { 963792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // need to make sure we only shows this once 964792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOpenFailedCounter = 0; 965792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!mQuietMode) { 966792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 967792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 968792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 969792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 970792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mOpenFailedCounter = 0; 971792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 972792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 973792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 974792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 975792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 976792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Starts playback of a previously opened file. 977792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 978792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void play() { 979792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 980792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.start(); 981792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setForeground(true); 982792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 983792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project NotificationManager nm = (NotificationManager) 984792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getSystemService(Context.NOTIFICATION_SERVICE); 985792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 986792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project RemoteViews views = new RemoteViews(getPackageName(), R.layout.statusbar); 987792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project views.setImageViewResource(R.id.icon, R.drawable.stat_notify_musicplayer); 988792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (getAudioId() < 0) { 989792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // streaming 990792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project views.setTextViewText(R.id.trackname, getPath()); 991792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project views.setTextViewText(R.id.artistalbum, null); 992792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 993792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String artist = getArtistName(); 994792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project views.setTextViewText(R.id.trackname, getTrackName()); 995792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (artist == null || artist.equals(MediaFile.UNKNOWN_STRING)) { 996792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project artist = getString(R.string.unknown_artist_name); 997792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 998792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project String album = getAlbumName(); 999792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (album == null || album.equals(MediaFile.UNKNOWN_STRING)) { 1000792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project album = getString(R.string.unknown_album_name); 1001792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1002792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1003792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project views.setTextViewText(R.id.artistalbum, 1004792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getString(R.string.notification_artist_album, artist, album) 1005792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ); 1006792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1007792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1008792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Intent statusintent = new Intent("com.android.music.PLAYBACK_VIEWER"); 1009792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project statusintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 1010792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Notification status = new Notification(); 1011792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.contentView = views; 1012792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.flags |= Notification.FLAG_ONGOING_EVENT; 1013792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.icon = R.drawable.stat_notify_musicplayer; 1014792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project status.contentIntent = PendingIntent.getActivity(this, 0, 1015792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new Intent("com.android.music.PLAYBACK_VIEWER"), 0); 1016792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nm.notify(PLAYBACKSERVICE_STATUS, status); 1017792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (!mWasPlaying) { 1018792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(PLAYSTATE_CHANGED); 1019792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1020792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWasPlaying = true; 1021792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mPlayListLen <= 0) { 1022792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This is mostly so that if you press 'play' on a bluetooth headset 1023792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // without every having played anything before, it will still play 1024792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // something. 1025792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setShuffleMode(SHUFFLE_AUTO); 1026792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1027792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1028792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1029792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void stop(boolean remove_status_icon) { 1030792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 1031792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.stop(); 1032792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1033792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mFileToPlay = null; 1034792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor != null) { 1035792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor.close(); 1036792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mCursor = null; 1037792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1038792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (remove_status_icon) { 1039792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project gotoIdleState(); 1040792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1041792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setForeground(false); 1042792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (remove_status_icon) { 1043792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWasPlaying = false; 1044792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1045792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1046792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1047792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1048792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Stops playback. 1049792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1050792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void stop() { 1051792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(true); 1052792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1053792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1054792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1055792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Pauses playback (call play() to resume) 1056792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1057792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void pause() { 1058792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPlaying()) { 1059792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayer.pause(); 1060792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project gotoIdleState(); 1061792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project setForeground(false); 1062792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWasPlaying = false; 1063792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(PLAYSTATE_CHANGED); 1064792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveBookmarkIfNeeded(); 1065792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1066792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1067792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1068792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** Returns whether playback is currently paused 1069792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 1070792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @return true if playback is paused, false if not 1071792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1072792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean isPlaying() { 1073792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 1074792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayer.isPlaying(); 1075792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1076792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 1077792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1078792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1079792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /* 1080792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Desired behavior for prev/next/shuffle: 1081792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1082792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project - NEXT will move to the next track in the list when not shuffling, and to 1083792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a track randomly picked from the not-yet-played tracks when shuffling. 1084792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project If all tracks have already been played, pick from the full set, but 1085792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project avoid picking the previously played track if possible. 1086792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project - when shuffling, PREV will go to the previously played track. Hitting PREV 1087792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project again will go to the track played before that, etc. When the start of the 1088792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project history has been reached, PREV is a no-op. 1089792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project When not shuffling, PREV will go to the sequentially previous track (the 1090792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project difference with the shuffle-case is mainly that when not shuffling, the 1091792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project user can back up to tracks that are not in the history). 1092792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1093792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Example: 1094792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project When playing an album with 10 tracks from the start, and enabling shuffle 1095792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while playing track 5, the remaining tracks (6-10) will be shuffled, e.g. 1096792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project the final play order might be 1-2-3-4-5-8-10-6-9-7. 1097792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project When hitting 'prev' 8 times while playing track 7 in this example, the 1098792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project user will go to tracks 9-6-10-8-5-4-3-2. If the user then hits 'next', 1099792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project a random track will be picked again. If at any time user disables shuffling 1100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project the next/previous track will be picked in sequential order again. 1101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void prev() { 1104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mOneShot) { 1106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we were playing a specific file not part of a playlist, so there is no 'previous' 1107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(0); 1108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mShuffleMode == SHUFFLE_NORMAL) { 1112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // go to previously-played track and remove it from the history 1113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int histsize = mHistory.size(); 1114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (histsize == 0) { 1115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // prev is a no-op 1116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Integer pos = mHistory.remove(histsize - 1); 1119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = pos.intValue(); 1120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos > 0) { 1122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos--; 1123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = mPlayListLen - 1; 1125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveBookmarkIfNeeded(); 1128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(false); 1129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 1130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 1132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void next(boolean force) { 1136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mOneShot) { 1138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we were playing a specific file not part of a playlist, so there is no 'next' 1139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project seek(0); 1140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Store the current file in the history, but keep the history at a 1145792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // reasonable size 1146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos >= 0) { 1147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHistory.add(Integer.valueOf(mPlayPos)); 1148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mHistory.size() > MAX_HISTORY_SIZE) { 1150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHistory.removeElementAt(0); 1151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mShuffleMode == SHUFFLE_NORMAL) { 1154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Pick random next track from the not-yet-played ones 1155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // TODO: make it work right after adding/removing items in the queue. 1156792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1157792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int numTracks = mPlayListLen; 1158792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int[] tracks = new int[numTracks]; 1159792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i=0;i < numTracks; i++) { 1160792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project tracks[i] = i; 1161792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1162792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1163792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int numHistory = mHistory.size(); 1164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int numUnplayed = numTracks; 1165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i=0;i < numHistory; i++) { 1166792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int idx = mHistory.get(i).intValue(); 1167792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (idx < numTracks && tracks[idx] >= 0) { 1168792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project numUnplayed--; 1169792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project tracks[idx] = -1; 1170792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1171792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1172792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // 'numUnplayed' now indicates how many tracks have not yet 1174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // been played, and 'tracks' contains the indices of those 1175792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // tracks. 1176792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numUnplayed <=0) { 1177792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // everything's already been played 1178792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mRepeatMode == REPEAT_ALL || force) { 1179792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project //pick from full set 1180792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project numUnplayed = numTracks; 1181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i=0;i < numTracks; i++) { 1182792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project tracks[i] = i; 1183792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1184792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1185792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // all done 1186792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project gotoIdleState(); 1187792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1188792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1189792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int skip = mRand.nextInt(numUnplayed); 1191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int cnt = -1; 1192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (true) { 1193792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project while (tracks[++cnt] < 0) 1194792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ; 1195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project skip--; 1196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (skip < 0) { 1197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 1198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = cnt; 1201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mShuffleMode == SHUFFLE_AUTO) { 1202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doAutoShuffleUpdate(); 1203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos++; 1204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos >= mPlayListLen - 1) { 1206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // we're at the end of the list 1207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mRepeatMode == REPEAT_NONE && !force) { 1208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // all done 1209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project gotoIdleState(); 1210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(PLAYBACK_COMPLETE); 1211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mRepeatMode == REPEAT_ALL || force) { 1213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = 0; 1214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos++; 1217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1218792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1219792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveBookmarkIfNeeded(); 1220792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(false); 1221792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 1222792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1223792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 1224792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1225792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1227792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void gotoIdleState() { 1228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project NotificationManager nm = 1229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 1230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project nm.cancel(PLAYBACKSERVICE_STATUS); 1231792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.removeCallbacksAndMessages(null); 1232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Message msg = mDelayedStopHandler.obtainMessage(); 1233792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY); 1234792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void saveBookmarkIfNeeded() { 1237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (isPodcast()) { 1239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long pos = position(); 1240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long bookmark = getBookmark(); 1241792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project long duration = duration(); 1242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if ((pos < bookmark && (pos + 10000) > bookmark) || 1243792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project (pos > bookmark && (pos - 10000) < bookmark)) { 1244792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // The existing bookmark is close to the current 1245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // position, so don't update it. 1246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (pos < 15000 || (pos + 10000) > duration) { 1249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // if we're near the start or end, clear the bookmark 1250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project pos = 0; 1251792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // write 'pos' to the bookmark field 1254792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentValues values = new ContentValues(); 1255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project values.put(MediaStore.Audio.Media.BOOKMARK, pos); 1256792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Uri uri = ContentUris.withAppendedId( 1257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, mCursor.getLong(IDCOLIDX)); 1258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project getContentResolver().update(uri, values, null, null); 1259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (SQLiteException ex) { 1261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1262792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1263792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1264792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Make sure there are at least 5 items after the currently playing item 1265792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and no more than 10 items before. 1266792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private void doAutoShuffleUpdate() { 1267792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean notify = false; 1268792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // remove old entries 1269792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos > 10) { 1270792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project removeTracks(0, mPlayPos - 9); 1271792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notify = true; 1272792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1273792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // add new entries if needed 1274792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int to_add = 7 - (mPlayListLen - (mPlayPos < 0 ? -1 : mPlayPos)); 1275792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < to_add; i++) { 1276792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // pick something at random from the list 1277792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int idx = mRand.nextInt(mAutoShuffleList.length); 1278792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Integer which = mAutoShuffleList[idx]; 1279792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ensurePlayListCapacity(mPlayListLen + 1); 1280792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[mPlayListLen++] = which; 1281792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notify = true; 1282792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1283792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (notify) { 1284792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 1285792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1286792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1287792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1288792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // A simple variation of Random that makes sure that the 1289792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // value it returns is not equal to the value it returned 1290792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // previously, unless the interval is 1. 1291792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private class Shuffler { 1292792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int mPrevious; 1293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Random mRandom = new Random(); 1294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int nextInt(int interval) { 1295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int ret; 1296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project do { 1297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ret = mRandom.nextInt(interval); 1298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } while (ret == mPrevious && interval > 1); 1299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPrevious = ret; 1300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return ret; 1301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean makeAutoShuffleList() { 1305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentResolver res = getContentResolver(); 1306792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Cursor c = null; 1307792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1308792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c = res.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 1309792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project new String[] {MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.IS_MUSIC + "=1", 1310792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project null, null); 1311792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c == null || c.getCount() == 0) { 1312792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 1313792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1314792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int len = c.getCount(); 1315792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int[] list = new int[len]; 1316792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < len; i++) { 1317792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.moveToNext(); 1318792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project list[i] = c.getInt(0); 1319792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1320792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mAutoShuffleList = list; 1321792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 1322792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (RuntimeException ex) { 1323792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } finally { 1324792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (c != null) { 1325792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project c.close(); 1326792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1327792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1328792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 1329792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Removes the range of tracks specified from the play list. If a file within the range is 1333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * the file currently being played, playback will move to the next file after the 1334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * range. 1335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param first The first file to be removed 1336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param last The last file to be removed 1337792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @return the number of tracks deleted 1338792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int removeTracks(int first, int last) { 1340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int numremoved = removeTracksInternal(first, last); 1341792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numremoved > 0) { 1342792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 1343792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1344792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return numremoved; 1345792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private int removeTracksInternal(int first, int last) { 1348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1349792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (last < first) return 0; 1350792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (first < 0) first = 0; 1351792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (last >= mPlayListLen) last = mPlayListLen - 1; 1352792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1353792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean gotonext = false; 1354792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (first <= mPlayPos && mPlayPos <= last) { 1355792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = first; 1356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project gotonext = true; 1357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else if (mPlayPos > last) { 1358792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos -= (last - first + 1); 1359792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1360792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int num = mPlayListLen - last - 1; 1361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < num; i++) { 1362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayList[first + i] = mPlayList[last + 1 + i]; 1363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen -= last - first + 1; 1365792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1366792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (gotonext) { 1367792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayListLen == 0) { 1368792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(true); 1369792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = -1; 1370792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos >= mPlayListLen) { 1372792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = 0; 1373792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1374792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project boolean wasPlaying = isPlaying(); 1375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(false); 1376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 1377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (wasPlaying) { 1378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1379792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1380792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1381792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1382792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return last - first + 1; 1383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1386792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1387792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Removes all instances of the track with the given id 1388792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * from the playlist. 1389792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param id The id to be removed 1390792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @return how many instances of the track were removed 1391792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1392792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int removeTrack(int id) { 1393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project int numremoved = 0; 1394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1395792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project for (int i = 0; i < mPlayListLen; i++) { 1396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayList[i] == id) { 1397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project numremoved += removeTracksInternal(i, i); 1398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project i--; 1399792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1400792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1401792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1402792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (numremoved > 0) { 1403792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(QUEUE_CHANGED); 1404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return numremoved; 1406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setShuffleMode(int shufflemode) { 1409792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 1410792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mShuffleMode == shufflemode && mPlayListLen > 0) { 1411792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1412792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1413792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mShuffleMode = shufflemode; 1414792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mShuffleMode == SHUFFLE_AUTO) { 1415792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (makeAutoShuffleList()) { 1416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayListLen = 0; 1417792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project doAutoShuffleUpdate(); 1418792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = 0; 1419792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 1420792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1421792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 1422792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1423792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1424792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // failed to build a list of files to shuffle 1425792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mShuffleMode = SHUFFLE_NONE; 1426792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1427792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(false); 1429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1431792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getShuffleMode() { 1432792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mShuffleMode; 1433792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1434792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1435792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setRepeatMode(int repeatmode) { 1436792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 1437792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mRepeatMode = repeatmode; 1438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project saveQueue(false); 1439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getRepeatMode() { 1442792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mRepeatMode; 1443792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1444792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getMediaMountedCount() { 1446792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mMediaMountedCount; 1447792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1448792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1449792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1450792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the path of the currently playing file, or null if 1451792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * no file is currently playing. 1452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getPath() { 1454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mFileToPlay; 1455792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1456792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the rowid of the currently playing file, or -1 if 1459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * no file is currently playing. 1460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getAudioId() { 1462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayPos >= 0 && mPlayer.isInitialized()) { 1464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayList[mPlayPos]; 1465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the position in the queue 1472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @return the position in the queue 1473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1474792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getQueuePosition() { 1475792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 1476792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayPos; 1477792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1478792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1479792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1480792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1481792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Starts playing the track at the given position in the queue. 1482792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param pos The position in the queue of the track that will be played. 1483792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1484792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setQueuePosition(int pos) { 1485792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 1486792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project stop(false); 1487792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mPlayPos = pos; 1488792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project openCurrent(); 1489792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project play(); 1490792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(META_CHANGED); 1491792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1492792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1493792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1494792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getArtistName() { 1495792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized(this) { 1496792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1497792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 1498792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1499792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); 1500792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1501792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1502792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1503792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getArtistId() { 1504792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1505792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1506792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1507792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1508792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getInt(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST_ID)); 1509792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1510792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1511792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1512792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getAlbumName() { 1513792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1514792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1515792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 1516792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1517792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); 1518792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1519792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1520792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1521792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getAlbumId() { 1522792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1523792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1524792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1525792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1526792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getInt(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)); 1527792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1528792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1529792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1530792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getTrackName() { 1531792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1532792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1533792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return null; 1534792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1535792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); 1536792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1537792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1538792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1539792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean isPodcast() { 1540792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1541792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1542792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 1543792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1544792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return (mCursor.getInt(PODCASTCOLIDX) > 0); 1545792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1546792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1547792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1548792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private long getBookmark() { 1549792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project synchronized (this) { 1550792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mCursor == null) { 1551792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return 0; 1552792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1553792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mCursor.getLong(BOOKMARKCOLIDX); 1554792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1555792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1556792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1557792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1558792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the duration of the file in milliseconds. 1559792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Currently this method returns -1 for the duration of MIDI files. 1560792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1561792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long duration() { 1562792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 1563792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayer.duration(); 1564792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1565792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1566792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1567792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1568792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1569792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Returns the current playback position in milliseconds 1570792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1571792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long position() { 1572792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 1573792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayer.position(); 1574792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1575792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1576792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1577792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1578792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1579792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Seeks to the position specified. 1580792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * 1581792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * @param pos The position to seek to, in milliseconds 1582792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1583792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long seek(long pos) { 1584792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (mPlayer.isInitialized()) { 1585792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (pos < 0) pos = 0; 1586792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (pos > mPlayer.duration()) pos = mPlayer.duration(); 1587792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mPlayer.seek(pos); 1588792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1589792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return -1; 1590792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1591792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1592792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project /** 1593792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Provides a unified interface for dealing with midi files and 1594792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * other media files. 1595792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */ 1596792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private class MultiPlayer { 1597792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private MediaPlayer mMediaPlayer = new MediaPlayer(); 1598792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private Handler mHandler; 1599792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private boolean mIsInitialized = false; 1600792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1601792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public MultiPlayer() { 1602792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setWakeMode(MediaPlaybackService.this, PowerManager.PARTIAL_WAKE_LOCK); 1603792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1604792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1605792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setDataSourceAsync(String path) { 1606792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1607792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.reset(); 1608792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setDataSource(path); 1609792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 1610792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnPreparedListener(preparedlistener); 1611792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.prepareAsync(); 1612792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException ex) { 1613792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // TODO: notify the user why the file couldn't be opened 1614792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1615792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1616792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IllegalArgumentException ex) { 1617792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // TODO: notify the user why the file couldn't be opened 1618792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1619792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1620792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1621792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnCompletionListener(listener); 1622792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnErrorListener(errorListener); 1623792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1624792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = true; 1625792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1626792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1627792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setDataSource(String path) { 1628792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project try { 1629792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.reset(); 1630792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnPreparedListener(null); 1631792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (path.startsWith("content://")) { 1632792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setDataSource(MediaPlaybackService.this, Uri.parse(path)); 1633792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } else { 1634792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setDataSource(path); 1635792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1636792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 1637792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.prepare(); 1638792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IOException ex) { 1639792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // TODO: notify the user why the file couldn't be opened 1640792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1641792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1642792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } catch (IllegalArgumentException ex) { 1643792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // TODO: notify the user why the file couldn't be opened 1644792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1645792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return; 1646792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1647792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnCompletionListener(listener); 1648792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setOnErrorListener(errorListener); 1649792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1650792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = true; 1651792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1652792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1653792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean isInitialized() { 1654792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mIsInitialized; 1655792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1656792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1657792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void start() { 1658792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.start(); 1659792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1660792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1661792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void stop() { 1662792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.reset(); 1663792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1664792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1665792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1666792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void pause() { 1667792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.pause(); 1668792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1669792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1670792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean isPlaying() { 1671792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mMediaPlayer.isPlaying(); 1672792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1673792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1674792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setHandler(Handler handler) { 1675792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHandler = handler; 1676792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1677792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1678792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() { 1679792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onCompletion(MediaPlayer mp) { 1680792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Acquire a temporary wakelock, since when we return from 1681792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // this callback the MediaPlayer will release its wakelock 1682792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // and allow the device to go to sleep. 1683792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This temporary wakelock is released when the RELEASE_WAKELOCK 1684792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // message is processed, but just in case, put a timeout on it. 1685792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mWakeLock.acquire(30000); 1686792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHandler.sendEmptyMessage(TRACK_ENDED); 1687792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHandler.sendEmptyMessage(RELEASE_WAKELOCK); 1688792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1689792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1690792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1691792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlayer.OnPreparedListener preparedlistener = new MediaPlayer.OnPreparedListener() { 1692792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void onPrepared(MediaPlayer mp) { 1693792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project notifyChange(ASYNC_OPEN_COMPLETE); 1694792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1695792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1696792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1697792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlayer.OnErrorListener errorListener = new MediaPlayer.OnErrorListener() { 1698792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean onError(MediaPlayer mp, int what, int extra) { 1699792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project switch (what) { 1700792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project case MediaPlayer.MEDIA_ERROR_SERVER_DIED: 1701792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mIsInitialized = false; 1702792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.release(); 1703792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Creating a new MediaPlayer and settings its wakemode does not 1704792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // require the media service, so it's OK to do this now, while the 1705792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // service is still being restarted 1706792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer = new MediaPlayer(); 1707792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setWakeMode(MediaPlaybackService.this, PowerManager.PARTIAL_WAKE_LOCK); 1708792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mHandler.sendMessageDelayed(mHandler.obtainMessage(SERVER_DIED), 2000); 1709792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return true; 1710792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project default: 1711792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project break; 1712792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1713792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return false; 1714792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1715792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1716792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1717792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long duration() { 1718792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mMediaPlayer.getDuration(); 1719792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1720792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1721792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long position() { 1722792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return mMediaPlayer.getCurrentPosition(); 1723792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1724792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1725792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long seek(long whereto) { 1726792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.seekTo((int) whereto); 1727792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return whereto; 1728792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1729792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1730792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setVolume(float vol) { 1731792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project mMediaPlayer.setVolume(vol, vol); 1732792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1733792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1734792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 1735792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private final IMediaPlaybackService.Stub mBinder = new IMediaPlaybackService.Stub() 1736792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project { 1737792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void openfileAsync(String path) 1738792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project { 1739792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.openAsync(path); 1740792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1741792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void openfile(String path) 1742792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project { 1743792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.open(path, true); 1744792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1745792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void open(int [] list, int position) { 1746792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.open(list, position); 1747792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1748792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getQueuePosition() { 1749792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getQueuePosition(); 1750792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1751792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setQueuePosition(int index) { 1752792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.setQueuePosition(index); 1753792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1754792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public boolean isPlaying() { 1755792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.isPlaying(); 1756792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1757792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void stop() { 1758792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.stop(); 1759792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1760792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void pause() { 1761792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.pause(); 1762792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1763792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void play() { 1764792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.play(); 1765792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1766792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void prev() { 1767792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.prev(); 1768792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1769792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void next() { 1770792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.next(true); 1771792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1772792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getTrackName() { 1773792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getTrackName(); 1774792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1775792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getAlbumName() { 1776792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getAlbumName(); 1777792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1778792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getAlbumId() { 1779792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getAlbumId(); 1780792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1781792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getArtistName() { 1782792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getArtistName(); 1783792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1784792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getArtistId() { 1785792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getArtistId(); 1786792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1787792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void enqueue(int [] list , int action) { 1788792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.enqueue(list, action); 1789792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1790792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int [] getQueue() { 1791792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getQueue(); 1792792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1793792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void moveQueueItem(int from, int to) { 1794792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.moveQueueItem(from, to); 1795792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1796792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public String getPath() { 1797792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getPath(); 1798792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1799792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getAudioId() { 1800792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getAudioId(); 1801792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1802792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long position() { 1803792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.position(); 1804792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1805792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long duration() { 1806792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.duration(); 1807792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1808792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public long seek(long pos) { 1809792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.seek(pos); 1810792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1811792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setShuffleMode(int shufflemode) { 1812792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.setShuffleMode(shufflemode); 1813792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1814792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getShuffleMode() { 1815792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getShuffleMode(); 1816792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1817792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int removeTracks(int first, int last) { 1818792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.removeTracks(first, last); 1819792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1820792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int removeTrack(int id) { 1821792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.removeTrack(id); 1822792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1823792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public void setRepeatMode(int repeatmode) { 1824792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project MediaPlaybackService.this.setRepeatMode(repeatmode); 1825792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1826792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getRepeatMode() { 1827792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getRepeatMode(); 1828792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1829792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public int getMediaMountedCount() { 1830792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return MediaPlaybackService.this.getMediaMountedCount(); 1831792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 1832792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project }; 1833792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 1834