简体   繁体   English

如何将参数传递给BroadcastReceiver的子类?

[英]How to pass a parameter to a subclass of BroadcastReceiver?

I managed to get my headset buttons get recognized by my app when pressed, but one of the buttons needs to call a method that's in MyCustomActivity. 我按下时设法让我的应用程序识别我的耳机按钮 ,但其中一个按钮需要调用MyCustomActivity中的方法。 The problem is onReceive's 1st parameter is a Context that cannot be cast to Activity and using a MyCustomActivity's inner class won't work in Android 4.1 unless it is static (which has the same problem of inability to access MyCustomActivity's method. 问题是onReceive的第一个参数是一个不能强制转换为Activity的Context,并且使用MyCustomActivity的内部类 在Android 4.1中不起作用,除非它是静态的(具有无法访问MyCustomActivity方法的相同问题)。

So the only option left for me (in order to support both 2.x and 4.1) is to pass the activity as a parameter to RemoteControlReceiver . 所以我唯一的选择(为了支持2.x和4.1)是将活动作为参数传递给RemoteControlReceiver

But how do I do that, when the only way to instantiate it is via: 但是,如何实现它的唯一方法是通过:

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

Which doesn't accept any additional parameters? 哪个不接受任何其他参数?

Any idea how to work around this limitation? 任何想法如何解决这个限制?

Note: If I try to define RemoteControlReceiver as having a constructor with a parameter, I receive the following exception: 注意:如果我尝试将RemoteControlReceiver定义为具有带参数的构造函数, 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)

So it is clear that this new registerMediaButtonEventReceiver requirement (introduced in Android 4.1) expects an empty constructor . 很明显,这个新的registerMediaButtonEventReceiver要求(在Android 4.1中引入)需要一个空的构造函数

Is there no way to work around this? 有没有办法解决这个问题?

For example, is there a way to get a reference to the actual RemoteControlReceiver object (instantiated indirectly via mAudioManager.registerMediaButtonEventReceiver() )? 例如,有没有办法获取对实际RemoteControlReceiver对象的引用(通过mAudioManager.registerMediaButtonEventReceiver()间接实例化)? So that I can use an accessor to set a data-member of RemoteControlReceiver after it has been instantiated? 这样我可以使用访问器在实例化设置RemoteControlReceiver的数据成员吗?

registerMediaButtonEventReceiver requires the BroadcastReceiver to be declared in the application manifest. registerMediaButtonEventReceiver要求在应用程序清单中声明BroadcastReceiver。 This means that the receiver must be a standalone class, meaning it knows nothing about your current activity or service. 这意味着接收器必须是独立的类,这意味着它对您当前的活动或服务一无所知。

In order to get this message to your activity or service, you have a number of options: 为了将此消息发送到您的活动或服务,您有许多选择:

  • Use a static global for the activity or service so the receiver can forward the message to it. 为活动或服务使用静态全局,以便接收方可以将消息转发给它。 This is generally not a good idea as it leads to leaks and isn't very adaptable when you want to change the code later. 这通常不是一个好主意,因为它会导致泄漏,并且当您想稍后更改代码时,它不具有很强的适应性。 Statics are generally to be avoided. 通常要避免使用静力学。

  • Re-broadcast the message to a specific class, which happens to be an inner class of the activity or service you want to invoke. 将消息重新广播到特定的类,该类恰好是您要调用的活动或服务的内部类。 Eg in the BroadcastReceiver for 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); } } 

And in your activity: 在你的活动中:

    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() {
        }
    }
  • Similar to the above method, it doesn't necessarily have to be a broadcast, it could be an Intent passed to the activity, depending on your use case. 与上述方法类似,它不一定必须是广播,它可以是传递给活动的Intent,具体取决于您的用例。 To do this instead of using sendBroadcast, you'd use startActivity (or startService if you're using a service). 要执行此操作而不是使用sendBroadcast,您可以使用startActivity(如果您正在使用服务,则使用startService)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM