4

I'm trying to get a process timer to run and keep it running in the background on android (starts with a button click).

The timer must be on 30 seconds and should even continue growing application in the background (with home button and power / screen off).

How can I do this? I tried with service and handler but not working ...

EDIT

My service tracking (process with 30 sec)

public class TrackingService extends IntentService {

    private Handler mHandler;
    private Runnable mRunnable;

    public TrackingService() {

        super("TrackingService");

    }

    public TrackingService(String name) {

        super(name);

    }

    @Override
    protected void onHandleIntent(Intent intent) {

        long timer = 30000;

        mHandler = new Handler();
        mRunnable = new Runnable() {

            @Override
            public void run() {

                    //TODO - process with update timer for new 30 sec

                    mHandler.postDelayed(this, timer);

            }
        };

        mHandler.postDelayed(mRunnable, timer);

    }

}

My click button:

mButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        //TODO - start first time and it continued every 30 seconds and continue in the background
        startService(Intent intent = new Intent(this, TrackingService.class));

    }
});
VTR2015
  • 429
  • 2
  • 6
  • 15
  • Welcome to StackOverflow ! If you are looking for an answer to your question, you should consider giving us your approach first, so that we can help you understand what you are doing wrong/what to do. – YounesM Feb 23 '16 at 13:18
  • You can not run anything on a powered off device. Other than that, check `AlarmManager` and/or `JobScheduler` – F43nd1r Feb 23 '16 at 13:27
  • Something to keep in mind in regards to running something in the background, the Android OS retains the right to kill the background process at any time if it deems necessary. If it is a mission critical timer that has to be called, you may want to rethink your approach. – Charles Caldwell Feb 23 '16 at 13:38

2 Answers2

12

Ok, first of all, I really don't know if I got your question quite right. But I think you want a timer that's being executed every 30 seconds ,if i'm not mistaken. If so, do as following:

AlarmManager

Note: This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running. Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.

Example:

in your onClick() register your timer:

int repeatTime = 30;  //Repeat alarm time in seconds
AlarmManager processTimer = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, processTimerReceiver.class);   
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,  intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Repeat alarm every second
processTimer.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),repeatTime*1000, pendingIntent); 

And your processTimerReceiver class:

//This is called every second (depends on repeatTime)
public class processTimerReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        //Do something every 30 seconds
    }
}

Don't forget to register your receiver in your Manifest.XML

<receiver android:name="processTimer" >
   <intent-filter>
       <action android:name="processTimerReceiver" >
       </action>
   </intent-filter>
</receiver>

If you ever want to cancel the alarm: use this to do so:

//Cancel the alarm
Intent intent = new Intent(this, processTimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);

Hope this helps you out.

PS: if this is not exactly what u want, please leave it in the comments, or if someone wants to edit this, please do so.

Community
  • 1
  • 1
Strider
  • 4,452
  • 3
  • 24
  • 35
1

Oh god, don't ever use AlarmManager for 30s timers. It's kind of an overkill and also put a significant drain on device resources (battery, CPU...).

Perhaps you could try using a real background Service instead of IntentService as IntentService tends to shut itself down when it runs out of work. Not sure if this is the case here, but it's worth a try.

Zoran P
  • 336
  • 1
  • 9
  • I agree, **but** he wants his timer to continue no matter what, so the `AlarmManager` is the best option, dispite the battery drainage. for a better answer read [this](http://stackoverflow.com/a/7820613/4782930). – Strider Feb 23 '16 at 14:30
  • Yes, but if you need repeated 30s timer in the background even if the app is not running, then that's a poor app design. Triggering an alarm every 30s is really a bad design. – Zoran P Feb 23 '16 at 14:35
  • True, but I don't know if I got his question quitte right :P . So maybe that is not even exactly what he wants. What did u make of his question? I only wanted to push him in the right direction – Strider Feb 23 '16 at 14:36
  • 2
    I know he want a 30s timer to trigger even if app is in background (not sure what he means by power off). Background service will do the trick here up until the OS decides to kill it due to a lack of resources (low memory). Other then that it would be a better solution, unless the author want's something completely different here. – Zoran P Feb 23 '16 at 14:47
  • @ZoranP you said that it is a bad design, but let's say if I had to send my location almost in "realtime" to get some results based on, that location wouldn't be static, what is the best solution ? – Nathiel Barros Sep 12 '17 at 10:51
  • @Nathiel Start a background service when you want location update and do all the processing in it. Stop the service when you'r done with it. – Zoran P Oct 05 '17 at 07:33