4

I need your help. I'm stuck with this problem. Alarms work properly. However, when device is rebooted, and the specified time stored in db is in the past (3pm) and current time is 4pm, how can I check to prevent triggering the alarm immediately?

Docs say:

If the stated trigger time is in the past, the alarm will be triggered immediately. Here's what I've tried so far:

class DeviceBootReceiver extends BroadcastReceiver {

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

    // Check if successful reboot
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {

        SharedPreferences shared = context.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
        // Check if daily notification is enabled
        // If yes, call NotificationPublisher to communicate with NotificationAlarmService
        if(shared.getBoolean(Constants.KEY_IS_DAILY_NOTIFIED, false)) {
            DBHelper dbHelper = new DBHelper(context);
            DBConnector.dbConnect(dbHelper);

            int DAILY_NOTIFICATION_ID = Constants.DAILY_VERSE_NOTIFICATION_1_ID;
            ArrayList<Notification> notificationList = dbHelper.getNotifications();
            Log.e("", "notificationList: " + notificationList.size());

            for(Notification obj : notificationList) {
                Calendar datetime = Calendar.getInstance();
                datetime.set(Calendar.HOUR_OF_DAY, obj.getHourOfDay());
                datetime.set(Calendar.MINUTE, obj.getMinute());
                datetime.set(Calendar.SECOND, 0);

                Calendar now = Calendar.getInstance();
                if (now.after(datetime)) {
                    datetime.add(Calendar.DATE, now.get(Calendar.DATE) + 1);
                }

                Log.e("BOOT RECEIVER", "" + obj.getHourOfDay() + ":" + obj.getMinute());

                Intent myIntent = new Intent(context, NotificationPublisher.class);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                        DAILY_NOTIFICATION_ID++,
                        myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                        datetime.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
                        pendingIntent);
            }

        }

    }
}

AndroidManifest:

<receiver
        android:name=".utils.DeviceBootReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

What seems to be wrong with my code? I'd appreciate any help. Thanks!

2 Answers2

1

I set & check alarm time like this and it works for me now:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if (calendar.before(now))
    calendar.add(Calendar.DAY_OF_MONTH, 1);
Laura
  • 46
  • 3
0

A sample code to set repetition of Alarm at interval day.

  1. I have set the Alarm in MainActivity if your want to set Alarm once you can do it by extending Application class and write code to set Alarm inside onCreate.

    public class MainActivity extends AppCompatActivity {
    
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, AlarmReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
    
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 15);
    calendar.set(Calendar.MINUTE, 30);
    
    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, alarmIntent);
    }
    }
    
  2. SampleBootReciver - set Alarm after the device is rebooted

    public class SampleBootReceiver extends BroadcastReceiver {
    
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    
    @Override
    public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
    
        alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent1 = new Intent(context, AlarmReceiver.class);
        alarmIntent = PendingIntent.getBroadcast(context, 0, intent1, 0);
    
        Calendar now = Calendar.getInstance();
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 15);
        calendar.set(Calendar.MINUTE, 30);
    
        if (calendar.before(now))
            calendar.add(Calendar.DAY_OF_MONTH, 1);
    
        alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY, alarmIntent);
    
    }
    }
    }
    
  3. AlarmReceiver - perform action after Alarm is fired.

    public class AlarmReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
    }
    }
    

I'm just displaying a toast.

  1. Lastly the manifest file -

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    

    package="com.bits.kevz.samplealarm">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
    <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
    
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
    <receiver android:name=".AlarmReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
    
    <receiver android:name=".SampleBootReceiver"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    
    </application>
    
    </manifest>
    

I want you to run above code and check onBootCompleted output.

kevz
  • 2,727
  • 14
  • 39
  • Will try this one bro. How about if it is later than current time? It always fails to alarm at the specified time (5pm) against current time (4pm) –  Jan 07 '16 at 10:29
  • @bEtTy Barnes: When you reboot device Alarm set from App is discarded. After reboot If the alarm time is later then current time then it will set Alarm otherwise it will fire an Alarm. – kevz Jan 07 '16 at 10:35
  • @bEtTyBarnes: der you go I've added the code snippet. – kevz Jan 07 '16 at 10:58
  • @kevz Calendar.DATE and Calendar.DAY_OF_MONTH both are same. – Pankaj Kumar Jan 07 '16 at 11:03
  • @Pankaj Kumar: Agreed :) – kevz Jan 07 '16 at 11:10
  • @kevz in the condition now.before(datetime) it's not working –  Jan 07 '16 at 11:13
  • @bEtTy Barnes: let continue in chat http://chat.stackoverflow.com/rooms/100036/android-device-reboot-check-if-specified-time-to-alarm-is-in-the-past – kevz Jan 07 '16 at 11:15