android - 如果服务正在运行,如何启动不同的 Activity (并恢复状态)?

标签 android android-intent android-activity android-manifest

我已经有了一个相当完整的位置跟踪应用程序,但仍然有一个问题困扰着我。启动时,如果跟踪服务当前正在运行,应用程序需要显示第二个 Activity 。

  • 我有 2 个 Activity (LoginActivity 和 MainActivity)和 2 个服务(LocationService 和 ReportingService - 都在自己的进程中运行)。
  • 当应用正在跟踪位置时,这 2 个服务必须保持 Activity 状态,但可以终止 MainActivity。
  • LocationService 创建一个不可移除的通知以确保用户知道他们正在被跟踪。当用户点击通知时,它将重新启动/创建 MainActivity - Intent 包含 MainActivity 需要的所有相关数据的额外信息(他们有权访问的帐户和 Assets ,以及哪些已被选中)。

但是,如果应用程序正在跟踪并且 MainActivity 已被终止,然后用户通过常规启动器图标打开应用程序,他们将被带到 LoginActivity。 LoginActivity 是应用程序的典型入口点,如 list 中所定义:

<intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

如果 LocationService 当前正在跟踪,我如何才能将 MainActivity 用作备用入口点?它应该如何恢复其以前的状态数据?

  • 我是否需要在 LoginActivity 的 onCreate() 中添加一些特殊逻辑来检查正在运行的服务,然后立即启动 MainActivity?
  • 如果我这样做,我就会遇到另一个问题:MainActivity 将没有状态数据。如果用户没有通过通知打开通知,有没有办法访问通知的 Intent ?
  • MainActivity.onSaveInstanceState() 将状态数据保存到一个包中,但我认为它在 Activity 被终止后就消失了,不是吗?
  • 我曾考虑过将状态数据直接保存到 SharedPreferences,但这感觉太老套了。我的“东西”对象都实现了 Parcelable,因此它们可以放在 bundle 和 intent extras 中,但你不能将 Parcelables 放在 SharedPreferences 中。我可以通过对它们进行 JSON 化来解决这个问题,但对象的 JSON 表示仅用于与 RESTful 服务器通信,因此它们不包含某些特定于应用程序的数据。我不喜欢肮脏的技巧,所以我宁愿以正确的方式来做这件事。

我认为需要的步骤:

  1. 当跟踪开始时,MainActivity 将帐户和 Assets 的数据库 ID 存储在 SharedPreferences 中
  2. 创建LoginActivity时,检查LocationService是否正在运行
  3. 如果是这样,启动 MainActivity 并附加一个特殊的“从 SharedPreferences 恢复”
  4. MainActivity.onCreate() 显示加载对话框并从 SharedPreferences 获取数据库 ID
  5. 向 ReportingService 广播我们需要获取与 DB ID 对应的对象
  6. 监听响应,然后更新 UI 并取消加载对话框

解决这些问题的最佳方法是什么?

最佳答案

LoginActivity.onCreate()您应该检查跟踪服务是否正在运行,如果正在运行,请立即将用户转到 MainActivity .你想这样做就好像用户点击了 Notification , 这样您就可以使用 PendingIntent 中的附加功能您已存储在 Notification 中.没问题。

LoginActivity.onCreate()这样做:

// Find the PendingIntent that is stored in the Notification
Intent notificationIntent = new Intent(this, MainActivity.class);
// Add any ACTION or DATA or flags that you added when you created the
//  Intent and PendingIntent when you created the Notification

// Now get the `PendingIntent` that is stored in the notification
//  (make sure you use the same "requestCode" as you did when creating
//  the PendingIntent that you stored in the Notification)
PendingIntent pendingIntent = PendingIntent.getActivity(this,
    requestCode, notificationIntent, PendingIntent.FLAG_NO_CREATE);
// Now start MainActivity with the Intent wrapped in the PendingIntent
//  (it contains the extras)
pendingIntent.send();
// Finish LoginActivity (if you usually do that when you launch MainActivity)
finish();

关于android - 如果服务正在运行,如何启动不同的 Activity (并恢复状态)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46200716/

相关文章:

Android:Volley HTTP 请求自定义 header

android - Intent 在 Android Chrome 应用程序版本 40 中不起作用

android - 如何在所有 Activity 中使用一个加载窗口实例

java.lang.RuntimeException : Unable to start activity ComponentIn}: . support.v7.app.ActionBarActivity

android - 如何使用 Android LintFix 添加导入

android - 如何完成应用程序并返回上一屏幕

java - 如何使用 httpUrlConnection 获取 url 的查询字符串,android

安卓 : How to launch Pending intent from another activity with extras?

android - 除了使用 Intent 过滤器之外,我还可以过滤 BroadcastReceiver 吗?

android - 从相同状态重新启动我的应用程序失败,糟糕 :(