Search code examples
androidandroid-intentbroadcastreceiverandroid-broadcastandroid-wake-lock

WakefulBroadcastReceiver is never invoked


I have following schema BOOT_COMPLETE intent ->BroadcastReciever starts, then starting WakefullBroadcastReceiver -> sending intent to NotificationIntentService.

But my WakefullBroadcastReceiver is never working, if i change schema to BOOT_COMPLETE intent ->BroadcastReciever-> sending intent to NotificationIntentService. everething works perfectly

BroadcastReceiver:

    public class BootBroadcastReciever extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!App.isRunning) {
                Log.d("wakefull", "start");
                Intent startIntent = new Intent("SOMEACTION");
                //startIntent.setAction(Utils.NOTIFY_INTENT);
                PendingIntent startPIntent = PendingIntent.getService(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;
            }
            Log.e("bool",App.isRunning+"");
        }
    }

WakefulBroadcastReceiver:

public class SimpleWakefulReciever extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("wakefull","received");
        Intent service = new Intent(context, NotificationWakefulIntentService.class);
        startWakefulService(context,service);
    }
}

NotificationIntentService:

public class NotificationWakefulIntentService extends IntentService {

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

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

Manifest:

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

        <receiver android:name=".wakefullBroadcastReciever.SimpleWakefulReciever">
            <intent-filter>
                <action android:name="SOMEACTION"/>
                <action android:name="WAKEFUL"/>
            </intent-filter>
        </receiver>

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

Solution

  • First, get rid of all <intent-filter> elements other than the one wrapping <action android:name="android.intent.action.BOOT_COMPLETED"/>. Never put an <intent-filter> on a component unless you want arbitrary third-party apps to start that component whenever they want to.

    Then, replace:

    Intent startIntent = new Intent("SOMEACTION");
    PendingIntent startPIntent = PendingIntent.getService(context, 0, startIntent, 0);
    

    with:

    Intent startIntent = new Intent(context, SimpleWakefulReciever.class);
    PendingIntent startPIntent = PendingIntent.getBroadcast(context, 0, startIntent, 0);
    

    This fixes your Intent to no longer use the action string and fixes your PendingIntent to use getBroadcast(), since you are trying to trigger a BroadcastReceiver.

    Then, replace 5000 with a value of at least 60000, since you cannot have a repeating alarm more frequently than that on Android 5.1+.