We all know what a timer app does, and we also know it runs on background. So my question is, which does it belong to? Does it belong to service or broadcast receiver?
It's very simple to do what you want
public class MyService extends Service {
Timer timer;
Handler helper;
public static long TIME = 60000; // Repeats every 1 minute
#Override
public void onCreate() {
super.onCreate();
timer = new Timer();
helper = new Handler(Looper.getMainLooper());
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Actions to be made every 1 minute
}
}, 0, TIME);
}
#Override
public void onDestroy() {
timer.cancel();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Related
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
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
my application requires a service that changes the system wallpaper in a particular time interval how should I implement this, please help???
Create your service class
class WallpaperService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Timer progressTimer = new Timer();
timeTask = new ProgressTimerTask();
progressTimer.scheduleAtFixedRate(timeTask, 0, 1000);
}
private class ProgressTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int currenMinutes = 0; // set your time here
changeWallpapers(currentMinutes);
}
});
}
}
private void changeWallpapers(int minutes) {
if(minutes == 1)
layout.setBackGround(Color.RED);
if(minutes == 2)
layout.setBackGround(Color.BLUE);
}
}
}
And then call your service Intent where your want
Well, I have implemented this function. I register an Alarm in the system and connect it to a BroadcastReceiver. When the BroadcastReceiver is triggered, in the OnReceive() method, you can set a wallpaper for the system.
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.