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