龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 移动开发 > Android开发 >

Android Wear计时器开发(3)

时间:2014-11-29 02:49来源:网络整理 作者:网络 点击:
分享到:
我们需要的就是newInstance()方法从SharedPreference中构造一个MatchTimer实例,我们还需要save()方法,可以帮我们把当前的计时器状态保存到SharedPreference中。 最后

我们需要的就是newInstance()方法从SharedPreference中构造一个MatchTimer实例,我们还需要save()方法,可以帮我们把当前的计时器状态保存到SharedPreference中。

最后我们要说明的是,如果某一部分持有MatchTimer对象的引用,但是其他对象已经改变了计时器的状态,就可能会发生异常(见下一篇文章)。所以我们还需要提供一些方法去注册和注销MatchTImer的实例,在Sharedpreference的值改变时去接收计时器状态的变化。

现在我们已经定义了一个基本的计时器了,下一篇文章我们会介绍怎么保持计时器的状态以及在需要的时候去唤醒这些状态。

Match Timer 可以在Google Play上下载:Match Timer.

在本系列前几篇文章中,我们介绍了Android Wear计时器app,对设计思路和app的结构进行了分析。本文将讲解如何定时唤醒程序提醒用户。

对于为什么不用后台服务的方式一直运行,我们已经进行了解释——这种方式非常耗电。因此,我们必须要有一个定时唤醒机制。我们可以使用AlarmManager来实现这个机制,定时执行一个Intent,然后通知BroadcastReceiver。之所以选择BroadcastReceiver而不用IntentService,是因为我们要运行的任务是轻量级的而且生命周期非常短暂。使用BroadcastReceiver可以避免每次执行任务的时候都经历Service的整个生命周期。因此,对于我们这种轻量级的任务来说非常合适——我们执行的任务都在毫秒级。

BroadcastReceiver的核心在于onReceiver方法,我们需要在这里安排各种事件响应。

 
  public class MatchTimerReceiver extends BroadcastReceiver {
  public static final int MINUTE_MILLIS = 60000;
  private static final long DURATION = 45 * MINUTE_MILLIS;
 
  private static final Intent UPDATE_INTENT = new Intent(ACTION_UPDATE);
  private static final Intent ELAPSED_ALARM = new Intent(ACTION_ELAPSED_ALARM);
  private static final Intent FULL_TIME_ALARM = new Intent(ACTION_FULL_TIME_ALARM);
 
  private static final int REQUEST_UPDATE = 1;
  private static final int REQUEST_ELAPSED = 2;
  private static final int REQUEST_FULL_TIME = 3;
 
  public static void setUpdate(Context context) {
    context.sendBroadcast(UPDATE_INTENT);
  }
  .
  .
  .
  private void reset(MatchTimer timer) {
    timer.reset();
  }
 
  private void resume(Context context, MatchTimer timer) {
    timer.resume();
    long playedEnd = timer.getStartTime() + timer.getTotalStoppages() + DURATION;
    if (playedEnd > System.currentTimeMillis()) {
      setAlarm(context, REQUEST_FULL_TIME, FULL_TIME_ALARM, playedEnd);
    }
  }
 
  private void pause(Context context, MatchTimer timer) {
    timer.pause();
    cancelAlarm(context, REQUEST_FULL_TIME, FULL_TIME_ALARM);
    long elapsedEnd = timer.getStartTime() + DURATION;
    if (!isAlarmSet(context, REQUEST_ELAPSED, ELAPSED_ALARM) && elapsedEnd > System.currentTimeMillis()) {
      setAlarm(context, REQUEST_ELAPSED, ELAPSED_ALARM, elapsedEnd);
    }
  }
 
  private void stop(Context context, MatchTimer timer) {
    timer.stop();
    cancelAlarm(context, REQUEST_UPDATE, UPDATE_INTENT);
    cancelAlarm(context, REQUEST_ELAPSED, ELAPSED_ALARM);
    cancelAlarm(context, REQUEST_FULL_TIME, FULL_TIME_ALARM);
  }
 
  private void start(Context context, MatchTimer timer) {
    timer.start();
    long elapsedEnd = timer.getStartTime() + DURATION;
    setRepeatingAlarm(context, REQUEST_UPDATE, UPDATE_INTENT);
    if (timer.getTotalStoppages() > 0 && !timer.isPaused()) {
      long playedEnd = timer.getStartTime() + timer.getTotalStoppages() + DURATION;
      if (playedEnd > System.currentTimeMillis()) {
        setAlarm(context, REQUEST_FULL_TIME, FULL_TIME_ALARM, playedEnd);
      }
      if (elapsedEnd > System.currentTimeMillis()) {
        setAlarm(context, REQUEST_ELAPSED, ELAPSED_ALARM, elapsedEnd);
      }
    } else {
      if (elapsedEnd > System.currentTimeMillis()) {
        setAlarm(context, REQUEST_FULL_TIME, FULL_TIME_ALARM, elapsedEnd);
      }
    }
  }
  .
  .
  .
  }
 

代码还是非常直观易于理解的。首先实例化一个MatchTimer对象(从SharedPreference中读取数据),然后分别传给对应的事件处理Handler。之后等待动作发生,最后更新Notification。

精彩图集

赞助商链接