在ubuntu 11, Android2.2, Eclipse 3.6下展示一个媒体播放功能及其遇到的问题探讨
启动模拟器后,在DDMS透视图中,选择File Explorer,选择/mnt/sdcard目录,点击视图工具栏的+,将选择的文件push进去。
注:如果push失败,提示Read-Only File System,请将sdcard目录授以读+写权限,命令为
$ adb shell mount -o remount rw /
使用ls -l查看指定目录下的文件及文件夹详细信息,权限信息在第一列。如
$ adb shell
# ls -l /mnt/sdcard
注:在File Explorer中,已经列出了各文件夹和文件的权限。如果sdcard没有读写权限,请先授权。
为什么要用VideoView?VideoView使用起来简单,而且封装了播放器,如播放错误,android会给出警告提示 ,不需要用户编程处理这些异常。代码如下:
viedoView.setVideoPath(filePath);//filePath = “/sdcard/test.mp3”;
videoView.start();
简单是简单,但不幸的是,如果媒体源没问题,但播放异常的话,定位就复杂一些了。
注:启动后,系统提示”对不起,该视频无法播放“,在LogCat中看到MediaPlayer和VideoView都指打印了一条error(1, -2147483648)的LOG。
导致此错误的典型原因有:
1,文件路径不对,如目录错误,不存在的URL及URI
2,媒体文件错误,或不支持的格式
3,缺少权限
经过debug,发现问题出在VideoView#openVidio的mMediaPlayer.prepareAsync();处。
prepare失败了,prepare的方法有两个,还有一个是prepare(),官网给的说明,它位的不同之处是,前者是异步执行。但个人认为,应该还有一个不同之处,前者不会抛出异常。
使用MediaPlayer也很简单。如下代码所示:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(this,uri);
mp.prepare();// 使用mp.prepareAsync(),不会抛出异常,但有错误LOG,为error(38,0);
mp.start();
注:对上面那个无法播放的问题,可以在prepare()处捕获到IO异常:
java.io.IOException: Prepare failed.: status=0x1
// FileInputStream fis = new FileInputStream(file);
// mp.setDataSource(fis.getFD());
前者我没有试过,如果有度过的,请告诉我结果。我使用的是后者,发现在创建输入流时,抛出了FileNotFoundException:file not exists(permission denied),关键在permission denied这句,应该是缺少权限,但媒体文件是有权限的,sdcard目录没有,于是给sdcard目录授以最大权限。
$ adb shell
# chmod 777 /mnt/sdcard
讨论1:在准备工作中,已经使用
$ adb shell mount -o remount rw /
或
$ adb shell mount -o remount 777 /
给目录授权过了,但为何sdcard目录还是无权限?
讨论2:Android对网络播放是否存在bug,对于本地可以正常播放的3gp,mp4等视频,放到服务器中使用http get方式进行网络播放,却只有少数片源可以播放,大多数在prepare()时就抛出了异常。