1/* 2 * Copyright (C) 2015 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 17package com.android.deskclock.alarms; 18 19import android.app.Activity; 20import android.app.Dialog; 21import android.app.DialogFragment; 22import android.app.Fragment; 23import android.app.FragmentManager; 24import android.app.FragmentTransaction; 25import android.os.Bundle; 26import android.text.format.DateFormat; 27import android.widget.TimePicker; 28 29import com.android.datetimepicker.time.RadialPickerLayout; 30import com.android.datetimepicker.time.TimePickerDialog; 31import com.android.deskclock.R; 32import com.android.deskclock.Utils; 33import com.android.deskclock.provider.Alarm; 34 35import java.util.Calendar; 36 37/** 38 * Displays and handles callback for time picker UI. 39 */ 40public final class TimePickerCompat { 41 42 /** 43 * Callback when a valid time is selected from UI. 44 */ 45 public interface OnTimeSetListener { 46 void processTimeSet(int hourOfDay, int minute); 47 } 48 49 // Tag for timer picker fragment in FragmentManager. 50 private static final String FRAG_TAG_TIME_PICKER = "time_dialog"; 51 52 // Do not instantiate. 53 private TimePickerCompat() {} 54 55 /** 56 * Pre-L implementation of timer picker UI. 57 */ 58 public static class TimerPickerPreL extends TimePickerDialog { 59 60 public static TimerPickerPreL newInstance(final Fragment targetFragment, final int hour, 61 final int minutes, final boolean use24hourFormat) { 62 final TimerPickerPreL dialog = new TimerPickerPreL(); 63 dialog.initialize(new OnTimeSetListener() { 64 @Override 65 public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) { 66 ((TimePickerCompat.OnTimeSetListener) targetFragment) 67 .processTimeSet(hourOfDay, minute); 68 } 69 }, hour, minutes, use24hourFormat); 70 dialog.setTargetFragment(targetFragment, 0); 71 dialog.setThemeDark(true); 72 return dialog; 73 } 74 75 @Override 76 public void onAttach(Activity activity) { 77 super.onAttach(activity); 78 if (getTargetFragment() instanceof TimePickerCompat.OnTimeSetListener) { 79 setOnTimeSetListener(new OnTimeSetListener() { 80 @Override 81 public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) { 82 ((TimePickerCompat.OnTimeSetListener) getTargetFragment()) 83 .processTimeSet(hourOfDay, minute); 84 } 85 }); 86 } 87 } 88 } 89 90 /** 91 * Post-L implmenetation of timer picker UI. 92 */ 93 public static class TimePickerPostL extends DialogFragment { 94 95 private Alarm mAlarm; 96 private android.app.TimePickerDialog.OnTimeSetListener mListener; 97 98 @Override 99 public Dialog onCreateDialog(Bundle savedInstanceState) { 100 final int hour, minute; 101 if (mAlarm == null) { 102 final Calendar c = Calendar.getInstance(); 103 hour = c.get(Calendar.HOUR_OF_DAY); 104 minute = c.get(Calendar.MINUTE); 105 } else { 106 hour = mAlarm.hour; 107 minute = mAlarm.minutes; 108 } 109 110 return new android.app.TimePickerDialog(getActivity(), R.style.TimePickerTheme, 111 mListener, hour, minute, DateFormat.is24HourFormat(getActivity())); 112 } 113 114 @Override 115 public void onAttach(Activity activity) { 116 super.onAttach(activity); 117 if (getTargetFragment() instanceof OnTimeSetListener) { 118 setOnTimeSetListener((OnTimeSetListener) getTargetFragment()); 119 } 120 } 121 122 public void setOnTimeSetListener(final OnTimeSetListener listener) { 123 mListener = new android.app.TimePickerDialog.OnTimeSetListener() { 124 @Override 125 public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 126 listener.processTimeSet(hourOfDay, minute); 127 } 128 }; 129 } 130 131 public void setAlarm(Alarm alarm) { 132 mAlarm = alarm; 133 } 134 } 135 136 /** 137 * Show the time picker dialog for post-L devices. 138 * This is called from AlarmClockFragment to set alarm. 139 * 140 * @param targetFragment The calling fragment (which is also a {@link OnTimeSetListener}), 141 * we use it as the target fragment of the time picker fragment, so later 142 * the latter can retrieve it and set it as its onTimeSetListener when 143 * the fragment is recreated. 144 * @param alarm The clicked alarm, it can be null if user was clicking the fab. 145 * @param use24hourFormat Whether or not the time picker should use 24-hour format if supported. 146 */ 147 public static void showTimeEditDialog(Fragment targetFragment, Alarm alarm, 148 boolean use24hourFormat) { 149 // Make sure the dialog isn't already added. 150 final FragmentManager manager = targetFragment.getFragmentManager(); 151 final FragmentTransaction ft = manager.beginTransaction(); 152 final Fragment prev = manager.findFragmentByTag(FRAG_TAG_TIME_PICKER); 153 if (prev != null) { 154 ft.remove(prev); 155 } 156 ft.commit(); 157 158 if (Utils.isLOrLater()) { 159 final TimePickerPostL picker = new TimePickerPostL(); 160 picker.setTargetFragment(targetFragment, 0); 161 picker.setOnTimeSetListener((OnTimeSetListener) targetFragment); 162 picker.setAlarm(alarm); 163 picker.show(manager, FRAG_TAG_TIME_PICKER); 164 } else { 165 final int hour, minutes; 166 if (alarm == null) { 167 hour = 0; 168 minutes = 0; 169 } else { 170 hour = alarm.hour; 171 minutes = alarm.minutes; 172 } 173 TimerPickerPreL picker = TimerPickerPreL.newInstance(targetFragment, hour, 174 minutes, use24hourFormat); 175 if (!picker.isAdded()) { 176 picker.show(manager, FRAG_TAG_TIME_PICKER); 177 } 178 } 179 } 180} 181