2

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

JNI_OnLoad
  • 5,472
  • 4
  • 35
  • 60
  • 1
    OK, this code is seriously bizarre. `TimerTask`, `AlarmManager`, and a `Handler`, all in a service? You may have better luck if you explain, in words, what you are trying to accomplish with all of this. Is it that you want to get control every 10 minutes while your UI is in the foreground? While your process is running? All the time, even if Android terminates your process? Something else? – CommonsWare May 14 '15 at 23:25
  • But I use alarm manager coz timertask stop automatically...another reason to use alarm manager is that start_sticky does not work in android kitkat – JNI_OnLoad May 14 '15 at 23:38
  • Then get rid of `TimerTask` and just use `AlarmManager`. – CommonsWare May 14 '15 at 23:50
  • But I have current mode of 5 sec which may cause battery draining in this mode, the idea was to use alarm manager when app is in background as timers do not work on same android version. So I did not able to use them both efficiently and I have no idea how to use alarm manager for both 5 sec and 10 mins mode – JNI_OnLoad May 15 '15 at 05:11
  • I see you awarded a post the bounty. Did that answer your question? If so, please accept it as the answer so other people know it worked – mray190 Jun 24 '15 at 15:40

3 Answers3

1

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);
mray190
  • 496
  • 3
  • 13
0

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.

Anggrayudi H
  • 14,977
  • 11
  • 54
  • 87
  • But timers does not work in android kitkat when app is in background, and also I have 10 mins period when app is in background so I think alarm manager is best but I do not know how to use it – JNI_OnLoad May 15 '15 at 05:07
  • I have an app that uses `Timer` to schedule my `TimerTask`. My min SDK = 14, compile with API 21. Tested to KitKat & Lollipop, worked for me. I don't know your problem. – Anggrayudi H May 15 '15 at 12:08
  • I am talking about exactly this issue http://stackoverflow.com/questions/20636330/start-sticky-does-not-work-on-android-kitkat-edit-and-jelly-bean – JNI_OnLoad May 15 '15 at 21:22
0

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

Pradeep Bishnoi
  • 1,843
  • 2
  • 22
  • 26