0

I know there are a lot of questions about setting alarms on Android 6 on the internet, but I havnt found an answer that suits me yet.

As the question states, I need to set an alarm that ring every 24 hours. After looking on stackoverflow I started using the setExactAndAllowWhileIdle() to make sure the alarm works. It still doesnt. The alarm works on android 5 and below tough.

I need to make sure the alarm repeats every 24 hours almost exactly to that some tasks are executed at that time. MY question is :

  1. Do the alarms get un initialized or set when the app is closed?
  2. What other methods can I use to make sure that the alarm goes off? I tought of have a service check the time repeatedly but it seems even that can be stopped and that might be a problem, in addition it would be a waste not to user the AlarmManager provided by Google. When I set an alarm fews minutes in advance (ie to ring in a few minutes that works), is it because of doze mode? I tought that setExactAndAllowWhileIdle() would definitely work.
  3. In short, how can I make sure the alarm rings neverthless?

Here is my code, just in case it might be useful. In the apps MainActivity set only if the app is installed for the first time :

public void setExactNextDayChangeAlarm(Context context){
        // At a time
        Log.d("ALARM", "create next day alarm");
        Intent intent_next_day_change;
        intent_next_day_change = new Intent(context, AlarmReceiver.class);
        intent_next_day_change.setAction(NEXT_DAY_CHANGE_ACTION);
        PendingIntent pi_next_day_change;
        pi_next_day_change = PendingIntent.getBroadcast(context, 1003, intent_next_day_change,0);
        AlarmManager alarm_next_day_change;
        alarm_next_day_change = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 20); // For 1 PM or 2 PM
        calendar.set(Calendar.MINUTE, 30);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarm_next_day_change.setExactAndAllowWhileIdle(alarm_next_day_change.RTC_WAKEUP,calendar.getTimeInMillis(),pi_next_day_change);
        }
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarm_next_day_change.setExact(alarm_next_day_change.RTC_WAKEUP,calendar.getTimeInMillis(),pi_next_day_change);
        }
        else {
            alarm_next_day_change.set(alarm_next_day_change.RTC_WAKEUP, calendar.getTimeInMillis(), pi_next_day_change);
        }

    }

That is the initial setting up, after that repeating alarms are set the following way:

public class AlarmClass {

    public static String NOTIFICATION_ACTION = "com.example.meek.alarm.notification";
    public static String NEXT_DAY_CHANGE_ACTION = "com.example.meek.alarm.next.day.change";

    public void setApproxNotificationAlarm(Context context){
        Intent intent_notification;
        Log.d("ALARM", "create notification alarm");
        intent_notification = new Intent(context, AlarmReceiver.class);
        intent_notification.setAction(NOTIFICATION_ACTION);
        PendingIntent pi_notification;
        pi_notification = PendingIntent.getBroadcast(context, 111, intent_notification, 0);
        AlarmManager alarm_notification;
        alarm_notification = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
        alarm_notification.set(alarm_notification.RTC_WAKEUP, System.currentTimeMillis() + 5000* 1000, pi_notification);
    }

    // Ring after 24 hours
    public void setExactNextDayChangeAlarm(Context context){
        // At a time
        Log.d("ALARM", "create next day alarm");
        Intent intent_next_day_change;
        intent_next_day_change = new Intent(context, AlarmReceiver.class);
        intent_next_day_change.setAction(NEXT_DAY_CHANGE_ACTION);
        PendingIntent pi_next_day_change;
        pi_next_day_change = PendingIntent.getBroadcast(context, 1003, intent_next_day_change,0);
        AlarmManager alarm_next_day_change;
        alarm_next_day_change = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
        // set for 24 hours from now
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarm_next_day_change.setExactAndAllowWhileIdle(alarm_next_day_change.RTC_WAKEUP,System.currentTimeMillis() + 86400*1000,pi_next_day_change);
        }
        else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            alarm_next_day_change.setExact(alarm_next_day_change.RTC_WAKEUP, System.currentTimeMillis() + 86400*1000, pi_next_day_change);
        } else {
            alarm_next_day_change.set(alarm_next_day_change.RTC_WAKEUP, System.currentTimeMillis() + 86400*1000, pi_next_day_change);
        }


    }
}

This is my manifest file :

<receiver
            android:name="com.example.meek.BroadcastReceivers.BootReceiver"
            android:label="StartMyServiceAtBootReceiver"
            android:enabled="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >>
            <intent-filter>
                <action android:name="com.example.meek.trialapp04.NEXT_DAY_CHANGE_ACTION" />
                <action android:name="com.example.meek.helpers.AlarmClass.NEXT_DAY_CHANGE_ACTION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

Any help is appreciated, thanks!!

LoveMeow
  • 3,858
  • 9
  • 44
  • 66
  • Alarms don't survive rebooting, and it looks like you might be trying to account for that, but that `permission` shouldn't be set on the ``, and you don't have the `BOOT_COMPLETED` `` specified. – Mike M. Jul 03 '16 at 09:09
  • could you elaborate please? – LoveMeow Jul 03 '16 at 09:42
  • 1
    If you want to receive the `BOOT_COMPLETED` broadcast, you need a `` element for `RECEIVE_BOOT_COMPLETED` instead, not the `permission` attribute on the ``. You also need an `` on your `` to have an `` of `"android.intent.action.BOOT_COMPLETED"`. There's an example in [this post](http://stackoverflow.com/questions/8277207). Also note that your app needs to run at least once after installation for the Receiver to be delivered the `BOOT_RECEIVED` broadcast. – Mike M. Jul 03 '16 at 09:52
  • I dont actually need my alarm to survive restart, the problem is that my app doesnt even get triggered when the phone is never switched off, and the app is never closed, just put in background. – LoveMeow Jul 03 '16 at 10:43
  • OK, I was just pointing it out as a possible cause. You should at least remove the `permission` attribute from your ``. – Mike M. Jul 03 '16 at 10:48
  • ok I will remove it thanks? will that fix it? – LoveMeow Jul 03 '16 at 10:51
  • Dunno. In previous versions, your app is able to broadcast to its own components, regardless of permissions, but they might've changed that in Marshmallow. I find that slightly unlikely, though, but I'm not familiar enough with Marshmallow's idle and alarm behaviors to speculate on what else might be causing your problem. – Mike M. Jul 03 '16 at 11:16

0 Answers0