Search code examples
androidservicebroadcastreceiver

How to run a service every day at noon, and on every boot


In my app I have SQLite database that has one table with date rows in milliseconds. I would like to have a notification shown every day IF 30 days has passed since the last date value stored in my database. A service seems to be a good way to accomplish this check up.

I ran into Commonsware's WakefulIntentService and thought it could be the answer but I really don't know how should I implement it. In the demo it starts a service after 5 minutes since boot is complete which is just fine but what do I need to add to get it also start at every noon. (... but only to show one notification / day, not both, as from boot and regular daily check up)

I know this could be solved using AlarmManager but really don't know how. So, the help I need is to give me some samples / key points to get the service start on every boot and/or every day without app running.

thanks


Solution

  • Android alarmmanager is your answer. use it with a broadcast receiver which also resets the alarms on phone wake.

    Now with code example: Setting alarm inside a method:

    Intent intent = new Intent(context, AlarmReceiver.class);
    intent.setAction("packagename.ACTION");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
            AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarm.cancel(pendingIntent);
    alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    

    Receiver for your interval:

    public class AlarmReceiver extends BroadcastReceiver {
    private final String SOMEACTION = "packagename.ACTION"; //packagename is com.whatever.www
    @Override
    public void onReceive(Context context, Intent intent) {
        Time now = new Time();
        now.setToNow();
        String time = FileHandler.timeFormat(now);
    
        String action = intent.getAction();
        if(SOMEACTION.equals(action)) {
            // here you call a service etc.
        }
    

    Receiver for resetting alarms whenever phone has been shut down.

    public class AlarmSetter extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            // get preferences
            SharedPreferences preferences = context.getSharedPreferences("name_of_your_pref", 0);
            Map<String, ?> scheduleData = preferences.getAll();
    
            // set the schedule time
            if(scheduleData.containsKey("fromHour") && scheduleData.containsKey("toHour")) {
                int fromHour = (Integer) scheduleData.get("fromHour");
                int fromMinute = (Integer) scheduleData.get("fromMinute");
    
                int toHour = (Integer) scheduleData.get("toHour");
                int toMinute = (Integer) scheduleData.get("toMinute");
    
                //Do some action
            }
        }
    
    }
    

    Manifest very important, this is added under application:

            <receiver android:name="AlarmReceiver">
            <intent-filter>
                <action android:name="packagename.ACTION"/>
                <action android:name="packagename.ACTION2"/>
            </intent-filter>
        </receiver>
    
        <receiver android:name="AlarmSetter" >
            <intent-filter>
                <action
                    android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    

    Also in order for this to work you need to add permission to receive the boot Broadcast in the manifest with following line:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    

    Hope this cleared things up, if any errors plz tell.

    Edit (added alarmsetter example):

    public class AlarmSetter extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            // Do your stuff
        }
    }