声明:学习的书籍《Android应用开发揭秘》,这里记录学习该书籍的日志,引用的相关代码与总结描述,没有商业的用途,完全是自我学习的一个记录,刚刚学习不可避免会出现很多问题,若是有错误还请大家多多批评。
今天开始学习多媒体相关的操作,因为我们的智能手机一部分重要的作用就是播放音频,视频,显示图片等操作。Android主要是通过Open Core作为多媒体框架的核心,也被称作为PV,支持多种格式的音频,视频。Open Core框架主要包含两部分:
(1) PVPlayer:提供媒体播放器功能。
(2) PVAuthor:提供媒体流记录的功能,完成各种音频,视频的流以及图像的捕捉功能。
当然我们开发中,不会直接操作底层的PV,主要使用Android提供的Media API。
1. MediaPlayer类
该类主要用来播放,音频,视频和流媒体,包含了Audio和Video的播放功能,具体的生命周期与相关方法,可以参考下面音乐播放实例。
2. MediaRecorder类
该类主要用于媒体的采样,包括音频视频。MediaRecorder作为状态机运行,需要设置不同的,比如源设备和格式。设置后,可以执行任何时间长度的录制,直到用户停止。
一、多媒体之音乐播放
下面就以音乐播放的例子来验证MediaPlayer的生命周期以及相关方法,关于音乐播放其实之前例子已经实现,当时是播放的raw目录下得mp3文件,本例子自动播放SDCard下的mp3例子。
关键源码:
public class SDCardMusicPlayActivity extends ListActivity {
private ImageButton mFrontImageButton = null;
private ImageButton mStopImageButton = null;
private ImageButton mStartImageButton = null;
private ImageButton mPauseImageButton = null;
private ImageButton mNextImageButton = null;
public MediaPlayer mMediaPlayer = null; //MediaPlayer对象
private List<String> mMusicList = new ArrayList<String>();//播放列表
private int currentListItem = 0; //当前播放歌曲的索引
private static final String MUSIC_PATH = new String("/mnt/sdcard/");//音乐的路径
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
musicList(); //更新显示播放列表
mMediaPlayer = new MediaPlayer();
mFrontImageButton = (ImageButton) findViewById(R.id.LastImageButton);
mStopImageButton = (ImageButton) findViewById(R.id.StopImageButton);
mStartImageButton = (ImageButton) findViewById(R.id.StartImageButton);
mPauseImageButton = (ImageButton) findViewById(R.id.PauseImageButton);
mNextImageButton = (ImageButton) findViewById(R.id.NextImageButton);
//停止按钮
mStopImageButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View v) {
if(mMediaPlayer.isPlaying()){ //当前是否正在播放
mMediaPlayer.reset(); //重置MediaPlayer到初始状态
}
}
});
//开始按钮
mStartImageButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View v) {
playMusic(MUSIC_PATH + mMusicList.get(currentListItem));
}
});
//暂停按钮
mPauseImageButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View v) {
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}else{
mMediaPlayer.start();
}
}
});
//下一首
mNextImageButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View arg0){
nextMusic();
}
});
//上一首
mFrontImageButton.setOnClickListener(new ImageButton.OnClickListener() {
public void onClick(View arg0){
FrontMusic();
}
});
}
//播放列表
private void musicList() {
//取得指定位置的文件,设置显示到播放列表
File home = new File(MUSIC_PATH);
if(home.list(new MusicFilter()).length > 0){
for(File file : home.listFiles(new MusicFilter())){
mMusicList.add(file.getName());
}
ArrayAdapter<String> musicListAdapter = new ArrayAdapter<String>(SDCardMusicPlayActivity.this, R.layout.musicitme, mMusicList);
this.setListAdapter(musicListAdapter);
}
}
private void playMusic(String path){
try {
mMediaPlayer.reset();//重置MediaPlayer
mMediaPlayer.setDataSource(path);//设置要播放的文件路径
mMediaPlayer.prepare();//准备播放
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
nextMusic();//播放完成一首之后进行下一首
}
});
} catch (IOException e) {
// TODO: handle exception
}
}
//下一首
private void nextMusic() {
// TODO Auto-generated method stub
if(++currentListItem >= mMusicList.size()){
currentListItem = 0;
}else{
playMusic(MUSIC_PATH + mMusicList.get(currentListItem));
}
}
//上一首
private void FrontMusic(){
if (--currentListItem >= 0){
currentListItem = mMusicList.size();
}else{
playMusic(MUSIC_PATH + mMusicList.get(currentListItem));
}
}
public boolean onKeyDown(int keyCode, KeyEvent event){
if ( keyCode == KeyEvent.KEYCODE_BACK){
mMediaPlayer.stop();
mMediaPlayer.release();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
//播放被点击的音乐
protected void onListItemClick(ListView l, View v, int position, long id){
currentListItem = position;
playMusic(MUSIC_PATH + mMusicList.get(position));
}
}
class MusicFilter implements FilenameFilter{
@Override
public boolean accept(File dir, String filename) {
//这里还可以设置其他格式的音乐文件
return (filename.endsWith(".mp3"));
}
}
运行效果:
【遇到问题】
在往模拟器的SDCard里放置mp3文件的时候,报:Failed to push selection: Read-only file system 错误。
切换到DDMS视图下,看到mnt下的sdcard文件夹的操作权限为可读,后来在AVD Edit的时候,之前SDCard没设置大小,所以设置了大小重新启动AVD,该sdcard文件夹就可以可以编辑的了。