SelectPhoneAccountDialogFragment.java revision 68a654db6f82a83fbcd71b61cc4fbb2b1cc1d7d1
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        ArrayList<PhoneAccountHandle> accountHandlesCopy = new ArrayList<PhoneAccountHandle>();
91        if (accountHandles != null) {
92            accountHandlesCopy.addAll(accountHandles);
93        }
94        SelectPhoneAccountDialogFragment fragment = new SelectPhoneAccountDialogFragment();
95        final Bundle args = new Bundle();
96        args.putInt(ARG_TITLE_RES_ID, titleResId);
97        args.putBoolean(ARG_CAN_SET_DEFAULT, canSetDefault);
98        args.putParcelableArrayList(ARG_ACCOUNT_HANDLES, accountHandlesCopy);
99        fragment.setArguments(args);
100        fragment.setListener(listener);
101        return fragment;
102    }
103
104    public SelectPhoneAccountDialogFragment() {
105    }
106
107    public void setListener(SelectPhoneAccountListener listener) {
108        mListener = listener;
109    }
110
111    public interface SelectPhoneAccountListener {
112        void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, boolean setDefault);
113        void onDialogDismissed();
114    }
115
116    @Override
117    public void onSaveInstanceState(Bundle outState) {
118        super.onSaveInstanceState(outState);
119        outState.putBoolean(ARG_IS_DEFAULT_CHECKED, mIsDefaultChecked);
120    }
121
122    @Override
123    public Dialog onCreateDialog(Bundle savedInstanceState) {
124        mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
125        mCanSetDefault = getArguments().getBoolean(ARG_CAN_SET_DEFAULT);
126        mAccountHandles = getArguments().getParcelableArrayList(ARG_ACCOUNT_HANDLES);
127        if (savedInstanceState != null) {
128            mIsDefaultChecked = savedInstanceState.getBoolean(ARG_IS_DEFAULT_CHECKED);
129        }
130        mIsSelected = false;
131        mTelecomManager =
132                (TelecomManager) getActivity().getSystemService(Context.TELECOM_SERVICE);
133
134        final DialogInterface.OnClickListener selectionListener =
135                new DialogInterface.OnClickListener() {
136            @Override
137            public void onClick(DialogInterface dialog, int which) {
138                mIsSelected = true;
139                PhoneAccountHandle selectedAccountHandle = mAccountHandles.get(which);
140                mListener.onPhoneAccountSelected(selectedAccountHandle, mIsDefaultChecked);
141            }
142        };
143
144        final CompoundButton.OnCheckedChangeListener checkListener =
145                new CompoundButton.OnCheckedChangeListener() {
146            @Override
147            public void onCheckedChanged(CompoundButton check, boolean isChecked) {
148                mIsDefaultChecked = isChecked;
149            }
150        };
151
152        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
153        ListAdapter selectAccountListAdapter = new SelectAccountListAdapter(
154                builder.getContext(),
155                R.layout.select_account_list_item,
156                mAccountHandles);
157
158        AlertDialog dialog = builder.setTitle(mTitleResId)
159                .setAdapter(selectAccountListAdapter, selectionListener)
160                .create();
161
162        if (mCanSetDefault) {
163            // Generate custom checkbox view
164            LinearLayout checkboxLayout = (LinearLayout) getActivity()
165                    .getLayoutInflater()
166                    .inflate(R.layout.default_account_checkbox, null);
167
168            CheckBox cb =
169                    (CheckBox) checkboxLayout.findViewById(R.id.default_account_checkbox_view);
170            cb.setOnCheckedChangeListener(checkListener);
171            cb.setChecked(mIsDefaultChecked);
172
173            dialog.getListView().addFooterView(checkboxLayout);
174        }
175
176        return dialog;
177    }
178
179    private class SelectAccountListAdapter extends ArrayAdapter<PhoneAccountHandle> {
180        private int mResId;
181
182        public SelectAccountListAdapter(
183                Context context, int resource, List<PhoneAccountHandle> accountHandles) {
184            super(context, resource, accountHandles);
185            mResId = resource;
186        }
187
188        @Override
189        public View getView(int position, View convertView, ViewGroup parent) {
190            LayoutInflater inflater = (LayoutInflater)
191                    getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
192
193            View rowView;
194            final ViewHolder holder;
195
196            if (convertView == null) {
197                // Cache views for faster scrolling
198                rowView = inflater.inflate(mResId, null);
199                holder = new ViewHolder();
200                holder.labelTextView = (TextView) rowView.findViewById(R.id.label);
201                holder.numberTextView = (TextView) rowView.findViewById(R.id.number);
202                holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
203                rowView.setTag(holder);
204            }
205            else {
206                rowView = convertView;
207                holder = (ViewHolder) rowView.getTag();
208            }
209
210            PhoneAccountHandle accountHandle = getItem(position);
211            PhoneAccount account = mTelecomManager.getPhoneAccount(accountHandle);
212            if (account == null) {
213                return rowView;
214            }
215            holder.labelTextView.setText(account.getLabel());
216            if (account.getAddress() == null ||
217                    TextUtils.isEmpty(account.getAddress().getSchemeSpecificPart())) {
218                holder.numberTextView.setVisibility(View.GONE);
219            } else {
220                holder.numberTextView.setVisibility(View.VISIBLE);
221                holder.numberTextView.setText(
222                        PhoneNumberUtils.getPhoneTtsSpannable(
223                                account.getAddress().getSchemeSpecificPart()));
224            }
225            holder.imageView.setImageDrawable(account.getIcon().loadDrawable(getContext()));
226            return rowView;
227        }
228
229        private class ViewHolder {
230            TextView labelTextView;
231            TextView numberTextView;
232            ImageView imageView;
233        }
234    }
235
236    @Override
237    public void onStop() {
238        if (!mIsSelected) {
239            mListener.onDialogDismissed();
240        }
241        super.onStop();
242    }
243}
244