Android4开发入门经典 之 第十部分:多媒体

简介

Android的多媒体框架,在2.3之前是采用的Open Core,在2.3之后采用的是Stagefright。不管框架的内部实现如何变化,对外提供的API都是一样的。
Android的多媒体框架提供了对大多数主流多媒体格式的支持,使得我们能够很方便的进行音频、视频和图片的操作。最主要的就是使用MediaPlayer接口。

MediaPlayer接口的常见功能

1:create :创建一个MediaPlayer对象
2:setDataSource :设置要播放的资源
3:start() :开始播放
4:pause() :暂停播放
5:prepare() :准备要播放的内容,同步的
6:release() :释放播放器对象
7:reset() :重置播放的资源
8:seekTo(int site) :跳转到开始播放的位置
9:stop() :停止播放

使用MediaPlayer

MediaPlayer既能播放音频,也能播放视频,是我们要主要学习的内容。它能支持如下的多媒体资源:

1:Local资源
2:内部的URI,比如从其他的ContentProvider中获取的媒体资源
3:外部的URI,可能是通过流式获取的媒体资源

MediaPlayer访问本地多媒体资源

所谓本地资源,多是放置在res/raw/下面的多媒体文件。示例代码如下:
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start();
不需要调用prepare()了,create()方法已经帮我们完成这个功能了

MediaPlayer访问内部的URI

这通常都是从其他的内容提供者那里去获取,一般都采用流来处理,示例代码如下:


java代码:
  1. Uri myUri = ....; //访问其他的Content,基本上都是通过URI  
  2. MediaPlayer mediaPlayer = new MediaPlayer();  
  3. mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
  4. mediaPlayer.setDataSource(getApplicationContext(), myUri);  
  5. mediaPlayer.prepare();  
  6. mediaPlayer.start();  

MediaPlayer访问远程多媒体资源,多是通过流式来处理,示例代码如下:


java代码:
  1. String url = "http://........";  
  2. MediaPlayer mediaPlayer = new MediaPlayer();  
  3. mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
  4. mediaPlayer.setDataSource(url);  
  5. mediaPlayer.prepare();  
  6. mediaPlayer.start();  

释放MediaPlayer,示例代码如下:


java代码:
  1. mediaPlayer.release();  
  2. mediaPlayer = null;  
  3.    
如果要播放视频,方式也差不多,只不过需要添加用来显示视频的Widget,常用的是SurfaceView,它的功能较强,可以实现很多定制功能。当然也可以使用VideoView,它使用简单,但定制功能不强。

这里有一个简单的播放视频的示例,布局文件的示例代码如下:


java代码:
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="fill_parent"  
  3.     android:layout_height="fill_parent"  
  4.     android:orientation="vertical" >  
  5.     <SurfaceView  
  6.         android:id="@+id/surface"  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="200dp"      />  
  9.     <Button  
  10.         android:id="@+id/start"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         android:text="播放"       />  
  14.     <Button  
  15.         android:id="@+id/stop"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="停止"       />  
  19. </LinearLayout>  

程序里面的示例代码如下:


java代码:
  1. public class MtActivity extends Activity {  
  2.     private MediaPlayer mMediaPlayer;  
  3.     private SurfaceView mPreview;  
  4.     private SurfaceHolder holder;  
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main);  
  8.          
  9.         mPreview = (SurfaceView) findViewById(R.id.surface);  
  10.         holder = mPreview.getHolder();  
  11.         holder.setFixedSize(100,100);  
  12.         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        
  13.          
  14.         Button start = (Button)this.findViewById(R.id.start);  
  15.         Button stop = (Button)this.findViewById(R.id.stop);  

java代码:
  1. start.setOnClickListener(new OnClickListener(){  
  2. @Override  
  3. public void onClick(View v) {  
  4. mMediaPlayer = MediaPlayer.create(MtActivity.this, R.raw.t1);  
  5.             mMediaPlayer.setDisplay(holder);  
  6. //            mMediaPlayer.prepare();  
  7.           mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
  8.                      mMediaPlayer.start();  
  9. }  
  10.         });  
  11.         stop.setOnClickListener(new OnClickListener(){  
  12. @Override  
  13. public void onClick(View v) {  
  14. mMediaPlayer.stop();  
  15. }  
  16.         });  
  17.     }     
  18. }  
  19. 视频文件,尽量选用3gp或mp4的格式  
  20.    

异步preparation

使用MediaPlayer,在调用prepare()方法的时候,该方法可能会执行较长的时间,比如它需要对媒体文件进行解码,这意味着它不应该运行在UI Thread里面,否则会阻塞UI线程。
解决方案是:使用另外的线程来准备媒体资源,准备好后通知主线程。
这个模式在Android的多媒体框架里面已经得到支持,你可以调用prepareAsync()方法,这个方法会在后台进行资源的准备,并在准备好后通知监听器:MediaPlayer.OnPreparedListener,然后执行onPrepared()方法即可。

在Service里面异步使用MediaPlayer

使用MdeiaPlayer来播放音乐,通常都是在Service中使用,为了不阻塞UI线程,通常会异步的使用,示例代码如下:

java代码:
  1. public class MyService extends Service implements MediaPlayer.OnPreparedListener {  
  2.     MediaPlayer mMediaPlayer = null;  
  3.     public int onStartCommand(Intent intent, int flags, int startId) {  
  4.         mMediaPlayer = new MediaPlayer();  
  5.         mMediaPlayer.setDataSource(getApplicationContext(), myUri);  
  6.         mMediaPlayer.setOnPreparedListener(this);  
  7.         mMediaPlayer.prepareAsync();  
  8.     }  
  9.     public void onPrepared(MediaPlayer player) {  
  10.         player.start();  
  11.     }  
  12. }  

处理异步使用MediaPlayer的错误

异步使用MdeiaPlayer的时候,对于可能出现的错误,可以通过实现MediaPlayer.OnErrorListener,来监听并处理,示例代码如下:

java代码:
  1. public class MyService extends Service implements MediaPlayer.OnPreparedListener , MediaPlayer.OnErrorListener {  
  2.     MediaPlayer mMediaPlayer = null;  
  3.     public int onStartCommand(Intent intent, int flags, int startId) {  
  4.         //………  
  5. mMediaPlayer.setOnErrorListener(this);  
  6.     }  
  7.     public void onPrepared(MediaPlayer player) {  
  8.         player.start();  
  9.     }  
  10.     public boolean onError(MediaPlayer mp, int what, int extra) {  
  11. //在这里处理错误  
  12.     }  
  13. }  

使用wake lock

当使用MdeiaPlayer在后台播放音乐的时候,用户可能会关闭或锁定手机,以节约电量,此时所有的应用都会强制sleep。
为了当手机重新开启或解除锁定的时候,播放音乐的后台服务能继续运行,你需要设置wake lock的模式。
基本的设置方式很简单,就一句话,示例代码如下:

java代码:
  1. mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);  
还需要添加权限如下:

java代码:
  1. <uses-permission android:name="android.permission.WAKE_LOCK"/>  
  2.    
但要注意一定,如果你的service还需要其他服务的支持,比如需要通过蓝牙去获取数据,那么,在wake你的service的时候,还需要wake这些相应的服务。
 

在foreground Service中使用MediaPlayer

使用MdeiaPlayer来播放音乐,也经常需要在前端界面上,同步显示一些信息,比如:歌曲名称等,这就需要实现foreground service,示例代码如下:

java代码:
  1. String songName;  
  2. PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,  
  3.                 new Intent(getApplicationContext(), MainActivity.class),  
  4.                 PendingIntent.FLAG_UPDATE_CURRENT);  
  5.    
  6. Notification notification = new Notification();  
  7. notification.tickerText = text;  
  8. notification.icon = R.drawable.play0;  
  9. notification.flags |= Notification.FLAG_ONGOING_EVENT;  
  10.    
  11. notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample","Playing: " + songName, pi);  
  12.    
  13. startForeground(NOTIFICATION_ID, notification);  


视频配套PPT,视频地址【Android4开发入门经典独家视频课程

原创内容 转自请注明【  http://sishuok.com/forum/blogPost/list/0/2750.html#7734

猜你喜欢

转载自jenmhdn.iteye.com/blog/1584937