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; 668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private int mDuration; 678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private Uri mUri; 688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private long mMediaId = -1; 698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private static final int OPEN_IN_MUSIC = 1; 708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private AudioManager mAudioManager; 718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private boolean mPausedByTransientLossOfFocus; 728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onCreate(Bundle icicle) { 758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen super.onCreate(icicle); 768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Intent intent = getIntent(); 788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (intent == null) { 798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mUri = intent.getData(); 838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mUri == null) { 848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String scheme = mUri.getScheme(); 888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setVolumeControlStream(AudioManager.STREAM_MUSIC); 908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen requestWindowFeature(Window.FEATURE_NO_TITLE); 918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setContentView(R.layout.audiopreview); 928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1 = (TextView) findViewById(R.id.line1); 948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2 = (TextView) findViewById(R.id.line2); 958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText = (TextView) findViewById(R.id.loading); 968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (scheme.equals("http")) { 978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String msg = getString(R.string.streamloadingtext, mUri.getHost()); 988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setText(msg); 998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setVisibility(View.GONE); 1018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar = (SeekBar) findViewById(R.id.progress); 1038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher = new Handler(); 1048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 1058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 106f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen PreviewPlayer player = (PreviewPlayer) getLastNonConfigurationInstance(); 1078d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (player == null) { 108f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = new PreviewPlayer(); 109f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setActivity(this); 1108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen try { 111f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setDataSourceAndPrepare(mUri); 11280b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen } catch (Exception ex) { 11380b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // catch generic Exception, since we may be called with a media 11480b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // content URI, another content provider's URI, a file URI, 11580b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // an http URI, and there are different exceptions associated 11680b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen // with failure to open each of those. 11780b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen Log.d(TAG, "Failed to open file: " + ex); 11880b9ee1600d16f0b2dde128685290ddefb5dc89aMarco Nelissen Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 1198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 1208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 1218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 122f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } else { 123f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = player; 124f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer.setActivity(this); 125f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen if (mPlayer.isPrepared()) { 126f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen showPostPrepareUI(); 127f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 1288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen AsyncQueryHandler mAsyncQueryHandler = new AsyncQueryHandler(getContentResolver()) { 1318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 1328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 133e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (cursor != null && cursor.moveToFirst()) { 134e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen 135e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int titleIdx = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE); 136e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int artistIdx = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); 137e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int idIdx = cursor.getColumnIndex(MediaStore.Audio.Media._ID); 138e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen int displaynameIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); 1398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (idIdx >=0) { 1418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mMediaId = cursor.getLong(idIdx); 1428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (titleIdx >= 0) { 1458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String title = cursor.getString(titleIdx); 1468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(title); 1478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (artistIdx >= 0) { 1488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String artist = cursor.getString(artistIdx); 1498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setText(artist); 1508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (displaynameIdx >= 0) { 1528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String name = cursor.getString(displaynameIdx); 1538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(name); 1548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Couldn't find anything to display, what to do now? 1568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "Cursor had no names for us"); 1578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1598d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen Log.w(TAG, "empty cursor"); 1608d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 161e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen 162e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (cursor != null) { 163e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen cursor.close(); 164e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 1658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 1668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 1688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { 1708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mUri.getAuthority() == MediaStore.AUTHORITY) { 1718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // try to get title and artist from the media content provider 1728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAsyncQueryHandler.startQuery(0, null, mUri, new String [] { 1738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST}, 1748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen null, null, null); 1758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1764b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Try to get the display name from another content provider. 1774b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // Don't specifically ask for the display name though, since the 1784b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen // provider might not actually support that column. 1794b83a8c009d8dcc3ed66505604101ee757f5a99fMarco Nelissen mAsyncQueryHandler.startQuery(0, null, mUri, null, null, null, null); 1808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else if (scheme.equals("file")) { 1828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // check if this file is in the media database (clicking on a download 1838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // in the download manager might follow this path 1848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen String path = mUri.getPath(); 1858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAsyncQueryHandler.startQuery(0, null, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 1868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen new String [] {MediaStore.Audio.Media._ID, 1878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST}, 1888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MediaStore.Audio.Media.DATA + "=?", new String [] {path}, null); 1898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 1908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // We can't get metadata from the file/stream itself yet, because 1918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // that API is hidden, so instead we display the URI being played 192f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen if (mPlayer.isPrepared()) { 193f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setNames(); 194f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 1958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 1978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 1988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 1998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public Object onRetainNonConfigurationInstance() { 200f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen PreviewPlayer player = mPlayer; 2018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer = null; 2028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return player; 2038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 2068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onDestroy() { 207f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 208f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onDestroy(); 209f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 210f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 211f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private void stopPlayback() { 212e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen if (mProgressRefresher != null) { 213e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 214e1d2fb1745f10c9206e8972f783273866b3df1dcMarco Nelissen } 2158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer != null) { 2168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.release(); 217f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = null; 2188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(mAudioFocusListener); 2198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 220f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 221f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 222f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 223f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onUserLeaveHint() { 224f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 225f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen finish(); 226f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen super.onUserLeaveHint(); 2278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onPrepared(MediaPlayer mp) { 2308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (isFinishing()) return; 231f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mPlayer = (PreviewPlayer) mp; 2328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen setNames(); 233a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mPlayer.start(); 2348d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen showPostPrepareUI(); 2358d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2368d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2378d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void showPostPrepareUI() { 2388d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ProgressBar pb = (ProgressBar) findViewById(R.id.spinner); 2398d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen pb.setVisibility(View.GONE); 2408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mDuration = mPlayer.getDuration(); 241bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mDuration != 0) { 242bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setMax(mDuration); 243bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen mSeekBar.setVisibility(View.VISIBLE); 244bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen } 2458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setOnSeekBarChangeListener(mSeekListener); 2468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mLoadingText.setVisibility(View.GONE); 2478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen View v = findViewById(R.id.titleandbuttons); 2488d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen v.setVisibility(View.VISIBLE); 249a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 250a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 251a3e7351123432c29401a46438c9a4bf4ed2d5d0fMarco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 2528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 2538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { 2568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onAudioFocusChange(int focusChange) { 2578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer == null) { 2588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // this activity has handed its MediaPlayer off to the next activity 2598d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // (e.g. portrait/landscape switch) and should abandon its focus 2608d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.abandonAudioFocus(this); 2618d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 2628d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2638d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (focusChange) { 2648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS: 2658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 2668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 2698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 2708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 2718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = true; 2728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 2738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case AudioManager.AUDIOFOCUS_GAIN: 2768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPausedByTransientLossOfFocus) { 2778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPausedByTransientLossOfFocus = false; 2788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 2798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen break; 2818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 2838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 2858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void start() { 2878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 2888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 2898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.start(); 2908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 2918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 2938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void setNames() { 2948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine1.getText())) { 2958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine1.setText(mUri.getLastPathSegment()); 2968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 2978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (TextUtils.isEmpty(mTextLine2.getText())) { 2988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.GONE); 2998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mTextLine2.setVisibility(View.VISIBLE); 3018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen class ProgressRefresher implements Runnable { 3058d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3068d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void run() { 307bc7fa6597f72c1ddeae6b6a2f150140d84319ebfMarco Nelissen if (mPlayer != null && !mSeeking && mDuration != 0) { 3088d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen int progress = mPlayer.getCurrentPosition() / mDuration; 3098d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mPlayer.getCurrentPosition()); 3108d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3118d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 3128d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.postDelayed(new ProgressRefresher(), 200); 3138d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3148d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private void updatePlayPause() { 3178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen ImageButton b = (ImageButton) findViewById(R.id.playpause); 3188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (b != null) { 3198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_pause_small); 3218d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3228d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen b.setImageResource(R.drawable.btn_playback_ic_play_small); 3238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mProgressRefresher.removeCallbacksAndMessages(null); 3248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3288d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { 3298d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStartTrackingTouch(SeekBar bar) { 3308d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = true; 3318d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3328d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { 3338d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (!fromuser) { 3348d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return; 3358d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3364732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on seek bar and exit 3374732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3384732e676e10f22796826dabb916645808561c82asergey return; 3394732e676e10f22796826dabb916645808561c82asergey } 3408d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.seekTo(progress); 3418d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3428d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onStopTrackingTouch(SeekBar bar) { 3438d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeeking = false; 3448d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3458d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen }; 3468d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3478d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onError(MediaPlayer mp, int what, int extra) { 34832905800f25785d072974cab56e72473d904c567Marco Nelissen Toast.makeText(this, R.string.playback_failed, Toast.LENGTH_SHORT).show(); 3498d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 3508d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 3518d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3528d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3538d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void onCompletion(MediaPlayer mp) { 3548d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mSeekBar.setProgress(mDuration); 3558d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3568d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3578d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3588d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public void playPauseClicked(View v) { 3594732e676e10f22796826dabb916645808561c82asergey // Protection for case of simultaneously tapping on play/pause and exit 3604732e676e10f22796826dabb916645808561c82asergey if (mPlayer == null) { 3614732e676e10f22796826dabb916645808561c82asergey return; 3624732e676e10f22796826dabb916645808561c82asergey } 3638d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 3658d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 3668d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 3678d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3688d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 3698d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3708d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3718d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 3728d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onCreateOptionsMenu(Menu menu) { 3738d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen super.onCreateOptionsMenu(menu); 3748d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // TODO: if mMediaId != -1, then the playing file has an entry in the media 3758d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // database, and we could open it in the full music app instead. 3768d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // Ideally, we would hand off the currently running mediaplayer 3778d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen // to the music UI, which can probably be done via a public static 3788d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen menu.add(0, OPEN_IN_MUSIC, 0, "open in music"); 3798d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 3808d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3818d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3828d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 3838d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onPrepareOptionsMenu(Menu menu) { 3848d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen MenuItem item = menu.findItem(OPEN_IN_MUSIC); 3858d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mMediaId >= 0) { 3868d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(true); 3878d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 3888d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3898d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen item.setVisible(false); 3908d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return false; 3918d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 3928d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen 3938d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen @Override 3948d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen public boolean onKeyDown(int keyCode, KeyEvent event) { 3958d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen switch (keyCode) { 3968d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_HEADSETHOOK: 3978d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 3988d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen if (mPlayer.isPlaying()) { 3998d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen mPlayer.pause(); 4008d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } else { 4018d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen start(); 4028d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4038d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen updatePlayPause(); 4048d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 405cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PLAY: 406cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen start(); 407cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 408cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 409cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen case KeyEvent.KEYCODE_MEDIA_PAUSE: 410cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen if (mPlayer.isPlaying()) { 411cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen mPlayer.pause(); 412cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen } 413cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen updatePlayPause(); 414cb3dc09ab1e96891a06adbcd11fe3047ccf8f494Marco Nelissen return true; 4158d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 4168d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_NEXT: 4178d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 4188d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_REWIND: 4198d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4208d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen case KeyEvent.KEYCODE_MEDIA_STOP: 421f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen case KeyEvent.KEYCODE_BACK: 422f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen stopPlayback(); 4238d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen finish(); 4248d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return true; 4258d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 4268d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen return super.onKeyDown(keyCode, event); 4278d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen } 428f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 429f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* 430f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * Wrapper class to help with handing off the MediaPlayer to the next instance 431f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * of the activity in case of orientation change, without losing any state. 432f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 433f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen private static class PreviewPlayer extends MediaPlayer implements OnPreparedListener { 434f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen AudioPreview mActivity; 435f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean mIsPrepared = false; 436f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 437f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setActivity(AudioPreview activity) { 438f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity = activity; 439f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnPreparedListener(this); 440f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnErrorListener(mActivity); 441f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setOnCompletionListener(mActivity); 442f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 443f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 444f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void setDataSourceAndPrepare(Uri uri) throws IllegalArgumentException, 445f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen SecurityException, IllegalStateException, IOException { 446f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen setDataSource(mActivity,uri); 447f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen prepareAsync(); 448f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 449f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 450f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen /* (non-Javadoc) 451f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen * @see android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer) 452f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen */ 453f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen @Override 454f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen public void onPrepared(MediaPlayer mp) { 455f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mIsPrepared = true; 456f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen mActivity.onPrepared(mp); 457f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 458f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 459f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen boolean isPrepared() { 460f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen return mIsPrepared; 461f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 462f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen } 463f98e6c60a6db78adb2fe4afbce53b849767eaaecMarco Nelissen 4648d08ec235831d71fdd7f7b6f7757c2bc19528faeMarco Nelissen} 465