diff options
author | Anne Rong <annerong@google.com> | 2015-09-18 17:28:38 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-09-18 17:28:38 +0000 |
commit | 59b2b5578aa8864b9fffd089f35a04d284d9e1c9 (patch) | |
tree | 6a1904c54296d2cb56c36dd328fa72402cbd9689 | |
parent | 91037cc532bfdbf991228c2d5ee7901bffb92be4 (diff) | |
parent | 6fb201a4f048e1a5763465a2e31f3a93e649fff7 (diff) |
Merge "Build management screen for managing blocked numbers." into ub-contactsdialer-a-dev
-rw-r--r-- | res/layout/blocked_number_fragment.xml | 56 | ||||
-rw-r--r-- | res/layout/blocked_number_header.xml | 40 | ||||
-rw-r--r-- | res/layout/blocked_number_item.xml | 75 | ||||
-rw-r--r-- | res/values/colors.xml | 7 | ||||
-rw-r--r-- | res/values/dimens.xml | 8 | ||||
-rw-r--r-- | res/values/strings.xml | 34 | ||||
-rw-r--r-- | src/com/android/dialer/calllog/CallLogListItemViewHolder.java | 2 | ||||
-rw-r--r-- | src/com/android/dialer/database/DialerDatabaseHelper.java | 6 | ||||
-rw-r--r-- | src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java | 2 | ||||
-rw-r--r-- | src/com/android/dialer/database/FilteredNumberContract.java | 2 | ||||
-rw-r--r-- | src/com/android/dialer/filterednumber/BlockedNumberAdapter.java | 148 | ||||
-rw-r--r-- | src/com/android/dialer/filterednumber/BlockedNumberFragment.java | 154 | ||||
-rw-r--r-- | src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java | 15 | ||||
-rw-r--r-- | src/com/android/dialer/settings/DialerSettingsActivity.java | 11 | ||||
-rw-r--r-- | src/com/android/dialer/util/PhoneNumberUtil.java | 43 |
15 files changed, 587 insertions, 16 deletions
diff --git a/res/layout/blocked_number_fragment.xml b/res/layout/blocked_number_fragment.xml new file mode 100644 index 000000000..b1e4d0f57 --- /dev/null +++ b/res/layout/blocked_number_fragment.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:card_view="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + android:background="@color/blocked_number_background" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <android.support.v7.widget.CardView + android:layout_width="match_parent" + android:layout_height="wrap_content" + card_view:cardCornerRadius="0dp"> + + <ListView android:id="@id/android:list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/background_dialer_white" + android:layout_weight="1" + android:drawSelectorOnTop="false" + android:headerDividersEnabled="false" /> + + <LinearLayout + android:id="@android:id/empty" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> + + <include layout="@layout/blocked_number_header" /> + + <TextView android:id="@id/android:empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingStart="@dimen/blocked_number_horizontal_margin" + android:paddingTop="@dimen/blocked_number_top_margin" + android:paddingBottom="@dimen/blocked_number_bottom_margin" + android:text="@string/listNoBlockedNumbers" /> + + </LinearLayout> + + </android.support.v7.widget.CardView> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/blocked_number_header.xml b/res/layout/blocked_number_header.xml new file mode 100644 index 000000000..fed94cc37 --- /dev/null +++ b/res/layout/blocked_number_header.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/textView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/blockList" + android:paddingStart="@dimen/blocked_number_horizontal_margin" + android:paddingTop="@dimen/blocked_number_top_margin" + android:paddingBottom="@dimen/blocked_number_bottom_margin" + android:textColor="@color/blocked_number_accent_color" + style="@android:style/TextAppearance.Material.Subhead" /> + + <Button + android:id="@+id/add_number_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/blockNumber" + android:layout_gravity="right" + android:textColor="@color/blocked_number_accent_color" + style="?android:attr/borderlessButtonStyle" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/blocked_number_item.xml b/res/layout/blocked_number_item.xml new file mode 100644 index 000000000..6c87533f1 --- /dev/null +++ b/res/layout/blocked_number_item.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/caller_information" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="@dimen/blocked_number_horizontal_margin" + android:paddingTop="@dimen/blocked_number_top_margin" + android:paddingBottom="@dimen/blocked_number_bottom_margin" + android:baselineAligned="false" + android:gravity="center_vertical" + android:orientation="horizontal" + android:focusable="true" + android:background="@color/background_dialer_white"> + + <QuickContactBadge + android:id="@+id/quick_contact_photo" + android:layout_width="@dimen/contact_photo_size" + android:layout_height="@dimen/contact_photo_size" + android:focusable="true" /> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center_vertical" + android:layout_marginStart="@dimen/blocked_number_horizontal_margin"> + + <TextView + android:id="@+id/caller_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/blocked_number_primary_text_color" + android:textSize="@dimen/blocked_number_primary_text_size" + android:includeFontPadding="false" + android:layout_marginBottom="5dp" + android:singleLine="true" /> + + <TextView + android:id="@+id/caller_number" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/blocked_number_secondary_text_color" + android:textSize="@dimen/blocked_number_secondary_text_size" + android:layout_marginBottom="1dp" + android:singleLine="true" /> + </LinearLayout> + + <ImageView + android:id="@+id/delete_button" + android:layout_width="@dimen/blocked_number_delete_icon_size" + android:layout_height="@dimen/blocked_number_delete_icon_size" + android:layout_marginEnd="16dp" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:src="@drawable/ic_remove" + android:scaleType="center" + android:tint="@color/delete_icon_tint" + android:contentDescription="@string/description_blocked_number_list_delete" /> + +</LinearLayout> diff --git a/res/values/colors.xml b/res/values/colors.xml index 8ce3c17ba..a747927d1 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -104,4 +104,11 @@ <color name="floating_action_button_touch_tint">#80ffffff</color> <color name="call_log_action_divider">#eeeeee</color> + + <!-- Colors for blocked numbers list --> + <color name="blocked_number_primary_text_color">@color/dialtacts_primary_text_color</color> + <color name="blocked_number_secondary_text_color">@color/dialtacts_secondary_text_color</color> + <color name="delete_icon_tint">#6D6D6D</color> + <color name="blocked_number_background">#E0E0E0</color> + <color name="blocked_number_accent_color">#42A5F5</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 776cd1150..b5acf2019 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -147,4 +147,12 @@ <dimen name="promo_card_line_spacing">4dp</dimen> <dimen name="voicemail_playback_top_padding">12dp</dimen> + + <!-- Size of entries in blocked numbers list --> + <dimen name="blocked_number_horizontal_margin">16dp</dimen> + <dimen name="blocked_number_top_margin">16dp</dimen> + <dimen name="blocked_number_bottom_margin">16dp</dimen> + <dimen name="blocked_number_primary_text_size">16sp</dimen> + <dimen name="blocked_number_secondary_text_size">12sp</dimen> + <dimen name="blocked_number_delete_icon_size">32dp</dimen> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 7bd88baef..093aa190e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -805,6 +805,40 @@ <!-- Label for the call settings section [CHAR LIMIT=30] --> <string name="call_settings_label">Calls</string> + <!-- Label for the blocked calls settings section [CHAR LIMIT=30] --> + <string name="blocked_calls_settings_label">Spam and blocked calls</string> + + <!-- String describing the delete icon on a blocked number list item. + When tapped, it will show a dialog confirming the unblocking of the number. + [CHAR LIMIT=NONE]--> + <string name="description_blocked_number_list_delete">Unblock number</string> + + <!-- Displayed in the blocked numbers list when there are no blocked numbers. + [CHAR LIMIT=NONE] --> + <string name="listNoBlockedNumbers">No blocked numbers</string> + + <!-- Button to bring up UI to add a number to the blocked call list. [CHAR LIMIT=40] --> + <string name="blockNumber">Add number</string> + + <!-- Heading for the block list in the "Spam and blocked calls" settings. [CHAR LIMIT=64] --> + <string name="blockList">Block list</string> + + <!-- Label for progress dialog when validating a number to be added to the block list. + [CHAR LIMIT=64] --> + <string name="checkingNumber">Checking + <xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> + </string> + + <!-- Error message shown when user tries to add invalid number to the block list. + [CHAR LIMIT=64] --> + <string name="invalidNumber"><xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> + is invalid.</string> + + <!-- Error message shown when user tries to add a number to the block list that was already + blocked. [CHAR LIMIT=64] --> + <string name="alreadyBlocked"><xliff:g id="number" example="(555) 555-5555">%1$s</xliff:g> + is already blocked.</string> + <!-- Label for the phone account settings [CHAR LIMIT=30] --> <string name="phone_account_settings_label">Calling accounts</string> diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java index 521b2a429..7fc62a222 100644 --- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java +++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java @@ -320,6 +320,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder FilterNumberDialogFragment.newInstance(blockId, info.normalizedNumber, number, countryIso, info.formattedNumber); newFragment.setQueryHandler(mFilteredNumberAsyncQueryHandler); + newFragment.setParentView( + ((Activity) mContext).findViewById(R.id.floating_action_button_container)); newFragment.show(((Activity) mContext).getFragmentManager(), FilterNumberDialogFragment.BLOCK_DIALOG_FRAGMENT); return true; diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java index d36a0f6d8..271afeed3 100644 --- a/src/com/android/dialer/database/DialerDatabaseHelper.java +++ b/src/com/android/dialer/database/DialerDatabaseHelper.java @@ -75,7 +75,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { * 0-98 KitKat * </pre> */ - public static final int DATABASE_VERSION = 6; + public static final int DATABASE_VERSION = 7; public static final String DATABASE_NAME = "dialer.db"; /** @@ -440,7 +440,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { return; } - if (oldVersion < 6) { + if (oldVersion < 7) { db.execSQL("DROP TABLE IF EXISTS " + Tables.FILTERED_NUMBER_TABLE); db.execSQL("CREATE TABLE " + Tables.FILTERED_NUMBER_TABLE + " (" + FilteredNumberColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," @@ -453,7 +453,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { + FilteredNumberColumns.TYPE + " INTEGER," + FilteredNumberColumns.SOURCE + " INTEGER" + ");"); - oldVersion = 6; + oldVersion = 7; } if (oldVersion != DATABASE_VERSION) { diff --git a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java index cedde27f6..061d62883 100644 --- a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java +++ b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java @@ -121,7 +121,7 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { isBlocked(listener, normalizedNumber); } - private String getNormalizedNumber(String number, String countryIso) { + public static String getNormalizedNumber(String number, String countryIso) { if (PhoneNumberHelper.isUriNumber(number)) { return number; } else { diff --git a/src/com/android/dialer/database/FilteredNumberContract.java b/src/com/android/dialer/database/FilteredNumberContract.java index 0ec171b15..38c49dc9d 100644 --- a/src/com/android/dialer/database/FilteredNumberContract.java +++ b/src/com/android/dialer/database/FilteredNumberContract.java @@ -61,7 +61,7 @@ public final class FilteredNumberContract { public interface FilteredNumberColumns { // TYPE: INTEGER - static final String _ID = "id"; + static final String _ID = "_id"; /** * Represents the number to be filtered, normalized to compare phone numbers for equality. * diff --git a/src/com/android/dialer/filterednumber/BlockedNumberAdapter.java b/src/com/android/dialer/filterednumber/BlockedNumberAdapter.java new file mode 100644 index 000000000..504b5205b --- /dev/null +++ b/src/com/android/dialer/filterednumber/BlockedNumberAdapter.java @@ -0,0 +1,148 @@ +/* + * 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.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.database.Cursor; +import android.provider.ContactsContract; +import android.text.BidiFormatter; +import android.text.TextDirectionHeuristics; +import android.text.TextUtils; +import android.view.View; +import android.widget.QuickContactBadge; +import android.widget.SimpleCursorAdapter; +import android.widget.TextView; + +import com.android.contacts.common.ContactPhotoManager; +import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; +import com.android.contacts.common.GeoUtil; +import com.android.contacts.common.util.UriUtils; +import com.android.dialer.R; +import com.android.dialer.calllog.ContactInfo; +import com.android.dialer.calllog.ContactInfoHelper; +import com.android.dialer.database.FilteredNumberAsyncQueryHandler; +import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; +import com.android.dialer.util.PhoneNumberUtil; + +public class BlockedNumberAdapter extends SimpleCursorAdapter { + + private Context mContext; + private ContactInfoHelper mContactInfoHelper; + private Resources mResources; + private BidiFormatter mBidiFormatter = BidiFormatter.getInstance(); + private ContactPhotoManager mContactPhotoManager; + private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; + + public BlockedNumberAdapter(Context context, + FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) { + super(context, R.layout.blocked_number_item, null, new String[]{}, new int[]{}, 0); + mContext = context; + mContactInfoHelper = new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context)); + mContactPhotoManager = ContactPhotoManager.getInstance(context); + mResources = context.getResources(); + mFilteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler; + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + super.bindView(view, context, cursor); + final TextView callerName = (TextView) view.findViewById(R.id.caller_name); + final TextView callerNumber = (TextView) view.findViewById(R.id.caller_number); + final View deleteNumber = view.findViewById(R.id.delete_button); + final QuickContactBadge quickContactBadge = + (QuickContactBadge) view.findViewById(R.id.quick_contact_photo); + quickContactBadge.setOverlay(null); + quickContactBadge.setPrioritizedMimeType( + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + + final Integer id = cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns._ID)); + final String countryIso = cursor.getString(cursor.getColumnIndex( + FilteredNumberColumns.COUNTRY_ISO)); + final String number = cursor.getString(cursor.getColumnIndex(FilteredNumberColumns.NUMBER)); + final String normalizedNumber = cursor.getString(cursor.getColumnIndex( + FilteredNumberColumns.NORMALIZED_NUMBER)); + final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso); + final CharSequence locationOrType = getNumberTypeOrLocation(info); + final String displayNumber = getDisplayNumber(info); + final String displayNumberStr = mBidiFormatter.unicodeWrap( + displayNumber.toString(), TextDirectionHeuristics.LTR); + + deleteNumber.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FilterNumberDialogFragment newFragment = + FilterNumberDialogFragment.newInstance(id, normalizedNumber, number, + countryIso, displayNumber); + newFragment.setQueryHandler(mFilteredNumberAsyncQueryHandler); + newFragment.setParentView(view); + newFragment.show(((Activity) mContext).getFragmentManager(), + FilterNumberDialogFragment.BLOCK_DIALOG_FRAGMENT); + } + }); + + String nameForDefaultImage; + if (!TextUtils.isEmpty(info.name)) { + nameForDefaultImage = info.name; + callerName.setText(info.name); + callerNumber.setText(locationOrType + " " + displayNumberStr); + } else { + nameForDefaultImage = displayNumber; + callerName.setText(displayNumberStr); + if (!TextUtils.isEmpty(locationOrType)) { + callerNumber.setText(locationOrType); + callerNumber.setVisibility(View.VISIBLE); + } else { + callerNumber.setVisibility(View.GONE); + } + } + loadContactPhoto(info, nameForDefaultImage, quickContactBadge); + } + + private void loadContactPhoto(ContactInfo info, String displayName, QuickContactBadge badge) { + final String lookupKey = info.lookupUri == null + ? null : UriUtils.getLookupKeyFromUri(info.lookupUri); + final int contactType = mContactInfoHelper.isBusiness(info.sourceType) + ? ContactPhotoManager.TYPE_BUSINESS : ContactPhotoManager.TYPE_DEFAULT; + final DefaultImageRequest request = new DefaultImageRequest(displayName, lookupKey, + contactType, true /* isCircular */); + badge.assignContactUri(info.lookupUri); + badge.setContentDescription( + mResources.getString(R.string.description_contact_details, displayName)); + mContactPhotoManager.loadDirectoryPhoto(badge, info.photoUri, + false /* darkTheme */, true /* isCircular */, request); + } + + private String getDisplayNumber(ContactInfo info) { + if (!TextUtils.isEmpty(info.formattedNumber)) { + return info.formattedNumber; + } else if (!TextUtils.isEmpty(info.number)) { + return info.number; + } else { + return ""; + } + } + + private CharSequence getNumberTypeOrLocation(ContactInfo info) { + if (!TextUtils.isEmpty(info.name)) { + return ContactsContract.CommonDataKinds.Phone.getTypeLabel(mResources, info.type, + info.label); + } else { + return PhoneNumberUtil.getGeoDescription(mContext, info.number); + } + } +} diff --git a/src/com/android/dialer/filterednumber/BlockedNumberFragment.java b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java new file mode 100644 index 000000000..a65013ac6 --- /dev/null +++ b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java @@ -0,0 +1,154 @@ +/* + * 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.AlertDialog; +import android.app.ListFragment; +import android.app.LoaderManager; +import android.content.CursorLoader; +import android.content.DialogInterface; +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 + LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener { + + private BlockedNumberAdapter mAdapter; + private FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + LayoutInflater inflater = LayoutInflater.from(getContext()); + getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null)); + mFilteredNumberAsyncQueryHandler = + new FilteredNumberAsyncQueryHandler(getActivity().getContentResolver()); + if (mAdapter == null) { + mAdapter = new BlockedNumberAdapter(getContext(), mFilteredNumberAsyncQueryHandler); + } + setListAdapter(mAdapter); + final Button addNumberBtn = (Button) getActivity().findViewById(R.id.add_number_button); + addNumberBtn.setOnClickListener(this); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + setListAdapter(null); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLoaderManager().initLoader(0, null, this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.blocked_number_fragment, container, false); + return view; + } + + @Override + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + final String[] projection = { + FilteredNumberContract.FilteredNumberColumns._ID, + FilteredNumberContract.FilteredNumberColumns.COUNTRY_ISO, + FilteredNumberContract.FilteredNumberColumns.NUMBER, + FilteredNumberContract.FilteredNumberColumns.NORMALIZED_NUMBER + }; + final String selection = FilteredNumberContract.FilteredNumberColumns.TYPE + + "=" + FilteredNumberContract.FilteredNumberTypes.BLOCKED_NUMBER; + final CursorLoader cursorLoader = new CursorLoader( + getContext(), FilteredNumberContract.FilteredNumber.CONTENT_URI, projection, + selection, null, null); + return cursorLoader; + } + + @Override + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + mAdapter.swapCursor(data); + } + + @Override + public void onLoaderReset(Loader<Cursor> loader) { + mAdapter.swapCursor(null); + } + + @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.isBlocked( + 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(); + } +}
\ No newline at end of file diff --git a/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java index f94d0f842..e9a88c845 100644 --- a/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java +++ b/src/com/android/dialer/filterednumber/FilterNumberDialogFragment.java @@ -39,11 +39,16 @@ public class FilterNumberDialogFragment extends DialogFragment { private static final String ARG_DISPLAY_NUMBER = "argDisplayNumber"; private FilteredNumberAsyncQueryHandler mHandler; + private View mParentView; public void setQueryHandler (FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) { mHandler = filteredNumberAsyncQueryHandler; } + public void setParentView(View view) { + mParentView = view; + } + public static FilterNumberDialogFragment newInstance(Integer blockId, String normalizedNumber, String number, String countryIso, String displayNumber) { final FilterNumberDialogFragment fragment = new FilterNumberDialogFragment(); @@ -91,7 +96,6 @@ public class FilterNumberDialogFragment extends DialogFragment { } public void blockNumber() { - final View view = getActivity().findViewById(R.id.floating_action_button_container); final String displayNumber = getArguments().getString(ARG_DISPLAY_NUMBER); final String message = getString(R.string.snackbar_number_blocked, displayNumber); final String undoMessage = getString(R.string.snackbar_number_unblocked, displayNumber); @@ -99,7 +103,7 @@ public class FilterNumberDialogFragment extends DialogFragment { new FilteredNumberAsyncQueryHandler.OnUnblockNumberListener() { @Override public void onUnblockComplete(int rows, ContentValues values) { - Snackbar.make(view, undoMessage, Snackbar.LENGTH_LONG).show(); + Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); } }; @@ -107,7 +111,7 @@ public class FilterNumberDialogFragment extends DialogFragment { new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() { @Override public void onBlockComplete(final Uri uri) { - Snackbar.make(view, message, Snackbar.LENGTH_LONG) + Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) .setAction(R.string.block_number_undo, // Delete the newly created row on 'undo'. new View.OnClickListener() { @@ -123,7 +127,6 @@ public class FilterNumberDialogFragment extends DialogFragment { } public void unblockNumber() { - final View view = getActivity().findViewById(R.id.floating_action_button_container); final String displayNumber = getArguments().getString(ARG_DISPLAY_NUMBER); final String message = getString(R.string.snackbar_number_unblocked, displayNumber); final String undoMessage = getString(R.string.snackbar_number_blocked, displayNumber); @@ -131,14 +134,14 @@ public class FilterNumberDialogFragment extends DialogFragment { new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() { @Override public void onBlockComplete(final Uri uri) { - Snackbar.make(view, undoMessage, Snackbar.LENGTH_LONG).show(); + Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); } }; mHandler.unblock( new FilteredNumberAsyncQueryHandler.OnUnblockNumberListener() { @Override public void onUnblockComplete(int rows, final ContentValues values) { - Snackbar.make(view, message, Snackbar.LENGTH_LONG) + Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) .setAction(R.string.block_number_undo, new View.OnClickListener() { // Re-insert the row on 'undo', with a new ID. diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java index 01a9fcf5f..2b7277224 100644 --- a/src/com/android/dialer/settings/DialerSettingsActivity.java +++ b/src/com/android/dialer/settings/DialerSettingsActivity.java @@ -15,24 +15,20 @@ */ package com.android.dialer.settings; -import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Process; import android.os.UserManager; -import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.provider.Settings; import android.telecom.TelecomManager; import android.telephony.TelephonyManager; -import android.util.Log; import android.view.MenuItem; import android.widget.Toast; -import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.R; +import com.android.dialer.filterednumber.BlockedNumberFragment; import java.util.List; @@ -90,6 +86,11 @@ public class DialerSettingsActivity extends AppCompatPreferenceActivity { target.add(phoneAccountSettingsHeader); } + Header blockedCallsHeader = new Header(); + blockedCallsHeader.titleRes = R.string.blocked_calls_settings_label; + blockedCallsHeader.fragment = BlockedNumberFragment.class.getName(); + target.add(blockedCallsHeader); + if (telephonyManager.isTtyModeSupported() || telephonyManager.isHearingAidCompatibilitySupported()) { Header accessibilitySettingsHeader = new Header(); diff --git a/src/com/android/dialer/util/PhoneNumberUtil.java b/src/com/android/dialer/util/PhoneNumberUtil.java index 84f58aa85..539d8b9ba 100644 --- a/src/com/android/dialer/util/PhoneNumberUtil.java +++ b/src/com/android/dialer/util/PhoneNumberUtil.java @@ -25,13 +25,19 @@ import android.util.Log; import android.util.Pair; import com.android.contacts.common.util.PhoneNumberHelper; +import com.android.contacts.common.util.TelephonyManagerUtils; import com.google.common.collect.Sets; +import com.google.i18n.phonenumbers.NumberParseException; +import com.google.i18n.phonenumbers.Phonenumber; +import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Set; public class PhoneNumberUtil { + private static final String TAG = "PhoneNumberUtil"; private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3"); /** Returns true if it is possible to place a call to the given number. */ @@ -92,4 +98,41 @@ public class PhoneNumberUtil { public static boolean isLegacyUnknownNumbers(CharSequence number) { return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString()); } + + /** + * @return a geographical description string for the specified number. + * @see com.android.i18n.phonenumbers.PhoneNumberOfflineGeocoder + */ + public static String getGeoDescription(Context context, String number) { + Log.v(TAG, "getGeoDescription('" + number + "')..."); + + if (TextUtils.isEmpty(number)) { + return null; + } + + com.google.i18n.phonenumbers.PhoneNumberUtil util = + com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance(); + PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance(); + + Locale locale = context.getResources().getConfiguration().locale; + String countryIso = TelephonyManagerUtils.getCurrentCountryIso(context, locale); + Phonenumber.PhoneNumber pn = null; + try { + Log.v(TAG, "parsing '" + number + + "' for countryIso '" + countryIso + "'..."); + pn = util.parse(number, countryIso); + Log.v(TAG, "- parsed number: " + pn); + } catch (NumberParseException e) { + Log.v(TAG, "getGeoDescription: NumberParseException for incoming number '" + + number + "'"); + } + + if (pn != null) { + String description = geocoder.getDescriptionForNumber(pn, locale); + Log.v(TAG, "- got description: '" + description + "'"); + return description; + } + + return null; + } } |