title: Update and control multiple CountDownTimer in RecyclerView (pause, resume, delete)
body: <p>I've implemented to my Android app multiple countdown timers with Service. 
  CountDownTimer is running with service, thus data to fragment is being passed with BroadcastReceiver.</p>
  
  <p><strong>I would like to add each timer as a separate item to the RecyclerView in the fragment and be able to update it as timer is ticking and also to control it - pause, resume, add 1 min and delete.</strong> </p>
  
  <p>At the moment the <strong>problem</strong> is that <em>each second that timer is running, new item is added to RecyclerView</em> and I'm not able to control it - pause, resume and ect.</p>
  
  <p>Service Class:</p>
  
  <pre><code>public int onStartCommand(Intent intent, int flags, int startId) {
  
  
          if (intent.getAction().equals(Constants.ACTION.START_FOREGROUND_ACTION)){
  
              HandlerThread thread = new HandlerThread("ServiceStartArguments",
                      android.os.Process.THREAD_PRIORITY_BACKGROUND);
              thread.setName(nameOfFood);
              thread.start();
  
              mServiceLooper = thread.getLooper();
              mServiceHandler = new ServiceHandler(mServiceLooper);
      }
  
       private final class ServiceHandler extends Handler {
          public ServiceHandler(Looper looper) {
              super(looper);
  
          }
  
          @Override
          public void handleMessage(Message msg) {
              // Normally we would do some work here, like download a file.
  
              Thread.currentThread().setName(nameOfFood);
  
              try {
                  showCountDownTimer(enteredTimeFormatted);
              } catch (Exception e) {
                  // Restore interrupt status.
                  Thread.currentThread().interrupt();
              }
  
              stopSelf(msg.arg1);
          }
  
      private void showCountDownTimer(long number) {
  
          String normalStartTime = String.format(
                  "%02d:%02d:%02d",
                  TimeUnit.MILLISECONDS.toHours(number),
                  TimeUnit.MILLISECONDS.toMinutes(number) -
                          TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(number)),
                  TimeUnit.MILLISECONDS.toSeconds(number) -
                          TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(number)));
  
          Intent timerStartInfoIntent = new Intent(TIMER_START_INFO);
          timerStartInfoIntent.putExtra("VALUE", normalStartTime);
          timerStartInfoIntent.putExtra("NAME_FOOD", nameOfFood);
          LocalBroadcastManager.getInstance(NotificationService.this).sendBroadcast(timerStartInfoIntent);
  
  
          CountDownTimer timer = new CountDownTimer(number, 1000) {
  
              @Override
              public void onTick(long millisUntilFinished) {
                  timeLeft = millisUntilFinished;
  
  
                  counter = millisUntilFinished / 1000;
  
                  normalTime = String.format(
                          "%02d:%02d:%02d",
                          TimeUnit.MILLISECONDS.toHours(timeLeft),
                          TimeUnit.MILLISECONDS.toMinutes(timeLeft) -
                                  TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeLeft)),
                          TimeUnit.MILLISECONDS.toSeconds(timeLeft) -
                                  TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeLeft)));
  
                  Intent timerInfoIntent = new Intent(TIME_INFO);
                  timerInfoIntent.putExtra("VALUE", normalTime);
                  timerInfoIntent.putExtra("NAME_FOOD", nameOfFood);
                  LocalBroadcastManager.getInstance(NotificationService.this).sendBroadcast(timerInfoIntent);
  
              }
  
              @Override
              public void onFinish() {
                  counter = 0;
  
                  Intent timerFinishInfoIntent = new Intent(TIMER_FINISH_INFO);
                  LocalBroadcastManager.getInstance(NotificationService.this).sendBroadcast(timerFinishInfoIntent);
              }
          };
  
          timer.start();
      }
  </code></pre>
  
  <p>Adapter Class:</p>
  
  <pre><code>public class TimerRecyclerViewAdapter extends RecyclerView.Adapter&lt;TimerRecyclerViewAdapter.MyViewHolder&gt; {
  
  final private Context mContext;
  public List&lt;ModelTimer&gt; mModelTimerList;
  private final List&lt;MyViewHolder&gt; listHolder;
  
  
  public TimerRecyclerViewAdapter(List&lt;ModelTimer&gt; modelTimerList, Context context) {
      super();
      this.mContext = context;
      this.mModelTimerList = modelTimerList;
      listHolder = new ArrayList&lt;&gt;();
  }
  
  
  public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      public final TextView nameTextView;
      public final TextView timerTextView;
      public final Button pauseBtn;
      public final Button addMinBtn;
      public final Button deleteBtn;
      ModelTimer mModelTimer;
  
  
      public MyViewHolder(View itemView) {
          super(itemView);
          nameTextView = (TextView) itemView.findViewById(R.id.active_timer_name);
          timerTextView = (TextView) itemView.findViewById(R.id.active_timer_timeLeft);
          pauseBtn = (Button) itemView.findViewById(R.id.active_timer_btn_pause);
          pauseBtn.setOnClickListener(this);
          addMinBtn = (Button) itemView.findViewById(R.id.active_timer_btn_addMin);
          addMinBtn.setOnClickListener(this);
          deleteBtn = (Button) itemView.findViewById(R.id.active_timer_btn_delete);
          deleteBtn.setOnClickListener(this);
      }
  
      public void setData (ModelTimer modelTimer){
          this.mModelTimer = modelTimer;
          timerTextView.setText(modelTimer.expirationTime);
          nameTextView.setText(modelTimer.name);
      }
  
      @Override
      public void onClick(View v) {
        // TODO 
      }
  }
  
  @Override
  public TimerRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      if (parent instanceof RecyclerView) {
          View v = LayoutInflater.from(parent.getContext()).inflate(
                  R.layout.item_active_timer,
                  parent,
                  false);
          v.setFocusable(true);
          return new MyViewHolder(v);
      } else {
          throw new RuntimeException("No bound to RecyclerViewSelection");
      }
  }
  
  @Override
  public void onBindViewHolder(TimerRecyclerViewAdapter.MyViewHolder holder, int position) {
      holder.setData(mModelTimerList.get(position));
      synchronized (listHolder){
          listHolder.add(holder);
      }
  }
  
  @Override
  public int getItemCount() {
      return mModelTimerList.size();
  }
  </code></pre>
  
  <p>Here I tried to create a method that will be upgrading each second a timer on specific position instead of adding new item to RecyclerView each time that timer is ticking.</p>
  
  <pre><code>public void swap(List&lt;ModelTimer&gt; modelTimerList){
      mModelTimerList.clear();
      mModelTimerList.addAll(modelTimerList);
      notifyItemChanged(???);
  }
  
  public void delete() {
      mModelTimerList.clear();
      notifyDataSetChanged();
  }
  }
  </code></pre>
  
  <p>Fragment with RecyclerView:</p>
  
  <pre><code>public class ActiveTimersFragment extends Fragment {
  
  private RecyclerView mRecyclerView;
  private TimerRecyclerViewAdapter mAdapter;
  private ArrayList&lt;ModelTimer&gt; listOfTimers;
  private TimerStatusReceiver mTimerStatusReceiver;
  
  private static final String ARG_SECTION_NUMBER = "section_number";
  
  public ActiveTimersFragment() {
  }
  
  public static ActiveTimersFragment newInstance(int sectionNumber) {
      ActiveTimersFragment activeTimersFragment = new ActiveTimersFragment();
      Bundle args = new Bundle();
      args.putInt(ARG_SECTION_NUMBER, sectionNumber);
      activeTimersFragment.setArguments(args);
      return activeTimersFragment;
  }
  
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_active_timers, container, false);
  
      mRecyclerView = (RecyclerView) view.findViewById(R.id.fragment_active_timers_recycler_view);
      mTimerStatusReceiver = new TimerStatusReceiver();
  
      listOfTimers = new ArrayList&lt;&gt;();
  
      return view;
  }
  
  @Override
  public void onResume() {
      super.onResume();
      LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
              mTimerStatusReceiver, new IntentFilter(NotificationService.TIME_INFO));
      LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
              mTimerStatusReceiver, new IntentFilter(NotificationService.TIMER_START_INFO));
      LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
              mTimerStatusReceiver, new IntentFilter(NotificationService.TIMER_FINISH_INFO));
  
  }
  
  @Override
  public void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mTimerStatusReceiver);
  
  }
  
  private class TimerStatusReceiver extends BroadcastReceiver {
  
      @Override
      public void onReceive(Context context, Intent intent) {
  
          if (intent != null &amp;&amp; intent.getAction().equals(NotificationService.TIME_INFO)) {
  
              ModelTimer modelTimer = new ModelTimer();
  
              if (intent.hasExtra("VALUE")) {
                  modelTimer.setexpirationTime(intent.getStringExtra("VALUE"));
              }
              if (intent.hasExtra("NAME_FOOD")) {
                  modelTimer.setName(intent.getStringExtra("NAME_FOOD"));
              }
  
              listOfTimers.add(modelTimer);
              mAdapter = new TimerRecyclerViewAdapter(listOfTimers, getActivity());
              mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
              // Not working
              // mAdapter.swap(listOfTimers);
              mRecyclerView.setAdapter(mAdapter);
  
          }
  
          if (intent != null &amp;&amp; intent.getAction().equals(NotificationService.TIMER_FINISH_INFO)) {
              mAdapter.delete();
          }
  
      }
  }
  }
  </code></pre>