Как передать параметр в подкласс BroadcastReceiver?

Мне удалось заставить мои кнопки гарнитуры распознаваться моим приложением при нажатии, но одной из кнопок нужно вызвать метод, который находится в MyCustomActivity. Проблема состоит в том, что первый параметр onReceive – это контекст, который нельзя передать в Activity, а использование внутреннего класса MyCustomActivity не будет работать в Android 4.1, если оно не является статичным (что имеет ту же проблему неспособности получить доступ к методу 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() косвенно через mAudioManager.registerMediaButtonEventReceiver() )? Чтобы я мог использовать аксессуар для установки члена данных RemoteControlReceiver после его создания?

Solutions Collecting From Web of "Как передать параметр в подкласс BroadcastReceiver?"

RegisterMediaButtonEventReceiver требует, чтобы BroadcastReceiver был объявлен в манифесте приложения. Это означает, что приемник должен быть автономным классом, то есть он ничего не знает о вашей текущей деятельности или услуге.

Чтобы получить это сообщение в вашей деятельности или услуге, у вас есть несколько вариантов:

  • Используйте статический глобальный для активности или службы, чтобы получатель мог передать ему сообщение. Это, как правило, не очень хорошая идея, так как это приводит к утечкам и не очень адаптируется, когда вы хотите изменить код позже. Статики, как правило, следует избегать.

  • Повторно передайте сообщение определенному классу, который является внутренним классом активности или службы, которую вы хотите вызвать. Например, в 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, если вы используете службу).