1

I have an Android application where I want to send a notification to the user at a fixed time during the day

For this, I am using AlarmManager to schedule an alarm and then use that to generate notifications

But I am facing issue that if the user "Force Closed" the app, the Alarms is reset and hence I don't receive any notifications. Is this is a normal behaviour? Is there is any way out for this?

Also, the alarms also gets cancelled if the phone restarts. How do I control that? Do I need to listen to the Phone Reboot event and again schedule the alarm there? Is that the only option here?

user669231
  • 1,371
  • 3
  • 18
  • 27
  • show your code, because alarmManager allow you put an alarm and if you reboot the phone still working. – Litus Jul 17 '12 at 17:39

2 Answers2

2

I have a table in my database to store all my pending alarms in case of a reboot. If the phone is rebooted I have a Service Class that resets the alarms.

private AppDatabase mDbHelper;
public class BootService extends Service {

    @Override
    public IBinder onBind(final Intent intent) {
            return null;
    }

    @Override
    public void onCreate() {
            super.onCreate();
            mDbHelper = new AppDatabase(this);
            mDbHelper.open();
    }

    @Override
    public void onStart(final Intent intent, final int startId) {
            super.onStart(intent, startId);
            LoadNotificationsFromDB();             
    }

    private void LoadNotificationsFromDB() {
            Cursor c = mDbHelper.getPendingNotifications();
            if (c.moveToFirst()) {
                    do {

                            int id = c.getInt(AppDatabase.ID_COLUMN);
                            String date = c.getString(AppDatabase.DATE_COLUMN);
                            addNotification(id, date);
                    } while (c.moveToNext());
            }
            c.close();
    }

    private void addNotification(int id, String date) {
            Intent intent = new Intent(BootService.this,    
                           NotificationBroadcastReceiver.class);

            PendingIntent mAlarmSender = PendingIntent.getBroadcast(
                            BootService.this, id, intent, 0);

            long alarmDate = Long.valueOf(date);

            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            am.set(AlarmManager.RTC_WAKEUP, date, mAlarmSender);
    }
}

Then Create a Receiver class:

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
            if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
                    Intent mServiceIntent = new Intent();
                    mServiceIntent.setAction("<package name>.BootService");
                    ComponentName service = context.startService(mServiceIntent);
                    if (null == service) {
                            // something really wrong here
                    }
            } 
    }
}

And Add the following lines to the Manifest.xml

    <receiver android:name=".BootReceiver" android:enabled="true">
            <intent-filter>
                    <action android:name ="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
    </receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Woodsy
  • 3,177
  • 2
  • 26
  • 50
  • 1
    Hey, this post was really useful for me, but I have one question... why do you need the service? Is the same if I reload the Alarms from the onReceive of the boot receiver?? – Andres Apr 20 '13 at 20:49
  • IMO,both broadcast receiver and service runs on the UI thread.so creating it on either is the same effect.If you really want to move it off the UI thread,consider using IntentService,which works on a separate thread. – Basher51 Jul 24 '14 at 04:47
1

You are going to need to set up something similar to this to hook on to the boot completed intent.

<receiver android:name="MyStartupIntentReceiver">
<intent-filter>
<action
  android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>

Once you have that you're going to need to start a service or do something in

public void onReceive(Context context, Intent intent) {
    Intent serviceIntent = new Intent();
    serviceIntent.setAction("com.yourapp.yourservice");
    context.startService(serviceIntent);
}
Daniel Lockard
  • 615
  • 3
  • 11