Android音乐播放器监听传统电话和网络电话

对于传统电话,Android提供了注册广播BroadcastReceiver的方式和注册Listener的方式。当用户拨打电话的时候,会发出action = "android.intent.action.PHONE_STATE"的广播,intent里会带上当前的state。

注册广播BroadcastReceiver方式代码如下。

	public class MainActivity extends NGUActivity {
         /**
             * 来去电广播接收器
          */
        private PhoneReceiver mPhoneReceiver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 注册来去电监听器
        mPhoneReceiver = new PhoneReceiver();
        IntentFilter phoneFilter = new IntentFilter();
        phoneFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
        phoneFilter.setPriority(Integer.MAX_VALUE);
        registerReceiver(mPhoneReceiver, phoneFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消广播
        unregisterReceiver(mPhoneReceiver);
    }

    /**
     * 来去电状态广播接收者
     */
    private class PhoneReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            System.out.println("action" + intent.getAction());
            if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
              // 去电
            } else {
              // 来电
         String state = intent.getStringExtra("state");
         if((TelephonyManager.EXTRA_STATE_RINGING).equals(state)){
     //正在响铃
		}
       }}}}
     
Android还提供了一种更加常用的方式,那就是注册Listener。然后让Phone去回调它,以便告诉注册者phone现在的状态。代码如下。

    @Override
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        // 注册来去电Listener
       TelephonyManager tm = (TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);
         tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
    }

	PhoneStateListener listener = new PhoneStateListener() {

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                if (state == TelephonyManager.CALL_STATE_RINGING) {
                    // 来电话时停止播放录音
                }
            }
        };

以上的两种方式都需要相应的权限,在AndroidManifest.xml中加

对于传统的电话可以方便的使用以上两种方式,但是对于网络电话,在android4.4以后是无权限发送action = “android.intent.action.PHONE_STATE” 的广播,除非它是system app。而一般都是第三方开发者开发的,不是手机厂商内置,无法发送此广播,那我们怎么办呢?在查找资料时发现,android的自带音乐播放器是通过监听action = “com.android.music.musicservicecommand” 的广播,那我们也可以来试试。

我们可以在网络电话拨打或者来电的逻辑中加入以下代码,告诉其它音乐播放器现在应该做什么操作。当然,要生效,那就必须其它音乐播放器注册了接收此action的广播。

	Intent pauseIntent = new ("com.android.music.musicservicecommand");
	pauseIntent.putExtra("command", "pasue");
	sendBroadcast(pauseIntent);

android的音乐播放器的源码如下,它通过获取togglepause值来判断是应该暂停还是播放,以就是说在电话端应该发送两送这个广播,一次告诉暂停音乐播放,一次告诉开始音乐播放。但是在实验中发现,发送两次togglepause这个命令并不能使音乐暂停后再播放。这个还有待进一步验证,如有错误,再来更新哈。

	public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";  
	public static final String META_CHANGED = "com.android.music.metachanged";  
	public static final String QUEUE_CHANGED = "com.android.music.queuechanged";  
	public static final String PLAYBACK_COMPLETE = "com.android.music.playbackcomplete";  
	public static final String ASYNC_OPEN_COMPLETE = "com.android.music.asyncopencomplete";  
	public static final String SERVICECMD = "com.android.music.musicservicecommand";  
	public static final String CMDNAME = "command";  
	public static final String CMDTOGGLEPAUSE = "togglepause";  
	public static final String CMDSTOP = "stop";  
	public static final String CMDPAUSE = "pause";  
	public static final String CMDPREVIOUS = "previous";  
	public static final String CMDNEXT = "next";  
  
  
	private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {  
     @Override  
     public void onReceive(Context context, Intent intent) {  
         String action = intent.getAction();  
         String cmd = intent.getStringExtra("command");  
         if (CMDNEXT.equals(cmd) || NEXT_ACTION.equals(action)) {  
             next(true);  
         } else if (CMDPREVIOUS.equals(cmd) || PREVIOUS_ACTION.equals(action)) {  
             prev();  
         } else if (CMDTOGGLEPAUSE.equals(cmd) || TOGGLEPAUSE_ACTION.equals(action)) {  
             if (isPlaying()) {  
                 pause();  
             } else {  
                 play();  
             }  
         } else if (CMDPAUSE.equals(cmd) || PAUSE_ACTION.equals(action)) {  
             pause();  
         } else if (CMDSTOP.equals(cmd)) {  
             pause();  
             seek(0);  
         } else if (MediaAppWidgetProvider.CMDAPPWIDGETUPDATE.equals(cmd)) {  
             // Someone asked us to refresh a set of specific widgets, probably  
             // because they were just added.  
             int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);  
             mAppWidgetProvider.performUpdate(MediaPlaybackService.this, appWidgetIds);  
         }  
     }  
 };  

现在网络电话越来越流行,但很遗憾的是,并不是所有的第三方应用都同时监听了传统电话和网络电话,有些只是使用了传统的listener方法监听,所以无法监听到网络电话发出的action = “com.android.music.musicservicecommand” 的广播。比如说某天动听在播放音乐时,就无法监听到某Q拨打的网络电话,但能够正常的监听传统电话。但某米音乐就可以,估计就是它同时注册了传统电话的listener和musicservicecommand。说得不对的地方请指正。

文章目录
|