Permanent BroadcastReceiver - android

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

Related

How to detect when Android device was last used?

My app needs to know when the user last interacted with the phone, or when the device screen went off. Answers to similar questions suggested:
registering a SCREEN_OFF/DEVICE_IDLE_MODE_CHANGED broadcast receiver in manifest.
Problem: won't work since it's a protected broadcast
dynamically registering and unregistering SCREEN_OFF/DEVICE_IDLE_MODE_CHANGED when an app component is live
Problem: I can't or don't want to keep the app or service running since I need to know SCREEN_OFF 24x7.
Using ActivityManager or UsageStats
Problem: Gives details only for particular packages so to be able to figure out when the app was last used, will have to iterate over a list and make many function calls. And even after that, I am not sure if this covers the case when no app is used but only a quick device unlock and relock action.
Is there a way to reliably know in the background when the user last used their device without keeping a service running?

Android Oreo: Is there any way to auto - start the application on mobile reboot?

I am developing an application for a business entity. That application should run in the background in every employees' mobile phone. Employees are mostly salesman. The application basically detects location changes and suggest the salesman where they might visit. A kind of reminder application. It also lets other salesmen see where are their teammates.
Right now I am using a foreground activity and it works fine till the system forcefully doesn't kill the service or the phone doesn't reboot due to manual activity or battery discharge.
Ones the application is closed, as of now, the managers in the firm needs to call salespeople to turn on the application once, as on application start it automatically turn on its foreground service. But this is really an extra burden on the management team which can be automated.
I am ok to have any settings based or code based solution. One solution is to root the phones of salespeople and install some extra utility app or write the code based on root APIs, but this will be too much for this simple task.
THe permission RECEIVE_BOOT_COMPLETED was not added properly in the manifest. After adding the permission it worked calmly. In on receive method of the broadcast receiver, I am starting the foreground service.
At the moment, the best way is to use WorkManager https://developer.android.com/topic/libraries/architecture/workmanager/ Yes, it still alpha, but works very good.
From other side, you could work on automating the task "managers in the firm needs to call salespeople to turn on the application once". I mean, an app/backend could automatically call the salesman (with some pre-recorded message) or send SMS to them.

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.

BroadcastReceiver not working when I kill my application

I have noticed than whenever I manually kill my application by longpressing the back button of my cellphone my broadcast receiver stops working. The receiver is in charge of displaying a notification every time the user hangs up a phone call and the same is registered in the manifest.xml.
Is this the normal/expected behaviour? I thought the receiver should continue to work even if the user decides to kill my application... Is there a way to prevent this?
Thanks.
Edit
Here's the manifest entry for the receiver:
<receiver android:name=".BroadcastReceivers.CallReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
There are ~7 billion people on the planet. Only you know what you mean by "kill".
The symptoms that you are describing, though, are consistent with a "force stop". A user normally force-stops an application by going to Settings, finding your app in the list of installed apps, and tapping on the "Force Stop" button for your app. There are some devices and firmware builds that make "Force Stop" more readily accessible than this -- such devices and firmware builds were written by drooling idiots IMHO.
If your app is force-stopped, your code will never run again, until something uses an explicit Intent to start one of your components. Usually, the user does this by tapping on your app's icon in the home screen's launcher. Until the user does this, your BroadcastReceiver will not work, and there is nothing you can do about it.
Rather than using some on-device feature to "kill" your app, try terminating its process via DDMS. If your app continues to work in that case, then however you elected to "kill" your app before is doing a "force-stop". Merely having your process be terminated, such as due to low memory conditions, should not prevent you from receiving future broadcasts.
I know that some devices (like my ASUS) are deleting static receivers when you stop an application, yours is probably one of those.
The only thing you can do is trying with emulator or other device.

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