監視來電狀態
AudioFocus是Android2.2以後才有的功能,對於比2.2低得版本,用的是另一種方法,就是監聽電話的狀態。最起碼在電話打進來是能夠暫停音樂的播放。
實現這一功能的第一步是在AndroidManifest.xml中聲明用於接收PHONE_STATE通知的receiver
<receiver android:name=".PhoneStateReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
第二步是定義一個對應的PhoneStateReceiver,代碼如下
package LyricPlayer.xwg;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
public class PhoneStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//if android.os.Build.VERSION.SDK_INT >= 8 we use audio focus.
if (android.os.Build.VERSION.SDK_INT < 8){
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(tm.getCallState() != TelephonyManager.CALL_STATE_IDLE){
context.startService(new Intent(MediaPlayerService.ACTION_PAUSE));
}
}
}
}
這就夠了。
監視耳機插頭拔出
如果在音樂播放過程中拔出耳機,音樂就會通過擴音器播放出來。為了避免這種尷尬局面,我們會監視耳機拔出狀態,並在耳機拔出時暫停播放。
首先是在AndroidManifest.xml中聲明用於接收AUDIO_BECOMING_NOISY通知的receiver
<receiver android:name=".MusicIntentReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
然後就是定義用於處理通知的receiver,類名要和AndroidManifest.xml中聲明的一樣。
package LyricPlayer.xwg;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MusicIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
ctx.startService(new Intent(LyricPlayerService.ACTION_PAUSE));
}
}
}
MEDIA_BUTTON處理
在討論處理方法之前,必須先明確:那些鍵屬於MEDIA_BUTTON?根據我的實驗,MEDIA_BUTTON好像就是線控上面的上個按鈕。網上也有用同樣的方法取得音量鍵動作的內容,但是我沒有試出來。
繼續我們的話題,為了檢測MEDIA_BUTTON需要一些準備工作。
首先是在AndroidManifest.xml中聲明用於接收MEDIA_BUTTON通知的receiver
<receiver android:name="MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
當然需要定義真正的receiver,名字要和AndroidManifest.xml中的一樣。
package LyricPlayer.xwg;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
public class MediaButtonReceiver extends BroadcastReceiver {
private static final String TAG = new String("LyricVolumeKeyReceiver");
@Override
public void onReceive(Context context, Intent intent) {
//MusicPlaybackService service = (MusicPlaybackService)context;
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if(key.getAction() == KeyEvent.ACTION_DOWN){
Log.i(TAG, "OnReceive, getKeyCode = " + key.getKeyCode());
switch(key.getKeyCode()){
case KeyEvent.KEYCODE_HEADSETHOOK :
context.startService(new Intent(MediaPlayerService.ACTION_PLAY_PAUSE));
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
context.startService(new Intent(MediaPlayerService.ACTION_PREVIOUS));
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
context.startService(new Intent(MediaPlayerService.ACTION_NEXT));
break;
}
}
}
}
}
比較特別的是中間的鍵的索引值不是KEYCODE_PLAY_PAUSE而是KEYCODE_HEADSETHOOK。想想也是,接電話也用這個鍵。
準備工作的最後一步就是要把通過MediaButtonReceiver來接受MEDIA_BUTTON這件事報告給AudioMenager,由於這也是Android2.2及以後版本才有的功能,也需要做版本判斷。
if (android.os.Build.VERSION.SDK_INT >= 8){
mReceiverName = new ComponentName(getPackageName(),MediaButtonReceiver.class.getName());
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mAudioManager.registerMediaButtonEventReceiver(mReceiverName);
}
當然在結束的時候我們也會保持取消登入的良好習慣。
if(mAudioManager != null && mReceiverName != null){
mAudioManager.unregisterMediaButtonEventReceiver(mReceiverName);
}
Notification表示
Notification表示首先取得NotificationManager
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
在需要表示的時候調用showNotification()方法。和showNotification()方法有關的代碼:
public interface NotificationProvider{
public Notification createNotification(Context context);
}
NotificationProvider mNotificationProvider = null;
public void setNotificationProvider(NotificationProvider provider){
mNotificationProvider = provider;
}
/** * Show a notification while this service is running. */
private void showNotification() {
if(mNotificationProvider != null){
// Send the notification.
mNotificationManager.notify(NOTIFICATION, mNotificationProvider.createNotification(this));
}
}
已經用了N次的辦法了。不用再解釋了吧。當然,看看實現側的做法還有必要的。
mProxy.setNotificationProvider(new MediaPlayerService.NotificationProvider(){
@Override
public Notification createNotification(Context context) {
Notification notification = new Notification(R.drawable.button_blue_play, mProxy.getTitle(), System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, LyricMain.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(context, getText(R.string.media_player_label), mProxy.getTitle(), contentIntent);
return notification;
}
});
全文摘抄自:http://www.2cto.com/kf/201109/103784.html