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