Search code examples
androidalarmmanagerwakelock

Alarm Manager won't work when the app is killed in the background and device is locked


I have been stuck in this situation for a long time...

I want to use the alarm manager to show notification at the specific time, and now it worked in the situation listed below:

  1. when the app runs in the background, notification will be shown at the correct time, and no matter the device is locked or not.
  2. after the app has been killed in the background, i will still get correct notification when device is not locked, but things turn wrong when the device is locked, i can't receive any notification.

Here's the code AlarmReceiver.java, all the needed permission has been added into AndroidManifest.xml already:

@Override
public void onReceive(Context context, Intent intent) {
    WakeLocker.acquire(context);

    String action = intent.getAction();

    Log.d(TAG, action); //when app is killed and device is locked, no info is shown at the logcat

    if (ACTION_ALARM.equals(action)) {
        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(2 * 1000);

        notify(context, "Jello!");
    }

    WakeLocker.release();
}

public static void alarm(Context context) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReceiver.class);
    intent.setAction(ACTION_ALARM);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
    } else {
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
    }
}

private void notify(Context context, String msg) {
    NotificationManager notificationManager = (NotificationManager)
            context.getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
            new Intent(context, InfoActivity.class), 0);

    Notification notification =
            new NotificationCompat.Builder(context)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle(context.getString(R.string.alarm))
                    .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
                    .setContentText(msg)
                    .setAutoCancel(true)
                    .setContentIntent(contentIntent).build();

    notificationManager.notify(1, notification);
}

Permissions added:

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

Solution

  • I just found the solution, set flag named FLAG_INCLUDE_STOPPED_PACKAGES to intent of the alarm, things will go right. Here are the illustration in Android Developers