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