• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.contacts.common.widget;
18 
19 import android.telecom.PhoneAccount;
20 import android.telecom.PhoneAccountHandle;
21 import android.app.AlertDialog;
22 import android.app.Dialog;
23 import android.app.DialogFragment;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.os.Bundle;
27 import android.os.Handler;
28 import android.os.ResultReceiver;
29 import android.telecom.TelecomManager;
30 import android.telephony.PhoneNumberUtils;
31 import android.text.TextUtils;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.ViewGroup;
35 import android.widget.ArrayAdapter;
36 import android.widget.CheckBox;
37 import android.widget.CompoundButton;
38 import android.widget.ImageView;
39 import android.widget.LinearLayout;
40 import android.widget.ListAdapter;
41 import android.widget.TextView;
42 
43 import com.android.contacts.common.R;
44 
45 import java.util.ArrayList;
46 import java.util.List;
47 
48 /**
49  * Dialog that allows the user to select a phone accounts for a given action. Optionally provides
50  * the choice to set the phone account as default.
51  */
52 public class SelectPhoneAccountDialogFragment extends DialogFragment {
53     private static final String ARG_TITLE_RES_ID = "title_res_id";
54     private static final String ARG_CAN_SET_DEFAULT = "can_set_default";
55     private static final String ARG_ACCOUNT_HANDLES = "account_handles";
56     private static final String ARG_IS_DEFAULT_CHECKED = "is_default_checked";
57     private static final String ARG_LISTENER = "listener";
58 
59     private int mTitleResId;
60     private boolean mCanSetDefault;
61     private List<PhoneAccountHandle> mAccountHandles;
62     private boolean mIsSelected;
63     private boolean mIsDefaultChecked;
64     private TelecomManager mTelecomManager;
65     private SelectPhoneAccountListener mListener;
66 
67     /**
68      * Create new fragment instance with default title and no option to set as default.
69      *
70      * @param accountHandles The {@code PhoneAccountHandle}s available to select from.
71      * @param listener The listener for the results of the account selection.
72      */
newInstance( List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener)73     public static SelectPhoneAccountDialogFragment newInstance(
74             List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener) {
75         return newInstance(R.string.select_account_dialog_title, false,
76                 accountHandles, listener);
77     }
78 
79     /**
80      * Create new fragment instance.
81      * This method also allows specifying a custom title and "set default" checkbox.
82      *
83      * @param titleResId The resource ID for the string to use in the title of the dialog.
84      * @param canSetDefault {@code true} if the dialog should include an option to set the selection
85      * as the default. False otherwise.
86      * @param accountHandles The {@code PhoneAccountHandle}s available to select from.
87      * @param listener The listener for the results of the account selection.
88      */
newInstance(int titleResId, boolean canSetDefault, List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener)89     public static SelectPhoneAccountDialogFragment newInstance(int titleResId,
90             boolean canSetDefault, List<PhoneAccountHandle> accountHandles,
91             SelectPhoneAccountListener listener) {
92         ArrayList<PhoneAccountHandle> accountHandlesCopy = new ArrayList<PhoneAccountHandle>();
93         if (accountHandles != null) {
94             accountHandlesCopy.addAll(accountHandles);
95         }
96         SelectPhoneAccountDialogFragment fragment = new SelectPhoneAccountDialogFragment();
97         final Bundle args = new Bundle();
98         args.putInt(ARG_TITLE_RES_ID, titleResId);
99         args.putBoolean(ARG_CAN_SET_DEFAULT, canSetDefault);
100         args.putParcelableArrayList(ARG_ACCOUNT_HANDLES, accountHandlesCopy);
101         args.putParcelable(ARG_LISTENER, listener);
102         fragment.setArguments(args);
103         fragment.setListener(listener);
104         return fragment;
105     }
106 
SelectPhoneAccountDialogFragment()107     public SelectPhoneAccountDialogFragment() {
108     }
109 
setListener(SelectPhoneAccountListener listener)110     public void setListener(SelectPhoneAccountListener listener) {
111         mListener = listener;
112     }
113 
114     public static class SelectPhoneAccountListener extends ResultReceiver {
115         static final int RESULT_SELECTED = 1;
116         static final int RESULT_DISMISSED = 2;
117 
118         static final String EXTRA_SELECTED_ACCOUNT_HANDLE = "extra_selected_account_handle";
119         static final String EXTRA_SET_DEFAULT = "extra_set_default";
120 
SelectPhoneAccountListener()121         public SelectPhoneAccountListener() {
122             super(new Handler());
123         }
124 
125         @Override
onReceiveResult(int resultCode, Bundle resultData)126         protected void onReceiveResult(int resultCode, Bundle resultData) {
127             if (resultCode == RESULT_SELECTED) {
128                 onPhoneAccountSelected(
129                         (PhoneAccountHandle) resultData.getParcelable(
130                                 EXTRA_SELECTED_ACCOUNT_HANDLE),
131                         resultData.getBoolean(EXTRA_SET_DEFAULT));
132             } else if (resultCode == RESULT_DISMISSED) {
133                 onDialogDismissed();
134             }
135         }
136 
onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, boolean setDefault)137         public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle,
138                 boolean setDefault) {}
139 
onDialogDismissed()140         public void onDialogDismissed() {}
141     }
142 
143     @Override
onSaveInstanceState(Bundle outState)144     public void onSaveInstanceState(Bundle outState) {
145         super.onSaveInstanceState(outState);
146         outState.putBoolean(ARG_IS_DEFAULT_CHECKED, mIsDefaultChecked);
147     }
148 
149     @Override
onCreateDialog(Bundle savedInstanceState)150     public Dialog onCreateDialog(Bundle savedInstanceState) {
151         mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
152         mCanSetDefault = getArguments().getBoolean(ARG_CAN_SET_DEFAULT);
153         mAccountHandles = getArguments().getParcelableArrayList(ARG_ACCOUNT_HANDLES);
154         mListener = getArguments().getParcelable(ARG_LISTENER);
155         if (savedInstanceState != null) {
156             mIsDefaultChecked = savedInstanceState.getBoolean(ARG_IS_DEFAULT_CHECKED);
157         }
158         mIsSelected = false;
159         mTelecomManager =
160                 (TelecomManager) getActivity().getSystemService(Context.TELECOM_SERVICE);
161 
162         final DialogInterface.OnClickListener selectionListener =
163                 new DialogInterface.OnClickListener() {
164             @Override
165             public void onClick(DialogInterface dialog, int which) {
166                 mIsSelected = true;
167                 PhoneAccountHandle selectedAccountHandle = mAccountHandles.get(which);
168                 final Bundle result = new Bundle();
169                 result.putParcelable(SelectPhoneAccountListener.EXTRA_SELECTED_ACCOUNT_HANDLE,
170                         selectedAccountHandle);
171                 result.putBoolean(SelectPhoneAccountListener.EXTRA_SET_DEFAULT,
172                         mIsDefaultChecked);
173                 if (mListener != null) {
174                     mListener.onReceiveResult(SelectPhoneAccountListener.RESULT_SELECTED, result);
175                 }
176             }
177         };
178 
179         final CompoundButton.OnCheckedChangeListener checkListener =
180                 new CompoundButton.OnCheckedChangeListener() {
181             @Override
182             public void onCheckedChanged(CompoundButton check, boolean isChecked) {
183                 mIsDefaultChecked = isChecked;
184             }
185         };
186 
187         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
188         ListAdapter selectAccountListAdapter = new SelectAccountListAdapter(
189                 builder.getContext(),
190                 R.layout.select_account_list_item,
191                 mAccountHandles);
192 
193         AlertDialog dialog = builder.setTitle(mTitleResId)
194                 .setAdapter(selectAccountListAdapter, selectionListener)
195                 .create();
196 
197         if (mCanSetDefault) {
198             // Generate custom checkbox view
199             LinearLayout checkboxLayout = (LinearLayout) getActivity()
200                     .getLayoutInflater()
201                     .inflate(R.layout.default_account_checkbox, null);
202 
203             CheckBox cb =
204                     (CheckBox) checkboxLayout.findViewById(R.id.default_account_checkbox_view);
205             cb.setOnCheckedChangeListener(checkListener);
206             cb.setChecked(mIsDefaultChecked);
207 
208             dialog.getListView().addFooterView(checkboxLayout);
209         }
210 
211         return dialog;
212     }
213 
214     private class SelectAccountListAdapter extends ArrayAdapter<PhoneAccountHandle> {
215         private int mResId;
216 
SelectAccountListAdapter( Context context, int resource, List<PhoneAccountHandle> accountHandles)217         public SelectAccountListAdapter(
218                 Context context, int resource, List<PhoneAccountHandle> accountHandles) {
219             super(context, resource, accountHandles);
220             mResId = resource;
221         }
222 
223         @Override
getView(int position, View convertView, ViewGroup parent)224         public View getView(int position, View convertView, ViewGroup parent) {
225             LayoutInflater inflater = (LayoutInflater)
226                     getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
227 
228             View rowView;
229             final ViewHolder holder;
230 
231             if (convertView == null) {
232                 // Cache views for faster scrolling
233                 rowView = inflater.inflate(mResId, null);
234                 holder = new ViewHolder();
235                 holder.labelTextView = (TextView) rowView.findViewById(R.id.label);
236                 holder.numberTextView = (TextView) rowView.findViewById(R.id.number);
237                 holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
238                 rowView.setTag(holder);
239             }
240             else {
241                 rowView = convertView;
242                 holder = (ViewHolder) rowView.getTag();
243             }
244 
245             PhoneAccountHandle accountHandle = getItem(position);
246             PhoneAccount account = mTelecomManager.getPhoneAccount(accountHandle);
247             if (account == null) {
248                 return rowView;
249             }
250             holder.labelTextView.setText(account.getLabel());
251             if (account.getAddress() == null ||
252                     TextUtils.isEmpty(account.getAddress().getSchemeSpecificPart())) {
253                 holder.numberTextView.setVisibility(View.GONE);
254             } else {
255                 holder.numberTextView.setVisibility(View.VISIBLE);
256                 holder.numberTextView.setText(
257                         PhoneNumberUtils.createTtsSpannable(
258                                 account.getAddress().getSchemeSpecificPart()));
259             }
260             holder.imageView.setImageDrawable(account.getIcon() != null
261                     ? account.getIcon().loadDrawable(getContext()) : null);
262             return rowView;
263         }
264 
265         private class ViewHolder {
266             TextView labelTextView;
267             TextView numberTextView;
268             ImageView imageView;
269         }
270     }
271 
272     @Override
onStop()273     public void onStop() {
274         if (!mIsSelected && mListener != null) {
275             mListener.onReceiveResult(SelectPhoneAccountListener.RESULT_DISMISSED, null);
276         }
277         super.onStop();
278     }
279 }
280