Search code examples
androidandroid-intentandroid-pendingintentandroid-broadcastreceiverandroid-intentservice

Can't fix IntentService for notification with AlarmManager


I am trying to handle it this way: in BroadcastReceiver start AlarmManager repeated action, it will send intents to IntentService, service writes log. Now as I see from the log, BroadcastReceiver receives intent, starts AlarmManager, but IntentService never fires. What can be wrong here?

Manifest:

<receiver android:name=".wakefullBroadcastReciever.SimpleWakefulReciever" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="START"/>
            </intent-filter>
        </receiver>

        <service
            android:name=".wakefulService.NotificationWakefulIntentService"
            android:enabled="true">
            <intent-filter>
                <action android:name="NOTIFY_INTENT" />
            </intent-filter>
        </service>

WakefulReciever:

public class SimpleWakefulReciever extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (!App.isRunning) {
            Log.d("wakefull", "start");
            Intent startIntent = new Intent(context, NotificationWakefulIntentService.class);
            startIntent.setAction(Utils.NOTIFY_INTENT);
            PendingIntent startPIntent = PendingIntent.getBroadcast(context, 0, startIntent, 0);
            AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            am.setRepeating(AlarmManager.RTC_WAKEUP,
                    SystemClock.elapsedRealtime() + 3000, 5000, startPIntent);
            App.isRunning = true;
        }
    }
}

IntentService:

public class NotificationWakefulIntentService extends IntentService {

    public NotificationWakefulIntentService() {
        super("NotificationWakefulIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("time",(System.currentTimeMillis()/1000)+"");
    }
}

Solution

  • You're defining an explicit Service Intent, but calling getBroadcast() instead of getService().

    Change the following:

    PendingIntent startPIntent = PendingIntent
        .getBroadcast(context, 0, startIntent, 0);
    

    To this:

    PendingIntent startPIntent = PendingIntent
        .getService(context, 0, startIntent, 0);
    

    Also, this is not how WakefulBroadcastReceiver works. It's a helper class and its purpose is to provide a WakeLock until your Service finishes its work.

    You achieve nothing by simply extending WakefulBroadcastReceiver, a WakeLock is guaranteed during onReceive() anyway.

    To answer your comment below:

    You should set an exact alarm to fire every hour (check out this answer), start your IntentService from onReceive() by calling WakefulBroadcastReceiver.startWakefulService(), do your stuff in onHandleIntent() and call WakefulBroadcastReceiver.completeWakefulIntent() when finished.