I have to run a task in background when reach the scheduled time.i assigned the task of waking up my service to Alarm Manager
and it does well if the app is background/running.service keep running fine on app's background as well as foreground states if am not changing the state of app after beginning the service.for the purpose of well understanding the scenario's given below.
Case 1:
1.Setting up the schedule and sending the time to alarm manager and keep the app running.
2.Alarm manager calls the service when the time is reaching.
3.Service start running
4.when i close my app service get stopped
Case 2:
1.Setting up the schedule and sending the time to alarm manager and closing the app.now app in background.
2.Alarm manager calls the service when the time is reaching.
3.Service start running
4.Relaunching the app.service continuing running/working fine.
5.Now closing the app and the result is service dead.
I have to call the service only by Alarm Manager
, not on every time when app launches for that purpose in service onStartCommand
method i returned START_NOT_STICKY
and i don't want to use START_STICKY
.if i goes to START_STICKY
it won't consider the scheduled time.and the thing is i don't want to check the time again as it's doing well by Alarm Manager
.
When app running on low memory the services get destroyed.is the solution using startForeground instead of startService ?
How can i make my service running stable without bothering about the app opening/closing states ?
Setting schedule
public void setAction(View v) {
Calendar calendar = Calendar.getInstance();
int hour = Integer.parseInt(HH.getText().toString());
int minute = Integer.parseInt(MM.getText().toString());
int second = Integer.parseInt(SS.getText().toString());
String peried = PP.getText().toString();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.AM_PM, peried.equalsIgnoreCase("AM") ? Calendar.AM : Calendar.PM);
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
myIntent.putExtra(ACTION,
ACTION_SC_1);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, REQUEST_CODE_SC_1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
Service class
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
final String action = intent.getStringExtra(ACTION);
final Handler handler = new Handler();
final Timer timer = new Timer();
final TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Toast.makeText(MyAlarmService.this, "Running....", Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 1000, 5000); //execute in every 5000 msdo
// this.stopSelf();
} catch (Exception e) {
//TODO
}
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "Killed", Toast.LENGTH_LONG).show();
}
There are many ways to avoid killing of service...but we can not guarantee it. In low memory situations the service will be killed by the os. At this situation if you return
START_STICKY
this will restart the service with null intent. If you want the intent to be not null returnSTART_REDELIVER_INTENT
See the android docs here