13

ヘッドセットボタンを押すとアプリに認識されるようになりましたが、ボタンの1つがMyCustomActivityにあるメソッドを呼び出す必要があります。問題は、onReceiveの最初のパラメーターがActivityにキャストできないコンテキストであり、静的でない限り、Android 4.1ではMyCustomActivityの内部クラス の使用が機能しないことです(これには、MyCustomActivityのメソッドにアクセスできないという同じ問題があります。

したがって、(2.xと4.1の両方をサポートするために)私に残された唯一のオプションは、アクティビティをパラメーターとしてRemoteControlReceiverに渡すことです。

しかし、それをインスタンス化する唯一の方法が次の方法である場合、どうすればよいですか。

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

追加のパラメータを受け入れないのはどれですか?

この制限を回避する方法はありますか?

注: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のデータメンバーを設定できるようにするには?

4

1 に答える 1

7

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) を使用します。
于 2013-02-27T06:06:34.850 に答える