diff options
author | Yorke Lee <yorkelee@google.com> | 2013-09-04 18:24:48 -0700 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2013-09-05 12:00:30 -0700 |
commit | e142481570d7fbda5d035555fe217314e396ae90 (patch) | |
tree | 3a8217bc8f657c77d177620693862afdd4ff637d /src/com/android/dialer/list | |
parent | 55d46030f7e08c60eb0f8d4d271db1a1329572dc (diff) |
Add call shortcuts to phone number list adapters
* Add a new class DialerPhoneNumberListAdapter, which both
RegularSearchListADapter and SmartDialNumberListAdapter extend.
DialerPhoneNumberListAdapter allows the addition of pre-defined call
shortcuts at the end of the phone number list that can be toggled
on or off.
* For the SmartDialSearchFragment, the only shortcut that is available is
always the Add number to contacts shortcut.
* For the RegularSearchFragment, if the user enters a string that contains
all dialable numbers, it is treated as a phone number and the call directly
and add number to contacts shortcuts are enabled. Otherwise, it is treated
as a name, and only the add contact with a new name shortcut is enabled.
* Add a intent that allows the user to directly create a new contact
that has the name field pre-populated. This intent is used if the user
enters input that looks like a name in the search view.
Bug: 10339630
Change-Id: I2ae757ce505d85a8780d28d89e09fb7084c773b1
Diffstat (limited to 'src/com/android/dialer/list')
5 files changed, 257 insertions, 2 deletions
diff --git a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java new file mode 100644 index 000000000..e9117107e --- /dev/null +++ b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java @@ -0,0 +1,188 @@ +package com.android.dialer.list; + +import android.content.Context; +import android.content.res.Resources; +import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; + +import com.android.contacts.common.GeoUtil; +import com.android.contacts.common.list.ContactListItemView; +import com.android.contacts.common.list.PhoneNumberListAdapter; +import com.android.dialer.R; + +/** + * {@link PhoneNumberListAdapter} with the following added shortcuts, that are displayed as list + * items: + * 1) Directly calling the phone number query + * 2) Adding the phone number query to a contact + * + * These shortcuts can be enabled or disabled to toggle whether or not they show up in the + * list. + */ +public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter { + + private String mFormattedQueryString; + private String mCountryIso; + + public final static int SHORTCUT_INVALID = -1; + public final static int SHORTCUT_DIRECT_CALL = 0; + public final static int SHORTCUT_ADD_NUMBER_TO_CONTACTS = 1; + public final static int SHORTCUT_ADD_NEW_NAMED_CONTACT = 2; + + public final static int SHORTCUT_COUNT = 3; + + private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT]; + + public DialerPhoneNumberListAdapter(Context context) { + super(context); + + mCountryIso = GeoUtil.getCurrentCountryIso(context); + + // Enable all shortcuts by default + for (int i = 0; i < mShortcutEnabled.length; i++) { + mShortcutEnabled[i] = true; + } + } + + @Override + public int getCount() { + return super.getCount() + getShortcutCount(); + } + + /** + * @return The number of enabled shortcuts. Ranges from 0 to a maximum of SHORTCUT_COUNT + */ + public int getShortcutCount() { + int count = 0; + for (int i = 0; i < mShortcutEnabled.length; i++) { + if (mShortcutEnabled[i]) count++; + } + return count; + } + + @Override + public int getItemViewType(int position) { + final int shortcut = getShortcutTypeFromPosition(position); + if (shortcut >= 0) { + // shortcutPos should always range from 1 to SHORTCUT_COUNT + return super.getViewTypeCount() + shortcut; + } else { + return super.getItemViewType(position); + } + } + + @Override + public int getViewTypeCount() { + // Number of item view types in the super implementation + 2 for the 2 new shortcuts + return super.getViewTypeCount() + SHORTCUT_COUNT; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final int shortcutType = getShortcutTypeFromPosition(position); + if (shortcutType >= 0) { + if (convertView != null) { + assignShortcutToView((ContactListItemView) convertView, shortcutType); + return convertView; + } else { + final ContactListItemView v = new ContactListItemView(getContext(), null); + assignShortcutToView(v, shortcutType); + return v; + } + } else { + return super.getView(position, convertView, parent); + } + } + + /** + * @param position The position of the item + * @return The enabled shortcut type matching the given position if the item is a + * shortcut, -1 otherwise + */ + public int getShortcutTypeFromPosition(int position) { + int shortcutCount = position - super.getCount(); + if (shortcutCount >= 0) { + // Iterate through the array of shortcuts, looking only for shortcuts where + // mShortcutEnabled[i] is true + for (int i = 0; shortcutCount >= 0 && i < mShortcutEnabled.length; i++) { + if (mShortcutEnabled[i]) { + shortcutCount--; + if (shortcutCount < 0) return i; + } + } + throw new IllegalArgumentException("Invalid position - greater than cursor count " + + " but not a shortcut."); + } + return SHORTCUT_INVALID; + } + + @Override + public boolean isEmpty() { + return getShortcutCount() == 0 && super.isEmpty(); + } + + @Override + public boolean isEnabled(int position) { + final int shortcutType = getShortcutTypeFromPosition(position); + if (shortcutType >= 0) { + return true; + } else { + return super.isEnabled(position); + } + } + + private void assignShortcutToView(ContactListItemView v, int shortcutType) { + final CharSequence text; + final int drawableId; + final Resources resources = getContext().getResources(); + final String number = getFormattedQueryString(); + switch (shortcutType) { + case SHORTCUT_DIRECT_CALL: + text = resources.getString(R.string.search_shortcut_call_number, number); + drawableId = R.drawable.ic_phone_dk; + break; + case SHORTCUT_ADD_NUMBER_TO_CONTACTS: + text = resources.getString(R.string.search_shortcut_add_to_contacts); + drawableId = R.drawable.ic_add_person_dk; + break; + case SHORTCUT_ADD_NEW_NAMED_CONTACT: + text = resources.getString(R.string.search_shortcut_add_to_contacts); + drawableId = R.drawable.ic_add_person_dk; + break; + default: + throw new IllegalArgumentException("Invalid shortcut type"); + } + v.setDrawableResource(R.drawable.list_item_avatar_bg, drawableId); + v.setDisplayName(text); + v.setPhotoPosition(super.getPhotoPosition()); + } + + public void setShortcutEnabled(int shortcutType, boolean visible) { + mShortcutEnabled[shortcutType] = visible; + } + + public String getFormattedQueryString() { + return mFormattedQueryString; + } + + @Override + public void setQueryString(String queryString) { + boolean containsNonDialableCharacters = false; + for (int i = 0; i < queryString.length(); i++) { + if (!PhoneNumberUtils.isDialable(queryString.charAt(i))) { + containsNonDialableCharacters = true; + break; + } + } + + if (containsNonDialableCharacters) { + mFormattedQueryString = null; + } else { + mFormattedQueryString = PhoneNumberUtils.formatNumber(queryString, mCountryIso); + } + + super.setQueryString(queryString); + } +} diff --git a/src/com/android/dialer/list/RegularSearchListAdapter.java b/src/com/android/dialer/list/RegularSearchListAdapter.java index 390dbb56c..627262ebe 100644 --- a/src/com/android/dialer/list/RegularSearchListAdapter.java +++ b/src/com/android/dialer/list/RegularSearchListAdapter.java @@ -19,6 +19,7 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; +import android.text.TextUtils; import com.android.contacts.common.list.DirectoryPartition; import com.android.contacts.common.list.PhoneNumberListAdapter; @@ -27,7 +28,7 @@ import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; /** * List adapter to display regular search results. */ -public class RegularSearchListAdapter extends PhoneNumberListAdapter { +public class RegularSearchListAdapter extends DialerPhoneNumberListAdapter { public RegularSearchListAdapter(Context context) { super(context); @@ -59,4 +60,16 @@ public class RegularSearchListAdapter extends PhoneNumberListAdapter { } return info; } + + @Override + public void setQueryString(String queryString) { + final boolean showNumberShortcuts = !TextUtils.isEmpty(getFormattedQueryString()); + setShortcutEnabled(SHORTCUT_DIRECT_CALL, showNumberShortcuts); + // Either one of the add contacts options should be enabled. If the user entered + // a dialable number, then clicking add to contact should add it as a number. + // Otherwise, it should add it to a new contact as a name. + setShortcutEnabled(SHORTCUT_ADD_NUMBER_TO_CONTACTS, showNumberShortcuts); + setShortcutEnabled(SHORTCUT_ADD_NEW_NAMED_CONTACT, !showNumberShortcuts); + super.setQueryString(queryString); + } } diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java index 54ee43600..0302d9724 100644 --- a/src/com/android/dialer/list/SearchFragment.java +++ b/src/com/android/dialer/list/SearchFragment.java @@ -16,12 +16,19 @@ package com.android.dialer.list; import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; +import android.widget.Toast; import com.android.contacts.common.list.ContactEntryListAdapter; import com.android.contacts.common.list.ContactListItemView; +import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; import com.android.contacts.common.list.PhoneNumberPickerFragment; +import com.android.dialer.DialtactsActivity; +import com.android.dialer.R; +import com.android.dialer.dialpad.DialpadFragment; import com.android.dialer.list.OnListFragmentScrolledListener; public class SearchFragment extends PhoneNumberPickerFragment { @@ -73,4 +80,46 @@ public class SearchFragment extends PhoneNumberPickerFragment { adapter.setHasHeader(0, false); } } + + @Override + protected ContactEntryListAdapter createListAdapter() { + DialerPhoneNumberListAdapter adapter = new DialerPhoneNumberListAdapter(getActivity()); + adapter.setDisplayPhotos(true); + adapter.setUseCallableUri(super.usesCallableUri()); + return adapter; + } + + @Override + protected void onItemClick(int position, long id) { + final DialerPhoneNumberListAdapter adapter = (DialerPhoneNumberListAdapter) getAdapter(); + final int shortcutType = adapter.getShortcutTypeFromPosition(position); + + if (shortcutType == DialerPhoneNumberListAdapter.SHORTCUT_INVALID) { + super.onItemClick(position, id); + } else if (shortcutType == DialerPhoneNumberListAdapter.SHORTCUT_DIRECT_CALL) { + final OnPhoneNumberPickerActionListener listener = + getOnPhoneNumberPickerListener(); + if (listener != null) { + listener.onCallNumberDirectly(getQueryString()); + } + } else if (shortcutType == DialerPhoneNumberListAdapter.SHORTCUT_ADD_NUMBER_TO_CONTACTS) { + final String number = adapter.getFormattedQueryString(); + final Intent intent = DialtactsActivity.getAddNumberToContactIntent(number); + startActivityWithErrorToast(intent); + } else if (shortcutType == DialerPhoneNumberListAdapter.SHORTCUT_ADD_NEW_NAMED_CONTACT) { + final String name = adapter.getQueryString(); + final Intent intent = DialtactsActivity.getInsertContactWithNameIntent(name); + startActivityWithErrorToast(intent); + } + } + + private void startActivityWithErrorToast(Intent intent) { + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast toast = Toast.makeText(getActivity(), R.string.add_contact_not_available, + Toast.LENGTH_SHORT); + toast.show(); + } + } } diff --git a/src/com/android/dialer/list/SmartDialNumberListAdapter.java b/src/com/android/dialer/list/SmartDialNumberListAdapter.java index c5ce59af2..962d8ee43 100644 --- a/src/com/android/dialer/list/SmartDialNumberListAdapter.java +++ b/src/com/android/dialer/list/SmartDialNumberListAdapter.java @@ -37,7 +37,7 @@ import java.util.ArrayList; /** * List adapter to display the SmartDial search results. */ -public class SmartDialNumberListAdapter extends PhoneNumberListAdapter{ +public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter { private static final String TAG = SmartDialNumberListAdapter.class.getSimpleName(); private static final boolean DEBUG = false; diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java index a163f5db7..4248c85fb 100644 --- a/src/com/android/dialer/list/SmartDialSearchFragment.java +++ b/src/com/android/dialer/list/SmartDialSearchFragment.java @@ -38,6 +38,11 @@ public class SmartDialSearchFragment extends SearchFragment { SmartDialNumberListAdapter adapter = new SmartDialNumberListAdapter(getActivity()); adapter.setUseCallableUri(super.usesCallableUri()); adapter.setQuickContactEnabled(true); + // Disable the direct call shortcut for the smart dial fragment, since the call button + // will already be showing anyway. + adapter.setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_DIRECT_CALL, false); + adapter.setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_ADD_NEW_NAMED_CONTACT, + false); return adapter; } |