2013-02-27 62 views
11

按下按鈕時我設法讓我的應用程序獲得我的headset buttons get recognized,但其中一個按鈕需要調用MyCustomActivity中的方法。問題是的onReceive的第一個參數是不能轉換到活動並使用MyCustomActivity的內部類won't work in Android 4.1,除非它是靜態的(一個Context,它具有無法訪問MyCustomActivity的方法同樣的問題。如何將參數傳遞給BroadcastReceiver的子類?

那麼剩下的唯一選擇對我來說(以支持2.x和4.1)是通過活動作爲參數傳遞給RemoteControlReceiver

但我怎麼做,當只有這樣,才能實例化它是通過:

private ComponentName mRemoteControlReceiver = new ComponentName(this, RemoteControlReceiver.class); 

哪個不符合ept任何額外的參數?

任何想法如何解決這個限制?

注:如果我嘗試定義RemoteControlReceiver成爲具有參數的構造函數,我收到以下異常:

E/AndroidRuntime(2836): java.lang.RuntimeException: Unable to instantiate receiver com.example.RemoteControlReceiver: java.lang.InstantiationException: can't instantiate class com.example.RemoteControlReceiver; no empty constructor 

Caused by: 
E/AndroidRuntime(2836): Caused by: java.lang.InstantiationException: can't instantiate class com.example.RemoteControlReceiver; no empty constructor 
E/AndroidRuntime(2836):  at java.lang.Class.newInstanceImpl(Native Method) 
E/AndroidRuntime(2836):  at java.lang.Class.newInstance(Class.java:1319) 
E/AndroidRuntime(2836):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2205) 

所以,很顯然,這個新registerMediaButtonEventReceiver要求(的Android 4.1中引入)預計空的構造函數

有沒有辦法解決這個問題?

例如,是否有一種方法可以獲得對實際RemoteControlReceiver對象的引用(通過mAudioManager.registerMediaButtonEventReceiver()間接實例化)?這樣我可以使用訪問器在之後設置RemoteControlReceiver的數據成員它已被實例化?

+1

您可以在Activity的onResume/onCreate中創建並註冊BroadcastReceier,並在onPause/onStop內取消註冊。通過這種方式,當前活動可以處理其使用壽命,並且接收器應該能夠與其容器通信(活動)。 – 2013-02-27 00:30:16

+2

@SudarNimalan我已經試過了。這[只適用於Android 2.x](http://stackoverflow.com/questions/15058743/how-do-i-register-in-manifest-an-inner-media-button-broadcastreciver#comment21174031_15058783)。它在4.1中不起作用。我需要能夠以某種方式讓'RemoteControlReceiver'(不是BroadcastReceiver!)瞭解MyCustomActivity。謝謝。 – an00b 2013-02-27 00:40:00

+0

這是一個艱難的,但這裏是一個想法:你可以檢查與意圖onReceive傳遞的[額外](http://stackoverflow.com/a/14383023/418055)?或者使用[GlobalVariable trick](http://stackoverflow.com/a/6980006/418055)? – 2013-02-27 02:21:47

回答

6

registerMediaButtonEventReceiver要求在應用程序清單中聲明BroadcastReceiver。這意味着接收器必須是獨立的類,這意味着它對您當前的活動或服務一無所知。

爲了得到這個消息,您的活動或服務,你有多種選擇:

  • 使用靜態全局的活動或服務,以便接收器可以將郵件轉發到它。這通常不是一個好主意,因爲它會導致泄漏,並且在稍後想要更改代碼時不適合。靜力學通常是要避免的。

  • 將消息重新廣播到特定的類,這恰好是您要調用的活動或服務的內部類。例如。在廣播接收器的registerMediaButtonEventReceiver:

    // Standalone class, declared in the manifest 
    public class ButtonReceiver extends BroadcastReceiver { 
        @Override 
        public void onReceive(final Context context, final Intent intent) { 
         Intent intent = new Intent(); 
         intent.setAction("com.foo.ACTION"); 
    
         // Rebroadcasts to your own receiver. 
         // This receiver is not exported; it'll only be received if the receiver is currently registered. 
         context.sendBroadcast(intent); 
        } 
    } 
    

而在你的活動:

class MyActivity extends Activity { 
     private BroadcastReceiver myReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(final Context context, final Intent intent) { 
       MyActivity.this.onMessageReceived(); 
      } 
     } 
     @Override 
     protected void onResume() { 
      registerReceiver(myReceiver, new IntentFilter("com.foo.ACTION")); 
     } 

     @Override 
     protected void onPause() { 
      unregisterReceiver(myReceiver); 
     } 

     private void onMessageReceived() { 
     } 
    } 
  • 上述方法類似,但並不一定是廣播,也可能是一個意圖傳遞給活動,取決於你的用例。要做到這一點,而不是使用sendBroadcast,你可以使用startActivity(或者如果你使用的是服務,則使用startService)。
+2

你重新播放的配方就像一個魅力。謝謝! – an00b 2013-02-28 04:41:38