【问题标题】:How to have BroadcastService communicate with Activity?如何让 BroadcastService 与 Activity 通信?
【发布时间】:2015-04-29 22:54:25
【问题描述】:

我正在尝试使用 parse.com 的 push notification service 在我的 Android 应用程序中获取推送通知。他们实现了一个广播接收器,我正在自己的类中扩展它:

public class MyPushBroadcastReceiver extends ParsePushBroadcastReceiver
{
    @Override
    protected void onPushReceive(Context context, Intent intent)
    {
        JSONObject data = getDataFromIntent(intent);

        [...]

        super.onPushReceive(context, intent);
    }

    @Override
    protected void onPushOpen(Context context, Intent intent)
    {
        ParseAnalytics.trackAppOpenedInBackground(intent);

        Intent i = new Intent(context, MyActivity.class);
        i.putExtras(intent.getExtras());
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
}

我覆盖了两种方法:

  • onPushReceive - 当通知到达时调用它
  • onPushOpen - 当用户点击通知区域中的通知时调用它

我需要做三件事:

  1. 当通知到达时,我需要保存它
  2. 当用户点击通知时,我需要打开应用程序以显示我已保存的通知的活动
  3. 如果在我打开应用以显示通知活动时收到通知,我需要更新 UI 以包含新活动。

第一部分很简单。我只是将一些 JSON 写入文件。

第二个我没有遇到任何问题。我创建了一个意图,这将打开我的活动。它从文件中读取 JSON,而 Bob 是你的叔叔。

我一直无法找到处理第三部分的干净方法。

我认为我卡住的地方是我对活动或广播服务的生命周期没有清楚的了解。我也没有在我的应用程序中创建它们,它们在清单中声明,并在任何时候构建。

Android 框架在处理清单时是否会分别创建一个?活动是否可以找到广播接收器的实例?如果可以的话,我很容易在它们之间建立一个回调。

或者我是否需要定义我自己的 BroadcastService,ParsePushBroadcastReceiver 将使用它来发布事件,并且该活动将消耗?我看到的关于这样做的例子似乎过于复杂,因为这应该是一件相当简单的事情。

我们将不胜感激。

【问题讨论】:

  • 很抱歉提出不相关的问题。我是解析新手,是每个活动都必须使用这行代码“trackAppOpenedInBackground”还是仅启动页面以进行跟踪?

标签: android android-intent notifications android-broadcast


【解决方案1】:

关于使用静态变量的建议让我开始思考,我想我找到了一个可行的解决方案。

一个 Activity 可能有多个实例,但任何时候只能有一个实例处于活动状态。

我花了一些时间在要传递给 startActivity() 的 Intent 上设置各种标志,并且不喜欢我看到的任何行为。 (有些组合会崩溃,有些组合会在堆栈中创建多个条目,因此后退按钮会将您返回到 Activity 的旧实例,所有这些组合都会在旧 Activity 被新 Activity 替换时产生视觉效果。)

那么,为什么不创建一个指向当前活动 Activity 的静态字段呢?

public class MyActivity extends Activity implements ReceiveNotifications
{
    public static ReceiveNotifications notificationReceiver = null;

    @Override
    protected void onResume()
    {
        super.onResume();
        NotificationsActivity.notificationReceiver = this;

        updateMessages();
    }

    @Override
    protected void onPause()
    {
        NotificationsActivity.notificationReceiver = null;
        super.onPause();
    }

    @Override
    public void notificationReceived()
    {
        updateMessages();
    }

    private void updateMessages()
    {
        [...]
    }
}

只要 MyActivity 的一个实例处于活动状态,静态变量 notificationReceiver 就会指向它。当然,我正在使用一个接口来控制通过该变量可以看到多少 MyActivity:

public interface ReceiveNotifications
{
    void notificationReceived();
}

然后,当我们收到通知时,如果notificationReceiver不为null,我们调用notificationReceived():

public class MyPushBroadcastReceiver extends ParsePushBroadcastReceiver
{
    @Override
    protected void onPushReceive(Context context, Intent intent)
    {
        JSONObject data = getDataFromIntent(intent);

        [...]

        super.onPushReceive(context, intent);

    if (MyActivity.notificationReceiver != null)
        MyActivity.notificationReceiver.notificationReceived();
    }

    @Override
    protected void onPushOpen(Context context, Intent intent)
    {
        ParseAnalytics.trackAppOpenedInBackground(intent);

        Intent i = new Intent(context, MyActivity.class);
        i.putExtras(intent.getExtras());
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
}

【讨论】:

    【解决方案2】:

    您可以使用 Activity 的onNewIntent() (docs) 方法发送有关发生的事情的新信息,然后显示一些提示。

    【讨论】:

    • 我希望 BroadcastReceiver 仅在 Activity 处于活动状态时更新 Activity。如果不是,我不想让 Activity 提前。
    • 在这种情况下,您可以将活动上下文存储在某个静态变量中。当你收到一个新的通知时,检查这个静态变量是否为空,使用它来向用户显示提示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多