Turbozanik Turbozanik - 1 month ago 11
Android Question

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>

Answer

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+.