I've read about Android Oreo background execution limitations, and it clearly states that BOOT_COMPLETED
broadcast is unaffected, but I can't get it to work on Android Oreo.
First, I am compiling against SDK 27. Secondly, I declared the receiver inside the manifest file:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name="helpers.StartDetectionAtBoot"
android:label="StartDetectionAtBoot"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<!--For HTC devices-->
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<!--For MIUI devices-->
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
Then there's the implementation of the receiver, which can also be simple as that:
public class StartDetectionAtBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("test", "test");
Intent intent0 = new Intent( context, ActivityRecognitionService.class );
PendingIntent pendingIntent = PendingIntent.getService(context, 111, intent0, PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognitionClient activityRecognitionClient = ActivityRecognition.getClient(context);
activityRecognitionClient.requestActivityUpdates(5000, pendingIntent);
}
}
onReceive
method is not called and I will always get logcat error on Android Oreo devices/emulator:
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.BOOT_COMPLETED flg=0x400010 }
Reading other answers, they said there were some problems when registering explicit intents in the manifest but this is not the case of BOOT_COMPLETED
one.
Neither this helped because the receiver is not called at all.
Registering broadcast intent at runtime, get it to work (on the emulator, firing the intent from adb shell), but I'm not sure it's the right way to do it:
registerReceiver(new StartDetectionAtBoot(), new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
Are there any known bugs with this?
The solution was a combination of two attempts I had already made.
First, I had to start a foreground service (even a dummy service would be good) with sticky notification:
public class StartDetectionAtBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent1 = new Intent(context.getApplicationContext(), DummyService.class);
context.startForegroundService(intent1);
}
Intent intent0 = new Intent( context, ActivityRecognitionService.class );
PendingIntent pendingIntent = PendingIntent.getService(context, 111, intent0, PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognitionClient activityRecognitionClient = ActivityRecognition.getClient(context);
activityRecognitionClient.requestActivityUpdates(5000, pendingIntent);
}
}
Of course inside the service you start there must be an onCreate
method which creates a notification and calls startForeground
.
Secondly, I had did a cache invalidation in Android Studio and I also wiped emulator instance. This part of the solution was necessary for me since the first part still didn't work.