RecipientsAdapter.java revision 5e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39
172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.ui;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20225e57fc21ad8c625dd0d5af19211b8d8ec2d157Tom Taylorimport com.android.common.ArrayListCursor;
214759133e3c935e751815bf4f997d029caa64d889Bai Taoimport com.android.mms.MmsApp;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R;
2320b79e068c8aebff46f24fd3803cf7697df4eac4Ficus Kirkpatrickimport com.android.mms.data.Contact;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.MergeCursor;
29afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikovimport android.net.Uri;
30afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikovimport android.provider.ContactsContract.Contacts;
31afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
325e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylorimport android.provider.ContactsContract.DataUsageFeedback;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.PhoneNumberUtils;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Annotation;
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Spannable;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableString;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ResourceCursorAdapter;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.TextView;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This adapter is used to filter contacts on both name and number.
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class RecipientsAdapter extends ResourceCursorAdapter {
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    public static final int CONTACT_ID_INDEX = 1;
50afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    public static final int TYPE_INDEX       = 2;
51afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    public static final int NUMBER_INDEX     = 3;
52afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    public static final int LABEL_INDEX      = 4;
53afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    public static final int NAME_INDEX       = 5;
544759133e3c935e751815bf4f997d029caa64d889Bai Tao    public static final int NORMALIZED_NUMBER = 6;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final String[] PROJECTION_PHONE = {
579caba7e7dd6de58e9aac69cd3eb04ee518e39b64Dmitri Plotnikov        Phone._ID,                  // 0
589caba7e7dd6de58e9aac69cd3eb04ee518e39b64Dmitri Plotnikov        Phone.CONTACT_ID,           // 1
59afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        Phone.TYPE,                 // 2
60afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        Phone.NUMBER,               // 3
61afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        Phone.LABEL,                // 4
629caba7e7dd6de58e9aac69cd3eb04ee518e39b64Dmitri Plotnikov        Phone.DISPLAY_NAME,         // 5
634759133e3c935e751815bf4f997d029caa64d889Bai Tao        Phone.NORMALIZED_NUMBER,    // 6
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
66afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov    private static final String SORT_ORDER = Contacts.TIMES_CONTACTED + " DESC,"
67afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            + Contacts.DISPLAY_NAME + "," + Phone.TYPE;
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final Context mContext;
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ContentResolver mContentResolver;
714759133e3c935e751815bf4f997d029caa64d889Bai Tao    private final String mDefaultCountryIso;
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public RecipientsAdapter(Context context) {
74f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        // Note that the RecipientsAdapter doesn't support auto-requeries. If we
75f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        // want to respond to changes in the contacts we're displaying in the drop-down,
76f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        // code using this adapter would have to add a line such as:
77f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        //   mRecipientsAdapter.setOnDataSetChangedListener(mDataSetChangedListener);
78f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        // See ComposeMessageActivity for an example.
79f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        super(context, R.layout.recipient_filter_item, null, false /* no auto-requery */);
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContext = context;
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentResolver = context.getContentResolver();
824759133e3c935e751815bf4f997d029caa64d889Bai Tao        mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public final CharSequence convertToString(Cursor cursor) {
879ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor        String number = cursor.getString(RecipientsAdapter.NUMBER_INDEX);
889ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor        if (number == null) {
899ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor            return "";
909ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor        }
919ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor        number = number.trim();
929ec8e53a995088b9413280868d77a801d1e4b8ecTom Taylor
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String name = cursor.getString(RecipientsAdapter.NAME_INDEX);
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int type = cursor.getInt(RecipientsAdapter.TYPE_INDEX);
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String label = cursor.getString(RecipientsAdapter.LABEL_INDEX);
97afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        CharSequence displayLabel = Phone.getDisplayLabel(mContext, type, label);
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (name == null) {
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            name = "";
101bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor        } else {
102bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // Names with commas are the bane of the recipient editor's existence.
103bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // We've worked around them by using spans, but there are edge cases
104bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // where the spans get deleted. Furthermore, having commas in names
105bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // can be confusing to the user since commas are used as separators
106bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // between recipients. The best solution is to simply remove commas
107bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor            // from names.
1081224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor            name = name.replace(", ", " ")
1091224b6560c48e146ee304f9c807296f6c22cdefbTom Taylor                       .replace(",", " ");  // Make sure we leave a space between parts of names.
110bdf9b796ffd86c9f4cbeff413f957a88a492f43fTom Taylor        }
111afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov
1124759133e3c935e751815bf4f997d029caa64d889Bai Tao        String nameAndNumber = Contact.formatNameAndNumber(
1134759133e3c935e751815bf4f997d029caa64d889Bai Tao                name, number, cursor.getString(NORMALIZED_NUMBER), mDefaultCountryIso);
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SpannableString out = new SpannableString(nameAndNumber);
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int len = out.length();
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!TextUtils.isEmpty(name)) {
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            out.setSpan(new Annotation("name", name), 0, len,
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            out.setSpan(new Annotation("name", number), 0, len,
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
126afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        String person_id = cursor.getString(RecipientsAdapter.CONTACT_ID_INDEX);
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        out.setSpan(new Annotation("person_id", person_id), 0, len,
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        out.setSpan(new Annotation("label", displayLabel.toString()), 0, len,
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        out.setSpan(new Annotation("number", number), 0, len,
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return out;
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public final void bindView(View view, Context context, Cursor cursor) {
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        TextView name = (TextView) view.findViewById(R.id.name);
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        name.setText(cursor.getString(NAME_INDEX));
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        TextView label = (TextView) view.findViewById(R.id.label);
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int type = cursor.getInt(TYPE_INDEX);
14417daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        CharSequence labelText = Phone.getDisplayLabel(mContext, type,
14517daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor                cursor.getString(LABEL_INDEX));
14617daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        // When there's no label, getDisplayLabel() returns a CharSequence of length==1 containing
14717daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        // a unicode non-breaking space. Need to check for that and consider that as "no label".
14817daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        if (labelText.length() == 0 ||
14917daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor                (labelText.length() == 1 && labelText.charAt(0) == '\u00A0')) {
15017daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor            label.setVisibility(View.GONE);
15117daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        } else {
15217daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor            label.setText(labelText);
15317daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor            label.setVisibility(View.VISIBLE);
15417daf81a930e664d254cabcef00981a4c9a1f785Tom Taylor        }
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        TextView number = (TextView) view.findViewById(R.id.number);
1574759133e3c935e751815bf4f997d029caa64d889Bai Tao        number.setText(
1584759133e3c935e751815bf4f997d029caa64d889Bai Tao                PhoneNumberUtils.formatNumber(cursor.getString(NUMBER_INDEX),
1594759133e3c935e751815bf4f997d029caa64d889Bai Tao                        cursor.getString(NORMALIZED_NUMBER), mDefaultCountryIso));
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String phone = "";
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String cons = null;
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (constraint != null) {
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            cons = constraint.toString();
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (usefulAsDigits(cons)) {
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                phone = PhoneNumberUtils.convertKeypadLettersToDigits(cons);
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (phone.equals(cons)) {
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    phone = "";
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    phone = phone.trim();
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1805e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor        Uri uri = Phone.CONTENT_FILTER_URI.buildUpon()
1815e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor                .appendPath(Uri.encode(cons))
1825e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
1835e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
1845e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor                .build();
1859cb9fd6e387ed9f7278d47bc8743c79b18bbeb5bMark Wagner        /*
1869cb9fd6e387ed9f7278d47bc8743c79b18bbeb5bMark Wagner         * if we decide to filter based on phone types use a selection
1879cb9fd6e387ed9f7278d47bc8743c79b18bbeb5bMark Wagner         * like this.
188f8d043174b15c48438c441635f29824bb525951bTom Taylor        String selection = String.format("%s=%s OR %s=%s OR %s=%s",
189f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE,
190f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE_MOBILE,
191f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE,
192f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE_WORK_MOBILE,
193f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE,
194f8d043174b15c48438c441635f29824bb525951bTom Taylor                Phone.TYPE_MMS);
1959cb9fd6e387ed9f7278d47bc8743c79b18bbeb5bMark Wagner         */
196afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov        Cursor phoneCursor =
1979efd5d4913cb4c4da7802cb1be922b32223141e6Wei Huang            mContentResolver.query(uri,
1989caba7e7dd6de58e9aac69cd3eb04ee518e39b64Dmitri Plotnikov                    PROJECTION_PHONE,
1999cb9fd6e387ed9f7278d47bc8743c79b18bbeb5bMark Wagner                    null, //selection,
2009efd5d4913cb4c4da7802cb1be922b32223141e6Wei Huang                    null,
2015e1c97e1f90901c48bfde61a1ddb5fbc7e0a0c39Tom Taylor                    null);
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (phone.length() > 0) {
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayList result = new ArrayList();
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            result.add(Integer.valueOf(-1));                    // ID
2069caba7e7dd6de58e9aac69cd3eb04ee518e39b64Dmitri Plotnikov            result.add(Long.valueOf(-1));                       // CONTACT_ID
207afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            result.add(Integer.valueOf(Phone.TYPE_CUSTOM));     // TYPE
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            result.add(phone);                                  // NUMBER
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            /*
211afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov             * The "\u00A0" keeps Phone.getDisplayLabel() from deciding
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             * to display the default label ("Home") next to the transformation
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             * of the letters into numbers.
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             */
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            result.add("\u00A0");                               // LABEL
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            result.add(cons);                                   // NAME
217368cefca7f9b1c3049cdc5d804dc5f10bce91607Tom Taylor            result.add(phone);                                  // NORMALIZED_NUMBER
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayList<ArrayList> wrap = new ArrayList<ArrayList>();
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            wrap.add(result);
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayListCursor translated = new ArrayListCursor(PROJECTION_PHONE, wrap);
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return new MergeCursor(new Cursor[] { translated, phoneCursor });
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return phoneCursor;
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Returns true if all the characters are meaningful as digits
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * in a phone number -- letters, digits, and a few punctuation marks.
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean usefulAsDigits(CharSequence cons) {
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int len = cons.length();
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < len; i++) {
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            char c = cons.charAt(i);
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
240afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            if ((c >= '0') && (c <= '9')) {
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                continue;
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
243afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            if ((c == ' ') || (c == '-') || (c == '(') || (c == ')') || (c == '.') || (c == '+')
244afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov                    || (c == '#') || (c == '*')) {
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                continue;
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
247afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            if ((c >= 'A') && (c <= 'Z')) {
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                continue;
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
250afab47f1ea6db50df7f045131fed5dba9cead6b0Dmitri Plotnikov            if ((c >= 'a') && (c <= 'z')) {
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                continue;
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
260