private void stopAlert(Alarm alarm) {
   mVibrator.cancel();
   mCondition.open();
   mNotificationManager.cancel(alarm.hashCode());
   Log.d(TAG, "Stoped the alert.: " + alarm.dump());
   stopSelf();
 }
 @Override
 public void onCreate() {
   Log.d(TAG, "Start onCreate()");
   mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
   mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
   mCondition = new ConditionVariable();
 }
 private void startAlert(Alarm alarm) {
   // TODO 勝手にアラートが停止するようなら、foregroundにすることを検討。
   // foregroundにする場合は目的地到着のNotificationもここで行うべきか。
   // APIではonStartCommand()の間はforegroundと定義されているので問題ない
   // はずだが。Vibratorのスレッドまで停止されることがあるかもしれない。
   // startForeground(id, notification);
   // stopForeground(removeNotification);
   mCondition.close();
   vibrate(alarm);
   Log.d(TAG, "Started the alert.: " + alarm.dump());
 }
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
   Log.d(TAG, "Start onStartCommand()");
   Alarm alarm = Alarm.find(intent.getExtras().getLong("alarm.id"));
   boolean isStop = intent.getExtras().getBoolean("action.stop"); // TODO Intent.ACTIONを使ったほうが良い?
   if (isStop) {
     stopAlert(alarm);
   } else {
     startAlert(alarm);
   }
   return START_NOT_STICKY;
 }
 @Override
 public void onDestroy() {
   Log.d(TAG, "Start onDestroy()");
 }