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