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 package com.android.dialer.util; 17 18 import android.app.Activity; 19 import android.content.ActivityNotFoundException; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.content.res.Resources; 26 import android.graphics.Point; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.provider.Telephony; 30 import android.telecom.TelecomManager; 31 import android.text.TextUtils; 32 import android.view.View; 33 import android.view.inputmethod.InputMethodManager; 34 import android.widget.ImageView; 35 import android.widget.TextView; 36 import android.widget.Toast; 37 38 import com.android.contacts.common.ContactsUtils; 39 import com.android.contacts.common.interactions.TouchPointManager; 40 import com.android.dialer.R; 41 import com.android.incallui.CallCardFragment; 42 import com.android.incallui.Log; 43 44 import java.util.List; 45 import java.util.Locale; 46 47 /** 48 * General purpose utility methods for the Dialer. 49 */ 50 public class DialerUtils { 51 52 /** 53 * Attempts to start an activity and displays a toast with the default error message if the 54 * activity is not found, instead of throwing an exception. 55 * 56 * @param context to start the activity with. 57 * @param intent to start the activity with. 58 */ 59 public static void startActivityWithErrorToast(Context context, Intent intent) { 60 startActivityWithErrorToast(context, intent, R.string.activity_not_available); 61 } 62 63 /** 64 * Attempts to start an activity and displays a toast with a provided error message if the 65 * activity is not found, instead of throwing an exception. 66 * 67 * @param context to start the activity with. 68 * @param intent to start the activity with. 69 * @param msgId Resource ID of the string to display in an error message if the activity is 70 * not found. 71 */ 72 public static void startActivityWithErrorToast(Context context, Intent intent, int msgId) { 73 try { 74 if ((Intent.ACTION_CALL.equals(intent.getAction()) 75 || Intent.ACTION_CALL_PRIVILEGED.equals(intent.getAction())) 76 && context instanceof Activity) { 77 // All dialer-initiated calls should pass the touch point to the InCallUI 78 Point touchPoint = TouchPointManager.getInstance().getPoint(); 79 if (touchPoint.x != 0 || touchPoint.y != 0) { 80 Bundle extras = new Bundle(); 81 extras.putParcelable(TouchPointManager.TOUCH_POINT, touchPoint); 82 intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); 83 } 84 85 ((Activity) context).startActivityForResult(intent, 0); 86 } else { 87 context.startActivity(intent); 88 } 89 } catch (ActivityNotFoundException e) { 90 Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show(); 91 } 92 } 93 94 /** 95 * Returns the component name to use in order to send an SMS using the default SMS application, 96 * or null if none exists. 97 */ 98 public static ComponentName getSmsComponent(Context context) { 99 String smsPackage = Telephony.Sms.getDefaultSmsPackage(context); 100 if (smsPackage != null) { 101 final PackageManager packageManager = context.getPackageManager(); 102 final Intent intent = new Intent(Intent.ACTION_SENDTO, 103 Uri.fromParts(ContactsUtils.SCHEME_SMSTO, "", null)); 104 final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0); 105 for (ResolveInfo resolveInfo : resolveInfos) { 106 if (smsPackage.equals(resolveInfo.activityInfo.packageName)) { 107 return new ComponentName(smsPackage, resolveInfo.activityInfo.name); 108 } 109 } 110 } 111 return null; 112 } 113 114 /** 115 * Sets the image asset and text for an empty list view (see empty_list_view.xml). 116 * 117 * @param emptyListView The empty list view. 118 * @param imageResId The resource id for the drawable to set as the image. 119 * @param strResId The resource id for the string to set as the message. 120 * @param res The resources to obtain the image and string from. 121 */ 122 public static void configureEmptyListView( 123 View emptyListView, int imageResId, int strResId, Resources res) { 124 ImageView emptyListViewImage = 125 (ImageView) emptyListView.findViewById(R.id.emptyListViewImage); 126 127 emptyListViewImage.setImageDrawable(res.getDrawable(imageResId)); 128 emptyListViewImage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); 129 130 TextView emptyListViewMessage = 131 (TextView) emptyListView.findViewById(R.id.emptyListViewMessage); 132 emptyListViewMessage.setText(res.getString(strResId)); 133 } 134 135 /** 136 * Closes an {@link AutoCloseable}, silently ignoring any checked exceptions. Does nothing if 137 * null. 138 * 139 * @param closeable to close. 140 */ 141 public static void closeQuietly(AutoCloseable closeable) { 142 if (closeable != null) { 143 try { 144 closeable.close(); 145 } catch (RuntimeException rethrown) { 146 throw rethrown; 147 } catch (Exception ignored) { 148 } 149 } 150 } 151 152 /** 153 * Joins a list of {@link CharSequence} into a single {@link CharSequence} seperated by a 154 * localized delimiter such as ", ". 155 * 156 * @param resources Resources used to get list delimiter. 157 * @param list List of char sequences to join. 158 * @return Joined char sequences. 159 */ 160 public static CharSequence join(Resources resources, Iterable<CharSequence> list) { 161 final CharSequence separator = resources.getString(R.string.list_delimeter); 162 return TextUtils.join(separator, list); 163 } 164 165 /** 166 * @return True if the application is currently in RTL mode. 167 */ 168 public static boolean isRtl() { 169 return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == 170 View.LAYOUT_DIRECTION_RTL; 171 } 172 173 public static void showInputMethod(View view) { 174 final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( 175 Context.INPUT_METHOD_SERVICE); 176 if (imm != null) { 177 imm.showSoftInput(view, 0); 178 } 179 } 180 181 public static void hideInputMethod(View view) { 182 final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( 183 Context.INPUT_METHOD_SERVICE); 184 if (imm != null) { 185 imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 186 } 187 } 188 } 189