If I have an app that does not have any activities, just one BOOT_COMPLETED broadcast receiver and the simplest service. The receiver will just start the service and the service will just ran the following code:
public class ScreenStateService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
}
As as I understand, the service would ran until the end of time or until one of the following scenarios occurr:
Low memory: The system is running low on memory so it decides to stop the service.
ANR
The user manually stops the application or disables it.
In 1 and 2 the system would start the service again, after memory is no longer low or after the error is handled. In the case of 3 it wont be started again.
The question is: is the above right? Are there any other cases where the service would be stopped by an outside source? Please specify if it would be started again automatically if there are any.
Related
i'm trying to create an app that communicates with my localhost and search in a database.
I already make the connection and find the data, but i need to stay connected and send a notification if there's any changes in the table, but I can't figure it out how to keep the connection even when I close the app, because it closes everything, even the service.
The service doesn't stay open.
This is my Class:
public class SensorService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Starting",Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean bandera = true;
Toast.makeText(this, "Checking data...", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
stopService(new Intent(this,SensorService.class));
startService(new Intent(this,SensorService.class));
}
#Override
public void onDestroy() {
startService(new Intent(this,SensorService.class));
}
}
Every time I close the app, the service execute one more time and no more.
If you want the service to continue running after the app is closed, you need to call the startForeground(int, Notification) method from within the service. Android limits you to running longer running services in the background only as long as a notification is displayed to the user letting them know that a service is running (like a music player or a downloading service).
This is an intentional design constraint to ensure developers do not start services in the background that run indefinitely without the user being aware. Supply your own notification (can be anything) and you should be able to run the service in the background.
For more detailed information on this method, read it at: startForeground(int, Notification)
You can use onTaskRemoved and restart the service if needed.
#Override
public void onTaskRemoved(Intent rootIntent){
super.onTaskRemoved(rootIntent);
//restart your service
}
Please note that if you use onTaskRemoved, start your service as not sticky so it won't be restarted.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}
I have seen the default behaviour of many services, that they are restarted when killed by system or user.
Is it possible that if my service is killed or crashed the android device is rebooted instead of my service itself being restarted.
If so, then have android provided some mechanism that we can use to achieve the above.
First of all, it is really very bad pattern to reboot device on service destroy.
Anyways, you can achieve this using below code
public class demoService extends Service
{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
}
#Override
public void onDestroy() {
super.onDestroy();
// this won't restart your phone instead it will ask for action
Intent i = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
i.putExtra("android.intent.extra.KEY_CONFIRM", true);
startActivity(i);
}
}
i created a simple services, its job is to handle the incoming call. I created a services like below
public class CalldetectorService extends Service {
private CallHelper callHelper;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
callHelper = new CallHelper(this);
return res;
}
#Override
public void onDestroy() {
super.onDestroy();
//callHelper.stop();
}
}
Inside the helper, i m handling the call. This service is not running in background continuously. after some time, its getting halted. It works pretty well when i open app & move to background for some time, later on it wont work.
How to make my service to work in background always and catch the incoming calls
If you don't want the service to be killed by the OS: 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.)
In your case, 'catching' incoming calls is best achieved with a Broadcast Receiver, registered in the manifest for intent: <action android:name="android.intent.action.PHONE_STATE" />
the answer is you dont, The OS can kill a service at anytime it needs to. you can return START_STICKY which will flag you service to be restarted when it can but there is no way to make a service run forever
I am starting and stopping a service from an activity calling startSertice()/stopService() (when user select/deselect a check box and service is not bounded). Every thing is working fine even though the activity that starts the service is closed. In "Running apps" I'm able to see 1 processes, 1 service running. But when I kill the application, using Task manager kind of application, the process is getting killed and service is not working though the running apps showing 0 processes, 1 service. How to make the service working in such situations? I observed the same in some other security applications like Avast with 0 processes, 1 service, while service working properly. Please help me out on this.
Following is the activity on click method
#Override
public void onClick(View arg0) {
boolean value = checkBox.isChecked();
if(value){
// start the service
startService(new Intent(this, MyService.class));
Toast.makeText(this, "Background service started", Toast.LENGTH_SHORT).show();
} else {
stopService(new Intent(this, MyService.class));
Toast.makeText(this, "Background service stopped", Toast.LENGTH_SHORT).show();
}
}
Following is the service class:
public class MyService extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.d("######Service","Service created successfully");
}
#Override
public int onStartCommand(Intent intent, int flags, int stardId){
Log.d("######Service","Service started successfully");
IntentFilter powerButtonIntentFilter = new IntentFilter();
powerButtonIntentFilter.addAction("android.intent.action.SCREEN_ON");
this.registerReceiver(pbReceiver, powerButtonIntentFilter);
Log.d("#######","Power button register registered");
return START_STICKY;
}
#Override
public void onDestroy(){
Log.d("######Service","Service destroyed successfully");
this.unregisterReceiver(pbReceiver);
Log.d("#######","Power button register un-registered");
super.onDestroy();
}
}
Everything is working fine in ideal case. SCREEN ON action is being listened by the broadcast receiver properly even when the activity that starts the service is closed. I am able to see the app running in settings. But when I force kill the process using Task Manager kind of applications, processes is getting killed and in running apps I am able to see 0 process, 1 service running. Though the service is running after force killing the app from Task manager, broadcast receiver is not listening to the SCREEN ON action. Please help me out on this.
Thanks, JK
I am working on parental control/adult content filtering application. This app continuously monitors the calls and smses on a child's mobile and logs all the activity onto a server. For this I am starting a service (MyService.java)
on BOOT_COMPLETED and in the onCreate method of the service I register a contentobserver for the callLog and sms uri ( refer to the code snippet below ) .
Now the issue is, Since I want to monitor every outgoing, incoming call s and sms I want the service to be continuously running ( without being stopped/killed) . Moreover this Service is being just used for registering content observers and not doing any other processing(its OnstartCommand method is dummy ) , so android OS kills the service after sometime. How do I ensure that the service runs continuously and keeps the contentobserver object alive ?
public class MyService extends Service {
private CallLogObserver clLogObs = null;
public void onCreate() {
super.onCreate();
try{
clLogObs = new CallLogObserver(this);
this.getContentResolver().registerContentObserver(android.provider.CallLog.Calls.CONTENT_URI, true, clLogObs);
}catch(Exception ex)
{
Log.e("CallLogData", ex.toString());
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
if( clLogObs !=null )
{
this.getContentResolver().unregisterContentObserver(clLogObs);
}
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return Service.START_STICKY;
}
#Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
You cannot ensure your service to be running continuously on Android.
For the use-case you mention, it is better to rely on Broadcast receiver like ACTION_NEW_OUTGOING_CALL & SMS_RECEIVED.
If you feel, above supported Broadcast receivers doesn't cover all your use-cases. Use AlaramManager to periodically start your SERVICE and look into CALL_LOGS and SMS table for any change in data and take appropriate action (this may involve check marking the last visited data on CALL_LOGS and SMS table).
you can set the service to run in the foreground . this will give your service a much lower chance of being killed by the OS .
read here for more information .
The content observer get unregistered as soon as your service get killed. So registering once is not an option and your service must be running all the time. to guarantee this you must return START_STICKY from onStartCommand. You can also start the service in foreground.
But what if a new call arrive when the service is killed? To handle this you can store last processed _id in preferences of your app. and each time get all the new call logs with greater id than saved id. You must process the logs on service onCreate as well as on observer onChange.
You cant guarantee it will run continuously, but you can return START_STICKY from onStartCommand which guarantees that Android will re-start your service if it is killed for any reason.