2013-02-27 22 views
11

私のアプリではheadset buttons get recognizedが押されてしまいましたが、ボタンの1つはMyCustomActivityのメソッドを呼び出す必要があります。問題はonReceiveの第一パラメータは、活動にキャストし、それがMyCustomActivityのメソッドにアクセスすることができないのと同じ問題を抱えている静的(ある場合を除きMyCustomActivityの内部クラスwon't work in Android 4.1を使用することができない状況である。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) 

をだから(アンドロイド4.1で導入された)この新しいregisterMediaButtonEventReceiver要件ことは明らかです空のコンストラクタが必要です。

これを回避する方法はありませんか?

たとえば、実際のRemoteControlReceiverオブジェクトへの参照を取得する方法がありますか(間接的にmAudioManager.registerMediaButtonEventReceiver()によってインスタンス化されます)。私がアクセサリーを使用しての後にRemoteControlReceiver のデータメンバをインスタンス化することができますか?

+1

ActivityのonResume/onCreateにBroadcastReceierを作成して登録し、onPause/onStop内で登録を解除することができます。このようにして、現在のアクティビティはそのライフタイムを処理することができ、受信者はコンテナ(アクティビティ)と通信できる必要があります。 –

+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

+0

これは厳しいものですが、ここではアイデアがあります:[Extra](http://stackoverflow.com/a/14383023/418055)にIntent onReceiveが渡されたことを確認できますか?または、この[GlobalVariable trick](http://stackoverflow.com/a/6980006/418055)を使用しますか? –

答えて

6

registerMediaButtonEventReceiverでは、アプリケーションマニフェストでBroadcastReceiverを宣言する必要があります。つまり、レシーバはスタンドアロンクラスである必要があります。つまり、現在のアクティビティやサービスについては何も知らないという意味です。受信機はそれにメッセージを送ることができるように

  • が活動またはサービスのための静的なグローバルを使用してください:あなたの活動やサービスにこのメッセージを得るためには

    は、あなたは多くのオプションを持っています。後でコードを変更したいときは、リークにつながり、あまり適応しないため、これは一般的には良い考えではありません。統計は一般に避けなければならない。

  • 特定のクラスにメッセージを再ブロードキャストします。このクラスは、呼び出すアクティビティまたはサービスの内部クラスになります。例えば。 registerMediaButtonEventReceiverためBroadcastReceiverで:

そして、あなたの活動の

// 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

関連する問題