|
MediaPlayer mediaPlayer =MediaPlayer.create(context, R.raw.sound_file_1);播放URIs 中的音频:
mediaPlayer.start();// no need to call prepare(); create() does that for you
Uri myUri =....;// initialize Uri here播放远程网络上的音频:
MediaPlayer mediaPlayer =newMediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
String url ="http://........";// your URL here提醒:
MediaPlayer mediaPlayer =newMediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();// might take long! (for buffering, etc)
mediaPlayer.start();
mediaPlayer.release();在音乐播放器这种场景下或一些类似的场景下,即使用户已经离开了当前的activity,但是还需要播放多媒体。这时候,需要在Service中去控制MeidaPlayer。
mediaPlayer =null;
publicclassMyServiceextendsServiceimplementsMediaPlayer.OnPreparedListener{
privatestaticfinalString ACTION_PLAY ="com.example.action.PLAY";
MediaPlayer mMediaPlayer =null;
publicint onStartCommand(Intent intent,int flags,int startId){
...
if(intent.getAction().equals(ACTION_PLAY)){
mMediaPlayer =...// initialize it here
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync();// prepare async to not block main thread
}
}
/** Called when MediaPlayer is ready */
publicvoid onPrepared(MediaPlayer player){
player.start();
}
}
publicclassMyServiceextendsServiceimplementsMediaPlayer.OnErrorListener{尤其要记住的是:当错误发生的时候,MediaPlayer的进入到生命周期状态图中的Error State的状态。在重新使用它之前,必须进行重新reset().
MediaPlayer mMediaPlayer;
publicvoid initMediaPlayer(){
// ...initialize the MediaPlayer here...
mMediaPlayer.setOnErrorListener(this);
}
@Override
publicboolean onError(MediaPlayer mp,int what,int extra){
// ... react appropriately ...
// The MediaPlayer has moved to the Error state, must be reset!
}
}
mMediaPlayer =newMediaPlayer();
// ... other initialization here ...
mMediaPlayer.setWakeMode(getApplicationContext(),PowerManager.PARTIAL_WAKE_LOCK);
WifiLock wifiLock =((WifiManager) getSystemService(Context.WIFI_SERVICE))当你暂停或者停止媒体的时候,你不在需要网络的时候,需要释放这个锁:
.createWifiLock(WifiManager.WIFI_MODE_FULL,"mylock");
wifiLock.acquire();
wifiLock.release();Running as foreground service(作为前台服务运行)
String songName;当你的服务运行在前台的时候,你配置的通知在设备的通知区域可见的。如果用户选择了这个通知,系统会调起配置的PendingIntent。像上面的demo,系统打开了一个MainActivity。
// assign the song name to songName
PendingIntent pi =PendingIntent.getActivity(getApplicationContext(),0,
newIntent(getApplicationContext(),MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification =newNotification();
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);
AudioManager audioManager =(AudioManager) getSystemService(Context.AUDIO_SERVICE);requestAudioRequest()的第一个参数 AudioManager.OnAudioFocusChangeListener。当音频焦点改变的时候,会回调这个方法。因此你需要在你的service或者activities中去实现这个接口,举个例子:
int result = audioManager.requestAudioFocus(this,AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if(result !=AudioManager.AUDIOFOCUS_REQUEST_GRANTED){
// could not get audio focus.
}
classMyServiceextendsServiceonAudioFocusChange(int focusChange),focusChange 参数告诉我们音频焦点是如何改变的。参数的值如下(这些值都是在AudioManager中定义的)
implementsAudioManager.OnAudioFocusChangeListener{
// ....
publicvoid onAudioFocusChange(int focusChange){
// Do something based on focus change...
}
}
publicvoid onAudioFocusChange(int focusChange){
switch(focusChange){
caseAudioManager.AUDIOFOCUS_GAIN:
// resume playback
if(mMediaPlayer ==null) initMediaPlayer();
elseif(!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f,1.0f);
break;
caseAudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if(mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer =null;
break;
caseAudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if(mMediaPlayer.isPlaying()) mMediaPlayer.pause();
break;
caseAudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if(mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f,0.1f);
break;
}
}
publicclassMyServiceextendsService{你也应该尽可能的寻找一些其它的释放MediaPlayer资源的机会,而不仅仅在关闭的时候去释放。比如,如果你并不希望在某一段时间去播放Media(比如失去音频焦点之后)。你当然应该释放它然后在需要的时候,再去重新创建。另一方面,如果仅仅是暂停一下,就没有必要去频繁的释放和创建了,这样可以避免再一次的去准备。
MediaPlayer mMediaPlayer;
// ...
@Override
publicvoid onDestroy(){
if(mMediaPlayer !=null) mMediaPlayer.release();
}
}
android:name=".MusicIntentReceiver">
android:name="android.media.AUDIO_BECOMING_NOISY"/>
为这个意图注册一个广播接受器,如下:
publicclassMusicIntentReceiverextends android.content.BroadcastReceiver{接受到这个广播以后,需要通知service停止MediaPlayer。
@Override
publicvoid onReceive(Context ctx,Intent intent){
if(intent.getAction().equals(
android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)){
// signal your service to stop playback
// (via an Intent, for instance)
}
}
}
ContentResolver contentResolver = getContentResolver();和MediaPlayer使用,你可以写如下代码:
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri,null,null,null,null);
if(cursor ==null){
// query failed, handle error.
}elseif(!cursor.moveToFirst()){
// no media on the device
}else{
int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
do{
long thisId = cursor.getLong(idColumn);
String thisTitle = cursor.getString(titleColumn);
// ...process entry...
}while(cursor.moveToNext());
}
long id =/* retrieve it from somewhere */;
Uri contentUri =ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
mMediaPlayer =newMediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
// ...prepare and start...