Loading src/com/android/inputmethod/latin/ContactsDictionary.java 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.provider.Contacts; import android.provider.Contacts.People; import android.util.Log; public class ContactsDictionary extends ExpandableDictionary { private static final String[] PROJECTION = { People._ID, People.NAME, }; private static final int INDEX_NAME = 1; private ContentObserver mObserver; private boolean mRequiresReload; public ContactsDictionary(Context context) { super(context); // Perform a managed query. The Activity will handle closing and requerying the cursor // when needed. ContentResolver cres = context.getContentResolver(); cres.registerContentObserver(People.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { mRequiresReload = true; } }); loadDictionary(); } public synchronized void close() { if (mObserver != null) { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } } private synchronized void loadDictionary() { Cursor cursor = getContext().getContentResolver() .query(People.CONTENT_URI, PROJECTION, null, null, null); addWords(cursor); mRequiresReload = false; } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback) { if (mRequiresReload) loadDictionary(); super.getWords(codes, callback); } @Override public synchronized boolean isValidWord(CharSequence word) { if (mRequiresReload) loadDictionary(); return super.isValidWord(word); } private void addWords(Cursor cursor) { clearDictionary(); final int maxWordLength = getMaxWordLength(); if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { String name = cursor.getString(INDEX_NAME); int len = name.length(); // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { if (Character.isLetter(name.charAt(i))) { int j; for (j = i + 1; j < len; j++) { char c = name.charAt(j); if (!(c == '-' || c == '\'' || Character.isLetter(c))) { break; } } String word = name.substring(i, j); i = j - 1; // Safeguard against adding really long words. Stack // may overflow due to recursion if (word.length() < maxWordLength) { super.addWord(word, 128); } } } cursor.moveToNext(); } } cursor.close(); } } src/com/android/inputmethod/latin/LatinIME.java +4 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ public class LatinIME extends InputMethodService KeyboardSwitcher mKeyboardSwitcher; private UserDictionary mUserDictionary; private ContactsDictionary mContactsDictionary; private ExpandableDictionary mAutoDictionary; private String mLocale; Loading Loading @@ -188,8 +189,10 @@ public class LatinIME extends InputMethodService mSuggest = new Suggest(this, R.raw.main); mSuggest.setCorrectionMode(mCorrectionMode); mUserDictionary = new UserDictionary(this); mContactsDictionary = new ContactsDictionary(this); mAutoDictionary = new AutoDictionary(this); mSuggest.setUserDictionary(mUserDictionary); mSuggest.setContactsDictionary(mContactsDictionary); mSuggest.setAutoDictionary(mAutoDictionary); mWordSeparators = getResources().getString(R.string.word_separators); mSentenceSeparators = getResources().getString(R.string.sentence_separators); Loading @@ -197,6 +200,7 @@ public class LatinIME extends InputMethodService @Override public void onDestroy() { mUserDictionary.close(); mContactsDictionary.close(); unregisterReceiver(mReceiver); super.onDestroy(); } Loading src/com/android/inputmethod/latin/Suggest.java +21 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class Suggest implements Dictionary.WordCallback { private Dictionary mAutoDictionary; private Dictionary mContactsDictionary; private int mPrefMaxSuggestions = 12; private int[] mPriorities = new int[mPrefMaxSuggestions]; Loading Loading @@ -82,6 +84,13 @@ public class Suggest implements Dictionary.WordCallback { mUserDictionary = userDictionary; } /** * Sets an optional contacts dictionary resource to be loaded. */ public void setContactsDictionary(Dictionary userDictionary) { mContactsDictionary = userDictionary; } public void setAutoDictionary(Dictionary autoDictionary) { mAutoDictionary = autoDictionary; } Loading Loading @@ -110,8 +119,8 @@ public class Suggest implements Dictionary.WordCallback { if (len <= 2) return true; int matching = 0; for (int i = 0; i < len; i++) { if (UserDictionary.toLowerCase(original.charAt(i)) == UserDictionary.toLowerCase(suggestion.charAt(i))) { if (ExpandableDictionary.toLowerCase(original.charAt(i)) == ExpandableDictionary.toLowerCase(suggestion.charAt(i))) { matching++; } } Loading Loading @@ -148,8 +157,14 @@ public class Suggest implements Dictionary.WordCallback { } // Search the dictionary only if there are at least 2 characters if (wordComposer.size() > 1) { if (mUserDictionary != null || mContactsDictionary != null) { if (mUserDictionary != null) { mUserDictionary.getWords(wordComposer, this); } if (mContactsDictionary != null) { mContactsDictionary.getWords(wordComposer, this); } if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)) { mHaveCorrection = true; } Loading Loading @@ -263,7 +278,8 @@ public class Suggest implements Dictionary.WordCallback { return (mCorrectionMode == CORRECTION_FULL && mMainDict.isValidWord(word)) || (mCorrectionMode > CORRECTION_NONE && ((mUserDictionary != null && mUserDictionary.isValidWord(word))) || (mAutoDictionary != null && mAutoDictionary.isValidWord(word))); || (mAutoDictionary != null && mAutoDictionary.isValidWord(word)) || (mContactsDictionary != null && mContactsDictionary.isValidWord(word))); } private void collectGarbage() { Loading Loading
src/com/android/inputmethod/latin/ContactsDictionary.java 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.provider.Contacts; import android.provider.Contacts.People; import android.util.Log; public class ContactsDictionary extends ExpandableDictionary { private static final String[] PROJECTION = { People._ID, People.NAME, }; private static final int INDEX_NAME = 1; private ContentObserver mObserver; private boolean mRequiresReload; public ContactsDictionary(Context context) { super(context); // Perform a managed query. The Activity will handle closing and requerying the cursor // when needed. ContentResolver cres = context.getContentResolver(); cres.registerContentObserver(People.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { mRequiresReload = true; } }); loadDictionary(); } public synchronized void close() { if (mObserver != null) { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } } private synchronized void loadDictionary() { Cursor cursor = getContext().getContentResolver() .query(People.CONTENT_URI, PROJECTION, null, null, null); addWords(cursor); mRequiresReload = false; } @Override public synchronized void getWords(final WordComposer codes, final WordCallback callback) { if (mRequiresReload) loadDictionary(); super.getWords(codes, callback); } @Override public synchronized boolean isValidWord(CharSequence word) { if (mRequiresReload) loadDictionary(); return super.isValidWord(word); } private void addWords(Cursor cursor) { clearDictionary(); final int maxWordLength = getMaxWordLength(); if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { String name = cursor.getString(INDEX_NAME); int len = name.length(); // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { if (Character.isLetter(name.charAt(i))) { int j; for (j = i + 1; j < len; j++) { char c = name.charAt(j); if (!(c == '-' || c == '\'' || Character.isLetter(c))) { break; } } String word = name.substring(i, j); i = j - 1; // Safeguard against adding really long words. Stack // may overflow due to recursion if (word.length() < maxWordLength) { super.addWord(word, 128); } } } cursor.moveToNext(); } } cursor.close(); } }
src/com/android/inputmethod/latin/LatinIME.java +4 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ public class LatinIME extends InputMethodService KeyboardSwitcher mKeyboardSwitcher; private UserDictionary mUserDictionary; private ContactsDictionary mContactsDictionary; private ExpandableDictionary mAutoDictionary; private String mLocale; Loading Loading @@ -188,8 +189,10 @@ public class LatinIME extends InputMethodService mSuggest = new Suggest(this, R.raw.main); mSuggest.setCorrectionMode(mCorrectionMode); mUserDictionary = new UserDictionary(this); mContactsDictionary = new ContactsDictionary(this); mAutoDictionary = new AutoDictionary(this); mSuggest.setUserDictionary(mUserDictionary); mSuggest.setContactsDictionary(mContactsDictionary); mSuggest.setAutoDictionary(mAutoDictionary); mWordSeparators = getResources().getString(R.string.word_separators); mSentenceSeparators = getResources().getString(R.string.sentence_separators); Loading @@ -197,6 +200,7 @@ public class LatinIME extends InputMethodService @Override public void onDestroy() { mUserDictionary.close(); mContactsDictionary.close(); unregisterReceiver(mReceiver); super.onDestroy(); } Loading
src/com/android/inputmethod/latin/Suggest.java +21 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ public class Suggest implements Dictionary.WordCallback { private Dictionary mAutoDictionary; private Dictionary mContactsDictionary; private int mPrefMaxSuggestions = 12; private int[] mPriorities = new int[mPrefMaxSuggestions]; Loading Loading @@ -82,6 +84,13 @@ public class Suggest implements Dictionary.WordCallback { mUserDictionary = userDictionary; } /** * Sets an optional contacts dictionary resource to be loaded. */ public void setContactsDictionary(Dictionary userDictionary) { mContactsDictionary = userDictionary; } public void setAutoDictionary(Dictionary autoDictionary) { mAutoDictionary = autoDictionary; } Loading Loading @@ -110,8 +119,8 @@ public class Suggest implements Dictionary.WordCallback { if (len <= 2) return true; int matching = 0; for (int i = 0; i < len; i++) { if (UserDictionary.toLowerCase(original.charAt(i)) == UserDictionary.toLowerCase(suggestion.charAt(i))) { if (ExpandableDictionary.toLowerCase(original.charAt(i)) == ExpandableDictionary.toLowerCase(suggestion.charAt(i))) { matching++; } } Loading Loading @@ -148,8 +157,14 @@ public class Suggest implements Dictionary.WordCallback { } // Search the dictionary only if there are at least 2 characters if (wordComposer.size() > 1) { if (mUserDictionary != null || mContactsDictionary != null) { if (mUserDictionary != null) { mUserDictionary.getWords(wordComposer, this); } if (mContactsDictionary != null) { mContactsDictionary.getWords(wordComposer, this); } if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)) { mHaveCorrection = true; } Loading Loading @@ -263,7 +278,8 @@ public class Suggest implements Dictionary.WordCallback { return (mCorrectionMode == CORRECTION_FULL && mMainDict.isValidWord(word)) || (mCorrectionMode > CORRECTION_NONE && ((mUserDictionary != null && mUserDictionary.isValidWord(word))) || (mAutoDictionary != null && mAutoDictionary.isValidWord(word))); || (mAutoDictionary != null && mAutoDictionary.isValidWord(word)) || (mContactsDictionary != null && mContactsDictionary.isValidWord(word))); } private void collectGarbage() { Loading