[英]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.