I have a service that performs an action on the timer. Service runs from activity. While the application is running, the service works fine.If I close the application using the cleanup in the launcher, the service goes restart mode, but does not restart. is this normal?
Service:
public class MyService extends Service
{
private static Timer timer = new Timer();
public void onCreate()
{
super.onCreate();
}
private void startService()
{
timer.scheduleAtFixedRate(new mainTask(), 0, 10000);
}
private class mainTask extends TimerTask
{
public void run()
{
//MY CODE
}
}
public int onStartCommand(Intent intent, int flags, int startId)
{
startService();
return START_STICKY;
}
public void onDestroy()
{
super.onDestroy();
}
public IBinder onBind(Intent intent)
{
return null;
}
}
Related
Here I attached my code,I created a service which runs both cases while my app is in background and killed state. It is not running on android marshmallow devices, but it works on other devices. When I check other devices, Log will be executed when the app is kill state, only version 6 , not executed.
public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
super();
Log.e("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
When comes to destroy again I will call the service, It will go to broadcast receive, and then start service function will call.
#Override
public void onDestroy() {
super.onDestroy();
Log.e("EXIT", "ondestroy!");
Intent broadcastIntent = new Intent("sales.com.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
timer = new Timer();
initializeTimerTask();
timer.schedule(timerTask, 1000, 1000); //
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.e("in timer", "in timer ++++ "+ (counter++));
}
};
}
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
Below code for Broadcast Receiver code : app works, when i click back button, if the app was killed state, it is not working, other devices services running.
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
// context.startService(new Intent(context, SensorService.class));
Intent i = new Intent(context, SensorService.class);
context.startService(i);
}
}
Run a service in background continuously. For example, a service has to be kicked off which will display a toast message 20 seconds once even if the app is closed.
public class AppService extends IntentService {
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public AppService() {
super("AppService");
}
#Override
protected void onHandleIntent(Intent workIntent) {
Toast.makeText(getApplicationContext(), "hai", Toast.LENGTH_SHORT).show();
SystemClock.sleep(20000);
}
}
Below code works for me...
public class AppService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
Accepted answer will not work on from Android 8.0 (API level 26), see the android's background limitations here
Modification in Accepted Answer:
1: You have to invoke the service's startForeground() method within 5 seconds after starting the service. To do this, you can call startForeground() in onCreate() method of service.
public class AppService extends Service {
....
#Override
public void onCreate() {
startForeground(9999, Notification())
}
....
}
2: You must call startForegroundService() instead of startService() by checking API level from where you want to start the service.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
This code work for me..
public class ServiceClass extends Service {
public static final int notify = 300000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Log.d("service is ","Destroyed");
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d("service is ","running");
}
});
}
}
}
In your manifest, where you declare your service, add:
android:process=":processname"
This lets the service run on a separate process and thus it will not be killed with the app.
You can then chose if you want to use foreground. It will show a persistent notification, but reduces the likelihood if the service being killed.
Further, if you want to create a continuously running service, use Service, NOT IntentService. IntentService stops when it is finished doing its action.
I have an app that creates a never ending background service. The service is started when the app is launched. When the app is killed (e.g. by the user), the service sends a broadcast request that will restart it after it is killed.
The question is: when I restart the app, how can I know if the service is already running?
Naively I had thought that by restarting the service when the app is re-launched it would have stopped the existing service but this does not happen. The following code shows that if I do this, there are two services running at the same time (the printout in the timer moves from every second to every half a second).
Many thanks
public class MainActivity extends AppCompatActivity {
static Intent mServiceIntent;
private SensorService mSensorService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx=this;
setContentView(R.layout.activity_main);
mSensorService= new SensorService(getCtx());
mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
startService(mServiceIntent);
}
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i("MAINACT", "onDestroy!");
super.onDestroy();
}
}
public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to check if the service is there in 25s
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to check in x seconds if the sensorsService is active. If not it will start the service
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
long time= System.currentTimeMillis();
Log.i("in timer", "in timer ++ "+(time-oldTime)+" ++ "+ (counter++));
oldTime= time;
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
Intent broadcastIntent = new Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));;
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
And then use
isMyServiceRunning(MyService.class)
Credit
I have written a service with timer to do something periodically but when I stop service service from mainActivity if my service is in middle of their task it's continue to finish and after that stop it and the same issue when i want to close application that call OnDestroy on Main Activity service work and after finish their task don't start again.
My Question is how can Force stop service when i want to exit from my app?
this is my service code
public class MyTimerService extends Service{
private static int counter = 0;
private Timer timer = new Timer();
private int INTERVAL;
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
INTERVAL = intent.getIntExtra("time", 500);
repaet();
return START_NOT_STICKY;
}
private void repaet() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.i("Saeed", String.valueOf(++counter));
}
}, 0, INTERVAL);
}
#Override
public void onDestroy() {
Toast.makeText(this, "Stop Service", Toast.LENGTH_LONG).show();
if(timer!=null){
timer.cancel();
}
stopSelf();
super.onDestroy();
}
}
Have you tried to manually stop your service inside onDestroy() by using this stopService()?
For a demo I print a Toast after Evert 10 sec. using Service class.
It works fine, I'm getting the Toast after every 10 sec if I am on the Activity when I leave the app, Service is not giving the o/p.
But I want to that toast either I'll kill the App or back press Here is code snippet :
ServiceDemo.java
public class ServiceDemo extends Activity {
private Handler myHandler = new Handler();
private Runnable drawRunnable = new Runnable() {
#Override
public void run() {
as();
myHandler.postDelayed(this, 10000);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_demo);
myHandler.postDelayed(drawRunnable, 10000);
startService(new Intent(this, MyService.class));
}
public void as(){
startService(new Intent(this, MyService.class));
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
Service.java
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "HOHO Service Created...", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
}
}
Edit 1
moveTaskToBack(true);
I put this into the onBackPressed method I Service give the o/p if I am not on the screen but When I kill the App, Service not responding
I think you need to override onStartCommand instead of onStart()
like:
public int onStartCommand(Intent intent, int flags, int startid)
{
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
i think AlarmManager is what you want.
You have to user AlarmManager, here's an example : Alarm Manager Example
Your task will be executed even if the application is terminated.
But if the application is killed by the user, the Alarm will be canceled. See this discussion How to create a persistent AlarmManager