From e78b54ce7bbe51501e3c2a7f269bcdc0334d425a Mon Sep 17 00:00:00 2001 From: Anne Rong Date: Mon, 28 Sep 2015 11:18:42 -0700 Subject: Add search for adding blocked numbers to the blocked number management screen. Bug: 24134038 Change-Id: I30b283a6b67d7e64b58138762079c4bceb8fc64f --- AndroidManifest.xml | 7 + .../ic_not_interested_googblue_24dp.png | Bin 0 -> 565 bytes .../ic_not_interested_googblue_24dp.png | Bin 0 -> 377 bytes .../ic_not_interested_googblue_24dp.png | Bin 0 -> 755 bytes .../ic_not_interested_googblue_24dp.png | Bin 0 -> 1112 bytes .../ic_not_interested_googblue_24dp.png | Bin 0 -> 1458 bytes res/layout/search_activity.xml | 21 ++ res/values/dimens.xml | 1 + res/values/strings.xml | 7 + .../filterednumber/BlockedNumberFragment.java | 55 +---- .../BlockedNumberSearchActivity.java | 222 +++++++++++++++++++++ .../dialer/list/BlockedListSearchAdapter.java | 35 ++++ .../dialer/list/BlockedListSearchFragment.java | 62 ++++++ .../dialer/list/DialerPhoneNumberListAdapter.java | 7 +- .../dialer/list/RegularSearchListAdapter.java | 14 +- src/com/android/dialer/list/SearchFragment.java | 8 +- 16 files changed, 377 insertions(+), 62 deletions(-) create mode 100644 res/drawable-hdpi/ic_not_interested_googblue_24dp.png create mode 100644 res/drawable-mdpi/ic_not_interested_googblue_24dp.png create mode 100644 res/drawable-xhdpi/ic_not_interested_googblue_24dp.png create mode 100644 res/drawable-xxhdpi/ic_not_interested_googblue_24dp.png create mode 100644 res/drawable-xxxhdpi/ic_not_interested_googblue_24dp.png create mode 100644 res/layout/search_activity.xml create mode 100644 src/com/android/dialer/filterednumber/BlockedNumberSearchActivity.java create mode 100644 src/com/android/dialer/list/BlockedListSearchAdapter.java create mode 100644 src/com/android/dialer/list/BlockedListSearchFragment.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1faab2af4..e58d2ce9c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -148,6 +148,13 @@ android:exported="false"> + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index f71f12876..b36066a94 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -153,4 +153,5 @@ 16sp 12sp 32dp + 16sp diff --git a/res/values/strings.xml b/res/values/strings.xml index 093aa190e..c8b238f03 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -470,6 +470,10 @@ [CHAR LIMIT=30] --> Search contacts + + Add number or search contacts + sans-serif-light @@ -559,6 +563,9 @@ Make video call + + Block number + %s new missed calls diff --git a/src/com/android/dialer/filterednumber/BlockedNumberFragment.java b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java index 455982aef..de32fd612 100644 --- a/src/com/android/dialer/filterednumber/BlockedNumberFragment.java +++ b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java @@ -15,26 +15,19 @@ */ package com.android.dialer.filterednumber; -import android.app.AlertDialog; import android.app.ListFragment; import android.app.LoaderManager; import android.content.CursorLoader; -import android.content.DialogInterface; +import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; -import com.android.contacts.common.GeoUtil; -import com.android.contacts.common.dialog.IndeterminateProgressDialog; import com.android.dialer.R; import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener; import com.android.dialer.database.FilteredNumberContract; public class BlockedNumberFragment extends ListFragment implements @@ -105,50 +98,6 @@ public class BlockedNumberFragment extends ListFragment implements @Override public void onClick(final View v) { - final String countryIso = GeoUtil.getCurrentCountryIso(getContext()); - final EditText numberField = new EditText(getContext()); - final DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - final String number = numberField.getText().toString(); - final IndeterminateProgressDialog progressDialog = - IndeterminateProgressDialog.show(getFragmentManager(), - getString(R.string.checkingNumber, number), null, 1000); - final String normalizedNumber = - FilteredNumberAsyncQueryHandler.getNormalizedNumber(number, countryIso); - if (normalizedNumber == null) { - progressDialog.dismiss(); - Toast.makeText(getContext(), getString(R.string.invalidNumber, number), - Toast.LENGTH_LONG).show(); - } else { - final OnCheckBlockedListener onCheckListener = new OnCheckBlockedListener() { - @Override - public void onCheckComplete(Integer id) { - progressDialog.dismiss(); - if (id == null) { - FilterNumberDialogFragment newFragment = - FilterNumberDialogFragment.newInstance(id, normalizedNumber, - number, countryIso, number); - newFragment.setQueryHandler(mFilteredNumberAsyncQueryHandler); - newFragment.setParentView(v); - newFragment.show(getActivity().getFragmentManager(), - FilterNumberDialogFragment.BLOCK_DIALOG_FRAGMENT); - } else { - Toast.makeText(getContext(), - getString(R.string.alreadyBlocked, number), - Toast.LENGTH_LONG).show(); - } - } - }; - mFilteredNumberAsyncQueryHandler.startBlockedQuery( - onCheckListener, normalizedNumber, number, countryIso); - } - } - }; - new AlertDialog.Builder(getContext()) - .setTitle(getString(R.string.blockNumber)) - .setView(numberField) - .setPositiveButton(getString(R.string.blockNumberOk), okListener) - .setNegativeButton(android.R.string.cancel, null) - .show(); + startActivity(new Intent(getActivity(), BlockedNumberSearchActivity.class)); } } \ No newline at end of file diff --git a/src/com/android/dialer/filterednumber/BlockedNumberSearchActivity.java b/src/com/android/dialer/filterednumber/BlockedNumberSearchActivity.java new file mode 100644 index 000000000..5831ddc4a --- /dev/null +++ b/src/com/android/dialer/filterednumber/BlockedNumberSearchActivity.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.dialer.filterednumber; + +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.util.TypedValue; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; +import android.widget.Toast; + +import com.android.contacts.common.GeoUtil; +import com.android.contacts.common.dialog.IndeterminateProgressDialog; +import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; +import com.android.dialer.R; +import com.android.dialer.database.FilteredNumberAsyncQueryHandler; +import com.android.dialer.list.OnListFragmentScrolledListener; +import com.android.dialer.list.BlockedListSearchFragment; +import com.android.dialer.list.SearchFragment; +import com.android.dialer.widget.SearchEditTextLayout; + +public class BlockedNumberSearchActivity extends AppCompatActivity + implements SearchFragment.HostInterface, OnPhoneNumberPickerActionListener { + private static final String TAG = "BlockedNumberSearch"; + private static final String TAG_BLOCKED_SEARCH_FRAGMENT = "blocked_search"; + + private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; + private SearchFragment mSearchFragment; + private EditText mSearchView; + private ActionBar mActionBar; + private String mSearchQuery; + + private final TextWatcher mPhoneSearchQueryTextListener = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + final String newText = s.toString(); + if (newText.equals(mSearchQuery)) { + return; + } + mSearchQuery = newText; + mSearchFragment.setQueryString(mSearchQuery, false); + } + + @Override + public void afterTextChanged(Editable s) { + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mFilteredNumberAsyncQueryHandler = + new FilteredNumberAsyncQueryHandler(getContentResolver()); + + setContentView(R.layout.search_activity); + + mActionBar = getSupportActionBar(); + mActionBar.setCustomView(R.layout.search_edittext); + mActionBar.setBackgroundDrawable(null); + mActionBar.setDisplayShowCustomEnabled(true); + mActionBar.setDisplayHomeAsUpEnabled(false); + mActionBar.setDisplayShowHomeEnabled(false); + + final SearchEditTextLayout searchEditTextLayout = (SearchEditTextLayout) mActionBar + .getCustomView().findViewById(R.id.search_view_container); + searchEditTextLayout.expand(false, true); + searchEditTextLayout.setCallback(new SearchEditTextLayout.Callback() { + @Override + public void onBackButtonClicked() { + onBackPressed(); + } + + @Override + public void onSearchViewClicked() { + } + }); + + mSearchView = (EditText) searchEditTextLayout.findViewById(R.id.search_view); + mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener); + mSearchView.setHint(R.string.block_number_search_hint); + mSearchView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimension(R.dimen.blocked_number_search_text_size)); + + enterSearchUi(); + } + + private void enterSearchUi() { + if (mSearchFragment != null) { + return; + } + final FragmentTransaction transaction = getFragmentManager().beginTransaction(); + SearchFragment fragment = (SearchFragment) getFragmentManager() + .findFragmentByTag(TAG_BLOCKED_SEARCH_FRAGMENT); + if (fragment == null) { + fragment = new BlockedListSearchFragment(); + transaction.add(R.id.search_activity_container, fragment, TAG_BLOCKED_SEARCH_FRAGMENT); + } else { + transaction.show(fragment); + } + fragment.setHasOptionsMenu(false); + fragment.setShowEmptyListForNullQuery(true); + transaction.commit(); + } + + @Override + public void onAttachFragment(Fragment fragment) { + if (fragment instanceof BlockedListSearchFragment) { + mSearchFragment = (BlockedListSearchFragment) fragment; + mSearchFragment.setOnPhoneNumberPickerActionListener(this); + } + } + + @Override + public void onPickPhoneNumberAction(Uri dataUri, int callInitiationType) { + Log.w(TAG, "onPickPhoneNumberAction unsupported, ignoring."); + } + + @Override + public void onCallNumberDirectly( + String phoneNumber, boolean isVideoCall, int callInitiationType) { + blockNumber(phoneNumber); + } + + @Override + public void onShortcutIntentCreated(Intent intent) { + Log.w(TAG, "Unsupported intent has come (" + intent + "). Ignoring."); + } + + @Override + public void onHomeInActionBarSelected() { + } + + private void blockNumber(final String number) { + final String countryIso = GeoUtil.getCurrentCountryIso(BlockedNumberSearchActivity.this); + final IndeterminateProgressDialog progressDialog = + IndeterminateProgressDialog.show(getFragmentManager(), + getString(R.string.checkingNumber, number), null, 500); + final String normalizedNumber = + FilteredNumberAsyncQueryHandler.getNormalizedNumber(number, countryIso); + if (normalizedNumber == null) { + progressDialog.dismiss(); + Toast.makeText( + BlockedNumberSearchActivity.this, getString(R.string.invalidNumber, number), + Toast.LENGTH_SHORT).show(); + } else { + final FilteredNumberAsyncQueryHandler.OnCheckBlockedListener onCheckListener = + new FilteredNumberAsyncQueryHandler.OnCheckBlockedListener() { + @Override + public void onCheckComplete(Integer id) { + progressDialog.dismiss(); + if (id == null) { + final FilterNumberDialogFragment newFragment = + FilterNumberDialogFragment.newInstance(id, normalizedNumber, + number, countryIso, number); + newFragment.setQueryHandler(mFilteredNumberAsyncQueryHandler); + newFragment.setParentView( + findViewById(R.id.search_activity_container)); + newFragment.show(getFragmentManager(), + FilterNumberDialogFragment.BLOCK_DIALOG_FRAGMENT); + } else { + Toast.makeText(BlockedNumberSearchActivity.this, + getString(R.string.alreadyBlocked, number), + Toast.LENGTH_SHORT).show(); + } + } + }; + mFilteredNumberAsyncQueryHandler.startBlockedQuery( + onCheckListener, normalizedNumber, number, countryIso); + } + } + + @Override + public boolean isActionBarShowing() { + return true; + } + + @Override + public boolean isDialpadShown() { + return false; + } + + @Override + public int getDialpadHeight() { + return 0; + } + + @Override + public int getActionBarHideOffset() { + return getSupportActionBar().getHideOffset(); + } + + @Override + public int getActionBarHeight() { + return getResources().getDimensionPixelSize(R.dimen.action_bar_height_large); + } +} \ No newline at end of file diff --git a/src/com/android/dialer/list/BlockedListSearchAdapter.java b/src/com/android/dialer/list/BlockedListSearchAdapter.java new file mode 100644 index 000000000..52e0c646f --- /dev/null +++ b/src/com/android/dialer/list/BlockedListSearchAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.dialer.list; + +import android.content.Context; + +/** + * List adapter to display search results for adding a blocked number. + */ +public class BlockedListSearchAdapter extends RegularSearchListAdapter { + + public BlockedListSearchAdapter(Context context) { + super(context); + disableAllShortcuts(); + setShortcutEnabled(SHORTCUT_BLOCK_NUMBER, true); + } + + @Override + protected boolean isChanged(boolean showNumberShortcuts) { + return setShortcutEnabled(SHORTCUT_BLOCK_NUMBER, showNumberShortcuts || mIsQuerySipAddress); + } +} \ No newline at end of file diff --git a/src/com/android/dialer/list/BlockedListSearchFragment.java b/src/com/android/dialer/list/BlockedListSearchFragment.java new file mode 100644 index 000000000..bd1dd6f9e --- /dev/null +++ b/src/com/android/dialer/list/BlockedListSearchFragment.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.dialer.list; + +import android.util.Log; + +import com.android.contacts.common.list.ContactEntryListAdapter; +import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; + +public class BlockedListSearchFragment extends RegularSearchFragment { + private static final String TAG = BlockedListSearchFragment.class.getSimpleName(); + + @Override + protected ContactEntryListAdapter createListAdapter() { + BlockedListSearchAdapter adapter = new BlockedListSearchAdapter(getActivity()); + adapter.setDisplayPhotos(true); + adapter.setUseCallableUri(usesCallableUri()); + return adapter; + } + + @Override + protected void onItemClick(int position, long id) { + final DialerPhoneNumberListAdapter adapter = (DialerPhoneNumberListAdapter) getAdapter(); + final int shortcutType = adapter.getShortcutTypeFromPosition(position); + final OnPhoneNumberPickerActionListener listener = getOnPhoneNumberPickerListener(); + final String number; + + if (listener == null) { + Log.d(TAG, "getOnPhoneNumberPickerListener() returned null in onItemClick."); + return; + } + + switch (shortcutType) { + case DialerPhoneNumberListAdapter.SHORTCUT_INVALID: + // Handles click on a search result, either contact or nearby places result. + number = adapter.getPhoneNumber(position); + listener.onCallNumberDirectly(number, false, getCallInitiationType(false)); + break; + case DialerPhoneNumberListAdapter.SHORTCUT_BLOCK_NUMBER: + // Handles click on 'Block number' shortcut to add the user query as a number. + number = adapter.getQueryString(); + listener.onCallNumberDirectly(number, false, getCallInitiationType(false)); + break; + default: + Log.w(TAG, "Ignoring unsupported shortcut type: " + shortcutType); + break; + } + } +} diff --git a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java index 401b0b641..f56c6968a 100644 --- a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java +++ b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java @@ -33,8 +33,9 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter { public final static int SHORTCUT_ADD_TO_EXISTING_CONTACT = 2; public final static int SHORTCUT_SEND_SMS_MESSAGE = 3; public final static int SHORTCUT_MAKE_VIDEO_CALL = 4; + public final static int SHORTCUT_BLOCK_NUMBER = 5; - public final static int SHORTCUT_COUNT = 5; + public final static int SHORTCUT_COUNT = 6; private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT]; @@ -167,6 +168,10 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter { text = resources.getString(R.string.search_shortcut_make_video_call); drawableId = R.drawable.ic_videocam; break; + case SHORTCUT_BLOCK_NUMBER: + text = resources.getString(R.string.search_shortcut_block_number); + drawableId = R.drawable.ic_not_interested_googblue_24dp; + break; default: throw new IllegalArgumentException("Invalid shortcut type"); } diff --git a/src/com/android/dialer/list/RegularSearchListAdapter.java b/src/com/android/dialer/list/RegularSearchListAdapter.java index f431e6a44..748f4dcda 100644 --- a/src/com/android/dialer/list/RegularSearchListAdapter.java +++ b/src/com/android/dialer/list/RegularSearchListAdapter.java @@ -31,7 +31,7 @@ import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; * List adapter to display regular search results. */ public class RegularSearchListAdapter extends DialerPhoneNumberListAdapter { - private boolean mIsQuerySipAddress; + protected boolean mIsQuerySipAddress; public RegularSearchListAdapter(Context context) { super(context); @@ -84,16 +84,20 @@ public class RegularSearchListAdapter extends DialerPhoneNumberListAdapter { && hasDigitsInQueryString(); mIsQuerySipAddress = PhoneNumberHelper.isUriNumber(queryString); + if (isChanged(showNumberShortcuts)) { + notifyDataSetChanged(); + } + super.setQueryString(queryString); + } + + protected boolean isChanged(boolean showNumberShortcuts) { boolean changed = false; changed |= setShortcutEnabled(SHORTCUT_DIRECT_CALL, showNumberShortcuts || mIsQuerySipAddress); changed |= setShortcutEnabled(SHORTCUT_SEND_SMS_MESSAGE, showNumberShortcuts); changed |= setShortcutEnabled(SHORTCUT_MAKE_VIDEO_CALL, showNumberShortcuts && CallUtil.isVideoEnabled(getContext())); - if (changed) { - notifyDataSetChanged(); - } - super.setQueryString(queryString); + return changed; } /** diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java index 26ed117a4..f75fa0f83 100644 --- a/src/com/android/dialer/list/SearchFragment.java +++ b/src/com/android/dialer/list/SearchFragment.java @@ -106,8 +106,8 @@ public class SearchFragment extends PhoneNumberPickerFragment { try { mActivityScrollListener = (OnListFragmentScrolledListener) activity; } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() - + " must implement OnListFragmentScrolledListener"); + Log.d(TAG, activity.toString() + " doesn't implement OnListFragmentScrolledListener. " + + "Ignoring."); } } @@ -144,7 +144,9 @@ public class SearchFragment extends PhoneNumberPickerFragment { listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { - mActivityScrollListener.onListFragmentScrollStateChange(scrollState); + if (mActivityScrollListener != null) { + mActivityScrollListener.onListFragmentScrollStateChange(scrollState); + } } @Override -- cgit v1.2.3