如何从广播接收器发送结果数据到活动界面?

11

我有一个活动(Activity)调用了广播接收器(Broadcast Receiver)。广播接收器等待并监听GPS。当监听器获得新点时,我想将该新点发送给活动。如何从广播接收器向活动发送数据?

我需要在我的活动中添加一个监听器,以等待广播接收器的响应。我该如何做到这一点?

4个回答

22

您可以从您的活动中调用接收器。如果您不想在您的活动中添加接收器的逻辑,您可以使用抽象接收器。

您的抽象接收器:

public abstract class SmsReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
           //Add you receiver logic here
           ...
           ...
           onNewPosition();
        }

    protected abstract void onNewPosition();

}

在您的活动中:

public class MyActivity extends Activity {

    private smsReceiver smsReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_one_position);
        smsReceiver = new smsReceiver() {

            // this code is call asyncrously from the receiver
            @Override
            protected void onNewPosition() {
            //Add your activty logic here
            }

        };
        IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        intentFilter.setPriority(999);
        this.registerReceiver(smsReceiver, intentFilter);

    }

     @Override
        protected void onPause() {
            super.onPause();
            this.unregisterReceiver(this.smsReceiver);
        }

}

希望这能对你有所帮助...


9
你如何实例化抽象类? - Nitin Bansal

4

我为我的接收器定义了一个监听器,并在活动中使用它,现在它运行得很好。以后会出现任何问题吗?

public interface OnNewLocationListener {
public abstract void onNewLocationReceived(Location location);

在我的接收器类中,它被命名为ReceiverPositioningAlarm:

// listener ----------------------------------------------------

static ArrayList<OnNewLocationListener> arrOnNewLocationListener =
        new ArrayList<OnNewLocationListener>();

// Allows the user to set an Listener and react to the event
public static void setOnNewLocationListener(
        OnNewLocationListener listener) {
    arrOnNewLocationListener.add(listener);
}

public static void clearOnNewLocationListener(
        OnNewLocationListener listener) {
    arrOnNewLocationListener.remove(listener);
}

// This function is called after the new point received
private static void OnNewLocationReceived(Location location) {
    // Check if the Listener was set, otherwise we'll get an Exception when
    // we try to call it
    if (arrOnNewLocationListener != null) {
        // Only trigger the event, when we have any listener
        for (int i = arrOnNewLocationListener.size() - 1; i >= 0; i--) {
            arrOnNewLocationListener.get(i).onNewLocationReceived(
                    location);
        }
    }
}

在我的一个活动方法中:

OnNewLocationListener onNewLocationListener = new OnNewLocationListener() {
        @Override
        public void onNewLocationReceived(Location location) {
            // do something

            // then stop listening
            ReceiverPositioningAlarm.clearOnNewLocationListener(this);
        }
    };

    // start listening for new location
    ReceiverPositioningAlarm.setOnNewLocationListener(
            onNewLocationListener);

6
我担心你可能保持强引用,这可能不太好。 - GorillaApe

3
你有几种方法可以实现它,并需要考虑几个方面。
  1. 你可以轮询,使用Handler或Timer每隔一段时间检查是否有信息到达。
  2. 你可以将广播接收器注册为活动的内部类,然后可以在活动中调用该类的方法。
  3. 你可以将广播发送Intent到你的类中,但是如果你的活动不在前台,你可能会把它带到前台,这不是你想要的100% ...
关于一些考虑因素,BroadcastReceiver主要用作监听器而不是通知器,因此在我的意见中,将其作为内部类与活动一起使用是最佳实践。对于服务,您可以将其用作独立的类并在Manifest.xml中注册它... 现在你必须记住,当广播正在广播时,由于方向更改或暂停应用程序的事件,你的活动可能处于非活动状态,因此你可能会错过该事件。我不监听系统事件,而是使用黏性广播来防止这个问题。

谢谢。在第三个解决方案中,我该如何获取那个意图?你能否请详细解释一下? - Bobs
你可以使用context.startActivity()发送Intent。 在Activity中,你可以通过onCreate或onResume方法中的getIntent方法,或者是通过重写onNewIntent方法来获取Intent。问题是你的Activity是否会重新启动,你可以在Activity和Intent的Java文档中了解更多信息,特别是与Intent标志(SINGLE_TOP)相关的部分。 - codeScriber
你决定使用监听器模式,这可能可以正常工作,对我来说也是如此。但是不要忘记,如果你的监听器之一是一个Activity,当你获取方向或其他配置更改事件导致应用程序死亡并重新创建时,你会泄漏上下文。在这种情况下,你必须更改你的onResume和onPause代码(或onCreate和onDestroy),以便在Activity返回后删除监听器并将其放回。 - codeScriber
哦,当活动返回并重新设置侦听器后,您必须检查在此期间是否错过了任何事件... - codeScriber

0

只需要在活动中实现广播接收器。使用活动的上下文注册接收器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接