JNI_OnLoad
JNI_OnLoad

Reputation: 5442

Service timertask stop automatically android

I have service running in background with various timertask periodically with interval of 10 mins.

The the service works fine until the application is in foreground and the moment the app get killed the timertask behaves strangely for example not getting called in every 10 mins.

I saw it is common issue and I been through many answers but nothing seems to working for me. Here is my code snippets.Please guide me where I am wrong...

public class myService extends Service
{
@Override public void onCreate()
{
    super.onCreate();
    myServiceRunningBackground();
    service = myService.this;
    Log.d(TAG, "myServiceMain");
    myServiceRunningBackground();
    Message msgObj = serviceHandler.obtainMessage();
    serviceHandler.sendMessage(msgObj);
    running = true;
}

public final  Handler serviceHandler = new Handler()
{
    public void handleMessage(Message msg)
    {
        if(null != serviceTimer)
        {
            serviceTimer.cancel();
            serviceTimer.purge();
            serviceTimer = null;
        }
        serviceTimer = new Timer();

        serviceTimer.scheduleAtFixedRate(new myServiceMonitorPower(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
        serviceTimer.scheduleAtFixedRate(new myServiceMonitorLocation(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);

       /* if(target.equals(Target.SERVER))
        {*/
        serviceTimer.scheduleAtFixedRate(new myServiceMonitorTrafficStats(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
        // }

    }
};
@Override public int onStartCommand(Intent intent, int flags, int startId)
{
    if(intent != null)
    {      
        setTimerInfo(intent.getStringExtra("Current"));
        Message msgObj = serviceHandler.obtainMessage();
        serviceHandler.sendMessage(msgObj);
    }
    return START_STICKY;
}
@Override public IBinder onBind(Intent intent)
{
    return null;
}
@Override public boolean onUnbind(Intent intent)
{
    return super.onUnbind(intent);
}
@Override public void onRebind(Intent intent)
{
    super.onRebind(intent);
}
@Override public void onDestroy()
{
    super.onDestroy();
    running = false;
}

private void setTimerInfo(String check)
{
    if(check != null)
    {
        Log.d(TAG, "Check "+ check);
        if (check.equals("enable"))
        {
        //    alarm.SetAlarm(service, 5000);
            target = Target.DEVICE;
            DELAY_TIMER_TIME = 0;
            TIMER_START_TIME = 5000;
        }
        if (check.equals("disable"))
        {
         //   alarm.SetAlarm(service, 600000);
            myServiceRunningBackground();
            target = Target.SERVER;
            DELAY_TIMER_TIME = 300000;
            TIMER_START_TIME = 600000;
        }
    }
}

private void myServiceRunningBackground()
{
    Log.d(TAG,"esServcie  ");
    final int restartAlarmInterval = 600000;
    final int resetAlarmTimer = 2*30*1000;
    final Intent restartIntent = new Intent(this, myService.class);
    restartIntent.putExtra("ALARM_RESTART_SERVICE_DIED", true);
    final AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    Handler restartServiceHandler = new Handler()
    {
        @Override public void handleMessage(Message msg)
        {
            PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, restartIntent, 0);
          //  alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + restartAlarmInterval, pintent);
            alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pintent);
            sendEmptyMessageDelayed(0, resetAlarmTimer);
        }
    };
    restartServiceHandler.sendEmptyMessageDelayed(0, 0);

}

public enum Target
{
    SERVER,
    DEVICE
}
private static boolean running;
public Timer serviceTimer;
private static myService service; 

static Target target = null;

public  int DELAY_TIMER_TIME = 60000;
public  int TIMER_START_TIME = 600000;
private static final String TAG = "myService";

} SO I am using the Alarm manager as well, but does not seems like it is working. I want all the three timertask should be kept running when the application is in background which has the period of 10 mins.

To start and change the mode of services from 5 second to 10 mins I use below code from activity

  private void startServices() {
    Log.d(TAG, "StartServices ");
    Intent intent = new Intent(myActivity.this, myService.class);
    intent.putExtra("Current", "enable"); //disable for 10 mins on onDestroy 
    startService(intent);
}

Thanks for any suggestions

Upvotes: 2

Views: 2869

Answers (3)

Pradeep Bishnoi
Pradeep Bishnoi

Reputation: 1873

please see !!!

1.First of all you should save instance of service in Application file
2. You Can also use Alarm after few second if instance is live then no need start service other wise you have need again start SERVICE

It will be helpful for you

Upvotes: 0

mray190
mray190

Reputation: 506

EDIT: This doesn't act as a service. BUT, if anyone else wants code to run at a scheduled time not as a service, this will work

Overall application class:

public class ExampleApp extends Application {
    private SharedPreferences sharedPref;
    @Override
    public void onCreate() {
        super.onCreate();
        sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
    }
    private AlarmReceiver alarmReceiver;
    private void setAlarm(Long duration) {
        sharedPref.edit().putBoolean("alarmSet",true).apply();
        alarmReceiver = new AlarmReceiver();
        alarmReceiver.setTimer(this, duration);
    }

    public void cancelAlarm() {
        sharedPref.edit().putBoolean("alarmSet",false).apply();
        alarmReceiver.cancelTimer(this);
    }
}

AlarmReceiverClass

public class AlarmReceiver extends BroadcastReceiver {
    private PendingIntent pendingIntent;
    private AlarmManager alarmManager;
    private Intent intent;

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sharedPref = context.getSharedPreferences(context.getString(R.string.preference_file_key), Context.MODE_PRIVATE);
        sharedPref.edit().putBoolean("alarmSet",false).apply();
        //TODO: DO YOUR STUFF HERE
    }

    public void setTimer(Context context, Long addition) {
        alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        intent = new Intent(context, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + addition, pendingIntent);
}

    public void cancelTimer(Context context) {
        alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        intent = new Intent(context, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        alarmManager.cancel(pendingIntent);
    }
}

Start from any activity with:

((ExampleApp)getApplication()).setAlarm(10000);

Upvotes: 1

Anggrayudi H
Anggrayudi H

Reputation: 15165

You need to initialize three Timers for different schedule. From this snippet:

serviceTimer = new Timer();
serviceTimer.scheduleAtFixedRate(new myServiceMonitorPower(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
serviceTimer.scheduleAtFixedRate(new myServiceMonitorLocation(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
serviceTimer.scheduleAtFixedRate(new myServiceMonitorTrafficStats(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);

we can know that serviceTimer is completely confusing, which TimerTask will be scheduled. So the solution is, make sure that you initialize 3 Timers:

serviceTimer = new Timer();
timer2 = new Timer();
timer3 = new Timer();

serviceTimer.scheduleAtFixedRate(new myServiceMonitorPower(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
timer2.scheduleAtFixedRate(new myServiceMonitorLocation(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);
timer3.scheduleAtFixedRate(new myServiceMonitorTrafficStats(service, target), DELAY_TIMER_TIME, TIMER_START_TIME);

And cancel them once your Service get destroyed:

@Override
public void onDestroy(){
    running = false;
    serviceTimer.cancel();
    timer2.cancel();
    timer3.cancel();
    super.onDestroy();
}

Using AlarmManager for short time task may drains the user's battery, use Timer instead.

Upvotes: 0

Related Questions