Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2826d74 authored by Danny Baumann's avatar Danny Baumann
Browse files

Don't cache contact list and T9 characters longer than the dialer's

lifetime.

- T9 characters may change if the user changes the OS language
- Contacts may change anytime by user's actions (add, modify, delete,
  sync)

Fixes http://code.google.com/p/cyanogenmod/issues/detail?id=6084

Change-Id: I171032b441e56dd2b7ce3c90535db4683fb79668
parent 4de9c946
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent">
	<ProgressBar
		android:layout_width="wrap_content"
		android:layout_height="match_parent"
		android:layout_marginLeft="12dp"
		android:layout_marginRight="12dp"
		style="@android:style/Widget.ProgressBar.Small"
		android:gravity="center_vertical" />
	<TextView
		android:layout_weight="1"
		android:layout_width="wrap_content"
		android:layout_height="match_parent"
		android:gravity="center_vertical"
		android:text="@string/t9_loading" />
</LinearLayout>
+1 −0
Original line number Original line Diff line number Diff line
@@ -515,6 +515,7 @@
    <string name="title_about_credits">Danksagung</string>
    <string name="title_about_credits">Danksagung</string>
    <string name="summary_about_credits">Wysie, ChainsDD, geesun, niuchl, rac2030, sileht und der Rest von XDA! :)</string>
    <string name="summary_about_credits">Wysie, ChainsDD, geesun, niuchl, rac2030, sileht und der Rest von XDA! :)</string>


    <string name="t9_loading">Lade Kontakte\u2026</string>
    <string name="t9_sort_title">T9-Sortierung</string>
    <string name="t9_sort_title">T9-Sortierung</string>
    <string name="t9_sort_summary">Reihenfolge der T9-Resultate auswählen</string>
    <string name="t9_sort_summary">Reihenfolge der T9-Resultate auswählen</string>
    <string name="t9_sort_name">Namenstreffer bevorzugen</string>
    <string name="t9_sort_name">Namenstreffer bevorzugen</string>
+1 −1
Original line number Original line Diff line number Diff line
@@ -1303,6 +1303,7 @@
    <string name="title_about_credits">Credits</string>
    <string name="title_about_credits">Credits</string>
    <string name="summary_about_credits">Wysie, ChainsDD, geesun, niuchl, rac2030, sileht and the rest of XDA! :)</string>
    <string name="summary_about_credits">Wysie, ChainsDD, geesun, niuchl, rac2030, sileht and the rest of XDA! :)</string>


    <string name="t9_loading">Loading\u2026</string>
    <string name="t9_default_sort">1</string>
    <string name="t9_default_sort">1</string>
    <string name="t9_sort_title">T9 sorting mode</string>
    <string name="t9_sort_title">T9 sorting mode</string>
    <string name="t9_sort_summary">Choose how to filter T9 results</string>
    <string name="t9_sort_summary">Choose how to filter T9 results</string>
@@ -1321,5 +1322,4 @@
    <string name="t9_map_row_7">7pqrsßɾṕŕśřš</string>
    <string name="t9_map_row_7">7pqrsßɾṕŕśřš</string>
    <string name="t9_map_row_8">8tuvúùüûű</string>
    <string name="t9_map_row_8">8tuvúùüûű</string>
    <string name="t9_map_row_9">9wxyzýẃź</string>
    <string name="t9_map_row_9">9wxyzýẃź</string>

</resources>
</resources>
+175 −99
Original line number Original line Diff line number Diff line
@@ -31,11 +31,13 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.net.Uri;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneNumberUtils;
import android.text.Spannable;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View;
@@ -48,75 +50,129 @@ import android.widget.TextView;
 * @author shade, Danesh, pawitp
 * @author shade, Danesh, pawitp
 */
 */
class T9Search {
class T9Search {
    public interface LoadFinishCallback {
        public void onLoadFinished();
    }


    // List sort modes
    // List sort modes
    private static final int NAME_FIRST = 1;
    private static final int NAME_FIRST = 1;
    private static final int NUMBER_FIRST = 2;
    private static final int NUMBER_FIRST = 2;


    // Phone number queries
    // Phone number queries
    private static final String[] PHONE_PROJECTION = new String[] {Phone.NUMBER, Phone.CONTACT_ID, Phone.IS_SUPER_PRIMARY, Phone.TYPE, Phone.LABEL};
    private static final String[] PHONE_PROJECTION = new String[] {
        Phone.NUMBER,
        Phone.CONTACT_ID,
        Phone.IS_SUPER_PRIMARY,
        Phone.TYPE,
        Phone.LABEL
    };
    private static final int PHONE_COLUMN_NUMBER = 0;
    private static final int PHONE_COLUMN_CONTACT = 1;
    private static final int PHONE_COLUMN_PRIMARY = 2;
    private static final int PHONE_COLUMN_TYPE = 3;
    private static final int PHONE_COLUMN_LABEL = 4;

    private static final String PHONE_ID_SELECTION = Contacts.Data.MIMETYPE + " = ? ";
    private static final String PHONE_ID_SELECTION = Contacts.Data.MIMETYPE + " = ? ";
    private static final String[] PHONE_ID_SELECTION_ARGS = new String[] {Phone.CONTENT_ITEM_TYPE};
    private static final String[] PHONE_ID_SELECTION_ARGS = new String[] {
        Phone.CONTENT_ITEM_TYPE
    };
    private static final String PHONE_SORT = Phone.CONTACT_ID + " ASC";
    private static final String PHONE_SORT = Phone.CONTACT_ID + " ASC";
    private static final String[] CONTACT_PROJECTION = new String[] {Contacts._ID, Contacts.DISPLAY_NAME, Contacts.TIMES_CONTACTED};

    private static final String[] CONTACT_PROJECTION = new String[] {
        Contacts._ID,
        Contacts.DISPLAY_NAME,
        Contacts.TIMES_CONTACTED
    };
    private static final int CONTACT_COLUMN_ID = 0;
    private static final int CONTACT_COLUMN_NAME = 1;
    private static final int CONTACT_COLUMN_CONTACTED = 2;

    private static final String CONTACT_QUERY = Contacts.HAS_PHONE_NUMBER + " > 0";
    private static final String CONTACT_QUERY = Contacts.HAS_PHONE_NUMBER + " > 0";
    private static final String CONTACT_SORT = Contacts._ID + " ASC";
    private static final String CONTACT_SORT = Contacts._ID + " ASC";


    // Local variables
    // Local variables
    private Context mContext;
    private Context mContext;
    private int mSortMode;
    private LoadTask mLoadTask;
    private ArrayList<ContactItem> mNameResults = new ArrayList<ContactItem>();
    private boolean mLoaded;
    private ArrayList<ContactItem> mNumberResults = new ArrayList<ContactItem>();
    private LoadFinishCallback mLoadCallback;
    private Set<ContactItem> mAllResults = new LinkedHashSet<ContactItem>();
    private Set<ContactItem> mAllResults = new LinkedHashSet<ContactItem>();
    private ArrayList<ContactItem> mContacts = new ArrayList<ContactItem>();
    private ArrayList<ContactItem> mContacts = new ArrayList<ContactItem>();
    private String mPrevInput;
    private String mPrevInput;
    private static String sT9Chars;
    private String mT9Chars;
    private static String sT9Digits;
    private String mT9Digits;


    public T9Search(Context context) {
    public T9Search(Context context) {
        mContext = context;
        mContext = context;
        getAll();
    }
    }


    private void getAll() {
    public void load(LoadFinishCallback cb) {
        mLoadCallback = cb;
        mPrevInput = null;
        mAllResults.clear();
        mContacts.clear();
        if (mLoadTask == null || mLoadTask.getStatus() == AsyncTask.Status.FINISHED) {
            mLoaded = false;
            mLoadTask = new LoadTask();
            mLoadTask.execute();
        }
    }

    private class LoadTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... args) {
            initT9Map();
            initT9Map();


        Cursor contact = mContext.getContentResolver().query(Contacts.CONTENT_URI, CONTACT_PROJECTION, CONTACT_QUERY, null, CONTACT_SORT);
            Cursor contact = mContext.getContentResolver().query(
        Cursor phone = mContext.getContentResolver().query(Phone.CONTENT_URI, PHONE_PROJECTION, PHONE_ID_SELECTION, PHONE_ID_SELECTION_ARGS, PHONE_SORT);
                    Contacts.CONTENT_URI, CONTACT_PROJECTION, CONTACT_QUERY,
                    null, CONTACT_SORT);
            Cursor phone = mContext.getContentResolver().query(
                    Phone.CONTENT_URI, PHONE_PROJECTION, PHONE_ID_SELECTION,
                    PHONE_ID_SELECTION_ARGS, PHONE_SORT);

            phone.moveToFirst();
            phone.moveToFirst();


            while (contact.moveToNext()) {
            while (contact.moveToNext()) {
            long contactId = contact.getLong(0);
                long contactId = contact.getLong(CONTACT_COLUMN_ID);
            if (phone.isAfterLast()) {
                String contactName = contact.getString(CONTACT_COLUMN_NAME);
                break;
                int contactContactedCount = contact.getInt(CONTACT_COLUMN_CONTACTED);
            }

            while (phone.getLong(1) == contactId) {
                while (!phone.isAfterLast() && phone.getLong(PHONE_COLUMN_CONTACT) == contactId) {
                String num = phone.getString(0);
                    String num = phone.getString(PHONE_COLUMN_NUMBER);
                    ContactItem contactInfo = new BitmapContactItem();
                    ContactItem contactInfo = new BitmapContactItem();

                    contactInfo.id = contactId;
                    contactInfo.id = contactId;
                contactInfo.name = contact.getString(1);
                    contactInfo.name = contactName;
                    contactInfo.number = PhoneNumberUtils.formatNumber(num);
                    contactInfo.number = PhoneNumberUtils.formatNumber(num);
                    contactInfo.normalNumber = removeNonDigits(num);
                    contactInfo.normalNumber = removeNonDigits(num);
                contactInfo.normalName = nameToNumber(contact.getString(1));
                    contactInfo.normalName = nameToNumber(contactName);
                contactInfo.timesContacted = contact.getInt(2);
                    contactInfo.timesContacted = contactContactedCount;
                contactInfo.isSuperPrimary = phone.getInt(2) > 0;
                    contactInfo.isSuperPrimary = phone.getInt(PHONE_COLUMN_PRIMARY) > 0;
                contactInfo.groupType = Phone.getTypeLabel(mContext.getResources(), phone.getInt(3), phone.getString(4));
                    contactInfo.groupType = Phone.getTypeLabel(mContext.getResources(),
                            phone.getInt(PHONE_COLUMN_TYPE), phone.getString(PHONE_COLUMN_LABEL));
                    mContacts.add(contactInfo);
                    mContacts.add(contactInfo);
                if (!phone.moveToNext()) {
                    phone.moveToNext();
                    break;
                }
                }
                }
            }
            }

            contact.close();
            contact.close();
            phone.close();
            phone.close();
            return null;
        }
        }


    public static class T9SearchResult {
        @Override
        protected void onPostExecute(Void result) {
            mLoaded = true;
            if (mLoadCallback != null) {
                mLoadCallback.onLoadFinished();
            }
        }
    }


    public static class T9SearchResult {
        private final ArrayList<ContactItem> mResults;
        private final ArrayList<ContactItem> mResults;
        private final ContactItem mTopContact;
        private final ContactItem mTopContact;


        public T9SearchResult (final ArrayList<ContactItem> results, final Context mContext) {
        public T9SearchResult(final ArrayList<ContactItem> results) {
            mTopContact = results.get(0);
            mTopContact = results.get(0);
            mResults = results;
            mResults = results;
            mResults.remove(0);
            mResults.remove(0);
@@ -156,7 +212,8 @@ class T9Search {
        public Bitmap getPhoto() {
        public Bitmap getPhoto() {
            Bitmap result = null;
            Bitmap result = null;
            Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, this.id);
            Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, this.id);
            InputStream photoStream = Contacts.openContactPhotoInputStream(mContext.getContentResolver(), contactUri);
            InputStream photoStream = Contacts.openContactPhotoInputStream(
                    mContext.getContentResolver(), contactUri);
            if (photoStream != null) {
            if (photoStream != null) {
                result = BitmapFactory.decodeStream(photoStream);
                result = BitmapFactory.decodeStream(photoStream);
                try {
                try {
@@ -169,12 +226,17 @@ class T9Search {
    }
    }


    public T9SearchResult search(String number) {
    public T9SearchResult search(String number) {
        mNameResults.clear();
        if (!mLoaded) {
        mNumberResults.clear();
            return null;
        }

        number = removeNonDigits(number);
        number = removeNonDigits(number);
        int pos = 0;

        mSortMode = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(mContext).getString("t9_sort", "1"));
        int pos;
        final ArrayList<ContactItem> numberResults = new ArrayList<ContactItem>();
        final ArrayList<ContactItem> nameResults = new ArrayList<ContactItem>();
        boolean newQuery = mPrevInput == null || number.length() <= mPrevInput.length();
        boolean newQuery = mPrevInput == null || number.length() <= mPrevInput.length();

        // Go through each contact
        // Go through each contact
        for (ContactItem item : (newQuery ? mContacts : mAllResults)) {
        for (ContactItem item : (newQuery ? mContacts : mAllResults)) {
            item.numberMatchId = -1;
            item.numberMatchId = -1;
@@ -182,38 +244,49 @@ class T9Search {
            pos = item.normalNumber.indexOf(number);
            pos = item.normalNumber.indexOf(number);
            if (pos != -1) {
            if (pos != -1) {
                item.numberMatchId = pos;
                item.numberMatchId = pos;
                mNumberResults.add(item);
                numberResults.add(item);
            }
            }
            pos = item.normalName.indexOf(number);
            pos = item.normalName.indexOf(number);
            if (pos != -1) {
            if (pos != -1) {
                int last_space = item.normalName.lastIndexOf("0", pos);
                int lastSpace = item.normalName.lastIndexOf("0", pos);
                if (last_space == -1) {
                if (lastSpace == -1) {
                    last_space = 0;
                    lastSpace = 0;
                }
                }
                item.nameMatchId = pos - last_space;
                item.nameMatchId = pos - lastSpace;
                mNameResults.add(item);
                nameResults.add(item);
            }
            }
        }
        }

        mAllResults.clear();
        mAllResults.clear();
        mPrevInput = number;
        mPrevInput = number;
        Collections.sort(mNumberResults, new NumberComparator());

        Collections.sort(mNameResults, new NameComparator());
        Collections.sort(numberResults, sNumberComparator);
        if (mNameResults.size() > 0 || mNumberResults.size() > 0) {
        Collections.sort(nameResults, sNameComparator);
            switch (mSortMode) {

            case NAME_FIRST:
        if (nameResults.isEmpty() && numberResults.isEmpty()) {
                mAllResults.addAll(mNameResults);
                mAllResults.addAll(mNumberResults);
                break;
            case NUMBER_FIRST:
                mAllResults.addAll(mNumberResults);
                mAllResults.addAll(mNameResults);
            }
            return new T9SearchResult(new ArrayList<ContactItem>(mAllResults), mContext);
        }
            return null;
            return null;
        }
        }


    public static class NameComparator implements Comparator<ContactItem> {
        if (preferSortByName()) {
            mAllResults.addAll(nameResults);
            mAllResults.addAll(numberResults);
        } else {
            mAllResults.addAll(numberResults);
            mAllResults.addAll(nameResults);
        }
        return new T9SearchResult(new ArrayList<ContactItem>(mAllResults));
    }

    private boolean preferSortByName() {
        String mode = PreferenceManager.getDefaultSharedPreferences(mContext).getString(
                "t9_sort", mContext.getString(R.string.t9_default_sort));
        if (TextUtils.equals(mode, Integer.toString(NUMBER_FIRST))) {
            return false;
        }
        return true;
    }

    private static final Comparator<ContactItem> sNameComparator = new Comparator<ContactItem>() {
        @Override
        @Override
        public int compare(ContactItem lhs, ContactItem rhs) {
        public int compare(ContactItem lhs, ContactItem rhs) {
            int ret = compareInt(lhs.nameMatchId, rhs.nameMatchId);
            int ret = compareInt(lhs.nameMatchId, rhs.nameMatchId);
@@ -221,9 +294,9 @@ class T9Search {
            if (ret == 0) ret = compareBool(rhs.isSuperPrimary, lhs.isSuperPrimary);
            if (ret == 0) ret = compareBool(rhs.isSuperPrimary, lhs.isSuperPrimary);
            return ret;
            return ret;
        }
        }
    }
    };


    public static class NumberComparator implements Comparator<ContactItem> {
    private static final Comparator<ContactItem> sNumberComparator = new Comparator<ContactItem>() {
        @Override
        @Override
        public int compare(ContactItem lhs, ContactItem rhs) {
        public int compare(ContactItem lhs, ContactItem rhs) {
            int ret = compareInt(lhs.numberMatchId, rhs.numberMatchId);
            int ret = compareInt(lhs.numberMatchId, rhs.numberMatchId);
@@ -231,21 +304,17 @@ class T9Search {
            if (ret == 0) ret = compareBool(rhs.isSuperPrimary, lhs.isSuperPrimary);
            if (ret == 0) ret = compareBool(rhs.isSuperPrimary, lhs.isSuperPrimary);
            return ret;
            return ret;
        }
        }
    }
    };


    public static int compareInt (int lhs, int rhs) {
    private static int compareInt (int lhs, int rhs) {
        return lhs < rhs ? -1 : (lhs == rhs ? 0 : 1);
        return lhs < rhs ? -1 : (lhs == rhs ? 0 : 1);
    }
    }


    public static int compareBool (boolean lhs, boolean rhs) {
    private static int compareBool (boolean lhs, boolean rhs) {
        return lhs == rhs ? 0 : lhs ? 1 : -1;
        return lhs == rhs ? 0 : lhs ? 1 : -1;
    }
    }


    private void initT9Map() {
    private void initT9Map() {
        synchronized (this.getClass()) {
            if (sT9Chars != null)
                return;

        StringBuilder bT9Chars = new StringBuilder();
        StringBuilder bT9Chars = new StringBuilder();
        StringBuilder bT9Digits = new StringBuilder();
        StringBuilder bT9Digits = new StringBuilder();
        for (String item : mContext.getResources().getStringArray(R.array.t9_map)) {
        for (String item : mContext.getResources().getStringArray(R.array.t9_map)) {
@@ -255,25 +324,24 @@ class T9Search {
            }
            }
        }
        }


            sT9Chars = bT9Chars.toString();
        mT9Chars = bT9Chars.toString();
            sT9Digits = bT9Digits.toString();
        mT9Digits = bT9Digits.toString();
        }
    }
    }


    private static String nameToNumber(final String name) {
    private String nameToNumber(final String name) {
        int len = name.length();
        int len = name.length();
        StringBuilder sb = new StringBuilder(len);
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
        for (int i = 0; i < len; i++) {
            int pos = sT9Chars.indexOf(Character.toLowerCase(name.charAt(i)));
            int pos = mT9Chars.indexOf(Character.toLowerCase(name.charAt(i)));
            if (pos == -1) {
            if (pos == -1) {
                pos = 0;
                pos = 0;
            }
            }
            sb.append(sT9Digits.charAt(pos));
            sb.append(mT9Digits.charAt(pos));
        }
        }
        return sb.toString();
        return sb.toString();
    }
    }


    public static String removeNonDigits(final String number) {
    private String removeNonDigits(final String number) {
        int len = number.length();
        int len = number.length();
        StringBuilder sb = new StringBuilder(len);
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
        for (int i = 0; i < len; i++) {
@@ -286,23 +354,29 @@ class T9Search {
    }
    }


    protected class T9Adapter extends ArrayAdapter<ContactItem> {
    protected class T9Adapter extends ArrayAdapter<ContactItem> {

        private ArrayList<ContactItem> mItems;
        private ArrayList<ContactItem> mItems;
        private LayoutInflater mMenuInflate;
        private LayoutInflater mMenuInflate;
        //private ContactPhotoManager mPhotoLoader;
        private View mLoadingView;


        public T9Adapter(Context context, int textViewResourceId, ArrayList<ContactItem> items, LayoutInflater menuInflate) {
        public T9Adapter(Context context, int textViewResourceId,
                ArrayList<ContactItem> items, LayoutInflater menuInflate) {
            super(context, textViewResourceId, items);
            super(context, textViewResourceId, items);
            mItems = items;
            mItems = items;
            mMenuInflate = menuInflate;
            mMenuInflate = menuInflate;
            //mPhotoLoader = photoLoader;
        }
        }


        @Override
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            ViewHolder holder;


            if (convertView == null) {
            if (!mLoaded) {
                if (mLoadingView == null) {
                    mLoadingView = mMenuInflate.inflate(R.layout.row_loading, null);
                }
                return mLoadingView;
            }

            if (convertView == null || convertView.getTag() == null) {
                convertView = mMenuInflate.inflate(R.layout.row, null);
                convertView = mMenuInflate.inflate(R.layout.row, null);
                holder = new ViewHolder();
                holder = new ViewHolder();
                holder.name = (TextView) convertView.findViewById(R.id.rowName);
                holder.name = (TextView) convertView.findViewById(R.id.rowName);
@@ -321,27 +395,31 @@ class T9Search {
                holder.icon.assignContactFromPhone(o.number, true);
                holder.icon.assignContactFromPhone(o.number, true);
            } else {
            } else {
                holder.name.setText(o.name, TextView.BufferType.SPANNABLE);
                holder.name.setText(o.name, TextView.BufferType.SPANNABLE);
                holder.number.setText(o.normalNumber + " (" + o.groupType + ")", TextView.BufferType.SPANNABLE);
                holder.number.setText(o.normalNumber + " (" + o.groupType + ")",
                        TextView.BufferType.SPANNABLE);
                holder.number.setVisibility(View.VISIBLE);
                holder.number.setVisibility(View.VISIBLE);
                if (o.nameMatchId != -1) {
                if (o.nameMatchId != -1) {
                    Spannable s = (Spannable) holder.name.getText();
                    Spannable s = (Spannable) holder.name.getText();
                    int nameStart = o.normalName.indexOf(mPrevInput);
                    int nameStart = o.normalName.indexOf(mPrevInput);
                    s.setSpan(new ForegroundColorSpan(Color.WHITE),
                    s.setSpan(new ForegroundColorSpan(Color.WHITE),
                            nameStart, nameStart + mPrevInput.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                            nameStart, nameStart + mPrevInput.length(),
                            Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    holder.name.setText(s);
                    holder.name.setText(s);
                }
                }
                if (o.numberMatchId != -1) {
                if (o.numberMatchId != -1) {
                    Spannable s = (Spannable) holder.number.getText();
                    Spannable s = (Spannable) holder.number.getText();
                    int numberStart = o.numberMatchId;
                    int numberStart = o.numberMatchId;
                    s.setSpan(new ForegroundColorSpan(Color.WHITE),
                    s.setSpan(new ForegroundColorSpan(Color.WHITE),
                            numberStart, numberStart + mPrevInput.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                            numberStart, numberStart + mPrevInput.length(),
                            Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    holder.number.setText(s);
                    holder.number.setText(s);
                }
                }
                Bitmap photo = o.getPhoto();
                Bitmap photo = o.getPhoto();
                if (photo != null)
                if (photo != null) {
                    holder.icon.setImageBitmap(photo);
                    holder.icon.setImageBitmap(photo);
                else
                } else {
                    holder.icon.setImageResource(R.drawable.ic_contact_list_picture);
                    holder.icon.setImageResource(R.drawable.ic_contact_list_picture);
                }


                holder.icon.assignContactFromPhone(o.number, true);
                holder.icon.assignContactFromPhone(o.number, true);
            }
            }
@@ -353,7 +431,5 @@ class T9Search {
            TextView number;
            TextView number;
            QuickContactBadge icon;
            QuickContactBadge icon;
        }
        }

    }
    }

}
}
+42 −41
Original line number Original line Diff line number Diff line
@@ -163,7 +163,7 @@ public class TwelveKeyDialer extends Activity implements View.OnClickListener,


    /** Identifier for the "Add Call" intent extra. */
    /** Identifier for the "Add Call" intent extra. */
    static final String ADD_CALL_MODE_KEY = "add_call_mode";
    static final String ADD_CALL_MODE_KEY = "add_call_mode";
    private static T9Search sT9Search; // Static to avoid reloading when class is destroyed and recreated
    private T9Search mT9Search;
    private ToggleButton mT9Toggle;
    private ToggleButton mT9Toggle;
    private ListView mT9List;
    private ListView mT9List;
    private ListView mT9ListTop;
    private ListView mT9ListTop;
@@ -262,6 +262,8 @@ public class TwelveKeyDialer extends Activity implements View.OnClickListener,
        mDigits.setOnClickListener(this);
        mDigits.setOnClickListener(this);
        mDigits.setOnTouchListener(this);
        mDigits.setOnTouchListener(this);
        mDigits.setOnKeyListener(this);
        mDigits.setOnKeyListener(this);

        mT9Search = new T9Search(this);
        mT9List = (ListView) findViewById(R.id.t9list);
        mT9List = (ListView) findViewById(R.id.t9list);
        if (mT9List != null) {
        if (mT9List != null) {
            mT9List.setOnItemClickListener(this);
            mT9List.setOnItemClickListener(this);
@@ -505,13 +507,14 @@ public class TwelveKeyDialer extends Activity implements View.OnClickListener,
    @Override
    @Override
    protected void onResume() {
    protected void onResume() {
        super.onResume();
        super.onResume();
        if (sT9Search == null && isT9On()) {
        if (isT9On()) {
            Thread loadContacts = new Thread(new Runnable() {
            mT9Search.load(new T9Search.LoadFinishCallback() {
                public void run () {
                @Override
                    sT9Search = new T9Search(getBaseContext());
                public void onLoadFinished() {
                    Log.d(TAG, "load finished");
                    searchContacts();
                }
                }
            });
            });
            loadContacts.start();
        }
        }
        hideT9();
        hideT9();
        // Query the last dialed number. Do it first because hitting
        // Query the last dialed number. Do it first because hitting
@@ -617,17 +620,16 @@ public class TwelveKeyDialer extends Activity implements View.OnClickListener,
            return;
            return;
        final int length = mDigits.length();
        final int length = mDigits.length();
        if (length > 0) {
        if (length > 0) {
            if (sT9Search != null) {
            T9SearchResult result = mT9Search.search(mDigits.getText().toString());
                T9SearchResult result = sT9Search.search(mDigits.getText().toString());
            if (mT9AdapterTop == null) {
            if (mT9AdapterTop == null) {
                    mT9AdapterTop = sT9Search.new T9Adapter(this, 0, new ArrayList<ContactItem>(),getLayoutInflater());
                mT9AdapterTop = mT9Search.new T9Adapter(this, 0, new ArrayList<ContactItem>(),getLayoutInflater());
                mT9AdapterTop.setNotifyOnChange(true);
                mT9AdapterTop.setNotifyOnChange(true);
            } else {
            } else {
                mT9AdapterTop.clear();
                mT9AdapterTop.clear();
            }
            }
            if (result != null) {
            if (result != null) {
                if (mT9Adapter == null) {
                if (mT9Adapter == null) {
                        mT9Adapter = sT9Search.new T9Adapter(this, 0, result.getResults(),getLayoutInflater());
                    mT9Adapter = mT9Search.new T9Adapter(this, 0, result.getResults(),getLayoutInflater());
                    mT9Adapter.setNotifyOnChange(true);
                    mT9Adapter.setNotifyOnChange(true);
                } else {
                } else {
                    mT9Adapter.clear();
                    mT9Adapter.clear();
@@ -659,7 +661,6 @@ public class TwelveKeyDialer extends Activity implements View.OnClickListener,
            if (mT9ListTop.getAdapter() == null) {
            if (mT9ListTop.getAdapter() == null) {
                mT9ListTop.setAdapter(mT9AdapterTop);
                mT9ListTop.setAdapter(mT9AdapterTop);
            }
            }
            }
        } else {
        } else {
            mT9ListTop.setVisibility(View.INVISIBLE);
            mT9ListTop.setVisibility(View.INVISIBLE);
            mT9Toggle.setVisibility(View.INVISIBLE);
            mT9Toggle.setVisibility(View.INVISIBLE);