18d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen/* 28d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * Copyright (C) 2010 The Android Open Source Project 38d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * 48d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 58d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * you may not use this file except in compliance with the License. 68d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * You may obtain a copy of the License at 78d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * 88d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 98d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * 108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * Unless required by applicable law or agreed to in writing, software 118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * See the License for the specific language governing permissions and 148d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen * limitations under the License. 158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen */ 168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenpackage com.android.music; 188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.app.Activity; 208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.content.AsyncQueryHandler; 218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.content.ContentResolver; 228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.content.Context; 238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.content.Intent; 248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.database.Cursor; 258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.AudioManager; 268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.MediaPlayer; 278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.AudioManager.OnAudioFocusChangeListener; 288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.MediaPlayer.OnCompletionListener; 298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.MediaPlayer.OnErrorListener; 308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.media.MediaPlayer.OnPreparedListener; 318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.net.Uri; 328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.os.Bundle; 338d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.os.Handler; 348d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.provider.MediaStore; 358d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.provider.OpenableColumns; 368d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.text.TextUtils; 378d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.util.Log; 388d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.KeyEvent; 398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.Menu; 408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.MenuItem; 418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.View; 428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.Window; 438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.view.WindowManager; 448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.widget.ImageButton; 458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.widget.ProgressBar; 468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.widget.SeekBar; 478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.widget.TextView; 488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport android.widget.SeekBar.OnSeekBarChangeListener; 4932905800f25785d072974cab56e72473d904c567Marco Nelissenimport android.widget.Toast; 508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenimport java.io.IOException; 528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 5380b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen/** 5480b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen * Dialog that comes up in response to various music-related VIEW intents. 5580b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen */ 56b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack Hepublic class AudioPreview 57b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He extends Activity implements OnPreparedListener, OnErrorListener, OnCompletionListener { 588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private final static String TAG = "AudioPreview"; 59f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private PreviewPlayer mPlayer; 608d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private TextView mTextLine1; 618d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private TextView mTextLine2; 628d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private TextView mLoadingText; 638d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private SeekBar mSeekBar; 648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private Handler mProgressRefresher; 658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private boolean mSeeking = false; 66476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen private boolean mUiPaused = true; 678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private int mDuration; 688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private Uri mUri; 698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private long mMediaId = -1; 708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private static final int OPEN_IN_MUSIC = 1; 718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private AudioManager mAudioManager; 728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private boolean mPausedByTransientLossOfFocus; 738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onCreate(Bundle icicle) { 768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen super.onCreate(icicle); 77b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Intent intent = getIntent(); 798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (intent == null) { 808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mUri = intent.getData(); 848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mUri == null) { 858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String scheme = mUri.getScheme(); 89b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setVolumeControlStream(AudioManager.STREAM_MUSIC); 918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen requestWindowFeature(Window.FEATURE_NO_TITLE); 928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setContentView(R.layout.audiopreview); 938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1 = (TextView) findViewById(R.id.line1); 958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2 = (TextView) findViewById(R.id.line2); 968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText = (TextView) findViewById(R.id.loading); 978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (scheme.equals("http")) { 988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String msg = getString(R.string.streamloadingtext, mUri.getHost()); 998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setText(msg); 1008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setVisibility(View.GONE); 1028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar = (SeekBar) findViewById(R.id.progress); 1048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher = new Handler(); 1058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 1068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 107f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen PreviewPlayer player = (PreviewPlayer) getLastNonConfigurationInstance(); 1088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (player == null) { 109f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = new PreviewPlayer(); 110f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setActivity(this); 1118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen try { 112f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setDataSourceAndPrepare(mUri); 11380b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen } catch (Exception ex) { 11480b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // catch generic Exception, since we may be called with a media 11580b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // content URI, another content provider's URI, a file URI, 11680b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // an http URI, and there are different exceptions associated 11780b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // with failure to open each of those. 11880b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen Log.d(TAG, "Failed to open file: " + ex); 11980b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 1208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 1218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 1228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 123f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } else { 124f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = player; 125f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setActivity(this); 126476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen // onResume will update the UI 1278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen AsyncQueryHandler mAsyncQueryHandler = new AsyncQueryHandler(getContentResolver()) { 1308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 1318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 132e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (cursor != null && cursor.moveToFirst()) { 133e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int titleIdx = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE); 134e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int artistIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); 135e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int idIdx = cursor.getColumnIndex(MediaStore.Audio.Media._ID); 136e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int displaynameIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); 1378d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 138b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He if (idIdx >= 0) { 1398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mMediaId = cursor.getLong(idIdx); 1408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 141b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 1428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (titleIdx >= 0) { 1438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String title = cursor.getString(titleIdx); 1448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(title); 1458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (artistIdx >= 0) { 1468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String artist = cursor.getString(artistIdx); 1478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setText(artist); 1488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (displaynameIdx >= 0) { 1508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String name = cursor.getString(displaynameIdx); 1518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(name); 1528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Couldn't find anything to display, what to do now? 1548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "Cursor had no names for us"); 1558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "empty cursor"); 1588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 159e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen 160e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (cursor != null) { 161e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen cursor.close(); 162e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 1638d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 1648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 1668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { 1688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mUri.getAuthority() == MediaStore.AUTHORITY) { 1698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // try to get title and artist from the media content provider 170b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He mAsyncQueryHandler.startQuery(0, null, mUri, 171b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He new String[] {MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST}, 1728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen null, null, null); 1738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1744b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Try to get the display name from another content provider. 1754b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Don't specifically ask for the display name though, since the 1764b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // provider might not actually support that column. 1774b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen mAsyncQueryHandler.startQuery(0, null, mUri, null, null, null, null); 1788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (scheme.equals("file")) { 1808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // check if this file is in the media database (clicking on a download 1818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // in the download manager might follow this path 1828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String path = mUri.getPath(); 183b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He mAsyncQueryHandler.startQuery(0, null, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 184b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He new String[] {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE, 185b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He MediaStore.Audio.Media.ARTIST}, 186b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He MediaStore.Audio.Media.DATA + "=?", new String[] {path}, null); 1878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // We can't get metadata from the file/stream itself yet, because 1898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // that API is hidden, so instead we display the URI being played 190f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen if (mPlayer.isPrepared()) { 191f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setNames(); 192f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 1938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 197476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen public void onPause() { 198476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen super.onPause(); 199476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mUiPaused = true; 200476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mProgressRefresher != null) { 201476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 202476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 203476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 204476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen 205476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 206476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen public void onResume() { 207476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen super.onResume(); 208476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mUiPaused = false; 209476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mPlayer.isPrepared()) { 210476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen showPostPrepareUI(); 211476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 212476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 213476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen 214476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 2158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public Object onRetainNonConfigurationInstance() { 216f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen PreviewPlayer player = mPlayer; 2178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer = null; 2188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return player; 2198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 2228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onDestroy() { 223f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 224f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onDestroy(); 225f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 226f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 227f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private void stopPlayback() { 228e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (mProgressRefresher != null) { 229e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 230e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 2318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer != null) { 2328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.release(); 233f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = null; 2348d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(mAudioFocusListener); 2358d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 236f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 237f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 238f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 239f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onUserLeaveHint() { 240f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 241f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen finish(); 242f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onUserLeaveHint(); 2438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onPrepared(MediaPlayer mp) { 2468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (isFinishing()) return; 247f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = (PreviewPlayer) mp; 2488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 249a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mPlayer.start(); 2508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen showPostPrepareUI(); 2518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void showPostPrepareUI() { 2548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ProgressBar pb = (ProgressBar) findViewById(R.id.spinner); 2558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen pb.setVisibility(View.GONE); 2568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mDuration = mPlayer.getDuration(); 257bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mDuration != 0) { 258bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setMax(mDuration); 259bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setVisibility(View.VISIBLE); 260476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (!mSeeking) { 261476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mSeekBar.setProgress(mPlayer.getCurrentPosition()); 262476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 263bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen } 2648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setOnSeekBarChangeListener(mSeekListener); 2658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setVisibility(View.GONE); 2668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen View v = findViewById(R.id.titleandbuttons); 2678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen v.setVisibility(View.VISIBLE); 268a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 269a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 270476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mProgressRefresher != null) { 271476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 272476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 273476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 2748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 2758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 276b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 2778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { 2788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onAudioFocusChange(int focusChange) { 2798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer == null) { 2808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // this activity has handed its MediaPlayer off to the next activity 2818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // (e.g. portrait/landscape switch) and should abandon its focus 2828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(this); 2838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 2848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (focusChange) { 2868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS: 2878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 2888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 2918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 2928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 2938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = true; 2948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_GAIN: 2988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPausedByTransientLossOfFocus) { 2998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 3008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 3018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 3038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 307b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 3088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void start() { 3098d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 3108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 3118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.start(); 3128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 3138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 314b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 3158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void setNames() { 3168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine1.getText())) { 3178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(mUri.getLastPathSegment()); 3188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine2.getText())) { 3208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.GONE); 3218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.VISIBLE); 3238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen class ProgressRefresher implements Runnable { 327476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 3288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void run() { 329bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mPlayer != null && !mSeeking && mDuration != 0) { 3308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mPlayer.getCurrentPosition()); 3318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 333476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (!mUiPaused) { 334476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 335476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 3368d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3378d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 338b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 3398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void updatePlayPause() { 3408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ImageButton b = (ImageButton) findViewById(R.id.playpause); 341476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (b != null && mPlayer != null) { 3428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_pause_small); 3448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_play_small); 3468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 3478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { 3528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStartTrackingTouch(SeekBar bar) { 3538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = true; 3548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { 3568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (!fromuser) { 3578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 3588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3594732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on seek bar and exit 3604732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3614732e676e10f22796826dabb916645808561c82asergey return; 3624732e676e10f22796826dabb916645808561c82asergey } 3638d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.seekTo(progress); 3648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStopTrackingTouch(SeekBar bar) { 3668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = false; 3678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 3698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onError(MediaPlayer mp, int what, int extra) { 37132905800f25785d072974cab56e72473d904c567Marco Nelissen Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 3728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 3738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 3748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onCompletion(MediaPlayer mp) { 3778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mDuration); 3788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void playPauseClicked(View v) { 3824732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on play/pause and exit 3834732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3844732e676e10f22796826dabb916645808561c82asergey return; 3854732e676e10f22796826dabb916645808561c82asergey } 3868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 3888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 3908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 393b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 3948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 3958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onCreateOptionsMenu(Menu menu) { 3968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen super.onCreateOptionsMenu(menu); 3978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // TODO: if mMediaId != -1, then the playing file has an entry in the media 3988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // database, and we could open it in the full music app instead. 3998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Ideally, we would hand off the currently running mediaplayer 4008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // to the music UI, which can probably be done via a public static 4018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen menu.add(0, OPEN_IN_MUSIC, 0, "open in music"); 4028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 4058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 4068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onPrepareOptionsMenu(Menu menu) { 4078d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MenuItem item = menu.findItem(OPEN_IN_MUSIC); 4088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mMediaId >= 0) { 4098d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(true); 4108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(false); 4138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return false; 4148d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 415b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He 4168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 4178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onKeyDown(int keyCode, KeyEvent event) { 4188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (keyCode) { 4198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_HEADSETHOOK: 4208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 4228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 4238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 4248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 4258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 4278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 428cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY: 429cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen start(); 430cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 431cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 432cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PAUSE: 433cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen if (mPlayer.isPlaying()) { 434cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen mPlayer.pause(); 435cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen } 436cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 437cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 4388d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 4398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_NEXT: 4408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 4418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_REWIND: 4428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_STOP: 444f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen case KeyEvent.KEYCODE_BACK: 445f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 4468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 4478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return super.onKeyDown(keyCode, event); 4508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 451f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 452f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* 453f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * Wrapper class to help with handing off the MediaPlayer to the next instance 454f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * of the activity in case of orientation change, without losing any state. 455f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 456f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private static class PreviewPlayer extends MediaPlayer implements OnPreparedListener { 457f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen AudioPreview mActivity; 458f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean mIsPrepared = false; 459f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 460f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setActivity(AudioPreview activity) { 461f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity = activity; 462f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnPreparedListener(this); 463f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnErrorListener(mActivity); 464f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnCompletionListener(mActivity); 465f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 466f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 467f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setDataSourceAndPrepare(Uri uri) throws IllegalArgumentException, 468b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He SecurityException, 469b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He IllegalStateException, IOException { 470b0fba8b212a649f41c7cad4c9e7c33e94ca29bb0Jack He setDataSource(mActivity, uri); 471f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen prepareAsync(); 472f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 473f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 474f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* (non-Javadoc) 475f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * @see android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer) 476f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 477f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 478f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onPrepared(MediaPlayer mp) { 479f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mIsPrepared = true; 480f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity.onPrepared(mp); 481f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 482f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 483f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean isPrepared() { 484f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen return mIsPrepared; 485f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 486f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 4878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen} 488