Android Broadcastreceiver, Auto Run Service After Reboot of Device

Broadcast Receiver Not Working After Device Reboot in Android

Here's a tested and working solution on both the devices that you mentioned, OnePlus and Mi.

As you said the auto-start prevention feature on OnePlus and Mi devices prevent apps from starting up their services automatically on boot complete so as to improve the overall device boot speed and battery performance. However, there's a workaround to get your app working even when this feature is turned on.

I have noticed that if you have an AccessibilityService in your app and it is turned on by the user, then your app passes the filter that these manufacturers apply and the app receives it's boot complete event and any other BroadcastReceiver works as expected.

The possible explanation of this trick can be that since AccessibilityService is a system level service, so by registering your own service you are passing the certain filter applied by these manufacturers and as soon as your custom AccessibilityService gets triggered by the OS, your app becomes active in receiving the eligible BroadcastReceiver that you had registered.

So, here's how to do it,

Start by adding this permission to your AndroidManifest.xml,

<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>

This will allow you to register your app's AccessibilityService with the system.

Now, add a very basic configuration for your AccessibilityService by creating a file for example my_accessibility_service.xml inside XML folder under your res folder in your project.

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackSpoken"
android:description="@string/service_desc"
android:notificationTimeout="100"/>

There's just one more step left to do, define your custom AccessibilityService in your project,

public class MyAccessibilityService extends AccessibilityService {

@Override
public void onAccessibilityEvent(AccessibilityEvent event) { }

@Override
public void onInterrupt() {

}
}

Note, since you're not needing the AccessibilityService for any purpose rather than this workaround, you can leave the overridden methods empty.

Finally, just declare your AccessibilityService in your AndroidManifest.xml,

<service
android:name=".MyAccessibilityService"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>

<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/my_accessibility_service"/>
</service>

That's all. Now within your app, just ask your users to turn on the accessibility service for your app from the settings and leave it on and voila! Your app works fine on all devices even where the OS puts a filter on which apps should auto-start on boot.

EDIT 1

Here's how you can check if accessibility service is turned ON or not for your app,

private static final int ACCESSIBILITY_ENABLED = 1;

public static boolean isAccessibilitySettingsOn(Context context) {
int accessibilityEnabled = 0;
final String service = context.getPackageName() + "/" + MyAccessibilityService.class.getCanonicalName();
try {
accessibilityEnabled = Settings.Secure.getInt(
context.getApplicationContext().getContentResolver(),
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Settings.SettingNotFoundException e) {
Log.e("AU", "Error finding setting, default accessibility to not found: "
+ e.getMessage());
}
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');

if (accessibilityEnabled == ACCESSIBILITY_ENABLED) {
String settingValue = Settings.Secure.getString(
context.getApplicationContext().getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null) {
mStringColonSplitter.setString(settingValue);
while (mStringColonSplitter.hasNext()) {
String accessibilityService = mStringColonSplitter.next();

if (accessibilityService.equalsIgnoreCase(service)) {
return true;
}
}
}
}

return false;
}

Hope this helps.

Android - Auto-run a service after bootup

I cannot tell what else is in your code and/or which parts are working and/or which parts are crashing. But your reply to @brandall indicates that you don't care about the crash(es) and just want to use only one Broadcast Receiver. Then, is there a reason why you are not using the same BootCompletedIntentReceiver as the only receiver? Assuming everything is working (or you know how to get them to work), can you just use one receiver and modify the BootCompletedIntentReceiver to filter for PhotoPostUpdate as well, like:

public class BootCompletedIntentReceiver extends BroadcastReceiver { 
@Override
//this is your code
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, PhonePositionService.class);
context.startService(pushIntent);
}
//this part is added
if ("PhonePosUpdate".equals(intent.getAction())) {
//below is the same code you are using in phonePositionReceiver
float[] message = intent.getFloatArrayExtra("message");;
PhonePositionModule.this.sendEvent(message);
}
}
}

Or maybe I am misunderstanding the comment/question.

Android Starting Service at Boot Time , How to restart service class after device Reboot?

Create a BroadcastReceiver and register it to receive ACTION_BOOT_COMPLETED. You also need RECEIVE_BOOT_COMPLETED permission.

Read: Listening For and Broadcasting Global Messages, and Setting Alarms



Related Topics



Leave a reply



Submit