简体   繁体   English

如何使用广播接收器向布局中的对象发送命令?

[英]How Do I Use A Broadcast Receiver To Send Commands To Objects In A Layout?

I am using a service and a broadcast receiver.我正在使用服务和广播接收器。 When the service is started it will put a notification in the user's notification center that returns a START_STICKY.当服务启动时,它会在用户的通知中心放置一个返回 START_STICKY 的通知。 I added an action button to that notification that will stop the service.我在该通知中添加了一个操作按钮,它将停止服务。 That part works fine, but I also have a switch object on my activity_main.xml layout that I want it to uncheck when the user taps on that action button to stop the service if the user still has that layout opened, and in focus on their screen at the time they tapped on that action button.这部分工作正常,但我在我的activity_main.xml 布局上也有一个开关 object 我希望它取消选中当用户点击该操作按钮以停止服务时,如果用户仍然打开该布局,并专注于他们的他们点击该操作按钮时的屏幕。

I thought the solution was as easy as using a LayoutInflater, but it's not working for me.我认为解决方案就像使用 LayoutInflater 一样简单,但它对我不起作用。

Here is what I tried... I put the following code in the onReceive method in my Broadcast Receiver class.这是我尝试过的...我将以下代码放在我的广播接收器 class 的 onReceive 方法中。 All the other stuff that I have in that method is working fine except for this part in question.除了有问题的这一部分之外,我在该方法中拥有的所有其他东西都可以正常工作。

LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.activity_main, null);
Switch sw = (Switch) v.findViewById(R.id.mySwitch);
sw.setChecked(false);

You would think that would work.你会认为这行得通。 I'm telling it to look at a specific layout, and then I told it to execute a uncheck command to the switch object that exists on that layout from the action button in the notification.我告诉它查看特定布局,然后我告诉它从通知中的操作按钮对存在于该布局上的开关 object 执行取消选中命令。 It's not receiving the command.它没有收到命令。

Any ideas?有任何想法吗? I appreciate the help!!我很感激帮助!

[enter image description here] ( https://i.stack.imgur.com/8UKu6.jpg ) [在此处输入图片描述] ( https://i.stack.imgur.com/8UKu6.jpg )

If it helps my project can be downloaded here... enter link description here如果对我的项目有帮助,可以在这里下载...在此处输入链接描述

Here are my new changes...这是我的新变化...

Broadcast Receiver Class广播接收器 Class

public static String ACTION_TURN_OFF_THE_LIGHTS = "com.mathiasapps.lightsonexample.action.TURN_OFF_THE_LIGHTS";


Intent actionStopIntent = new Intent(this, actionTurnOffReceiver.class);
        actionStopIntent.setAction(ACTION_TURN_OFF_THE_LIGHTS);
        PendingIntent actionStopPI = PendingIntent.getBroadcast(this, 0, actionStopIntent, PendingIntent.FLAG_UPDATE_CURRENT);

MainActivity Class主要活动 Class

@Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IntentFilter filter = new IntentFilter(ACTION_TURN_OFF_THE_LIGHTS);
        registerReceiver(receiver, filter);

    private final MyActivityReceiver receiver = new MyActivityReceiver();

    @SuppressLint("UseSwitchCompatOrMaterialCode")
    public Switch sw;


    class MyActivityReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            @SuppressLint("UseSwitchCompatOrMaterialCode")
            Switch sw = findViewById(R.id.lights_on_switch);
            sw.setChecked(false);
        }
    }

Here is what I tried... I put the following code in the onReceive method in my Broadcast Receiver class.这是我尝试过的...我将以下代码放在我的广播接收器 class 的 onReceive 方法中。 All the other stuff that I have in that method is working fine except for this part in question.除了有问题的这一部分之外,我在该方法中拥有的所有其他东西都可以正常工作。

LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); View v = inflater.inflate(R.layout.activity_main, null);查看 v = inflater.inflate(R.layout.activity_main, null); Switch sw = (Switch) v.findViewById(R.id.mySwitch); Switch sw = (Switch) v.findViewById(R.id.mySwitch); sw.setChecked(false); sw.setChecked(false);

You would think that would work.你会认为这行得通。

No, you would not.不,你不会。

I'm telling it to look at a specific layout, and then I told it to execute a uncheck command to the switch object that exists on that layout from the action button in the notification.我告诉它查看特定布局,然后我告诉它从通知中的操作按钮对存在于该布局上的开关 object 执行取消选中命令。

No, you're not.不你不是。

Your Problem你的问题

You are inflating a brand new instance of your main activity layout, finding the switch within that layout, and setting that switch - which is NOT the switch in your activity - to unchecked.您正在扩充主要活动布局的全新实例,在该布局中找到开关,并将该开关(不是活动中的开关)设置为未选中。 You are not touching your actual Activity layout by doing this.通过这样做,您不会触及实际的 Activity 布局。

A Solution一个解法

You need to register a broadcast receiver with the Activity so the actual running instance of the Activity can receive the broadcast and toggle the switch that it contains.您需要向 Activity 注册广播接收器,以便 Activity 的实际运行实例可以接收广播并切换它包含的开关。 See the documentation for an example.有关示例,请参阅文档

Pseudocode (should go without saying, this is not tested and is meant to guide you towards the solution):伪代码(应该 go 不用说,这未经测试,旨在引导您找到解决方案):

class MyActivity {
    // The receiver that will listen for the "off" broadcast
    class MyActivityReceiver : BroadcastReceiver {
        // When this receiver gets notified, call the owning activity's method
        void onReceive(Intent intent) {
            turnOffToggle();
        }
    }

    private final MyActivityReceiver receiver = new MyActivityReceiver();

    protected void onCreate(...) {
        super.onCreate(...)

        // Register the receiver so we get notified while this activity is active
        IntentFilter filter = // create filter for your broadcast intent
        registerReceiver(receiver, filter);
    }

    proteced void onDestroy() {
        // Stop listening once we're killed
        unregisterReceiver(receiver);
    }

    private void turnOffToggle() {
        // Find the switch in THIS active Activity's layout
        Switch sw = (Switch) findViewById(R.id.mySwitch);
        sw.setChecked(false);
    }
}

Edit after questions:问题后编辑:

1 - when you set up the action you're targeting the service's local receiver with your intent: 1 - 当您设置操作时,您的意图是针对服务的本地接收器:

// Will only invoke `actionTurnOffReceiver` declared in the service.
Intent actionStopIntent = new Intent(this, actionTurnOffReceiver.class);

You need a more generic intent any receiver (ie, the one in the activity) can listen for.您需要任何接收者(即活动中的那个)都可以监听的更通用的意图。

// ACTION_TURN_OFF_THE_LIGHTS is some string like "com.my.package.action.TURN_OFF_THE_LIGHTS"
Intent actionStopIntent = new Intent(this, ACTION_TURN_OFF_THE_LIGHTS)

2 - Your activity registration is too generic: 2 - 您的活动注册过于笼统:

// This is blindly registering for all broadcasts - or Android will just ignore it
IntentFilter filter = new IntentFilter();
registerReceiver(receiver, filter);

As is shown in the example in the documentation I linked to, you have to set up your filter to match the intent you care about.如我链接到的文档中的示例所示,您必须设置过滤器以匹配您关心的意图。 In this case, it's for the "turn off" action:在这种情况下,它用于“关闭”操作:

IntentFilter filter = new IntentFilter(ACTION_TURN_OFF_THE_LIGHTS);
registerReceiver(receiver, filter);

Please review the entire section on Broadcasts so you have a better understanding of how they work.请查看有关广播的整个部分,以便更好地了解它们的工作原理。 And here's a Medium article that goes into Broadcast Receivers. 这是一篇关于广播接收器的 Medium 文章

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

相关问题 如何从广播接收机访问变量? - How do I access variables from a broadcast receiver? 如何在广播接收器中使用助手类作为单例? - How to use helper class as singleton in broadcast receiver? 如何在不重新启动的情况下将广播接收器的信息发送回我的主要活动 - how can i send information from broadcast receiver back to my main activity without restarting it 如何创建广播接收器? - How can i create a broadcast receiver? 尽管发送广播正在工作,但接收器广播不起作用 - Receiver Broadcast not Working although send Broadcast is working 如何在 Android API 30 设备中使用 Static 广播接收器或类似服务? - How can I use Static Broadcast Receiver or similar service in Android API 30 device? 我怎么知道何时从广播接收器与Android调用我的服务? - How do I know when my service is called from a broadcast receiver vs Android? 如何从广播接收器的 MainActivity 访问我的 UI class - How do I access my UI from MainActivity from Broadcast Receiver class Android Studio 中如何使用广播接收器接收短信? - How to use a broadcast receiver to receive SMS in Android Studio? 如何使用广播接收器在运行应用程序期间监视Internet连接 - How to use Broadcast receiver to Monitor Internet connection during running application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM