I created an Android app and need to make it difficult for users to stop the main service that the app spawns during its startup process. This is for a rooted Jelly Bean 4.1.2 device. Here are some steps I've taken so far:
Installed as System App
Uses the Device Admin APIs
android:allowClearUserData="false" is included in the AndroidManifest.
The steps I've taken so far takes care of most normal ways a user would stop/disable an app/process; however, when you check the running apps list in Settings -> Application manager -> Running, users can still hit the 'Stop' button on the long-running service that was started by the app (see picture below):
Is there any way to prevent users from stopping the service here? Or what's the best way to restart a service when a user hits this stop button? I tried putting some code in the service's onDisable() function, but that function does not seem to be called in this case.
Any help would be appreciated!
As explained above does not have this option unless it is executed as root, but you can create an AlarmManager when starting your service that runs from time to time, the system will run if the service is not running, it will be created again.
Is there any way to prevent users from stopping the service here?
Having your app be a device administrator probably blocks this. It definitely blocks the "Force Stop" option.
I tried putting some code in the service's onDisable() function, but that function does not seem to be called in this case.
Since there is no onDisable() on a Service, this is not surprising.
This is a security app for an enterprise, so its expected to be continuously running.
There is nothing intrinsic to "a security app for an enterprise" that would require it "to be continuously running".
Related
I am working on an Android application that most it logic is done in background and basically analyzing the user activities (walking, running, in_vehicle etc)..
The ui has only 2 screens for basic setup and for giving permissions.
In the Application class onCreate (not Activity) the app register to ActivityRecognition api and gets the ActivityDetected events in a broadcast receiver which process the DetectedActivity and so on.
The app has also a boot complete receiver, after device boot, the receiver onReceive invoked.. This, causing the Application class to start, onCreate is invoke, the ActivityRecognition begins as described. This works perfectly!
So actually, the process starts in boot complete and nothing stops it..
Additionally, in the Application onCreate I send a firebase analytics Event (like AppStarted)
Also, when ActivityRecognition registration done I send another event (like ActivityDetectSuccsesfullySrarted)
Now here is the thing, in firebase I see that these events are sent about 20 times a day!!
Is there explanation for this?
This means that something, kills and recreate the process? Why?
Android terminates unused processes to free up system memory.
If you want a process to run for a long time on an off-the-shelf Android device, you will need to use a foreground service. If you are working with your own custom firmware, you could take other steps to try to keep your process around.
Search engines and Android developer website didn't help and I guess you can help with my problem.
I want to make an app for personal use, which is supposed to run all the time on my old tablet (powered all the time). The app will have several features requiring user interaction but independent of those, it should run a background job to check something continuously (real time!) for instance sound detection. It should also always try to connect another device on the network.
That means that job needs to run almost eternally without being killed. Some comments I have found suggested AlarmManager or BroadcastReceiver. But those are triggered by very defined triggers (either time or broadcast). I don't want that, because it should perform its task continuously all the time. This background job should also be able to communicate with the main Activity of my app to report what it is doing and allow user to interact with it (change settings of the job for instance).
Do you know any way how to accomplish this? Is IntentService correct choice for this (hoping that it won't get killed or maybe I should let the Activity to restart it?)
Thanks!
Do you know any way how to accomplish this?
Build your own custom ROM, with a modified version of Android that contains your code as a native Linux daemon.
Otherwise, what you want is technically impossible.
You can come fairly close by using a foreground Service (not an IntentService) and returning START_STICKY or START_REDELIVER_INTENT from onStartCommand(). Android may terminate your process from time to time, but it should restart your service automatically after a short while. That service can use its own background threads to do whatever it is that you are trying to do.
I'm trying to implement a service relationship that roughly looks like this:
{ACTIVITY} -> {SERVICE1} -> {SERVICE2}
The ACTIVITY starts SERVICE1 which then starts SERVICE2. It is very very important that SERVICE2 can shut itself down. If SERVICE1 crashes, SERVICE2 should have a chance to shut itself down cleanly. I've already achieved that using a remote process for SERVICE2 so if SERVICE1 crashes it can shut itself down.
The tricky part is if the user does a Force Close through the application manager.
I understand that no solution is 100%. BUT! I've noticed that the Yahoo Weather app is able to run something they're calling a "Watchdog" in a completely separate app line. Killing the main Yahoo weather app doesn't kill the Watchdog app. WHAT VOODOO IS THIS? And how can I replicate something similar?
Images of the yahoo app:
https://dl.dropboxusercontent.com/u/2193687/device-2014-05-22-151216.png
https://dl.dropboxusercontent.com/u/2193687/device-2014-05-22-151236.png
(converting conversation in the comments to an answer)
Background
Typically a "watchdog service" would refer to a service running in a separate process that would try to restart some other target service if it crashes, or if the user force closes it.
Another similar trick would be to register with the AlarmManager to broadcast a periodic intent that would restart your app / service.
Somewhere along the way (HoneyComb I think), Android changed their security model. Apps could be marked as "bad" by the system, which would not launch them again until the user manually launched them. An app became "bad" if it crashed too often, or the user force closed it.
This includes apps that receive the ON_BOOT_COMPLETED intent - they will not restart if they have been marked bad like this.
So the "watchdog" stopped being as useful (some may say annoying, or battery draining) as it used to be. It might still be useful for an app that has an occasional crash
Remote Process
I initially recommended a remote process as the best way to accomplish this. I then saw that you had already done this, and it works.
Unfortunately this will still not be able to restart the service if it has been stopped manually. It doesn't seem like Yahoo's WeatherServiceWatchdog is able to restart the main Weather service either.
I want to perform action/event when application killed from task manager or any other app. Is there any to perform action when application killed. My application is running in background like service. If i terminate the application then main service stop . I want to start it again.
No, there's no reliable way to know if your application was killed by a another process. The whole point of "killing" an app is to terminate it as soon as possible, without letting it run any code.
== Do not actually use the following suggestions in production application. They are here purely as potential technical solutions, but in general are not a good idea for apps running on end user devices. ==
It might be possible to use IBinder.linkToDeath() from a secondary application, which acts as a monitor for your primary one. However, you will have to convince the user to install the secondary app as well. If you can do it, you could establish two-side monitoring between the two apps, and have one of them restart the other if the second is killed.
You could also attempt to set an alarm through the AlarmManager that fires every so often, to restart your application if it happens to be killed. However, if your alarm period is too big, you risk having certain period of time where your app is not running. And if your time period is too small, most likely your app will not be allowed by Google in the Google Play Store, and the malware app analysis on the phone (JB+) might kick in. Also, alarms that kick in too often will keep the device awaken, and drain the battery very fast.
If you kill some process, you just kill it, so it stops working immediately. There is no event sent to the application.
I looked for the same thing and the answer that i found is : NO, the application does not go to OnDestroy() or anything like that.
I have a question about the exit button. I have read several posts on here about use of an exit button/back button. Also the blog: http://blog.radioactiveyak.com/2010/05/when-to-include-exit-button-in-android.html, which clears discourages the use of an exit button.
Here is my question. I have an app that is very small; however it pulls data from the webservice/MySql database online. It is supposed to only pull data on first open. Or, if the user selects update data from a menu. I do not have an exit button in the app, However I thought that if the user would back completely out of the app, this would be the same as an EXIT.
After backing out of the app, I can still see the app in Setting>Applications>Running Services. It says "1 process and 1 service". In Manage Applicaions, it says that the app has been running for 36 hours.
Is this okay? I do not want users to think my app is using their battery.
On a separate note, I do not see an additional updating (pull from webservice) after backing out. But if I install the app on my galaxy Tablet 10.1 running Android 3.1, I do see an occasional update from the webservice.
Anyone have some advice for me?
Android won't stop an application when the user presses "back". The application will stay on memory until Android needs the memory for another application. Any thread that was running when the user presses "back" will continue to run. Traditionally, you're supposed to stop all those processes on the onPause() method of your Activity (additionally, store all preferences and other cleanup.)
Also, if you've started a Service (as stated), then it will continue to run until you tell it to stop. On rare occasions, Android will kill a Service to free up resources, but for the most part you have to kill it.
As you mentioned it is showing 1 service running. So you need to stop this service and release the resource if any you have used in the service as android will not do it for you.
If you're only downloading the information with the webservice on startup and then manually, why not just stop the service, once its downloaded the data and then start it again when the user has requested a manual refresh?
Android rarely kills a service in Android, however will (whenever it wants) stop your application from running in memory. BUT with how the Android handles activities, your app will likely be started again from the last activity window it was in.
After backing out of the app, I can still see the app in Setting>Applications>Running Services. It says "1 process and 1 service".
This means you started a service and never stopped it. For an operation like the one you describe, perhaps you should be using an IntentService, which automatically shuts down when the work is complete.
Is this okay?
It is certainly not ideal. Some users get very irritated with apps that behave like yours, using task killers or the Manage Services screen in Settings to force-stop your app.
First create a button and place this code onClick event
System.runFinalizersOnExit(true);
System.exit(0);