Android BroadcastReceiver not working after install - android

Greetings! I'm working on an application that has a BroadcastReceiver listening on "android.intent.action.PHONE_STATE", which is run when the phone state is changed (I used it to run code when an incoming call is detected). This works fine on most of my test phones, but a few don't seem to trigger the receiver at all. However, once these problem phones are restarted everything works as expected.
Is there a reason these phones need to be restarted before the BroadcaseReceiver can pick anything up? Is there a way I can detect if it isn't running and manually "start" the BroadcaseReceiver? I'm stumped, so I'd appreciate any help you can offer.
Thank You.

To expand on the issue: starting from Android 3.1, installed applications are put in "STOPPED" state. To invoke BroadcastReceiver(s) from stopped application an additional broadcast intent flag is required.
More details: http://developer.android.com/sdk/android-3.1.html#launchcontrols
I created FLAG_INCLUDE_STOPPED_PACKAGES constant (=32) in my application (for pre-Android 3.1) and just add it to my broadcast intent intent.addFlags(FLAG_INCLUDE_STOPPED_PACKAGES);

Is there a reason these phones need to be restarted before the BroadcaseReceiver can pick anything up?
Assuming that your application has its BroadcastReceiver registered in the manifest for the PHONE_STATE broadcast, it should work immediately upon install. If it does not, it feels like a buggy ROM to me.
Is there a way I can detect if it isn't running and manually "start" the BroadcaseReceiver?
No, mostly because it's not running, usually, even when things are working. An instance of your BroadcastReceiver is created at the point of the Intent - <intent-filter> match, it is called with onReceive(), and the BroadcastReceiver is disposed of once onReceive() returns.

Related

Wear OS - How to automatically start app on device restart

I've created a Wear OS app. It has a service running in the foreground. I need to have the app always executing. When I restart the watch the app doesn't start executing again. How can I automatically relaunch the app?
It's my first app for Wear OS and I don't know how to search for this.
Thank you!
I'm not 100% certain, and it's a bad idea for an app to do in most cases. But I believe
https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED
This will wake up your broadcast receiver so you can run some code, but as you discovered you are probably restricted against starting an activity.
https://developer.android.com/guide/components/activities/background-starts

Permanent BroadcastReceiver

An application, let us call it Application A, that is installed on my phone produces very interesting data. I am not in control of Application A, but the developers were so kind as to broadcast the interesting information locally, so that other applications (like the one I am building, Application B) can work with the data produced by the other application.
I am registering a BroadcastReceiver via the following code in the onResume() of my MainActivity:
registerReceiver(new CustomBroadCastReceiver, new IntentFilter("com.intent.filter.DATA"));
This works perfectly fine, until my application is either force stopped or stopped by Android (presumably to preserve power/free up memory?).
However, Application A produces data all day and all night long. Based on this data, Application B calculates further results and is supposed to sound an alarm, as soon as the readings go in the wrong direction. It is imperative that the BroadcastReceiver in Application B can sound an alarm at any point in time.
What is currently best-practice to keep the BroadcastReceiver alive as long as possible (maybe even surviving a force stop (swiping away) of the application by the user)?
Edit: I found out, months later, that my Samsung phone had put my application in a power saving list of apps that it will forcefully and regularly kill to preserve power. Make sure your application is not in a similar list on your own phone.
You need to register your receiver in your manifest, not programmatically. See:
https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers
However, if you target Oreo+, you won't be able to do that anymore. App A would need to explicitly call out your package for the broadcast to be received by an receiver declared in App B's manifest. You can read for about that here:
https://developer.android.com/about/versions/oreo/android-8.0-changes#back-all
This isn't a great way for your apps to share data (and hence why Google are phasing it out). It's inefficient to have to load your app into memory each time something happens in another app. Imagine tens or hundreds of apps doing the same thing for all manner of broadcasts, and what that means for battery life.
A better way would be for App A to expose the data in a content provider, and your app to wake up (infrequently) and pull the data.
You need to register your BroadcastReceiver in the app manifest file AndroidManifest.xml
<receiver android:name=".CustomBroadCastReceiver" android:exported="true">
<intent-filter>
<action android:name="com.intent.filter.DATA"/>
</intent-filter>
</receiver>
The system package manager registers the receiver when the app is installed. The >receiver then becomes a separate entry point into your app which means that the >system can start the app and deliver the broadcast if the app is not currently running.
https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers
Which means that the system will launch your BroadcastReceiver even if you app is closed, unless your app was force stopped by the user https://stackoverflow.com/a/9240705/1905761
You need to keep in mind though that some restrictions are applied starting from android 8.0 (Oreo)
https://developer.android.com/guide/components/broadcasts#changes-system-broadcasts

No response from Service and BroastReciver running on App install [duplicate]

I have a device management application, which essentially runs as a service in the background from boot. I'd like to start this application immediately after installation. How do I achieve this?
You cannot do this -- there is no way to automatically start your service merely because it was installed.
The application must first be invoked by the user through some sort of activity. Or, you are going to need to hook into some relevant broadcast Intent via the manifest, so you can get control when one of those events occur and kick off your service that way. Or, you are going to need to ask the user to reboot so your BOOT_COMPLETED Intent filter can get control.
There was a hole - the Android Analytics SDK used to send an intent right after installation - but that got closed (producing lots of confusion, of course).
But the final answer, I believe, is here:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
This seems to suggest that, as of 3.1, Google made the decision that apps are in a stopped state until the user explicitly activates them, e.g. by launching app or placing widget.
This means that the strategy of listening of a common broadcast (i.e. to get your app launched surreptitiously) won't work either.

Is there a faster way to call a receiver than on boot completed?

some context:
I have an alarm app I use for myself that locks the screen when the alarm goes off for the duration you request prior. Essentially your phone is a ringing brick for x minutes. The only problem is my sleepy self is very irrational and in the morning I figured out that if I turn off the phone and get to the app location and uninstall it before the receiver gets called (boot completed) then I can bypass it bricking my phone. This didn't use to be a big deal when my LG G2 was on 4.2.2 because of how fast the receiver was called I would usually have to restart my phone about 5-8 times to uninstall the app before it was bricked so I just gave up and quit trying. Now, I upgraded to 4.4.2 and the receiver is called about a full 10 seconds later letting me delete the app on the first try every time. Making the app completely useless.
What I have tried:
I have tried using quick_boot in the manifest but I believe that this is only for HTC because on_boot doesn't get called for that OS for some reason. I have also tried the user present which only seems to work after the boot is completed when doing things like unlocking your phone.
Is there really no way to make onReceive be called quicker than onBoot? It would make sense if there isn't , I'm just hoping someone could provide a definite answer either way.
In some cases it is. I'm not 100% sure but i think (some) systemapps have higher priority then the ACTION_BOOT_COMPLETED event. AND there is ACTION_SCREEN_ON which should be triggered before ACTION_BOOT_COMPLETED.
I should have answered this a week or so after I asked this question because I found a pretty useful workaround, although, it is a little sloppy.
I made a new activity(homeLock) with the intent filter . homeLock extends activity and my old main activity(alarmMain) extends homeLock now instead of activity. All homeLock does is start the overlay service(so you can't stop the alarm/use the phone) that will be turned off by alarmMain when it determines whether an alarm should be ringing currently or not. In alarmMain there is a button now that says "change home" which lets you make homeLock the home application. Now, when you turn off the phone and restart to try and delete the application before onBootReceived is called which starts the broadcast receiver(triggers alarm and overlay) the homeLock activity is called which puts an overlay on the screen until it can be removed after the application determines if an alarm should be playing or not (after onBootReceived).
Basically, before you go to sleep just set this application as your home application from within the app or through settings. Now, it should be impossible to delete the application or turn off the alarm once it has started ringing until it has rung its duration because there will always be an overlay on the screen even when restarting the phone.
Obviously this addition is only needed for phones that boot slowly or extremely degenerate sleepers, or both like me. While it is unlikely this will help anyone because it is such a unique problem I thought I should post the workaround I have been using just in case someone does end up finding it useful.

How to start android service on installation

I have a device management application, which essentially runs as a service in the background from boot. I'd like to start this application immediately after installation. How do I achieve this?
You cannot do this -- there is no way to automatically start your service merely because it was installed.
The application must first be invoked by the user through some sort of activity. Or, you are going to need to hook into some relevant broadcast Intent via the manifest, so you can get control when one of those events occur and kick off your service that way. Or, you are going to need to ask the user to reboot so your BOOT_COMPLETED Intent filter can get control.
There was a hole - the Android Analytics SDK used to send an intent right after installation - but that got closed (producing lots of confusion, of course).
But the final answer, I believe, is here:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
This seems to suggest that, as of 3.1, Google made the decision that apps are in a stopped state until the user explicitly activates them, e.g. by launching app or placing widget.
This means that the strategy of listening of a common broadcast (i.e. to get your app launched surreptitiously) won't work either.

Categories

Resources