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
How to Animate Addition or Removal of Android Listview Rows
Swiperefreshlayout Setrefreshing() Not Showing Indicator Initially
Remove Image from Cache in Glide Library
Actionbar Logo Centered and Action Items on Sides
"Canvas: Trying to Draw Too Large Bitmap" When Android N Display Size Set Larger Than Small
Run Code When Android App Is Closed/Sent to Background
Volley JSONobjectrequest Post Parameters No Longer Work
Default Interface Methods Are Only Supported Starting with Android 7.0 (Nougat)
Android - How to Make a Button Flash
Android Vpnservice to Capture Packets Won't Capture Packets
Why Do Most Fields (Class Members) in Android Tutorial Start with 'M'
How to Get a Dialog Style Activity Window to Fill the Screen
Trying to Get the Display Size of an Image in an Imageview
Detect When Recyclerview Reaches the Bottom Most Position While Scrolling
Calculate Text Size According to Width of Text Area