CallEntryFormatter.java revision d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9
1/* 2 * Copyright (C) 2017 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.dialer.calllogutils; 18 19import android.content.Context; 20import android.icu.lang.UCharacter; 21import android.icu.text.BreakIterator; 22import android.os.Build.VERSION; 23import android.os.Build.VERSION_CODES; 24import android.text.format.DateUtils; 25import android.text.format.Formatter; 26import com.android.dialer.util.DialerUtils; 27import java.util.ArrayList; 28import java.util.List; 29import java.util.Locale; 30 31/** Utility class for formatting data and data usage in call log entries. */ 32public class CallEntryFormatter { 33 34 /** 35 * Formats the provided date into a value suitable for display in the current locale. 36 * 37 * <p>For example, returns a string like "Wednesday, May 25, 2016, 8:02PM" or "Chorshanba, 2016 38 * may 25,20:02". 39 * 40 * <p>For pre-N devices, the returned value may not start with a capital if the local convention 41 * is to not capitalize day names. On N+ devices, the returned value is always capitalized. 42 */ 43 public static CharSequence formatDate(Context context, long callDateMillis) { 44 CharSequence dateValue = 45 DateUtils.formatDateRange( 46 context, 47 callDateMillis /* startDate */, 48 callDateMillis /* endDate */, 49 DateUtils.FORMAT_SHOW_TIME 50 | DateUtils.FORMAT_SHOW_DATE 51 | DateUtils.FORMAT_SHOW_WEEKDAY 52 | DateUtils.FORMAT_SHOW_YEAR); 53 54 // We want the beginning of the date string to be capitalized, even if the word at the beginning 55 // of the string is not usually capitalized. For example, "Wednesdsay" in Uzbek is "chorshanba” 56 // (not capitalized). To handle this issue we apply title casing to the start of the sentence so 57 // that "chorshanba, 2016 may 25,20:02" becomes "Chorshanba, 2016 may 25,20:02". 58 // 59 // The ICU library was not available in Android until N, so we can only do this in N+ devices. 60 // Pre-N devices will still see incorrect capitalization in some languages. 61 if (VERSION.SDK_INT < VERSION_CODES.N) { 62 return dateValue; 63 } 64 65 // Using the ICU library is safer than just applying toUpperCase() on the first letter of the 66 // word because in some languages, there can be multiple starting characters which should be 67 // upper-cased together. For example in Dutch "ij" is a digraph in which both letters should be 68 // capitalized together. 69 70 // TITLECASE_NO_LOWERCASE is necessary so that things that are already capitalized like the 71 // month ("May") are not lower-cased as part of the conversion. 72 return UCharacter.toTitleCase( 73 Locale.getDefault(), 74 dateValue.toString(), 75 BreakIterator.getSentenceInstance(), 76 UCharacter.TITLECASE_NO_LOWERCASE); 77 } 78 79 private static CharSequence formatDuration(Context context, long elapsedSeconds) { 80 long minutes = 0; 81 long seconds = 0; 82 83 if (elapsedSeconds >= 60) { 84 minutes = elapsedSeconds / 60; 85 elapsedSeconds -= minutes * 60; 86 seconds = elapsedSeconds; 87 return context.getString(R.string.call_details_duration_format, minutes, seconds); 88 } else { 89 seconds = elapsedSeconds; 90 return context.getString(R.string.call_details_short_duration_format, seconds); 91 } 92 } 93 94 /** 95 * Formats a string containing the call duration and the data usage (if specified). 96 * 97 * @param elapsedSeconds Total elapsed seconds. 98 * @param dataUsage Data usage in bytes, or null if not specified. 99 * @return String containing call duration and data usage. 100 */ 101 public static CharSequence formatDurationAndDataUsage( 102 Context context, long elapsedSeconds, Long dataUsage) { 103 CharSequence duration = formatDuration(context, elapsedSeconds); 104 List<CharSequence> durationItems = new ArrayList<>(); 105 if (dataUsage != null) { 106 durationItems.add(duration); 107 durationItems.add(Formatter.formatShortFileSize(context, dataUsage)); 108 return DialerUtils.join(durationItems); 109 } else { 110 return duration; 111 } 112 } 113} 114