通过VideoView播放视频:
手机存储里保存文件,/mnt/sdcard/Movies/test.mp4
AndroidManifest.xml添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center|clip_horizontal"
android:weightSum="2"
android:orientation="horizontal"
tools:context=".MainActivity">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Java代码文件
public class VideoViewActivity extends Activity{
private VideoView mView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoview);
mView = (VideoView) findViewById(R.id.video_view);
mView.setVideoPath((new File("/mnt/sdcard/Movies/test.mp4")).getAbsolutePath());
mView.setMediaController(new MediaPlayer(this));
mView.requestFocus();
mView.start();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
private class MediaPlayer extends MediaController {
MediaPlayer(Context ctxt) {
super(ctxt);
}
}
}
针对屏幕旋转重头播放的问题,主要是从Activity生命周期来处理MediaPlayer的播放位置。在Activity销毁时记录播放位置,旋转后读取播放位置,实现无缝播放。这里贴出完整代码。
public class RectangleActivity extends Activity implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
private static final String TAG = "zxz";
private VideoView mView;
private ProgressDialog mDialog;
private int mPosition = 0;
private String file = Environment.getExternalStorageDirectory() + "/Movies/test.mp4";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoview);
mDialog = new ProgressDialog(this);
mDialog.setTitle("視頻播放器");
mDialog.setMessage("加載中...");
mDialog.setCancelable(false);
mView = (VideoView) findViewById(R.id.video_view);
mView.setMediaController(new MediaController(this));
mView.setOnCompletionListener(this);
mView.setOnPreparedListener(this);
mView.setOnErrorListener(this);
mView.requestFocus();
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart " + file);
mDialog.show();
try {
mView.setVideoPath(file);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onPause() {
super.onPause();
if (mView.isPlaying()) {
mView.pause();
}
mPosition = mView.getCurrentPosition();
Log.d(TAG, "onPause ");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop ");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy ");
mView.destroyDrawingCache();
}
@Override
protected void onSaveInstanceState(Bundle outState) {//super调用之前
outState.putInt("position", mPosition);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {//super调用之后
super.onRestoreInstanceState(savedInstanceState);
mPosition = savedInstanceState.getInt("position", 0);
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "onError");
mDialog.dismiss();
return false;
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "onCompletion");
Toast.makeText(RectangleActivity.this, "播放完成", Toast.LENGTH_SHORT).show();
mp.release();
}
@Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "onPrepared" + mPosition);
if (mDialog.isShowing()) {
mDialog.dismiss();
}
mView.seekTo(mPosition);
mView.start();
}
}
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">从日志里看到,需要在onPause()记录播放位置,因为</span><span style="font-family: Arial, Helvetica, sans-serif;">onSaveInstanceState</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在onDestroy之前执行了。</span>