I am building a toast every 5 sec using some sample found.
The code works ok, but the service wont stop even i stopped the app.
Can anyone point out what is wrong?
public class MyService extends Service {
public static final long INTERVAL=5000;//variable to execute services every 5 second
private Handler mHandler=new Handler(); // run on another Thread to avoid crash
private Timer mTimer=null; // timer handling
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("unsupported Operation");
}
#Override
public void onCreate() {
// cancel if service is already existed
if(mTimer!=null)
mTimer.cancel();
else
mTimer=new Timer(); // recreate new timer
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),0,INTERVAL);// schedule task
}
#Override
public void onDestroy() {
Toast.makeText(this, "In Destroy", Toast.LENGTH_SHORT).show();//display toast when method called
mTimer.cancel();//cancel the timer
}
//inner class of TimeDisplayTimerTask
private class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast at every 5second
Toast.makeText(getApplicationContext(), "Notify", Toast.LENGTH_SHORT).show();
}
});
}
}
}
I keep receiving the toast Notify even the app had been closed.
add onTaskRemoved() method in your MyService,like this
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();///its will stop service
super.onTaskRemoved(rootIntent);
}
In your Activity onStop() you should call stopService(new Intent(context,YourService.class)); in order to stop your service
Related
I followed this to Run a Service for Every 5 Min
Till now Its working fine.. But I have added a Intent for Next service in TimeDisplay But its working fine only for the First Time But the second Activity is not running for Every 30 seconds...Its only Working on First Run..
this is MyService
public class ServMain1 extends Service {
private static final String TAG = "ServMain1";
public static final int notify = 30000;
private Handler mHandler = new Handler();
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
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);
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
}
//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() {
// display toast
Toast.makeText(ServMain1.this, "ServMain1 : Service is running", Toast.LENGTH_SHORT).show();
startService(new Intent(ServMain1.this, ServMain2.class));
}
});
}
}
}
Here at TimeDisplay I am using this to start second service startService(new Intent(ServMain1.this, ServMain2.class));
How ever I am getting Toast for Every 30 Seconds But Along with that toast I am using a intent is not working...
Its working only for the first time... but I am getting toast of every 30seconds
Can Any one suggest me How to using this kind of activity
A service will only run once even after you call startService multiple times.
If you want to keep restarting the service in your handler, you need to first check if it already running, kill it if it is already running and call startService post that.
You can check if the service is running using
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
And inside your handler make these changes
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
Toast.makeText(ServMain1.this, "ServMain1 : Service is running", Toast.LENGTH_SHORT).show();
if(!isMyServiceRunning(ServMain2.class)){
startService(new Intent(ServMain1.this, ServMain2.class));
} else{
stopService(ServMain2.class);
startService(new Intent(ServMain1.this, ServMain2.class));
}
}
});
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 want to stop the service when I come to the activity . This is my activity code :
stopService(new Intent(this, Services_chat.class));
on call this on the mainactivity and in the oncreate method . so I certainly called .
this is my service code:
public class Services_chat extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("this","caa");
}
}, 0, 1000);//put here time 1000 milliseconds=1 second
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
As you can seen I log and run this code every second , so after running my app and it calls for stopping service , it doesn't stop and it still runs .
How can I stop this service ?
thanks
write this method in Services_chat class.
#Override
public boolean stopService(Intent name) {
// TODO Auto-generated method stub
timer.cancel();
task.cancel();
return super.stopService(name);
}
If you are binding service via onBind() from MainActivity then call unBindService() method to stop service
If you are starting service via startService() from MainActivity then call stopService() or stopSelf()
Android system will try to stop service as soon as possible upon stop request from application
UPDATE :
Add code to stop timer in onDestroy() like :
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel();
}
Make object of Timer instead of using Annonymous class Timer :
in onStartCommand() :
Timer mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("this","caa");
}
},0,1000);
My question is Android related:
How do I run a task every 20 seconds within an intentservice ?
Problem is, I have to init some classes which will be used in the Handler "run" process.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds (probably because of the classes that got eliminated when the service stopped?). So maybe the solution is to get the service to stay running as long as the Handler runs or to throw away the code and do it right ?
Hope, someone can help me.
public class Fadenzieher extends IntentService{
private Handler handler = new Handler();
private Runnable timedTask = new Runnable(){
#Override
public void run() {
// My functions get called here...
// class1member.getDBWorkdone();
handler.postDelayed(timedTask, 20000);
handler.obtainMessage();
}};
public Fadenzieher() {
super("Fadenzieher");
}
#Override
protected void onHandleIntent(Intent intent) {
// SOME INITIALISING
// I have to init some vars & functions here that
// will also be used inside the handler loop
// Class1 class1member = new Class1();
// class1member.startUpDB();
handler.post(timedTask); }
Thank you very much in advance!!!
---- So this is the updated code now (14. nov. 2011)
public class Fadenzieher extends Service{
private static final long UPDATE_INTERVAL = 60000;
Context context = this;
private Timer timer = new Timer();
DbHelper dbHelper;
public void onCreate(){
dbHelper = new DbHelper(context);
runTheLoop();
}
protected void runTheLoop() {
timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
dbHelper.dosomethings();
Toast.makeText(context, "CALL", Toast.LENGTH_LONG).show();
}}, 0, UPDATE_INTERVAL);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Starte Service“, Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
public void onDestroy() {
super.onDestroy();
dbHelper.close();
Toast.makeText(this, "Stoppe Service“, Toast.LENGTH_LONG).show();
}
// We return the binder class upon a call of bindService
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
Fadenzieher getService() {
return Fadenzieher.this;
}
}
}
The whole application crashes immediately.
How do I run a task every 20 seconds within an intentservice ?
That is not an appropriate use of IntentService. Use a regular Service, please.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds
IntentService shuts down when onHandleIntent() returns, which is why this is breaking for you. Use a regular Service, please.
Also:
Please allow the user to configure the polling period
Make sure that this service will shut down when the user no longer wants it to be running
I need a service that should always be running till its stopped explicitly by my activity and should start again even if it is stopped due to some issue (START_STICKY flag). This service should continuously do something (every couple of seconds) using a TimerTask. I ended up with the following code.
public class SomeService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
TimerTask timerTask;
final Handler handler = new Handler();
Timer timer = new Timer();
#Override
public void onCreate() {
// code to execute when the service is first created
super.onCreate();
}
#Override
public void onDestroy() {
// code to execute when the service is shutting down
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
// code to execute when the service is starting up
timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
//KEEP RUNNING SOME ERRANDS HERE
}
}
});
}
};
timer.scheduleAtFixedRate(timerTask, 100L, 1700L);
}
}
Is there anyway that I can optimize this to run continuously?
Running every second sounds pretty excessive, but is there a reason why you don't use the AlarmManager to trigger an IntentService? Then the system would be responsible for triggering your service reliably. Whether you can achieve reliable 1 second retriggers, I don't know. Seems like a bad idea for the reasons Mark is mentioning in the other answer.