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 */ 568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissenpublic class AudioPreview extends Activity implements OnPreparedListener, OnErrorListener, OnCompletionListener 578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen{ 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); 778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 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(); 898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 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 134e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int titleIdx = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE); 135e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int artistIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); 136e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int idIdx = cursor.getColumnIndex(MediaStore.Audio.Media._ID); 137e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int displaynameIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); 1388d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (idIdx >=0) { 1408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mMediaId = cursor.getLong(idIdx); 1418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (titleIdx >= 0) { 1448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String title = cursor.getString(titleIdx); 1458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(title); 1468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (artistIdx >= 0) { 1478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String artist = cursor.getString(artistIdx); 1488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setText(artist); 1498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (displaynameIdx >= 0) { 1518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String name = cursor.getString(displaynameIdx); 1528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(name); 1538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Couldn't find anything to display, what to do now? 1558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "Cursor had no names for us"); 1568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "empty cursor"); 1598d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 160e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen 161e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (cursor != null) { 162e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen cursor.close(); 163e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 1648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 1658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 1678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { 1698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mUri.getAuthority() == MediaStore.AUTHORITY) { 1708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // try to get title and artist from the media content provider 1718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAsyncQueryHandler.startQuery(0, null, mUri, new String [] { 1728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST}, 1738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen null, null, null); 1748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1754b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Try to get the display name from another content provider. 1764b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Don't specifically ask for the display name though, since the 1774b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // provider might not actually support that column. 1784b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen mAsyncQueryHandler.startQuery(0, null, mUri, null, null, null, null); 1798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (scheme.equals("file")) { 1818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // check if this file is in the media database (clicking on a download 1828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // in the download manager might follow this path 1838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String path = mUri.getPath(); 1848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAsyncQueryHandler.startQuery(0, null, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 1858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen new String [] {MediaStore.Audio.Media._ID, 1868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST}, 1878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.DATA + "=?", new String [] {path}, null); 1888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // We can't get metadata from the file/stream itself yet, because 1908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // that API is hidden, so instead we display the URI being played 191f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen if (mPlayer.isPrepared()) { 192f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setNames(); 193f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 1948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 198476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen public void onPause() { 199476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen super.onPause(); 200476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mUiPaused = true; 201476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mProgressRefresher != null) { 202476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 203476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 204476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 205476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen 206476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 207476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen public void onResume() { 208476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen super.onResume(); 209476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mUiPaused = false; 210476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mPlayer.isPrepared()) { 211476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen showPostPrepareUI(); 212476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 213476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 214476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen 215476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 2168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public Object onRetainNonConfigurationInstance() { 217f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen PreviewPlayer player = mPlayer; 2188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer = null; 2198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return player; 2208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 2238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onDestroy() { 224f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 225f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onDestroy(); 226f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 227f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 228f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private void stopPlayback() { 229e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (mProgressRefresher != null) { 230e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 231e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 2328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer != null) { 2338d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.release(); 234f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = null; 2358d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(mAudioFocusListener); 2368d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 237f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 238f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 239f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 240f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onUserLeaveHint() { 241f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 242f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen finish(); 243f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onUserLeaveHint(); 2448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onPrepared(MediaPlayer mp) { 2478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (isFinishing()) return; 248f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = (PreviewPlayer) mp; 2498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 250a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mPlayer.start(); 2518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen showPostPrepareUI(); 2528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void showPostPrepareUI() { 2558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ProgressBar pb = (ProgressBar) findViewById(R.id.spinner); 2568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen pb.setVisibility(View.GONE); 2578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mDuration = mPlayer.getDuration(); 258bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mDuration != 0) { 259bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setMax(mDuration); 260bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setVisibility(View.VISIBLE); 261476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (!mSeeking) { 262476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mSeekBar.setProgress(mPlayer.getCurrentPosition()); 263476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 264bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen } 2658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setOnSeekBarChangeListener(mSeekListener); 2668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setVisibility(View.GONE); 2678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen View v = findViewById(R.id.titleandbuttons); 2688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen v.setVisibility(View.VISIBLE); 269a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 270a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 271476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (mProgressRefresher != null) { 272476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 273476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 274476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 2758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 2768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { 2798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onAudioFocusChange(int focusChange) { 2808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer == null) { 2818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // this activity has handed its MediaPlayer off to the next activity 2828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // (e.g. portrait/landscape switch) and should abandon its focus 2838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(this); 2848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 2858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (focusChange) { 2878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS: 2888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 2898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 2928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 2938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 2948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = true; 2958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_GAIN: 2998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPausedByTransientLossOfFocus) { 3008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 3018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 3028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 3048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3078d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 3088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3098d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void start() { 3108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 3118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 3128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.start(); 3138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 3148d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void setNames() { 3178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine1.getText())) { 3188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(mUri.getLastPathSegment()); 3198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine2.getText())) { 3218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.GONE); 3228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.VISIBLE); 3248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen class ProgressRefresher implements Runnable { 3288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 329476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen @Override 3308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void run() { 331bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mPlayer != null && !mSeeking && mDuration != 0) { 3328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mPlayer.getCurrentPosition()); 3338d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3348d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 335476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (!mUiPaused) { 336476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 337476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen } 3388d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void updatePlayPause() { 3428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ImageButton b = (ImageButton) findViewById(R.id.playpause); 343476fb244a96139af3740cf7686fc5408131ba028Marco Nelissen if (b != null && mPlayer != null) { 3448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_pause_small); 3468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_play_small); 3488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 3498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { 3548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStartTrackingTouch(SeekBar bar) { 3558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = true; 3568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { 3588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (!fromuser) { 3598d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 3608d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3614732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on seek bar and exit 3624732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3634732e676e10f22796826dabb916645808561c82asergey return; 3644732e676e10f22796826dabb916645808561c82asergey } 3658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.seekTo(progress); 3668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStopTrackingTouch(SeekBar bar) { 3688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = false; 3698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 3718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onError(MediaPlayer mp, int what, int extra) { 37332905800f25785d072974cab56e72473d904c567Marco Nelissen Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 3748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 3758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 3768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onCompletion(MediaPlayer mp) { 3798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mDuration); 3808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void playPauseClicked(View v) { 3844732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on play/pause and exit 3854732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3864732e676e10f22796826dabb916645808561c82asergey return; 3874732e676e10f22796826dabb916645808561c82asergey } 3888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 3908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 3928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 3978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onCreateOptionsMenu(Menu menu) { 3988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen super.onCreateOptionsMenu(menu); 3998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // TODO: if mMediaId != -1, then the playing file has an entry in the media 4008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // database, and we could open it in the full music app instead. 4018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Ideally, we would hand off the currently running mediaplayer 4028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // to the music UI, which can probably be done via a public static 4038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen menu.add(0, OPEN_IN_MUSIC, 0, "open in music"); 4048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 4078d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 4088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onPrepareOptionsMenu(Menu menu) { 4098d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MenuItem item = menu.findItem(OPEN_IN_MUSIC); 4108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mMediaId >= 0) { 4118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(true); 4128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4148d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(false); 4158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return false; 4168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 4188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 4198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onKeyDown(int keyCode, KeyEvent event) { 4208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (keyCode) { 4218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_HEADSETHOOK: 4228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 4248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 4258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 4268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 4278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 4298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 430cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY: 431cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen start(); 432cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 433cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 434cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PAUSE: 435cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen if (mPlayer.isPlaying()) { 436cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen mPlayer.pause(); 437cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen } 438cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 439cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 4408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 4418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_NEXT: 4428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 4438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_REWIND: 4448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_STOP: 446f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen case KeyEvent.KEYCODE_BACK: 447f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 4488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 4498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return super.onKeyDown(keyCode, event); 4528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 453f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 454f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* 455f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * Wrapper class to help with handing off the MediaPlayer to the next instance 456f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * of the activity in case of orientation change, without losing any state. 457f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 458f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private static class PreviewPlayer extends MediaPlayer implements OnPreparedListener { 459f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen AudioPreview mActivity; 460f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean mIsPrepared = false; 461f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 462f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setActivity(AudioPreview activity) { 463f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity = activity; 464f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnPreparedListener(this); 465f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnErrorListener(mActivity); 466f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnCompletionListener(mActivity); 467f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 468f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 469f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setDataSourceAndPrepare(Uri uri) throws IllegalArgumentException, 470f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen SecurityException, IllegalStateException, IOException { 471f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setDataSource(mActivity,uri); 472f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen prepareAsync(); 473f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 474f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 475f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* (non-Javadoc) 476f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * @see android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer) 477f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 478f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 479f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onPrepared(MediaPlayer mp) { 480f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mIsPrepared = true; 481f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity.onPrepared(mp); 482f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 483f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 484f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean isPrepared() { 485f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen return mIsPrepared; 486f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 487f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 488f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 4898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen} 490