/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/UserDictionary.java
Java | 143 lines | 91 code | 21 blank | 31 comment | 9 complexity | 2afbc20b16dd6bc4c5745007c4d4b612 MD5 | raw file
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.googlecode.eyesfree.inputmethod.latin; 18 19import android.content.ContentResolver; 20import android.content.ContentValues; 21import android.content.Context; 22import android.database.ContentObserver; 23import android.database.Cursor; 24import android.provider.UserDictionary.Words; 25 26public class UserDictionary extends ExpandableDictionary { 27 28 private static final String[] PROJECTION = { 29 Words._ID, 30 Words.WORD, 31 Words.FREQUENCY 32 }; 33 34 private static final int INDEX_WORD = 1; 35 private static final int INDEX_FREQUENCY = 2; 36 37 private ContentObserver mObserver; 38 private String mLocale; 39 40 public UserDictionary(Context context, String locale) { 41 super(context, Suggest.DIC_USER); 42 mLocale = locale; 43 // Perform a managed query. The Activity will handle closing and requerying the cursor 44 // when needed. 45 ContentResolver cres = context.getContentResolver(); 46 47 cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { 48 @Override 49 public void onChange(boolean self) { 50 setRequiresReload(true); 51 } 52 }); 53 54 loadDictionary(); 55 } 56 57 @Override 58 public synchronized void close() { 59 if (mObserver != null) { 60 getContext().getContentResolver().unregisterContentObserver(mObserver); 61 mObserver = null; 62 } 63 super.close(); 64 } 65 66 @Override 67 public void loadDictionaryAsync() { 68 Cursor cursor = getContext().getContentResolver() 69 .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)", 70 new String[] { mLocale }, null); 71 addWords(cursor); 72 } 73 74 /** 75 * Adds a word to the dictionary and makes it persistent. 76 * @param word the word to add. If the word is capitalized, then the dictionary will 77 * recognize it as a capitalized word when searched. 78 * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered 79 * the highest. 80 * @TODO use a higher or float range for frequency 81 */ 82 @Override 83 public synchronized void addWord(String word, int frequency) { 84 // Force load the dictionary here synchronously 85 if (getRequiresReload()) loadDictionaryAsync(); 86 // Safeguard against adding long words. Can cause stack overflow. 87 if (word.length() >= getMaxWordLength()) return; 88 89 super.addWord(word, frequency); 90 91 // Update the user dictionary provider 92 final ContentValues values = new ContentValues(5); 93 values.put(Words.WORD, word); 94 values.put(Words.FREQUENCY, frequency); 95 values.put(Words.LOCALE, mLocale); 96 values.put(Words.APP_ID, 0); 97 98 final ContentResolver contentResolver = getContext().getContentResolver(); 99 new Thread("addWord") { 100 @Override 101 public void run() { 102 contentResolver.insert(Words.CONTENT_URI, values); 103 } 104 }.start(); 105 106 // In case the above does a synchronous callback of the change observer 107 setRequiresReload(false); 108 } 109 110 @Override 111 public synchronized void getWords(final WordComposer codes, final WordCallback callback, 112 int[] nextLettersFrequencies) { 113 super.getWords(codes, callback, nextLettersFrequencies); 114 } 115 116 @Override 117 public synchronized boolean isValidWord(CharSequence word) { 118 return super.isValidWord(word); 119 } 120 121 private void addWords(Cursor cursor) { 122 if (cursor == null) { 123 return; 124 } 125 126 clearDictionary(); 127 128 final int maxWordLength = getMaxWordLength(); 129 if (cursor.moveToFirst()) { 130 while (!cursor.isAfterLast()) { 131 String word = cursor.getString(INDEX_WORD); 132 int frequency = cursor.getInt(INDEX_FREQUENCY); 133 // Safeguard against adding really long words. Stack may overflow due 134 // to recursion 135 if (word.length() < maxWordLength) { 136 super.addWord(word, frequency); 137 } 138 cursor.moveToNext(); 139 } 140 } 141 cursor.close(); 142 } 143}