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

Android Wear计时器开发(4)

时间:2014-11-29 02:49来源:网络整理 作者:网络 点击:
分享到:
这里会处理8个事件动作,其中5个负责控制计时器的状态(START、STOP、PAUSE、RESUME、RESET);一个负责更新Notification,剩下两个负责到45分钟唤醒后震动提示

这里会处理8个事件动作,其中5个负责控制计时器的状态(START、STOP、PAUSE、RESUME、RESET);一个负责更新Notification,剩下两个负责到45分钟唤醒后震动提示。

我们先从这几个控制状态开始:

 
  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的状态,然后设置时间提醒的闹铃,改变参数就可以播放闹铃。这个功能还可以封装成一个工具方法,叫setUpdate()。这样外部也可以触发计时器的更新。

我们使用标准AlarmManager的方法来设置闹铃:

 
  public class MatchTimerReceiver extends BroadcastReceiver {
  .
  .
  .
  public static final int MINUTE_MILLIS = 60000;
  .
  .
  .
 
  private void setRepeatingAlarm(Context context, int requestCode, Intent intent) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), MINUTE_MILLIS, pendingIntent);
  }
 
  private boolean isAlarmSet(Context context, int requestCode, Intent intent) {
    return PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE) != null;
  }
 
  private void setAlarm(Context context, int requestCode, Intent intent, long time) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
  }
 
  private void cancelAlarm(Context context, int requestCode, Intent intent) {
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE);
    if (pendingIntent != null) {
      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      alarmManager.cancel(pendingIntent);
      pendingIntent.cancel();
    }
  }
  .
  .
  .
  }
 

这里值得讨论的是setRepeatingAlarm()这个方法。因为在Wear在实现方式上有点不一样。我们会在Start事件中每秒钟触发一次闹铃更新Notification动作,所以这里需要记录具体已经过去了多少分钟。正常来说我们会每隔60秒触发一次这个动作,但是在Wear上不能这么做。原因是——当设备在唤醒着的时候可以这样做,但是如果设备进入睡眠状态就需要重新计算下一分钟的边界值。这就需要异步更新部件,然后设备只需要每分钟唤醒一次。一分钟结束后在计时器需要更新状态的时候触发操作。

精彩图集

赞助商链接