0

I need all users to be directed to an activity in the same time, no matter what their timezone is or what their phone time is set to, so I need to specify a specific timezone to be considered in 'AlarmManager' regardless of what the user have as a time in his phone. However the 'setTimeZone' of 'AlarmManager' works only on system apps. So what is the solution ?

Here is my code :

Intent intent = new Intent(Start.this, Playing.class);
                        PendingIntent pendingIntent = PendingIntent.getActivity(Start.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
                        ((AlarmManager) getSystemService(ALARM_SERVICE)).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

1 Answers1

1

I’m no Android developer, but the way I read the documentation, this goes without any need to do anything special. When you set an alarm, you specify the count of milliseconds since the epoch for the time it should go off. The epoch is defined independently of time zones. So if you just pass the same triggerAtMillis value on all devices, the alarm will go off at the same time on all devices regardless of their time zones.

The AlarmManager has got a setTimeZone method too, but (1) you don’t need it, and (2) it will set the time zone for the entire system, which your users probably don’t want.

Edit: Getting a well-defined time using java.time

Since you are getting the milliseconds from calendar.getTimeInMillis(), if you are getting the wrong time, then the calendar is the problem.

You may want to solve it by adding ThreeTenABP to your Android project so you may use java.time, the modern Java date and time API, for calculating the milliseconds. See the links at the bottom. The Calendar class is poorly designed and long outdated, and the modern API is so much nicer to work with and generally gives clearer code. For example:

    ZoneId alarmZone = ZoneId.of("America/Argentina/Salta");
    ZonedDateTime alarmDateTime = ZonedDateTime.of(2019, 4, 10, 14, 30, 0, 0, alarmZone);
    long triggerAtMillis = alarmDateTime.toInstant().toEpochMilli();

    System.out.println(triggerAtMillis);

The output value is not very interesting in itself:

1554917400000

The point is that since we have hardcoded the time zone in the code snippet, the value will be the same regardless of the device time zone, and therefore your alarm will go off at the same time on all devices (provided that their clocks are set correctly).

Question: Can I use java.time on my Android version? Do I need ThreeTenABP?

java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thank you, but I tried changing the time in my phone and setting an alarm according to the new time, and it was using this new time. I added my code, I hope it can help find the problem. – unknown user Apr 07 '19 at 02:01
  • Thanks for the code, @unknownuser. I don’t know how you are creating the `calendar` that you are getting the millisecond value from, but I have edited and added a suggestion. – Ole V.V. Apr 07 '19 at 02:55