应用关闭时接收 TIME_SET 广播

Posted

技术标签:

【中文标题】应用关闭时接收 TIME_SET 广播【英文标题】:Receiving TIME_SET Broadcast when app is closed 【发布时间】:2016-10-10 09:26:57 【问题描述】:

当用户更改 android 系统时间时,我想在首选项中存储一个布尔值。因此我将广播动作 ACTION_TIME_CHANGED 添加到清单中:

<receiver android:name="test.TimeChangedReceiver">
   <intent-filter>
      <action android:name="android.intent.action.TIME_SET" />
      <action android:name="android.intent.action.TIMEZONE_CHANGED" />
   </intent-filter>
</receiver>

TimeChangedReceiver 扩展了 BroadcastReceiver 并覆盖了 onReceive()。在此类中,将存储布尔值并显示通知。

public class TimeChangedReceiver extends BroadcastReceiver 

private static final String TAG = "TimeChangedReceiver";

public TimeChangedReceiver() 
    super();


@Override
public void onReceive(Context context, Intent intent) 

    // store boolean to SharedPreferences
    PreferenceUtils.getInstance().storeBoolean(true, PreferenceUtils.CHECK_LICENSE);

    // build notification 
    int icon = android.R.drawable.ic_dialog_alert;
    String title = "changed time";
    String text = "user changed time";

    long when = System.currentTimeMillis();
    String timezone = intent.getStringExtra("time-zone");
    Notification notification = new Notification(icon, title, when);
    NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    int notification_id = (int) System.currentTimeMillis();
    Intent notificationIntent = new Intent(context, MainView.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    notificationIntent.putExtra("time-zone", timezone);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT );
    notification.setLatestEventInfo(context, title, text, contentIntent);
    mgr.notify(notification_id, notification);

在应用关闭之前一切正常 - 不再在后台运行。

这里说:

If you declare the BroadcastReceiver in the Manifest, it will always be active and be called even if the application is closed/stopped By putting your BroadcastReceiver in your Manifest, it, by default, is always active.

我怎样才能接收广播并存储布尔值?

我不需要查看通知。

【问题讨论】:

尝试在&lt;receiver ...&gt;android:name="..." 属性之后或之前将android:enabled="true" 添加到您的接收器中 默认开启^ @Marat link 默认值为“true”。它没有任何改变。 :( 您能否使用Log 测试您的应用,以确保在应用不活动时它没有运行onReceive @Marat 我在装有 Android 6.0.1 的三星设备上对其进行了测试。当应用程序在后台时有日志。当我“强制停止”应用程序并在之后更改日期时没有日志。 【参考方案1】:

在应用关闭之前一切正常 - 不再在后台运行。

当我“强制停止”应用程序并随后更改日期时没有日志。

您的观察是正确的,被认为是正常行为。在您通过系统设置“强制停止”后,您的BroadcastReceiver 将不再收到消息,即使您在 AndroidManifest.xml 中声明它们也是如此。通过执行“强制停止”,您基本上可以指示系统:“立即停止此应用程序,不要让它再次运行”。这是一项管理操作,因此只能从系统设置中访问。这很有意义不是吗?对于新安装的应用程序也是如此。在至少启动一次之前,它不会收到任何广播意图。

Android 系统就是这样设计的。你不能对它做任何事情。

我怎样才能接收广播并存储布尔值?

在“强制停止”之后,您的应用(或其组件之一)必须由用户手动(重新)启动一次至少一次。在这种情况下,您的 AndroidManifest.xml 中声明的接收器将按预期接收广播意图,即使在系统完全重启后也是如此。

您不应将“强制停止”与系统破坏您的应用的情况(例如,由于内存不足)混淆。这些不一样,因为“强制停止”会为您的应用设置一个永久标志,阻止它再次运行。

【讨论】:

【参考方案2】:

来自docs:

当前正在执行 BroadcastReceiver 的进程(即 当前在其 onReceive(Context, Intent) 方法中运行代码) 被认为是一个前台进程,将保持运行 系统,除非在极端内存压力的情况下。

然后

这意味着对于运行时间较长的操作,您通常会使用 Service 与 BroadcastReceiver 一起保持包含 进程在您的整个操作期间处于活动状态。

所以我猜你需要实现一个服务来注册接收者,以确保接收者的进程具有高优先级,从而保持运行。

【讨论】:

我如何启动一个永无止境的服务来收听来自安卓的 ACTION_TIME_CHANGED 广播? @米娜萨米 当您“强制停止”应用程序时,进程将终止,因此除非应用程序的进程再次运行,否则接收方无法接收事件。这是正常行为,因为用户想要强制停止您的应用程序。此处描述了一种解决方法***.com/a/21551045/235123,即使应用程序被强制停止,您也可以保持进程处于活动状态

以上是关于应用关闭时接收 TIME_SET 广播的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序关闭时,GCM 广播接收器未检测到 gcm 通知

应用程序关闭后,用于媒体控件的 Android 广播接收器停止工作

从广播接收器关闭活动

应用程序关闭时如何接收 Android Nougat 网络丢失的回调?

应用程序关闭后保持广播接收器运行

用户在Android应用中停用位置权限时的广播接收器?