Android START_NOT_STICKY not working - android

i am trying to write a sample Android service code to test whether , the service stop itself or not after returning START_NOT_STICKY to onStartCommand. But i whenever , i closed my app , the service stop itself , whereas according to the rule START_NOT_STICKY will not allow to stop the service automatically.
MyCode :
ServiceDemo.java
package com.example.servicedemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent in = new Intent(this,TrackService.class);
startService(in);
}}
TrackService.java
package com.example.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class TrackService 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_NOT_STICKY;
}
#Override
public boolean onUnbind(Intent intent)
{
return super.onUnbind(intent);
}}
this my above code , whenever i close my app , the app service stops itself , please help me out , how can i restrict my service to stop or restart itself.

close my app means , pressing home and from slide menu swipe up app to close completely
That means that you are terminating your background process. At that point, your service is gone, and since you are returning START_NOT_STICKY, it will not automatically restart.
In other words, what is happening is perfectly normal.

Close with swipe won't kill this code.
It's a service that runs in the foreground so android treats it as if it is on the screen. It runs in a seperate process so the main process can be killed. It shows a custom notification to the user when its running so its completely ligit and it is written.
Note Eclipse ADK Users only put the service in a different process when your done debugging it.
manifest
<service
android:name="com.gosylvester.bestrides.ServiceLocationRecorder"
android:process=":myService" >
</service>
</application>
MyService class
private boolean isRecording = false;
public int onStartCommand(Intent intent, int flags, int startId) {
boolean isTrackerMarker = SettingMarker.TRACKER_MARKER_DEFAULT;
if (intent != null) {
isRecording = intent.getBooleanExtra("isrecording", isRecording);
startRecording(isRecording);
}
//if isRecording keep the service running else let os know service can be killed
if (isRecording) {
startForeground(R.id.action_record, getMyCustomNotification());
return Service.START_STICKY;
} else {
stopForeground(true);
return Service.START_NOT_STICKY;
}
}

The service does get re-created, just not re-started.
If you override the onCreate and do a Log.d or a Toast, you will see that onCreate gets called after your activity and app is destroyed and even the service onDestroy is called.
So the trick to keep it running after it is re-created is to put your code on the onCreate method and use the onStartCommand just to return START_STICKY.
Note: onCreate is called before onStartCommand, so your code will run both when it is started by startService and from the system self re-creation.

Related

Reasons why a service could be stopped in android

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.

Restarting a service in the onDestroy method

I have made an app in which a service runs in the background. But if the android system requires resources, it will stop the service. However I may still require my service to run.
Is it a bad practice to restart the service (if condition relevant to my app still holds true) in the onDestroy method of my service?
How can I make sure my service runs indefinitely (if condition relevant to my app still holds true)? Or atleast on high priority?
Probably the best you can do is use the START_STICKY flag, which tells Android to attempt to restart the service if it has stopped. Beyond that ensure that it consumes as few resources as possible, so that it is less likely to be destroyed.
Android prioritizes the UI over everything. Then processes that are related to the UI. Then processes that are consuming the least amount of resources. A Service runs in the background, so unless it has resources that are also in use on the UI or connected to the UI in some way, it should be a lower priority.
Also you cannot tell Android how to prioritize your Service (everyone would make theirs the "highest priority" right?). So it goes by how well you minimize the impact on overall resources - why kill 3 Services when it could kill 1 and regain all the resources it needs?
To help understand how to manage memory better: http://developer.android.com/training/articles/memory.html
set it START_STICKY. It Causes after killing service the service will restart again. it is my code :
android manifest :
<application
....
<service android:name=".UpdateService" />
</application>
service class :
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.....);
filter.addAction(Intent....);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
Log.i("log", "action Called");
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
}
receiver class :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Log", "recevid");
}
}
in StartupActivity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = getApplicationContext();
Intent service = new Intent(context, UpdateService.class);
context.startService(service);
}

How to make a service working thought the process force killed in andorid?

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

Android starts my Service before the Air native extension calls it

I'm developing an Air (Flex) Mobile application for Android, which uses Air Native Extension (ANE) to take advantage of some platform functions that otherwise could not be used (at least to my knowledge). One of the platform functions that I want to use are services, specifically services that run as Foreground processes (using the startForeground() method).
When I invoke the service from my ANE everything works like a charm, the service is started correctly and it does what it needs to do but the problem is that Android seems to be trying to start it independently from my code, which, of course, results in errors that appear in the LogCat.
When I launch the application in debug mode in Flash Builder, and I use it for a while checking that the service works perfectly and no errors are thrown, after I close it from the Flash Builder (not from Eclipse ADT, which I also could) a couple of seconds later, the following errors appear:
01-16 10:56:06.953: E/AndroidRuntime(9757): java.lang.RuntimeException: Unable to start service com.mycompany.myextension.services.MyService#41594a50 with Intent { cmp=air.QOE.debug/com.mycompany.myextension.services.MyService }: java.lang.NullPointerException
01-16 10:56:06.953: E/AndroidRuntime(9757): at com.mycompany.myextension.services.MyService.onStartCommand(MyService.java:37)
It seems to be clear that Android tries to start the service but since its design to work inside the ANE -the extension is initialized but its context was already disposed- it crashes because it cannot reach the variables that are initialized within the context, therefore, ending in a crash or error the first time the code uses a context variable (line 37).
I would think that this has to do with the way I declared the service in my Android Manifest file. Next is part of the XML:
<application android:debuggable="true">
<service android:enabled="true" android:exported="true" android:name="com.mycompany.myextension.services.MyService">
<intent-filter>
<action android:name="air.com.mycompany.myextension.DO_CUSTOM_ACTION"/>
</intent-filter>
</service>
</application>
I hope you can tell me if I’m declaring the service incorrectly or if I’m making a mistake elsewhere. I appreciate the help.
EDIT: Service code
package com.mydomain.myapplicationextension.services;
import java.util.Timer;
import com.adobe.fre.FREContext;
import com.mydomain.myapplicationextension.myapplicationextension;
import com.mydomain.myapplicationextension.components.HttpServiceTask;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class MyApplicationService extends Service {
private Timer timer;
#Override
public IBinder onBind(Intent arg0) {
// Log.d("MyApplicationService", "onBind()");
return null;
}
#Override
public void onCreate() {
// Log.d("MyApplicationService", "onCreate()");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Log.d("MyApplicationService", "onStartCommand(): " + myapplicationextension.applicationID);
Context appContext = myapplicationextension.applicationContext;
Intent launchIntent = appContext.getPackageManager().getLaunchIntentForPackage(myapplicationextension.appPackageName);
PendingIntent pendingLaunchIntent = PendingIntent.getActivity(appContext, 0, launchIntent, 0);
FREContext extContext = myapplicationextension.extensionContext;
int icon = extContext.getResourceId("drawable.notification_icon");
Notification notification = new Notification.Builder(appContext)
.setContentTitle(myapplicationextension.applicationID)
.setContentText(myapplicationextension.notificationMessage)
.setSmallIcon(icon)
.setContentIntent(pendingLaunchIntent)
.build();
startForeground(1,notification);
// Log.d("MyApplicationService", "startForegroundService()");
if(myapplicationextension.checkStatus)
{
timer = new Timer("Printer");
HttpServiceTask serviceTask = new HttpServiceTask(timer, launchIntent,myapplicationextension.statusServiceURL, myapplicationextension.triggerResponse);
timer.schedule(serviceTask, 0, 2000);
// Log.d("MyApplicationService", "startTimer()");
}
return START_STICKY;
}
#Override
public void onDestroy() {
// Log.d("MyApplicationService", "onDestroy():");
if(myapplicationextension.checkStatus)
{
timer.cancel();
timer = null;
// Log.d("MyApplicationService", "onDestroy(): timer.cancel():");
}
super.onDestroy();
}
}
When the phone runs out of memory and kills the service before it finishes executing. START_STICKY tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. START_NOT_STICKY tells the OS to not bother recreating the service again. There is also a third code START_REDELIVER_INTENT that tells the OS to recreate the service AND redelivery the same intent to onStartCommand().
START_STICKY and START_NOT_STICKY
I have an ANE using START_STICKY that keeps launching the service

Android - Remote service is terminated if application is terminated

Android SDK says that remote service runs in another process with the application. I thought it mean if the app stops/ is terminated..., then remote service still remains running. But it does not.
For example I have this remote service:
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.os.IBinder;
import android.util.Log;
public class WatchDogService extends Service {
private Timer timer = new Timer();
#Override
public void onCreate() {
Log.i(WatchDogService.class.getName(), "WatchDog start");
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.i(WatchDogService.class.getName(), "WatchDog boo boo!!! ^^");
}
}, 0, 5000);
}
#Override
public void onDestroy() {
Log.i(WatchDogService.class.getName(), "WatchDog stop");
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(WatchDogService.class.getName(), "WatchDog has just been called...");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
}
AndroidManifest.xml:
<service
android:name="WatchDogService"
android:process=":remote" >
<intent-filter>
<action android:name="WatchDogService" />
</intent-filter>
</service>
In another activity I call it as:
startService(new Intent("WatchDogService"));
The service starts ok. But if I go to system apps manager, then stop the app, the service is terminated too.
I want to keep the service running even if the app is terminated. How can I do that?
I want to keep the service running even if the app is terminated. How can I do that?
You don't. If the user terminates your app, your app is terminated, period. The user is in control of their Android device, not you.
Please respect the user's wishes, and try not to build apps that the user will want to force-stop, task-kill, or otherwise get rid of.
Instead of a service you may create a separate application and invoke it or
Instead of a service you may create a separate background application using AIDL described in this link:
http://developer.android.com/guide/components/aidl.html
Note that the AIDL should register a notification with an intent to start the original app when it is done and ask the user if he wishes to act on it.
I expected that "service" means service, not "application". I mean, I want something like "Service manager". But I forgot that the Applications settings in Android is for end-users, not coder.
So far, I got my answer.

Categories

Resources