1f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov/* 2f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 3f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * 4f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * you may not use this file except in compliance with the License. 6f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * You may obtain a copy of the License at 7f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * 8f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * 10f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 12f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * See the License for the specific language governing permissions and 14f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * limitations under the License 15f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov */ 16f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor; 18f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 19f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.content.ContentResolver; 20f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.content.Context; 21d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikovimport android.database.ContentObserver; 22f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.database.Cursor; 23f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.net.Uri; 24f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.os.Handler; 25f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.os.HandlerThread; 26f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.os.Message; 27f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.os.Process; 28f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 29f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 30f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 31f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo; 32f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 33f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 34f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.Contacts.AggregationSuggestions; 35f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.Contacts.AggregationSuggestions.Builder; 36f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.provider.ContactsContract.Data; 37c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 38f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport android.text.TextUtils; 39f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 40851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta.ValuesDelta; 41e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.collect.Lists; 42e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 43f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.ArrayList; 44f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.Arrays; 45f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovimport java.util.List; 46f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 47f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov/** 48f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov * Runs asynchronous queries to obtain aggregation suggestions in the as-you-type mode. 49f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov */ 50f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikovpublic class AggregationSuggestionEngine extends HandlerThread { 51f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final String TAG = "AggregationSuggestionEngine"; 52f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 53f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public interface Listener { 54f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov void onAggregationSuggestionChange(); 55f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 56f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 57c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public static final class RawContact { 58c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public long rawContactId; 59c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public String accountType; 60c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public String accountName; 612b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro public String dataSet; 62c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov 63c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov @Override 64c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public String toString() { 652b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro return "ID: " + rawContactId + " account: " + accountType + "/" + accountName 662b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro + " dataSet: " + dataSet; 67c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 68c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 69c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov 70f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final class Suggestion { 71c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov 72f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public long contactId; 73f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String lookupKey; 74f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String name; 75f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String phoneNumber; 76f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String emailAddress; 77f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String nickname; 78f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public byte[] photo; 79c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public List<RawContact> rawContacts; 80f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 81f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 82f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public String toString() { 83c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov return "ID: " + contactId + " rawContacts: " + rawContacts + " name: " + name 84d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov + " phone: " + phoneNumber + " email: " + emailAddress + " nickname: " 85d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov + nickname + (photo != null ? " [has photo]" : ""); 86d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 87d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 88d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 89d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private final class SuggestionContentObserver extends ContentObserver { 90d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private SuggestionContentObserver(Handler handler) { 91d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov super(handler); 92d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 93d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 94d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov @Override 95d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov public void onChange(boolean selfChange) { 96d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov scheduleSuggestionLookup(); 97f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 98f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 99f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 100d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private static final int MESSAGE_RESET = 0; 101d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private static final int MESSAGE_NAME_CHANGE = 1; 102d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private static final int MESSAGE_DATA_CURSOR = 2; 103d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 104d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private static final long SUGGESTION_LOOKUP_DELAY_MILLIS = 300; 105d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 106d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private static final int MAX_SUGGESTION_COUNT = 3; 107d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 108d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private final Context mContext; 109d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 110d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private long[] mSuggestedContactIds = new long[0]; 111d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 112d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private Handler mMainHandler; 113d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private Handler mHandler; 114d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private long mContactId; 115d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private Listener mListener; 116d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private Cursor mDataCursor; 117d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private ContentObserver mContentObserver; 118d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov private Uri mSuggestionsUri; 119d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 120f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public AggregationSuggestionEngine(Context context) { 121f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov super("AggregationSuggestions", Process.THREAD_PRIORITY_BACKGROUND); 1222828c48cc4537fe981918f80297d5408bedc87b5Makoto Onuki mContext = context.getApplicationContext(); 123f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mMainHandler = new Handler() { 124f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 125f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void handleMessage(Message msg) { 126f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov AggregationSuggestionEngine.this.deliverNotification((Cursor) msg.obj); 127f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 128f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov }; 129f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 130f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 131f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov protected Handler getHandler() { 132f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mHandler == null) { 133f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mHandler = new Handler(getLooper()) { 134f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 135f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void handleMessage(Message msg) { 136f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov AggregationSuggestionEngine.this.handleMessage(msg); 137f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 138f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov }; 139f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 140f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return mHandler; 141f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 142f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 143f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void setContactId(long contactId) { 144916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov if (contactId != mContactId) { 145916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov mContactId = contactId; 146916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov reset(); 147916cf2661ada41a83556884d8f5b322d32ef452bDmitri Plotnikov } 148f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 149f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 150f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void setListener(Listener listener) { 151f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mListener = listener; 152f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 153f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 154f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov @Override 155f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public boolean quit() { 156f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mDataCursor != null) { 157f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mDataCursor.close(); 158f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 159f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mDataCursor = null; 160d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov if (mContentObserver != null) { 161d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContext.getContentResolver().unregisterContentObserver(mContentObserver); 162d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContentObserver = null; 163d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 164f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return super.quit(); 165f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 166f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 1679302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov public void reset() { 1689302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov Handler handler = getHandler(); 1699302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov handler.removeMessages(MESSAGE_NAME_CHANGE); 1709302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov handler.sendEmptyMessage(MESSAGE_RESET); 1719302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov } 1729302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov 173f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public void onNameChange(ValuesDelta values) { 174d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mSuggestionsUri = buildAggregationSuggestionUri(values); 175d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov if (mSuggestionsUri != null) { 176d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov if (mContentObserver == null) { 177d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContentObserver = new SuggestionContentObserver(getHandler()); 178d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContext.getContentResolver().registerContentObserver( 179d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov Contacts.CONTENT_URI, true, mContentObserver); 180d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 181d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } else if (mContentObserver != null) { 182d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContext.getContentResolver().unregisterContentObserver(mContentObserver); 183d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov mContentObserver = null; 184d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 185d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov scheduleSuggestionLookup(); 186d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov } 187d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov 188d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov protected void scheduleSuggestionLookup() { 189f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Handler handler = getHandler(); 190f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov handler.removeMessages(MESSAGE_NAME_CHANGE); 191f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 192d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov if (mSuggestionsUri == null) { 193f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return; 194f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 195f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 196d52121b61b71230d0f695f9d3891eaf0cbb7c549Dmitri Plotnikov Message msg = handler.obtainMessage(MESSAGE_NAME_CHANGE, mSuggestionsUri); 197f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov handler.sendMessageDelayed(msg, SUGGESTION_LOOKUP_DELAY_MILLIS); 198f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 199f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 200f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private Uri buildAggregationSuggestionUri(ValuesDelta values) { 201f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov StringBuilder nameSb = new StringBuilder(); 202f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(nameSb, values, StructuredName.PREFIX); 203f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(nameSb, values, StructuredName.GIVEN_NAME); 204f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(nameSb, values, StructuredName.MIDDLE_NAME); 205f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(nameSb, values, StructuredName.FAMILY_NAME); 206f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(nameSb, values, StructuredName.SUFFIX); 207f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 208c9916d303cc48b4a4ff94ef9c56d7ca5da72c4deDmitri Plotnikov if (nameSb.length() == 0) { 209c9916d303cc48b4a4ff94ef9c56d7ca5da72c4deDmitri Plotnikov appendValue(nameSb, values, StructuredName.DISPLAY_NAME); 210c9916d303cc48b4a4ff94ef9c56d7ca5da72c4deDmitri Plotnikov } 211c9916d303cc48b4a4ff94ef9c56d7ca5da72c4deDmitri Plotnikov 212f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov StringBuilder phoneticNameSb = new StringBuilder(); 213f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(phoneticNameSb, values, StructuredName.PHONETIC_FAMILY_NAME); 214f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(phoneticNameSb, values, StructuredName.PHONETIC_MIDDLE_NAME); 215f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov appendValue(phoneticNameSb, values, StructuredName.PHONETIC_GIVEN_NAME); 216f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 217f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (nameSb.length() == 0 && phoneticNameSb.length() == 0) { 218f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return null; 219f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 220f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 221f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Builder builder = AggregationSuggestions.builder() 222f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov .setLimit(MAX_SUGGESTION_COUNT) 223f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov .setContactId(mContactId); 224f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 225f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (nameSb.length() != 0) { 226f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov builder.addParameter(AggregationSuggestions.PARAMETER_MATCH_NAME, nameSb.toString()); 227f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 228f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 229f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (phoneticNameSb.length() != 0) { 230f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov builder.addParameter( 231f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov AggregationSuggestions.PARAMETER_MATCH_NAME, phoneticNameSb.toString()); 232f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 233f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 234f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return builder.build(); 235f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 236f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 237f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private void appendValue(StringBuilder sb, ValuesDelta values, String column) { 238f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov String value = values.getAsString(column); 239f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!TextUtils.isEmpty(value)) { 240f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (sb.length() > 0) { 241f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.append(' '); 242f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 243f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.append(value); 244f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 245f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 246f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 247f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov protected void handleMessage(Message msg) { 2489302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov switch (msg.what) { 2499302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov case MESSAGE_RESET: 2509302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov mSuggestedContactIds = new long[0]; 2519302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov break; 252f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov case MESSAGE_NAME_CHANGE: 253f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov loadAggregationSuggestions((Uri) msg.obj); 254f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov break; 255f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 256f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 257f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 258f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private static final class DataQuery { 259f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 260f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final String SELECTION_PREFIX = 261f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.MIMETYPE + " IN ('" 262f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + Phone.CONTENT_ITEM_TYPE + "','" 263f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + Email.CONTENT_ITEM_TYPE + "','" 264f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + StructuredName.CONTENT_ITEM_TYPE + "','" 265f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + Nickname.CONTENT_ITEM_TYPE + "','" 266f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + Photo.CONTENT_ITEM_TYPE + "')" 267f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov + " AND " + Data.CONTACT_ID + " IN ("; 268f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 269f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final String[] COLUMNS = { 270f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data._ID, 271f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.CONTACT_ID, 272f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.LOOKUP_KEY, 273f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.PHOTO_ID, 274f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.DISPLAY_NAME, 275f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.RAW_CONTACT_ID, 276f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.MIMETYPE, 277f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.DATA1, 278f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Data.IS_SUPER_PRIMARY, 279f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Photo.PHOTO, 280c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 281c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 2822b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro RawContacts.DATA_SET 283f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov }; 284f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 285f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int ID = 0; 286f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int CONTACT_ID = 1; 287f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int LOOKUP_KEY = 2; 288f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int PHOTO_ID = 3; 289f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int DISPLAY_NAME = 4; 290f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int RAW_CONTACT_ID = 5; 291f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int MIMETYPE = 6; 292f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int DATA1 = 7; 293f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int IS_SUPERPRIMARY = 8; 294f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public static final int PHOTO = 9; 295c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public static final int ACCOUNT_TYPE = 10; 296c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public static final int ACCOUNT_NAME = 11; 2972b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro public static final int DATA_SET = 12; 298f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 299f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 300f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private void loadAggregationSuggestions(Uri uri) { 301f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov ContentResolver contentResolver = mContext.getContentResolver(); 302f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Cursor cursor = contentResolver.query(uri, new String[]{Contacts._ID}, null, null, null); 303f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov try { 304f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov // If a new request is pending, chuck the result of the previous request 305f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (getHandler().hasMessages(MESSAGE_NAME_CHANGE)) { 306f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return; 307f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 308f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 309f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov boolean changed = updateSuggestedContactIds(cursor); 310f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!changed) { 311f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return; 312f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 313f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 314f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov StringBuilder sb = new StringBuilder(DataQuery.SELECTION_PREFIX); 315f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov int count = mSuggestedContactIds.length; 316f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov for (int i = 0; i < count; i++) { 317f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (i > 0) { 318f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.append(','); 319f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 320f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.append(mSuggestedContactIds[i]); 321f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 322f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.append(')'); 323f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov sb.toString(); 324f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 325f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Cursor dataCursor = contentResolver.query(Data.CONTENT_URI, 326f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov DataQuery.COLUMNS, sb.toString(), null, Data.CONTACT_ID); 327f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mMainHandler.sendMessage(mMainHandler.obtainMessage(MESSAGE_DATA_CURSOR, dataCursor)); 328f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } finally { 329f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov cursor.close(); 330f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 331f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 332f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 333f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov private boolean updateSuggestedContactIds(Cursor cursor) { 334f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov int count = cursor.getCount(); 335f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov boolean changed = count != mSuggestedContactIds.length; 336f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!changed) { 337f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov while (cursor.moveToNext()) { 338f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov long contactId = cursor.getLong(0); 339f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (Arrays.binarySearch(mSuggestedContactIds, contactId) < 0) { 340f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov changed = true; 341f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov break; 342f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 343f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 344f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 345f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 346f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (changed) { 347f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mSuggestedContactIds = new long[count]; 348f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov cursor.moveToPosition(-1); 349f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov for (int i = 0; i < count; i++) { 350f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov cursor.moveToNext(); 351f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mSuggestedContactIds[i] = cursor.getLong(0); 352f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 353f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Arrays.sort(mSuggestedContactIds); 354f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 355f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 356f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return changed; 357f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 358f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 359f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov protected void deliverNotification(Cursor dataCursor) { 360f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mDataCursor != null) { 361f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mDataCursor.close(); 362f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 363f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mDataCursor = dataCursor; 364f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mListener != null) { 365f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mListener.onAggregationSuggestionChange(); 366f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 367f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 368f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 369f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public int getSuggestedContactCount() { 3709302ba7bc47d995c88eba7604aeea00a7e41779fDmitri Plotnikov return mDataCursor != null ? mDataCursor.getCount() : 0; 371f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 372f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 373f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov public List<Suggestion> getSuggestions() { 374f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov ArrayList<Suggestion> list = Lists.newArrayList(); 375f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (mDataCursor != null) { 376f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov Suggestion suggestion = null; 377f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov long currentContactId = -1; 378f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov mDataCursor.moveToPosition(-1); 379f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov while (mDataCursor.moveToNext()) { 380f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov long contactId = mDataCursor.getLong(DataQuery.CONTACT_ID); 381f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (contactId != currentContactId) { 382f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion = new Suggestion(); 383f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.contactId = contactId; 384f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.name = mDataCursor.getString(DataQuery.DISPLAY_NAME); 385c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov suggestion.lookupKey = mDataCursor.getString(DataQuery.LOOKUP_KEY); 386c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov suggestion.rawContacts = Lists.newArrayList(); 387f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov list.add(suggestion); 388f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov currentContactId = contactId; 389f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 390f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 391c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov long rawContactId = mDataCursor.getLong(DataQuery.RAW_CONTACT_ID); 392c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov if (!containsRawContact(suggestion, rawContactId)) { 393c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov RawContact rawContact = new RawContact(); 394c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov rawContact.rawContactId = rawContactId; 395c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov rawContact.accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME); 396c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov rawContact.accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE); 3972b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro rawContact.dataSet = mDataCursor.getString(DataQuery.DATA_SET); 398c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov suggestion.rawContacts.add(rawContact); 399f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 400f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov 401f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov String mimetype = mDataCursor.getString(DataQuery.MIMETYPE); 402f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) { 403f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov String data = mDataCursor.getString(DataQuery.DATA1); 404f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY); 405f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!TextUtils.isEmpty(data) 406f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov && (superprimary != 0 || suggestion.phoneNumber == null)) { 407f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.phoneNumber = data; 408f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 409f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) { 410f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov String data = mDataCursor.getString(DataQuery.DATA1); 411f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY); 412f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!TextUtils.isEmpty(data) 413f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov && (superprimary != 0 || suggestion.emailAddress == null)) { 414f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.emailAddress = data; 415f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 416f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimetype)) { 417f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov String data = mDataCursor.getString(DataQuery.DATA1); 418f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (!TextUtils.isEmpty(data)) { 419f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.nickname = data; 420f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 421f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } else if (Photo.CONTENT_ITEM_TYPE.equals(mimetype)) { 422f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov long dataId = mDataCursor.getLong(DataQuery.ID); 423f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov long photoId = mDataCursor.getLong(DataQuery.PHOTO_ID); 424f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov if (dataId == photoId && !mDataCursor.isNull(DataQuery.PHOTO)) { 425f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov suggestion.photo = mDataCursor.getBlob(DataQuery.PHOTO); 426f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 427f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 428f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 429f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 430f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov return list; 431f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov } 432c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov 433c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov public boolean containsRawContact(Suggestion suggestion, long rawContactId) { 434c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov if (suggestion.rawContacts != null) { 435c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov int count = suggestion.rawContacts.size(); 436c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov for (int i = 0; i < count; i++) { 437c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov if (suggestion.rawContacts.get(i).rawContactId == rawContactId) { 438c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov return true; 439c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 440c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 441c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 442c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov return false; 443c0130cc28edccb21f6698066d90ce2120096eff2Dmitri Plotnikov } 444f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov} 445