1 /* 2 * Copyright (C) 2020 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 package com.android.deskclock 17 18 import android.content.Context 19 import android.text.format.DateFormat 20 import android.text.format.DateUtils 21 import android.view.View 22 import android.widget.Toast 23 import androidx.annotation.VisibleForTesting 24 25 import com.android.deskclock.provider.AlarmInstance 26 import com.android.deskclock.widget.toast.SnackbarManager 27 import com.android.deskclock.widget.toast.ToastManager 28 29 import com.google.android.material.snackbar.Snackbar 30 31 import java.util.Calendar 32 import java.util.Locale 33 34 /** 35 * Static utility methods for Alarms. 36 */ 37 object AlarmUtils { 38 @JvmStatic getFormattedTimenull39 fun getFormattedTime(context: Context, time: Calendar): String { 40 val skeleton = if (DateFormat.is24HourFormat(context)) "EHm" else "Ehma" 41 val pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton) 42 return DateFormat.format(pattern, time) as String 43 } 44 45 @JvmStatic getFormattedTimenull46 fun getFormattedTime(context: Context, timeInMillis: Long): String { 47 val c = Calendar.getInstance() 48 c.timeInMillis = timeInMillis 49 return getFormattedTime(context, c) 50 } 51 52 @JvmStatic getAlarmTextnull53 fun getAlarmText(context: Context, instance: AlarmInstance, includeLabel: Boolean): String { 54 val alarmTimeStr: String = getFormattedTime(context, instance.alarmTime) 55 return if (instance.mLabel!!.isEmpty() || !includeLabel) { 56 alarmTimeStr 57 } else { 58 alarmTimeStr + " - " + instance.mLabel 59 } 60 } 61 62 /** 63 * format "Alarm set for 2 days, 7 hours, and 53 minutes from now." 64 */ 65 @VisibleForTesting formatElapsedTimeUntilAlarmnull66 fun formatElapsedTimeUntilAlarm(context: Context, delta: Long): String { 67 // If the alarm will ring within 60 seconds, just report "less than a minute." 68 var variableDelta = delta 69 val formats = context.resources.getStringArray(R.array.alarm_set) 70 if (variableDelta < DateUtils.MINUTE_IN_MILLIS) { 71 return formats[0] 72 } 73 74 // Otherwise, format the remaining time until the alarm rings. 75 76 // Round delta upwards to the nearest whole minute. (e.g. 7m 58s -> 8m) 77 val remainder = variableDelta % DateUtils.MINUTE_IN_MILLIS 78 variableDelta += if (remainder == 0L) 0 else DateUtils.MINUTE_IN_MILLIS - remainder 79 var hours = variableDelta.toInt() / (1000 * 60 * 60) 80 val minutes = variableDelta.toInt() / (1000 * 60) % 60 81 val days = hours / 24 82 hours %= 24 83 84 val daySeq = Utils.getNumberFormattedQuantityString(context, R.plurals.days, days) 85 val minSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.minutes, minutes) 86 val hourSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.hours, hours) 87 88 val showDays = days > 0 89 val showHours = hours > 0 90 val showMinutes = minutes > 0 91 92 // Compute the index of the most appropriate time format based on the time delta. 93 val index = ((if (showDays) 1 else 0) 94 or (if (showHours) 2 else 0) 95 or (if (showMinutes) 4 else 0)) 96 97 return String.format(formats[index], daySeq, hourSeq, minSeq) 98 } 99 100 @JvmStatic popAlarmSetToastnull101 fun popAlarmSetToast(context: Context, alarmTime: Long) { 102 val alarmTimeDelta = alarmTime - System.currentTimeMillis() 103 val text = formatElapsedTimeUntilAlarm(context, alarmTimeDelta) 104 val toast = Toast.makeText(context, text, Toast.LENGTH_LONG) 105 ToastManager.setToast(toast) 106 toast.show() 107 } 108 109 @JvmStatic popAlarmSetSnackbarnull110 fun popAlarmSetSnackbar(snackbarAnchor: View, alarmTime: Long) { 111 val alarmTimeDelta = alarmTime - System.currentTimeMillis() 112 val text = formatElapsedTimeUntilAlarm( 113 snackbarAnchor.context, alarmTimeDelta) 114 SnackbarManager.show(Snackbar.make(snackbarAnchor, text, Snackbar.LENGTH_SHORT)) 115 snackbarAnchor.announceForAccessibility(text) 116 } 117 }