BroadcastReceiver 和 Activity 之间的通信 - android

Posted

技术标签:

【中文标题】BroadcastReceiver 和 Activity 之间的通信 - android【英文标题】:Communication between BroadcastReceiver and Activity - android 【发布时间】:2015-03-20 22:18:21 【问题描述】:

我的应用中有一个广播接收器,每次用户接到来电时都会触发它。现在,当它发生时,我需要广播接收器在特定活动中调用特定方法。现在,我尝试将这个方法设为静态并因此可用,但有人告诉我这是一个非常糟糕的主意。

因此,我尝试在我的活动中实例化广播接收器而不在我的清单中声明它,但问题是 - 当应用程序关闭时,活动不存在,因此我无法调用我的方法。

所以我的问题是 - 如何在广播接收器启动时调用此方法,而不将其设为“公共静态”?

这是我的活动代码(我已经删除了不相关的部分)

package com.silverfix.ringo.activities;

import com.silverfix.ringo.R;
import com.silverfix.ringo.activities.fragments.DataManagerFragment;

import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

public class RingtonesActivity extends Activity

    private DataManagerFragment dataManagerFragment;
    private IntentFilter filter;
    private BroadcastReceiver phoneCall;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ringtones);
        ActionBar ab = getActionBar();
        ab.setDisplayShowTitleEnabled(false);
        ab.setDisplayHomeAsUpEnabled(true);
        dataManagerFragment = new DataManagerFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(dataManagerFragment, "DataManagerFragment");
        ft.commit();
        filter = new IntentFilter();
        filter.addAction("android.intent.action.PHONE_STATE");
        phoneCall = new BroadcastReceiver() 

            @Override
            public void onReceive(Context context, Intent intent) 
                dataManagerFragment.act();
            
        ;
        registerReceiver(phoneCall, filter);
    

【问题讨论】:

当您接到电话时,您的应用程序将转为后台。那么您将如何处理活动(当您的应用程序在后台时)?? 该方法是否必须在 Activity 类中? 那个方法会做什么?? 你必须使用pendingIntent来通知。 在注册广播的同一个片段中声明方法或创建一个帮助类在此中移动方法。通过创建此类的对象。你将能够做到这一点。 【参考方案1】:

你可以使用观察者,比如

public class MyReceiver extends BroadcastReceiver 
    public MyReceiver() 
    

    @Override
    public void onReceive(Context context, Intent intent) 
        ObservableObject.getInstance().updateValue(intent);
    


public class MainActivity extends Activity implements Observer 
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ObservableObject.getInstance().addObserver(this);
    

    @Override
    public void update(Observable observable, Object data)             
        Toast.makeText(this, String.valueOf("activity observer " + data), Toast.LENGTH_SHORT).show();
    


public class ObservableObject extends Observable 
    private static ObservableObject instance = new ObservableObject();

    public static ObservableObject getInstance() 
        return instance;
    

    private ObservableObject() 
    

    public void updateValue(Object data) 
        synchronized (this) 
            setChanged();
            notifyObservers(data);
        
    

接收器可以通过清单使用。 ObservableObject - 必须是单例的。

【讨论】:

很好的答案!我喜欢使用设计模式) 与仅使用静态变量相比有什么好处?我的意思是单例无论如何都是静态的,对吧? BroadcastManager 和 BroadcastReceiver 不是类似于观察者模式吗?是什么阻止您将 MainActivity.update 中的代码移动到 MyReceiver.onReceive(从而忘记了中间人)? 赖!我不知道为什么我不记得使用 Observable。谢谢【参考方案2】:

这可能会有所帮助:how can I notify a running activity from a broadcast receiver?

另外,您可以尝试使用Observers

类似:

public class BroadcastObserver extends Observable 
    private void triggerObservers() 
        setChanged();
        notifyObservers();
    

    public void change() 
        triggerObservers();
    

在您的广播接收器中:

@Override
public void onReceive(Context context, Intent intent) 
    BroadcastObserver bco = new BroadcastObserver();
    bco.change();

和活动:

public class YourActivity extends Activity implements
        Observer 
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        BroadcastObserver bco = new BroadcastObserver();
        bco.addObserver(this);
    

    @Override
    public void update() 
        //TODO: call your desired function
    

【讨论】:

【参考方案3】:

如果有人需要 BroadcastReceiver 和 Activity 之间的双向通信,我编写了这个实用程序类,它可以简化相互调用方法,同时仍然是内存安全的。

https://gist.github.com/Jenjen1324/4a0c03beff827082cb641fc8fe2c4e71

【讨论】:

以上是关于BroadcastReceiver 和 Activity 之间的通信 - android的主要内容,如果未能解决你的问题,请参考以下文章

BroadcastReceiver 和 ReentrantLock。有啥问题吗?

具有 ResultReceiver 和生命周期的 BroadcastReceiver

如何从 BroadcastReceiver 在 Activity 中发送和保存字符串消息

BroadcastReceiver和AlarmManager Android

BroadcastReceiver 和 PHONE_STATE 不起作用

Android requestLocationUpdates 使用 PendingIntent 和 BroadcastReceiver