diff options
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/camera/MenuHelper.java | 7 | ||||
-rw-r--r-- | src/com/android/camera/MovieView.java | 214 | ||||
-rw-r--r-- | src/com/android/camera/MovieViewControl.java | 221 |
3 files changed, 238 insertions, 204 deletions
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index 1a92057..35f0028 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -21,6 +21,7 @@ import com.android.camera.gallery.IImage; import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.location.Address; @@ -970,7 +971,7 @@ public class MenuHelper { addCaptureVideoMenuItems(menu, activity); } - public static String formatDuration(final Activity activity, + public static String formatDuration(final Context context, int durationMs) { int duration = durationMs / 1000; int h = duration / 3600; @@ -979,10 +980,10 @@ public class MenuHelper { String durationValue; if (h == 0) { durationValue = String.format( - activity.getString(R.string.details_ms), m, s); + context.getString(R.string.details_ms), m, s); } else { durationValue = String.format( - activity.getString(R.string.details_hms), h, m, s); + context.getString(R.string.details_hms), h, m, s); } return durationValue; } diff --git a/src/com/android/camera/MovieView.java b/src/com/android/camera/MovieView.java index 602e989..3723fbb 100644 --- a/src/com/android/camera/MovieView.java +++ b/src/com/android/camera/MovieView.java @@ -18,58 +18,36 @@ package com.android.camera; import android.app.Activity; -import android.app.AlertDialog; -import android.content.ContentValues; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.database.Cursor; -import android.database.sqlite.SQLiteException; -import android.media.MediaPlayer; -import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.provider.MediaStore; -import android.provider.MediaStore.Video; import android.view.View; -import android.widget.MediaController; -import android.widget.VideoView; /** * This activity plays a video from a specified URI. */ -public class MovieView extends Activity implements MediaPlayer.OnErrorListener, - MediaPlayer.OnCompletionListener { +public class MovieView extends Activity { @SuppressWarnings("unused") private static final String TAG = "MovieView"; - // Copied from MediaPlaybackService in the Music Player app. Should be - // public, but isn't. - private static final String SERVICECMD = - "com.android.music.musicservicecommand"; - private static final String CMDNAME = "command"; - private static final String CMDPAUSE = "pause"; - - private VideoView mVideoView; - private View mProgressView; + private MovieViewControl mControl; private boolean mFinishOnCompletion; - private Uri mUri; - - // State maintained for proper onPause/OnResume behaviour. - private int mPositionWhenPaused = -1; - private boolean mWasPlayingWhenPaused = false; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - setContentView(R.layout.movie_view); - - mVideoView = (VideoView) findViewById(R.id.surface_view); - mProgressView = findViewById(R.id.progress_indicator); + View rootView = findViewById(R.id.root); Intent intent = getIntent(); + mControl = new MovieViewControl(rootView, this, intent.getData()) { + @Override + public void onCompletion() { + if (mFinishOnCompletion) { + finish(); + } + } + }; if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) { int orientation = intent.getIntExtra( MediaStore.EXTRA_SCREEN_ORIENTATION, @@ -80,183 +58,17 @@ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, } mFinishOnCompletion = intent.getBooleanExtra( MediaStore.EXTRA_FINISH_ON_COMPLETION, true); - mUri = intent.getData(); - - // For streams that we expect to be slow to start up, show a - // progress spinner until playback starts. - String scheme = mUri.getScheme(); - if ("http".equalsIgnoreCase(scheme) - || "rtsp".equalsIgnoreCase(scheme)) { - mHandler.postDelayed(mPlayingChecker, 250); - } else { - mProgressView.setVisibility(View.GONE); - } - - mVideoView.setOnErrorListener(this); - mVideoView.setOnCompletionListener(this); - mVideoView.setVideoURI(mUri); - mVideoView.setMediaController(new MediaController(this)); - - // make the video view handle keys for seeking and pausing - mVideoView.requestFocus(); - - Intent i = new Intent(SERVICECMD); - i.putExtra(CMDNAME, CMDPAUSE); - sendBroadcast(i); - { - final Integer bookmark = getBookmark(); - if (bookmark != null) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.resume_playing_title); - builder.setMessage(String.format( - getString(R.string.resume_playing_message), - MenuHelper.formatDuration(this, bookmark))); - builder.setOnCancelListener(new OnCancelListener() { - public void onCancel(DialogInterface dialog) { - finish(); - }}); - builder.setPositiveButton(R.string.resume_playing_resume, - new OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - mVideoView.seekTo(bookmark); - mVideoView.start(); - }}); - builder.setNegativeButton(R.string.resume_playing_restart, - new OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - mVideoView.start(); - }}); - builder.show(); - } else { - mVideoView.start(); - } - } - } - - private static boolean uriSupportsBookmarks(Uri uri) { - String scheme = uri.getScheme(); - String authority = uri.getAuthority(); - return ("content".equalsIgnoreCase(scheme) - && MediaStore.AUTHORITY.equalsIgnoreCase(authority)); - } - - private Integer getBookmark() { - if (!uriSupportsBookmarks(mUri)) { - return null; - } - - String[] projection = new String[] { - Video.VideoColumns.DURATION, - Video.VideoColumns.BOOKMARK - }; - - try { - Cursor cursor = getContentResolver().query(mUri, projection, - null, null, null); - if (cursor != null) { - try { - if (cursor.moveToFirst()) { - int duration = getCursorInteger(cursor, 0); - int bookmark = getCursorInteger(cursor, 1); - final int ONE_MINUTE = 60 * 1000; - final int TWO_MINUTES = 2 * ONE_MINUTE; - final int FIVE_MINUTES = 5 * ONE_MINUTE; - if ((bookmark < TWO_MINUTES) - || (duration < FIVE_MINUTES) - || (bookmark > (duration - ONE_MINUTE))) { - return null; - } - - return Integer.valueOf(bookmark); - } - } finally { - cursor.close(); - } - } - } catch (SQLiteException e) { - // ignore - } - - return null; - } - - private int getCursorInteger(Cursor cursor, int index) { - try { - return cursor.getInt(index); - } catch (SQLiteException e) { - return 0; - } catch (NumberFormatException e) { - return 0; - } - - } - - private void setBookmark(int bookmark) { - if (!uriSupportsBookmarks(mUri)) { - return; - } - - ContentValues values = new ContentValues(); - values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark)); - try { - getContentResolver().update(mUri, values, null, null); - } catch (SecurityException ex) { - // Ignore, can happen if we try to set the bookmark on a read-only - // resource such as a video attached to GMail. - } catch (SQLiteException e) { - // ignore. can happen if the content doesn't support a bookmark - // column. - } catch (UnsupportedOperationException e) { - // ignore. can happen if the external volume is already detached. - } } @Override public void onPause() { - mHandler.removeCallbacksAndMessages(null); - setBookmark(mVideoView.getCurrentPosition()); - - mPositionWhenPaused = mVideoView.getCurrentPosition(); - mWasPlayingWhenPaused = mVideoView.isPlaying(); - mVideoView.stopPlayback(); - + mControl.onPause(); super.onPause(); } @Override public void onResume() { - if (mPositionWhenPaused >= 0) { - mVideoView.setVideoURI(mUri); - mVideoView.seekTo(mPositionWhenPaused); - if (mWasPlayingWhenPaused) { - mVideoView.start(); - } - } - + mControl.onResume(); super.onResume(); } - - Handler mHandler = new Handler(); - - Runnable mPlayingChecker = new Runnable() { - public void run() { - if (mVideoView.isPlaying()) { - mProgressView.setVisibility(View.GONE); - } else { - mHandler.postDelayed(mPlayingChecker, 250); - } - } - }; - - public boolean onError(MediaPlayer player, int arg1, int arg2) { - mHandler.removeCallbacksAndMessages(null); - mProgressView.setVisibility(View.GONE); - return false; - } - - public void onCompletion(MediaPlayer mp) { - if (mFinishOnCompletion) { - finish(); - } - } } diff --git a/src/com/android/camera/MovieViewControl.java b/src/com/android/camera/MovieViewControl.java new file mode 100644 index 0000000..b17c41f --- /dev/null +++ b/src/com/android/camera/MovieViewControl.java @@ -0,0 +1,221 @@ +package com.android.camera; + +import android.app.AlertDialog; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.DialogInterface.OnCancelListener; +import android.content.DialogInterface.OnClickListener; +import android.database.Cursor; +import android.database.sqlite.SQLiteException; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Handler; +import android.provider.MediaStore; +import android.provider.MediaStore.Video; +import android.view.View; +import android.widget.MediaController; +import android.widget.VideoView; + +public class MovieViewControl implements MediaPlayer.OnErrorListener, + MediaPlayer.OnCompletionListener { + + @SuppressWarnings("unused") + private static final String TAG = "MovieViewControl"; + + private static final int ONE_MINUTE = 60 * 1000; + private static final int TWO_MINUTES = 2 * ONE_MINUTE; + private static final int FIVE_MINUTES = 5 * ONE_MINUTE; + + // Copied from MediaPlaybackService in the Music Player app. Should be + // public, but isn't. + private static final String SERVICECMD = + "com.android.music.musicservicecommand"; + private static final String CMDNAME = "command"; + private static final String CMDPAUSE = "pause"; + + private final VideoView mVideoView; + private final View mProgressView; + private final Uri mUri; + private final ContentResolver mContentResolver; + + // State maintained for proper onPause/OnResume behaviour. + private int mPositionWhenPaused = -1; + private boolean mWasPlayingWhenPaused = false; + + Handler mHandler = new Handler(); + + Runnable mPlayingChecker = new Runnable() { + public void run() { + if (mVideoView.isPlaying()) { + mProgressView.setVisibility(View.GONE); + } else { + mHandler.postDelayed(mPlayingChecker, 250); + } + } + }; + + public MovieViewControl(View rootView, Context context, Uri videoUri) { + mContentResolver = context.getContentResolver(); + mVideoView = (VideoView) rootView.findViewById(R.id.surface_view); + mProgressView = rootView.findViewById(R.id.progress_indicator); + + mUri = videoUri; + + // For streams that we expect to be slow to start up, show a + // progress spinner until playback starts. + String scheme = mUri.getScheme(); + if ("http".equalsIgnoreCase(scheme) + || "rtsp".equalsIgnoreCase(scheme)) { + mHandler.postDelayed(mPlayingChecker, 250); + } else { + mProgressView.setVisibility(View.GONE); + } + + mVideoView.setOnErrorListener(this); + mVideoView.setOnCompletionListener(this); + mVideoView.setVideoURI(mUri); + mVideoView.setMediaController(new MediaController(context)); + + // make the video view handle keys for seeking and pausing + mVideoView.requestFocus(); + + Intent i = new Intent(SERVICECMD); + i.putExtra(CMDNAME, CMDPAUSE); + context.sendBroadcast(i); + + final Integer bookmark = getBookmark(); + if (bookmark != null) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.resume_playing_title); + builder.setMessage(String.format( + context.getString(R.string.resume_playing_message), + MenuHelper.formatDuration(context, bookmark))); + builder.setOnCancelListener(new OnCancelListener() { + public void onCancel(DialogInterface dialog) { + onCompletion(); + }}); + builder.setPositiveButton(R.string.resume_playing_resume, + new OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + mVideoView.seekTo(bookmark); + mVideoView.start(); + }}); + builder.setNegativeButton(R.string.resume_playing_restart, + new OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + mVideoView.start(); + }}); + builder.show(); + } else { + mVideoView.start(); + } + } + + private static boolean uriSupportsBookmarks(Uri uri) { + String scheme = uri.getScheme(); + String authority = uri.getAuthority(); + return ("content".equalsIgnoreCase(scheme) + && MediaStore.AUTHORITY.equalsIgnoreCase(authority)); + } + + private Integer getBookmark() { + if (!uriSupportsBookmarks(mUri)) { + return null; + } + + String[] projection = new String[] { + Video.VideoColumns.DURATION, + Video.VideoColumns.BOOKMARK}; + + try { + Cursor cursor = mContentResolver.query( + mUri, projection, null, null, null); + if (cursor != null) { + try { + if (cursor.moveToFirst()) { + int duration = getCursorInteger(cursor, 0); + int bookmark = getCursorInteger(cursor, 1); + if ((bookmark < TWO_MINUTES) + || (duration < FIVE_MINUTES) + || (bookmark > (duration - ONE_MINUTE))) { + return null; + } + return Integer.valueOf(bookmark); + } + } finally { + cursor.close(); + } + } + } catch (SQLiteException e) { + // ignore + } + + return null; + } + + private static int getCursorInteger(Cursor cursor, int index) { + try { + return cursor.getInt(index); + } catch (SQLiteException e) { + return 0; + } catch (NumberFormatException e) { + return 0; + } + + } + + private void setBookmark(int bookmark) { + if (!uriSupportsBookmarks(mUri)) { + return; + } + + ContentValues values = new ContentValues(); + values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark)); + try { + mContentResolver.update(mUri, values, null, null); + } catch (SecurityException ex) { + // Ignore, can happen if we try to set the bookmark on a read-only + // resource such as a video attached to GMail. + } catch (SQLiteException e) { + // ignore. can happen if the content doesn't support a bookmark + // column. + } catch (UnsupportedOperationException e) { + // ignore. can happen if the external volume is already detached. + } + } + + public void onPause() { + mHandler.removeCallbacksAndMessages(null); + setBookmark(mVideoView.getCurrentPosition()); + + mPositionWhenPaused = mVideoView.getCurrentPosition(); + mWasPlayingWhenPaused = mVideoView.isPlaying(); + mVideoView.stopPlayback(); + } + + public void onResume() { + if (mPositionWhenPaused >= 0) { + mVideoView.setVideoURI(mUri); + mVideoView.seekTo(mPositionWhenPaused); + if (mWasPlayingWhenPaused) { + mVideoView.start(); + } + } + } + + public boolean onError(MediaPlayer player, int arg1, int arg2) { + mHandler.removeCallbacksAndMessages(null); + mProgressView.setVisibility(View.GONE); + return false; + } + + public void onCompletion(MediaPlayer mp) { + onCompletion(); + } + + public void onCompletion() { + } +} |