簡體   English   中英

如何使用廣播接收器向布局中的對象發送命令?

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

我正在使用服務和廣播接收器。 當服務啟動時,它會在用戶的通知中心放置一個返回 START_STICKY 的通知。 我在該通知中添加了一個操作按鈕,它將停止服務。 這部分工作正常,但我在我的activity_main.xml 布局上也有一個開關 object 我希望它取消選中當用戶點擊該操作按鈕以停止服務時,如果用戶仍然打開該布局,並專注於他們的他們點擊該操作按鈕時的屏幕。

我認為解決方案就像使用 LayoutInflater 一樣簡單,但它對我不起作用。

這是我嘗試過的...我將以下代碼放在我的廣播接收器 class 的 onReceive 方法中。 除了有問題的這一部分之外,我在該方法中擁有的所有其他東西都可以正常工作。

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);

你會認為這行得通。 我告訴它查看特定布局,然后我告訴它從通知中的操作按鈕對存在於該布局上的開關 object 執行取消選中命令。 它沒有收到命令。

有任何想法嗎? 我很感激幫助!

[在此處輸入圖片描述] ( https://i.stack.imgur.com/8UKu6.jpg )

如果對我的項目有幫助,可以在這里下載...在此處輸入鏈接描述

這是我的新變化...

廣播接收器 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);

主要活動 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);
        }
    }

這是我嘗試過的...我將以下代碼放在我的廣播接收器 class 的 onReceive 方法中。 除了有問題的這一部分之外,我在該方法中擁有的所有其他東西都可以正常工作。

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

你會認為這行得通。

不,你不會。

我告訴它查看特定布局,然后我告訴它從通知中的操作按鈕對存在於該布局上的開關 object 執行取消選中命令。

不你不是。

你的問題

您正在擴充主要活動布局的全新實例,在該布局中找到開關,並將該開關(不是活動中的開關)設置為未選中。 通過這樣做,您不會觸及實際的 Activity 布局。

一個解法

您需要向 Activity 注冊廣播接收器,以便 Activity 的實際運行實例可以接收廣播並切換它包含的開關。 有關示例,請參閱文檔

偽代碼(應該 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);
    }
}

問題后編輯:

1 - 當您設置操作時,您的意圖是針對服務的本地接收器:

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

您需要任何接收者(即活動中的那個)都可以監聽的更通用的意圖。

// 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 - 您的活動注冊過於籠統:

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

如我鏈接到的文檔中的示例所示,您必須設置過濾器以匹配您關心的意圖。 在這種情況下,它用於“關閉”操作:

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

請查看有關廣播的整個部分,以便更好地了解它們的工作原理。 這是一篇關於廣播接收器的 Medium 文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM