21

It is very important that my service stay running until someone with a password stops the service from my UI screen. My app runs great but it is designed to be turned on/off by parents (with a password) on their kids phones. I have managed to make everything work but the problem I'm having is that if the kid uses a task manager to kill my service then my app is useless. I would be grateful to anyone who knows a way to either

1) monitor the service and start it back up automatically if its "killed" or 2) prevent someone from being able to kill it except from the activity (administration screen) that launched the service. Or both?

I'm sorry if I'm not very clear in describing the problem, I'm a beginner. I've made great progress so far but I am stuck at this last hurdle.

casperOne
  • 73,706
  • 19
  • 184
  • 253
Don
  • 211
  • 1
  • 2
  • 3

6 Answers6

13

You can use API method: startForeground(). Here is the explanation of it:

A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)

Here you can find an example how to use this.

As for the question, you cannot prevent a service from being killed. It can be killed by the system. Even system services can be killed. If this happens they are restarted. You may use the same approach.

Yury
  • 20,618
  • 7
  • 58
  • 86
6

You can write a helper app to receive android broadcast "android.intent.action.PACKAGE_RESTARTED",when your app got killed,your helper will receive that broadcast and you can restart your app or whatever.

That's how 'Smart App Protector Free' do.

The bad thing is users must install two apps instead of one.

Tinfu
  • 111
  • 1
  • 5
6

There isn't a way to prevent this directly, without a rooted device. The SDK helpfully prevents these kinds of issues.

You can do the "truly evil" trick and have two services in two application. Each service monitors the other, and restarts it if it stops. This is kludgy, but in most cases even the fastest fingered kid couldn't kill both applications.

Yann Ramin
  • 32,895
  • 3
  • 59
  • 82
  • 3
    But a program can! Any program that can execute the equivalent of `kill -KILL -1` can cause all your instances to die simultaneously. – C. K. Young May 07 '10 at 02:55
  • 1
    If you would have system privileges, how would you sign your app in a way of hiding it or un-kill able from users? is there any specific permission you have to set? – rayman Dec 09 '10 at 10:15
  • 3
    I just installed an app called Smart App Protector Free, it ask you if you wanna install a helper than prevent it being killed. It works and I wonder how it is. I use the System Panel to kill everything (including system process) but the protector still come back. Even more, I can't see trace of the helper running, not in the System Panel, and even I ps in the device console (thru adb), I still can't see that helper exists. Any hints? – xandy Jul 09 '11 at 16:01
3

For anyone who is still searching for an answer - this one may be correct:

you can not: make a service unkillable, if running on low Memory the System will always kill your service. BUT

you can: Tell the System to restart your service when it is killed. Look at this piece of code:

public static final int START_REDELIVER_INTENT

Added in API level 5

Constant to return from onStartCommand(Intent, int, int):

if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then it will be scheduled for a restart and the last delivered Intent re-delivered to it again via onStartCommand(Intent, int, int). This Intent will remain scheduled for redelivery until the service calls stopSelf(int) with the start ID provided to onStartCommand(Intent, int, int). The service will not receive an onStartCommand(Intent, int, int) call with a null Intent because it will only be re-started if it is not finished processing all Intents sent to it (and any such pending events will be delivered at the point of restart).

Constant Value: 3 (0x00000003)

kelalaka
  • 5,064
  • 5
  • 27
  • 44
Matthew Fisher
  • 173
  • 1
  • 15
2

If you have system level permissions use persistent:true via manifest permissions.

https://developer.android.com/guide/topics/manifest/application-element

4b0
  • 21,981
  • 30
  • 95
  • 142
JoshuaTree
  • 1,211
  • 14
  • 19
  • Only works for system processes. User-installed processes have this forced to false. – Slawa Oct 26 '18 at 10:16
  • will it work with an application which has a system permissions on a rooted device? – Ofek Regev Mar 07 '19 at 12:59
  • I am not sure, I have never rooted a device before, but I should. Anyways, I think with a rooted device you could probably do anything :) – JoshuaTree Mar 14 '19 at 06:07
1

Just set the return type as START_STICKY .

Ananth
  • 4,227
  • 2
  • 20
  • 26