歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android中MediaButtonReceiver廣播監聽器的機制分析

在Android中並沒有定義MediaButtonReceive這個廣播類,MediaButtonReceive只是作為一種通俗的命名方式來響應插入耳機後,點擊耳機上的按鈕(名稱:MEDIA_BUTTON)接受該廣播事件的類。所有該MEDIA_BUTTON的按下我們就簡稱為MEDIA_BUTTON廣播吧。

顧名思義:它顯然是一個廣播接收器類(BroadbcastReceiver),那麼它就具備了BroadbcastReceiver類的使用方式,但是,因為它需要通過AudioManager對象注冊,所以它有著自己的獨特之處(否則我也不會單獨拿出來分析,- -),後面我們會慢慢的講解。

點擊MEDIA_BUTTON發送的Intent Action 為:

ACTION_MEDIA_BUTTON  ="android.intent.action.MEDIA_BUTTON"

Intent 附加值為(Extra)點擊MEDIA_BUTTON的按鍵碼 :    

                        //獲得KeyEvent對象

                        KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

                        //獲得Action

                        String intentAction = intent.getAction() ;

 

AudioManager對象注冊MEDIA_BUTTON廣播的方法原型為:

 

   public voidregisterMediaButtonEventReceiver(ComponentNameeventReceiver)

          Register a component to be the sole receiverof MEDIA_BUTTON intents

          Parameters:                   

                eventReceiver  : identifier of a BroadcastReceiver that will receive the media button intent. This broadcast receiver

                                   must be declared in the application manifest.

   從注釋可知以下兩點:

      1、 在AudioManager對象注冊一個MediaoButtonRecevie,使它成為MEDIA_BUTTON的唯一接收器(這很重要,

          我們會放在後面講解)   也就是說只有我能收到,其他的都收不到這個廣播了,否則的話大家都收到會照成一定的混亂;

      2、   該廣播必須在AndroidManifest.xml文件中進行聲明,否則就監聽不到該MEDIA_BUTTON廣播了。

 

下面我們就簡單的寫一個MediaButtonReceiver類,並且在AndroidManifest.xml定義

 

1、  自定義的MediaButtonReceiver 廣播類

[java]
  1. package com.qin.mediabutton;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7. import android.view.KeyEvent;  
  8.   
  9. public class MediaButtonReceiver extends BroadcastReceiver {  
  10.     private static String TAG = "MediaButtonReceiver";  
  11.     @Override  
  12.     public void onReceive(Context context, Intent intent) {  
  13.         // 獲得Action   
  14.         String intentAction = intent.getAction();  
  15.         // 獲得KeyEvent對象   
  16.         KeyEvent keyEvent = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);  
  17.   
  18.         Log.i(TAG, "Action ---->" + intentAction + "  KeyEvent----->"+ keyEvent.toString());  
  19.   
  20.         if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {  
  21.             // 獲得按鍵字節碼   
  22.             int keyCode = keyEvent.getKeyCode();  
  23.             // 按下 / 松開 按鈕   
  24.             int keyAction = keyEvent.getAction();  
  25.             // 獲得事件的時間   
  26.             long downtime = keyEvent.getEventTime();  
  27.   
  28.             // 獲取按鍵碼 keyCode   
  29.             StringBuilder sb = new StringBuilder();  
  30.             // 這些都是可能的按鍵碼 , 打印出來用戶按下的鍵   
  31.             if (KeyEvent.KEYCODE_MEDIA_NEXT == keyCode) {  
  32.                 sb.append("KEYCODE_MEDIA_NEXT");  
  33.             }  
  34.             // 說明:當我們按下MEDIA_BUTTON中間按鈕時,實際出發的是 KEYCODE_HEADSETHOOK 而不是   
  35.             // KEYCODE_MEDIA_PLAY_PAUSE   
  36.             if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == keyCode) {  
  37.                 sb.append("KEYCODE_MEDIA_PLAY_PAUSE");  
  38.             }  
  39.             if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) {  
  40.                 sb.append("KEYCODE_HEADSETHOOK");  
  41.             }  
  42.             if (KeyEvent.KEYCODE_MEDIA_PREVIOUS == keyCode) {  
  43.                 sb.append("KEYCODE_MEDIA_PREVIOUS");  
  44.             }  
  45.             if (KeyEvent.KEYCODE_MEDIA_STOP == keyCode) {  
  46.                 sb.append("KEYCODE_MEDIA_STOP");  
  47.             }  
  48.             // 輸出點擊的按鍵碼   
  49.             Log.i(TAG, sb.toString());  
  50.         }  
  51.     }  
  52. }  

 

  2、  在AndroidManifest.xml聲明我們定義的廣播類。

 

[java]
  1.  <receiver android:name="MediaButtonReceiver">  
  2.   <intent-filter >  
  3.         <action android:name="android.intent.action.MEDIA_BUTTON"></action>  
  4.   </intent-filter>  
  5. </receiver>  

 

         在模擬器上,我們可以手動構造MEDA_BUTTON的廣播,並且將它發送出去(後面會介紹)。

         如果有真機測試的話,按下MEDIA_BUTTON是可以接受到MEDIA_BUTTON廣播的,如果沒有接受到,請關閉所有應用

   程序,在觀察效果。

 

  繼續我們的下一步分析:

         前面我們說明通過registerMediaButtonEventReceiver(eventReceiver)方法注冊時使它成為MEDIA_BUTTON的

     唯一 接收器。這個唯一是怎麼實現的呢? 我們在源碼中,一步步追本溯源,相信一定可以找到答案,知道這“唯一“是

    怎麼來的。

 

第一步、   為AudioManager注冊一個MediaButtonReceiver() ;

[java]
  1. //獲得AudioManager對象   
  2. AudioManager mAudioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);     
  3. //構造一個ComponentName,指向MediaoButtonReceiver類   
  4. //下面為了敘述方便,我直接使用ComponentName類來替代MediaoButtonReceiver類   
  5. ComponentName  mbCN = new ComponentName(getPackageName(),MediaButtonReceiver.class.getName());  
  6. //注冊一個MedioButtonReceiver廣播監聽   
  7. mAudioManager.registerMediaButtonEventReceiver(mbCN);  
  8. //取消注冊的方法   
  9. mAudioManager.unregisterMediaButtonEventReceiver(mbCN);  

      

        MediaButtonReceiver就是我們用來接收MEDIA_BUTTON的廣播類,下面為了敘述方便和直觀上得體驗,我直接使用

    ComponentName類來替代真正的MediaoButtonReceiver廣播類。

 

   說明 接下來分析的文件路徑全部在   frameworks/base/media/java/android/media/ 下

Copyright © Linux教程網 All Rights Reserved