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