8

I have an android app that has a service witch fires an alert based on some time calculation.

The problem is when the timezone changes (i.e.: For a user who's located France and goes from UTC+1 to UTC+2). The application is not notified about this change and so, it fires the alert with a delay.

I have already checked android TimeZone API and know that there are some methods which can help, like:

IS IT POSSIBLE to know when the change will happen, in order to consider it in my calculation algorithm?

BTW: I already checked a lot of blogs and Q/A from Stackoverflow but don't help :(

EDIT (manifest file and receiver class):

Here is my manifest:

<receiver android:name=".receiver.NotificationReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.TIMEZONE_CHANGED" />
    </intent-filter>
</receiver>

Receiver class:

public class NotificationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLock.acquire(context);
        Intent service = new Intent(context, NotificationService.class);
        service.putExtras(intent);
        context.startService(service);

        // Timezone or time change
        if (intent.getAction() != null
            && (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
                || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)))
        {
            Intent i = new Intent(context, DialogPopUpTimeChange.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }
}
Soufiane ROCHDI
  • 1,543
  • 17
  • 24
  • Possible duplicate of [Date and time change listener in Android?](http://stackoverflow.com/questions/5481386/date-and-time-change-listener-in-android) – Remy Lebeau Mar 27 '16 at 23:42
  • Nope, it's not a duplicate because I already tried to use BroadcastReceiver but didn't help. I want to know when the timezone change **will** happen – Soufiane ROCHDI Mar 27 '16 at 23:45
  • You did not say that in your question. Why can't you use a BroadcastReceiver to update your alert when the time dies change? – Remy Lebeau Mar 27 '16 at 23:46
  • You commented while I was adding details :) For the BroadcastReceiver, it does not receive anything if change is made by the telecommunication company. That's why I'm looking for another alternatives. – Soufiane ROCHDI Mar 28 '16 at 00:01
  • Your results are the opposite of what other answers claim. The time change broadcasts can be triggered often, several times a day, even multiple times a minute, depending on how often the device has to resync with the carrier. I have seen several different workarounds to detect "true" DST changes. Even claims that `AlarmManager` handles DST changes automatically. But I can't find any reports of the broadcasts not being received. Maybe you are not registering them correctly. Can you show your registration manifest/code? – Remy Lebeau Mar 28 '16 at 02:57
  • @RemyLebeau, I added the code you asked. BTW, no need to downvote because I already checked other solutions and my question is not a duplicate one. – Soufiane ROCHDI Mar 28 '16 at 11:29

1 Answers1

13

Well, here is how I resolved this issue:

1- I kept the Android Manifest as it is (see the question)

2- Then i changed the receiver a bit:

public class NotificationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLock.acquire(context);
        // Timezone or time change
        if (intent.getAction() != null
            && (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
            || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)))
        {
            calculateTimeZone(context);
        }
    }
}

3- Here is the method that calculates the new timezone and the use of DST:

public void calculateTimeZone(Context context) {
    float ONE_HOUR_MILLIS = 60 * 60 * 1000;

    // Current timezone and date
    TimeZone timeZone = TimeZone.getDefault();
    Date nowDate = new Date();
    float offsetFromUtc = timeZone.getOffset(nowDate.getTime()) / ONE_HOUR_MILLIS;

    // Daylight Saving time
    if (timeZone.useDaylightTime()) {
        // DST is used
        // I'm saving this is preferences for later use

        // save the offset value to use it later
        float dstOffset = timeZone.getDSTSavings() / ONE_HOUR_MILLIS;
        // DstOffsetValue = dstOffset
        // I'm saving this is preferences for later use

        // save that now we are in DST mode
        if (timeZone.inDaylightTime(nowDate)) {
            // Now you are in use of DST mode
            // I'm saving this is preferences for later use
        } else {
            // DST mode is not used for this timezone
            // I'm saving this is preferences for later use
        }
    }
}

That's it. So, the solution was to combine all the ApIs (listed in the question) together.

I hope that this solution will help other. If you have any question just post it in comment

Soufiane ROCHDI
  • 1,543
  • 17
  • 24