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