在android中播放视频默认支持3GP,MP4格式,如果你需要支持其他格式必须软解码其他格式文件。API的选择有 MediaPlayer和VideoView。用VideoView 是android已经封装好的View 它继承自SurfaceView并实现了MediaPlayerControl接口。
public class MyVideoView extends VideoView {
public static int WIDTH;public static int HEIGHT;
public MyVideoView(Context context, AttributeSet attrs) {
super(context, attrs); }
设置该VideoView视频尺寸的大小
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(WIDTH, widthMeasureSpec);
int height = getDefaultSize(HEIGHT, heightMeasureSpec);
setMeasuredDimension(width,height);}}
activity:
public class VideoViewDemo extends Activity implements OnCompletionListener {
private String path = "/sdcard/main.mp4";
private MyVideoView mVideoView;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.videoview);
mVideoView = (MyVideoView) findViewById(R.id.surface_view);
mVideoView.setOnCompletionListener(this);
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
MyVideoView.WIDTH=dm.widthPixels;
MyVideoView.HEIGHT=dm.heightPixels;
if (path == "") {
// Tell the user to provide a media file URL/path.
Toast.makeText( VideoViewDemo.this,"Please edit VideoViewDemo Activity, and set path" + " variable to your media file URL/path", Toast.LENGTH_LONG).show(); } else {
mVideoView.setVideoURI(Uri.parse(URLstring));
*/ //mVideoView.setVideoPath(path);
mVideoView.setVideoURI(Uri.parse("android.resource://ss.ss/"+R.raw.main));
//如果你需要添加控制条就取消改注释
//mVideoView.setMediaController(new MediaController(this));
//1.6中测试自动播放的播放代码是不需要.start() //2.1中测试自动播放的播放代码
// mVideoView.start(); //所以为了兼容性 我们选择mVideoView.start();保证所有版本都在开始时自动播放
mVideoView.start(); } }
@Override
protected void onDestroy() {
super.onDestroy();
System.exit(0);
}
//播放完成后的事件处理
@Override
public void onCompletion(MediaPlayer mp) {
System.out.println("播放完成");
}}
1.如果需要播放工程资源中的视频则需要使用 mVideoView.setVideoURI(Uri.parse("android.resource://"+"包名"+"/"+R.raw.main));
2.如果需要播放SD卡中的文件则请看上面代码中
private String path = "/sdcard/main.mp4";
//mVideoView.setVideoPath(path);
3.吧设备的分辨率传到VideoView中用于适用不同分辨率的设备
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
MyVideoView.WIDTH=dm.widthPixels;
在播放视频的问题上 我遇到了以下这些问题
1.首先全屏播放时需要重写onMeasure的
2.不同版本下 有的会自动播放,有的不会自动播放。所以为了统一请采用VideoView.start()因为在1.6中 你不设置VideoView.start()他也会自动播放,但在2.1测试中必须明确。
一个按键有两个触发点,一是up,一是down,如果需要指定焦点,使用view.requestFocus(),而且需要在down上执行,因为up时,系统已经定位新的焦点了.再执行就未必是想要的结果.
if(keyCode==KeyEvent.KEYCODE_DPAD_UP){
} else if (keyCode==KeyEvent.KEYCODE_DPAD_LEFT) {
} else if (keyCode==KeyEvent.KEYCODE_DPAD_RIGHT) {
} else if (keyCode==KeyEvent.KEYCODE_DPAD_DOWN) {
} else if (keyCode==KeyEvent.KEYCODE_DPAD_CENTER||keyCode==KeyEvent.KEYCODE_ENTER) {
}
出现问题的多数是GridView,这样的ViewGroup控件,比如现在有两行,焦点在第一行,然后向下按键KeyEvent.KEYCODE_DPAD_DOWN.在event.getAction()==KeyEvent.ACTION_DOWN中判断,会出现不想要的结果,比如它不会定位下一个焦点还是GridView,也不是它的下一行,因为它把整个GridView当成一个控件,下一个:final View downView=currentFocus.focusSearch(View.FOCUS_DOWN);搜索得到的downView有可能是空的,有可能是另一个控件,比如Button,然而在焦点出现异常时,不能在这里return true;这样是无法到它第二行的.在ACTION_UP中,如果之前的down不返回true,会得到下一行焦点.
这里提供另一种方法:还是在down中处理:
if (currentFocus instanceof GridView) {
GridView gridView=(GridView) currentFocus.getParent();
int column=gridView.getNumColumns();
int selPos=gridView.getSelectedItemPosition();
int count=gridView.getAdapter().getCount();
Log.d(TAG, "selPos:"+selPos+" count:"+count+" column:"+column);
if (selPos>=column*2) { //如果是GridView的最下边,再向下,需要翻页.
if (fragment.pageDown()) {
Log.d(TAG, "向下翻页了.");
}
return true;
} else {
if (count<=column||(count>column&&count<=column*2&&selPos>=column)) {
if (fragment.pageDown()) {
Log.d(TAG, "品牌向下翻页了,已经是最后一页.");
}
return true;
}
}
}
这样可以判断当GridView的焦点在第一行时,如果选中项的位置也是第一行,可以依据系统定位,它会移动到第二行,依次类推.如果是最后一行,其实也可以依据系统定位,如果没有特殊要求.
}
单个控件,几乎都可以直接判断View right=currentFocus.focusSearch(View.FOCUS_RIGHT); 这四个方向的情况 就可以了.因为不存在控件内部的定位.