Search code examples
javaandroidbroadcastreceiver

Receiving TIME_SET Broadcast when app is closed


I want to store a boolean in the Preferences when the user changes the android system time. Therefore I added the broadcast action ACTION_TIME_CHANGED to the manifest:

<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>

The TimeChangedReceiver extends the BroadcastReceiver and overrides onReceive(). In this class the boolean will be stored and a notification will be shown.

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);
}

}

Everything is working fine until the app is closed - not runnning in the background anymore.

Here it says:


How can I receive the broadcast anyway and store the boolean?

I don't need to see the notification.


Solution

  • Everything is working fine until the app is closed - not runnning in the background anymore.

    There are no logs when I "force stop" the application and changing the date afterwards.

    Your observation is correct and considered to be the normal behaviour. After you did a "force stop" via the system settings, your BroadcastReceiver will no longer receive the messages, even when you declared them in your AndroidManifest.xml. By executing a "force stop" you basically instruct the system: "stop this app now and don't let it run again". It is an administrative action, hence it is only accessible from the system settings. This makes sense doesn't it? The same is true for a freshly installed app. It will not receive any broadcast intents until it got started at least once.

    That's how the Android system is designed. You can't do anything against it.

    How can I receive the broadcast anyway and store the boolean?

    After a "force stop", your app (or one of it's components) has to be manually (re)started by the user at least once again. In that case the receiver declared in your AndroidManifest.xml will receive the broadcast intents as expected even after a full system reboot.

    You should not confuse a "force stop" with the situation where the system destroys your app (e.g. because of lacking memory). These are not the same, as the "force stop" sets a permanent flag for your app which prevents it from running again.