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

Posted

技术标签:

【中文标题】如何将参数传递给 BroadcastReceiver 的子类?【英文标题】:How to pass a parameter to a subclass of BroadcastReceiver? 【发布时间】:2013-02-12 15:59:11 【问题描述】:

我在按下时设法通过我的应用程序获取了我的headset buttons get recognized,但其中一个按钮需要调用 MyCustomActivity 中的方法。问题是 onReceive 的第一个参数是一个 Context,它不能强制转换为 Activity 并使用 MyCustomActivity 的 inner class won't work in android 4.1,除非它是静态的(同样的问题是无法访问 MyCustomActivity 的方法。 p>

所以留给我的唯一选择(为了同时支持 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 的数据成员

【问题讨论】:

可以在Activity的onResume/onCreate中创建并注册BroadcastReceier,在onPause/onStop中取消注册。通过这种方式,当前活动可以照顾其生命周期,并且接收者应该能够与其容器(活动)进行通信。 @SudarNimalan 我已经尝试过了。这个only works in Android 2.x。它在 4.1 中不起作用。我需要能够以某种方式让RemoteControlReceiver(不是BroadcastReceiver!)知道MyCustomActivity。谢谢。 这是一个艰难的问题,但这里有一个想法:你能检查通过 Intent onReceive 传递的Extra 吗?或者使用这个GlobalVariable trick? 看到这个答案可能对你有帮助。 ***.com/questions/15059886/… 【参考方案1】:

registerMediaButtonEventReceiver 要求在应用程序清单中声明 BroadcastReceiver。这意味着接收器必须是一个独立的类,这意味着它对您当前的活动或服务一无所知。

为了向您的活动或服务发送此消息,您有多种选择:

为活动或服务使用静态全局,以便接收者可以将消息转发给它。这通常不是一个好主意,因为它会导致泄漏,并且在您以后想要更改代码时不是很适应。通常要避免静电。

将消息重新广播到特定类,该类恰好是您要调用的活动或服务的内部类。例如。在广播接收器中注册MediaButtonEventReceiver:

// 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() 
        
    
与上述方法类似,它不一定是广播,也可以是传递给活动的 Intent,具体取决于您的用例。要做到这一点,而不是使用 sendBroadcast,您可以使用 startActivity(或 startService,如果您使用的是服务)。

【讨论】:

以上是关于如何将参数传递给 BroadcastReceiver 的子类?的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数传递给进程

如何通过反射将参数传递给方法

如何将参数传递给 erlang os:cmd()?

如何使用 SwiftUI 将参数传递给 Button 的操作

如何将两个参数传递给 Pool.starmap()?

如何将参数传递给 JSP 组件?