Home | History | Annotate | Download | only in com.example.android.wearable.timer
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.wearable.timer;
     18 
     19 import android.app.Activity;
     20 import android.app.AlarmManager;
     21 import android.app.Notification;
     22 import android.app.NotificationManager;
     23 import android.app.PendingIntent;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.res.Resources;
     27 import android.os.Bundle;
     28 import android.provider.AlarmClock;
     29 import android.support.wearable.view.WearableListView;
     30 import android.util.Log;
     31 import android.view.LayoutInflater;
     32 import android.view.ViewGroup;
     33 import android.widget.TextView;
     34 
     35 import com.example.android.wearable.timer.util.Constants;
     36 import com.example.android.wearable.timer.util.TimerFormat;
     37 
     38 /** This class sets a timer. */
     39 public class SetTimerActivity extends Activity implements WearableListView.ClickListener {
     40 
     41     public static final int NUMBER_OF_TIMES = 10;
     42     public static final String TAG = "SetTimerActivity";
     43 
     44     private ListViewItem[] mTimeOptions = new ListViewItem[NUMBER_OF_TIMES];
     45     private WearableListView mWearableListView;
     46 
     47 
     48     @Override
     49     public void onCreate(Bundle savedInstanceState) {
     50         super.onCreate(savedInstanceState);
     51 
     52         int paramLength = getIntent().getIntExtra(AlarmClock.EXTRA_LENGTH, 0);
     53         if (Log.isLoggable(TAG, Log.DEBUG)) {
     54             Log.d(TAG, "SetTimerActivity:onCreate=" + paramLength);
     55         }
     56         if (paramLength > 0 && paramLength <= 86400) {
     57             long durationMillis = paramLength * 1000;
     58             setupTimer(durationMillis);
     59             finish();
     60             return;
     61         }
     62 
     63         Resources res = getResources();
     64         for (int i = 0; i < NUMBER_OF_TIMES; i++) {
     65             mTimeOptions[i] = new ListViewItem(
     66                     res.getQuantityString(R.plurals.timer_minutes, i + 1, i + 1),
     67                     (i + 1) * 60 * 1000);
     68         }
     69 
     70         setContentView(R.layout.timer_set_timer);
     71 
     72         // Initialize a simple list of countdown time options.
     73         mWearableListView = (WearableListView) findViewById(R.id.times_list_view);
     74         mWearableListView.setAdapter(new TimerWearableListViewAdapter(this));
     75         mWearableListView.setClickListener(this);
     76     }
     77 
     78     /**
     79      * Sets up an alarm (and an associated notification) to go off after <code>duration</code>
     80      * milliseconds.
     81      */
     82     private void setupTimer(long duration) {
     83         NotificationManager notifyMgr =
     84                 ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
     85 
     86         // Delete dataItem and cancel a potential old countdown.
     87         cancelCountdown(notifyMgr);
     88 
     89         // Build notification and set it.
     90         notifyMgr.notify(Constants.NOTIFICATION_TIMER_COUNTDOWN, buildNotification(duration));
     91 
     92         // Register with the alarm manager to display a notification when the timer is done.
     93         registerWithAlarmManager(duration);
     94 
     95         finish();
     96     }
     97 
     98     @Override
     99     public void onClick(WearableListView.ViewHolder holder) {
    100         long duration = mTimeOptions[holder.getPosition()].duration;
    101         setupTimer(duration);
    102     }
    103 
    104     @Override
    105     public void onTopEmptyRegionClick() {
    106     }
    107 
    108     private void registerWithAlarmManager(long duration) {
    109         // Get the alarm manager.
    110         AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    111 
    112         // Create intent that gets fired when timer expires.
    113         Intent intent = new Intent(Constants.ACTION_SHOW_ALARM, null, this,
    114                 TimerNotificationService.class);
    115         PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
    116                 PendingIntent.FLAG_UPDATE_CURRENT);
    117 
    118         // Calculate the time when it expires.
    119         long wakeupTime = System.currentTimeMillis() + duration;
    120 
    121         // Schedule an alarm.
    122         alarm.setExact(AlarmManager.RTC_WAKEUP, wakeupTime, pendingIntent);
    123     }
    124 
    125     /**
    126      * Build a notification including different actions and other various setup and return it.
    127      *
    128      * @param duration the duration of the timer.
    129      * @return the notification to display.
    130      */
    131 
    132     private Notification buildNotification(long duration) {
    133         // Intent to restart a timer.
    134         Intent restartIntent = new Intent(Constants.ACTION_RESTART_ALARM, null, this,
    135                 TimerNotificationService.class);
    136         PendingIntent pendingIntentRestart = PendingIntent
    137                 .getService(this, 0, restartIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    138 
    139         // Intent to delete a timer.
    140         Intent deleteIntent = new Intent(Constants.ACTION_DELETE_ALARM, null, this,
    141                 TimerNotificationService.class);
    142         PendingIntent pendingIntentDelete = PendingIntent
    143                 .getService(this, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    144 
    145         // Create countdown notification using a chronometer style.
    146         return new Notification.Builder(this)
    147                 .setSmallIcon(R.drawable.ic_cc_alarm)
    148                 .setContentTitle(getString(R.string.timer_time_left))
    149                 .setContentText(TimerFormat.getTimeString(duration))
    150                 .setUsesChronometer(true)
    151                 .setWhen(System.currentTimeMillis() + duration)
    152                 .addAction(R.drawable.ic_cc_alarm, getString(R.string.timer_restart),
    153                         pendingIntentRestart)
    154                 .addAction(R.drawable.ic_cc_alarm, getString(R.string.timer_delete),
    155                         pendingIntentDelete)
    156                 .setDeleteIntent(pendingIntentDelete)
    157                 .setLocalOnly(true)
    158                 .build();
    159     }
    160 
    161     /**
    162      * Cancels an old countdown and deletes the dataItem.
    163      *
    164      * @param notifyMgr the notification manager.
    165      */
    166     private void cancelCountdown(NotificationManager notifyMgr) {
    167         notifyMgr.cancel(Constants.NOTIFICATION_TIMER_EXPIRED);
    168     }
    169 
    170     /** Model class for the listview. */
    171     private static class ListViewItem {
    172 
    173         // Duration in milliseconds.
    174         long duration;
    175         // Label to display.
    176         private String label;
    177 
    178         public ListViewItem(String label, long duration) {
    179             this.label = label;
    180             this.duration = duration;
    181         }
    182 
    183         @Override
    184         public String toString() {
    185             return label;
    186         }
    187     }
    188 
    189     private final class TimerWearableListViewAdapter extends WearableListView.Adapter {
    190         private final Context mContext;
    191         private final LayoutInflater mInflater;
    192 
    193         private TimerWearableListViewAdapter(Context context) {
    194             mContext = context;
    195             mInflater = LayoutInflater.from(context);
    196         }
    197 
    198         @Override
    199         public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    200             return new WearableListView.ViewHolder(
    201                     mInflater.inflate(R.layout.timer_list_item, null));
    202         }
    203 
    204         @Override
    205         public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
    206             TextView view = (TextView) holder.itemView.findViewById(R.id.time_text);
    207             view.setText(mTimeOptions[position].label);
    208             holder.itemView.setTag(position);
    209         }
    210 
    211         @Override
    212         public int getItemCount() {
    213             return NUMBER_OF_TIMES;
    214         }
    215     }
    216 
    217 }
    218