Android4開發入門經典 之 第十部分:多媒體【私塾線上原創】

xinqing010發表於2012-03-01

簡介

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程式碼:
Uri myUri = ....; //訪問其他的Content,基本上都是通過URI
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();

MediaPlayer訪問遠端多媒體資源,多是通過流式來處理,示例程式碼如下:


java程式碼:
String url = "http://........";
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.start();

釋放MediaPlayer,示例程式碼如下:


java程式碼:
mediaPlayer.release();
mediaPlayer = null;
 
如果要播放視訊,方式也差不多,只不過需要新增用來顯示視訊的Widget,常用的是SurfaceView,它的功能較強,可以實現很多定製功能。當然也可以使用VideoView,它使用簡單,但定製功能不強。

這裡有一個簡單的播放視訊的示例,佈局檔案的示例程式碼如下:


java程式碼:

    
    
    

程式裡面的示例程式碼如下:


java程式碼:
public class MtActivity extends Activity {
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        mPreview = (SurfaceView) findViewById(R.id.surface);
        holder = mPreview.getHolder();
        holder.setFixedSize(100,100);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);      
       
        Button start = (Button)this.findViewById(R.id.start);
        Button stop = (Button)this.findViewById(R.id.stop);

java程式碼:
start.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mMediaPlayer = MediaPlayer.create(MtActivity.this, R.raw.t1);
            mMediaPlayer.setDisplay(holder);
//            mMediaPlayer.prepare();
          mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                     mMediaPlayer.start();
}
        });
        stop.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mMediaPlayer.stop();
}
        });
    }   
}
視訊檔案,儘量選用3gp或mp4的格式
 

非同步preparation

使用MediaPlayer,在呼叫prepare()方法的時候,該方法可能會執行較長的時間,比如它需要對媒體檔案進行解碼,這意味著它不應該執行在UI Thread裡面,否則會阻塞UI執行緒。
解決方案是:使用另外的執行緒來準備媒體資源,準備好後通知主執行緒。
這個模式在Android的多媒體框架裡面已經得到支援,你可以呼叫prepareAsync()方法,這個方法會在後臺進行資源的準備,並在準備好後通知監聽器:MediaPlayer.OnPreparedListener,然後執行onPrepared()方法即可。

在Service裡面非同步使用MediaPlayer

使用MdeiaPlayer來播放音樂,通常都是在Service中使用,為了不阻塞UI執行緒,通常會非同步的使用,示例程式碼如下:

java程式碼:
public class MyService extends Service implements MediaPlayer.OnPreparedListener {
    MediaPlayer mMediaPlayer = null;
    public int onStartCommand(Intent intent, int flags, int startId) {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setDataSource(getApplicationContext(), myUri);
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.prepareAsync();
    }
    public void onPrepared(MediaPlayer player) {
        player.start();
    }
}

處理非同步使用MediaPlayer的錯誤

非同步使用MdeiaPlayer的時候,對於可能出現的錯誤,可以通過實現MediaPlayer.OnErrorListener,來監聽並處理,示例程式碼如下:

java程式碼:
public class MyService extends Service implements MediaPlayer.OnPreparedListener , MediaPlayer.OnErrorListener {
    MediaPlayer mMediaPlayer = null;
    public int onStartCommand(Intent intent, int flags, int startId) {
        //………
mMediaPlayer.setOnErrorListener(this);
    }
    public void onPrepared(MediaPlayer player) {
        player.start();
    }
    public boolean onError(MediaPlayer mp, int what, int extra) {
//在這裡處理錯誤
    }
}

使用wake lock

當使用MdeiaPlayer在後臺播放音樂的時候,使用者可能會關閉或鎖定手機,以節約電量,此時所有的應用都會強制sleep。
為了當手機重新開啟或解除鎖定的時候,播放音樂的後臺服務能繼續執行,你需要設定wake lock的模式。
基本的設定方式很簡單,就一句話,示例程式碼如下:

java程式碼:
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
還需要新增許可權如下:

java程式碼:

 
但要注意一定,如果你的service還需要其他服務的支援,比如需要通過藍芽去獲取資料,那麼,在wake你的service的時候,還需要wake這些相應的服務。
 

在foreground Service中使用MediaPlayer

使用MdeiaPlayer來播放音樂,也經常需要在前端介面上,同步顯示一些資訊,比如:歌曲名稱等,這就需要實現foreground service,示例程式碼如下:

java程式碼:
String songName;
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
                new Intent(getApplicationContext(), MainActivity.class),
                PendingIntent.FLAG_UPDATE_CURRENT);
 
Notification notification = new Notification();
notification.tickerText = text;
notification.icon = R.drawable.play0;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
 
notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample","Playing: " + songName, pi);
 
startForeground(NOTIFICATION_ID, notification);



視訊配套PPT,視訊地址【Android4開發入門經典獨家視訊課程

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26715458/viewspace-717434/,如需轉載,請註明出處,否則將追究法律責任。

相關文章