2

I have a list of tasks that are displayed inside a RecyclerView. For each task I present an activity containing:

  • A play button that displays a chronometer when clicked
  • A done button to say a task is complete and to stop the service bound to the activity.
  • Various information

The user can stop a task to resume it later and launch various tasks at the same time.

I need to implement a Service to keep each chronometer running in the background during the lifetime of a task.

I followed the guidelines here : https://developer.android.com/guide/components/services.html

How can I create a unique service per task and display the chronometer back (with the elapsed time) when a previous task is selected by the user. What is the proper way to update an Activity second by second ?

public class TaskService extends Service {
    public static final String TAG = "TASK SERVICE";

    public static final String ACTION_TIMER = TaskService.class.getName() + "TIMER";

    private IBinder mBinderTask = new TimerTaskBinder();

    private Chronometer mChronometer;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommande: ");

        mChronometer = new Chronometer(this);
        mChronometer.setBase(SystemClock.elapsedRealtime());
        mChronometer.start();

        return START_STICKY; // Will be explicity started and stopped
    }


    public String getTimestamp() {
        long elapsedMillis = SystemClock.elapsedRealtime() - mChronometer.getBase();
        int hours = (int) (elapsedMillis / 3600000);
        int minutes = (int) (elapsedMillis - hours * 3600000) / 60000;
        int seconds = (int) (elapsedMillis - hours * 3600000 - minutes * 60000) / 1000;
        int millis = (int) (elapsedMillis - hours * 3600000 - minutes * 60000 - seconds * 1000);
        return hours + ":" + minutes + ":" + seconds + ":" + millis;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        return mBinderTask;
    }

    public class TimerTaskBinder extends Binder {
        public TaskService getService() {
            return TaskService.this;
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");

    }
}

Thanks

David Wasser
  • 93,459
  • 16
  • 209
  • 274
Jérôme
  • 403
  • 1
  • 3
  • 13

2 Answers2

0

I wouldn't create a service just to keep track of a timer. I would suggest storing the start time and the expected stop time of your task using SystemClock.elapsedRealtime(), and just setting the chronometer with the calculated time remaining every time the recyclerview becomes visible.

Pablo Baxter
  • 2,144
  • 1
  • 17
  • 36
0

Do not create a Service per task. Just create one Service and have it manage a list of tasks.

To communicate between the Service and the Activity you have multiple choices:

  • Use BroadcastReceiver. Your Activity creates a BroadcastReceiver and listens for broadcasts that are sent at intervals by your Service. The Service calls sendBroadcast() to broadcast events of interest. Hint: If your Activity and Service are running in the same OS process, you can use LocalBroadcastManager (it is a bit more efficient).
  • Use a bound Service. Bind your Activity to the Service and the Service can call back methods in the Activity as necessary.
  • Use an "Event Bus" implementation like Green Robot's EventBus library.
David Wasser
  • 93,459
  • 16
  • 209
  • 274