am 9e38f9a9: Merge "Use the system-wide interface to add a word."
* commit '9e38f9a9803b04d40c0956e5977a4fb6fce88759': Use the system-wide interface to add a word.main
commit
3e9135d76d
|
@ -5,7 +5,6 @@
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
|
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
|
||||||
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
|
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
|
|
||||||
<application android:label="@string/english_ime_name"
|
<application android:label="@string/english_ime_name"
|
||||||
|
|
|
@ -672,34 +672,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
|
||||||
mPreviewPopup.dismiss();
|
mPreviewPopup.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPreview(View view, CharSequence word) {
|
|
||||||
if (TextUtils.isEmpty(word))
|
|
||||||
return;
|
|
||||||
|
|
||||||
final TextView previewText = mPreviewText;
|
|
||||||
previewText.setTextColor(mParams.mColorTypedWord);
|
|
||||||
previewText.setText(word);
|
|
||||||
previewText.measure(
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
final int[] offsetInWindow = new int[2];
|
|
||||||
view.getLocationInWindow(offsetInWindow);
|
|
||||||
final int posX = offsetInWindow[0];
|
|
||||||
final int posY = offsetInWindow[1] - previewText.getMeasuredHeight();
|
|
||||||
final PopupWindow previewPopup = mPreviewPopup;
|
|
||||||
if (previewPopup.isShowing()) {
|
|
||||||
previewPopup.update(posX, posY, previewPopup.getWidth(), previewPopup.getHeight());
|
|
||||||
} else {
|
|
||||||
previewPopup.showAtLocation(this, Gravity.NO_GRAVITY, posX, posY);
|
|
||||||
}
|
|
||||||
previewText.setVisibility(VISIBLE);
|
|
||||||
mHandler.postHidePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addToDictionary(CharSequence word) {
|
private void addToDictionary(CharSequence word) {
|
||||||
if (mListener.addWordToDictionary(word.toString())) {
|
mListener.addWordToDictionary(word.toString());
|
||||||
final CharSequence message = getContext().getString(R.string.added_word, word);
|
|
||||||
showPreview(mParams.mWordToSaveView, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final KeyboardActionListener mMoreSuggestionsListener =
|
private final KeyboardActionListener mMoreSuggestionsListener =
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -38,11 +39,9 @@ public class UserDictionary extends ExpandableDictionary {
|
||||||
Words.FREQUENCY,
|
Words.FREQUENCY,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] PROJECTION_ADD = {
|
// This is not exported by the framework so we pretty much have to write it here verbatim
|
||||||
Words._ID,
|
private static final String ACTION_USER_DICTIONARY_INSERT =
|
||||||
Words.FREQUENCY,
|
"com.android.settings.USER_DICTIONARY_INSERT";
|
||||||
Words.LOCALE,
|
|
||||||
};
|
|
||||||
|
|
||||||
private ContentObserver mObserver;
|
private ContentObserver mObserver;
|
||||||
final private String mLocale;
|
final private String mLocale;
|
||||||
|
@ -164,54 +163,19 @@ public class UserDictionary extends ExpandableDictionary {
|
||||||
public synchronized void addWord(final String word, final int frequency) {
|
public synchronized void addWord(final String word, final int frequency) {
|
||||||
// Force load the dictionary here synchronously
|
// Force load the dictionary here synchronously
|
||||||
if (getRequiresReload()) loadDictionaryAsync();
|
if (getRequiresReload()) loadDictionaryAsync();
|
||||||
|
// TODO: do something for the UI. With the following, any sufficiently long word will
|
||||||
|
// look like it will go to the user dictionary but it won't.
|
||||||
// Safeguard against adding long words. Can cause stack overflow.
|
// Safeguard against adding long words. Can cause stack overflow.
|
||||||
if (word.length() >= getMaxWordLength()) return;
|
if (word.length() >= getMaxWordLength()) return;
|
||||||
|
|
||||||
super.addWord(word, frequency);
|
super.addWord(word, frequency);
|
||||||
|
|
||||||
// Update the user dictionary provider
|
// TODO: Add an argument to the intent to specify the frequency.
|
||||||
final ContentValues values = new ContentValues(5);
|
Intent intent = new Intent(ACTION_USER_DICTIONARY_INSERT);
|
||||||
values.put(Words.WORD, word);
|
intent.putExtra(Words.WORD, word);
|
||||||
values.put(Words.FREQUENCY, frequency);
|
intent.putExtra(Words.LOCALE, mLocale);
|
||||||
values.put(Words.LOCALE, mLocale);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
values.put(Words.APP_ID, 0);
|
getContext().startActivity(intent);
|
||||||
|
|
||||||
final ContentResolver contentResolver = getContext().getContentResolver();
|
|
||||||
final ContentProviderClient client =
|
|
||||||
contentResolver.acquireContentProviderClient(Words.CONTENT_URI);
|
|
||||||
if (null == client) return;
|
|
||||||
new Thread("addWord") {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Cursor cursor = null;
|
|
||||||
try {
|
|
||||||
cursor = client.query(Words.CONTENT_URI, PROJECTION_ADD,
|
|
||||||
"word=? and ((locale IS NULL) or (locale=?))",
|
|
||||||
new String[] { word, mLocale }, null);
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
final String locale = cursor.getString(cursor.getColumnIndex(Words.LOCALE));
|
|
||||||
// If locale is null, we will not override the entry.
|
|
||||||
if (locale != null && locale.equals(mLocale.toString())) {
|
|
||||||
final long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
|
|
||||||
final Uri uri =
|
|
||||||
Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
|
|
||||||
// Update the entry with new frequency value.
|
|
||||||
client.update(uri, values, null, null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Insert new entry.
|
|
||||||
client.insert(Words.CONTENT_URI, values);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
// If we come here, the activity is already about to be killed, and we
|
|
||||||
// have no means of contacting the content provider any more.
|
|
||||||
// See ContentResolver#insert, inside the catch(){}
|
|
||||||
} finally {
|
|
||||||
if (null != cursor) cursor.close();
|
|
||||||
client.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
// In case the above does a synchronous callback of the change observer
|
// In case the above does a synchronous callback of the change observer
|
||||||
setRequiresReload(false);
|
setRequiresReload(false);
|
||||||
|
|
Loading…
Reference in New Issue