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 
17 package android.provider;
18 
19 import java.util.Locale;
20 
21 import android.content.ContentResolver;
22 import android.content.ContentValues;
23 import android.content.Context;
24 import android.net.Uri;
25 import android.text.TextUtils;
26 
27 /**
28  * A provider of user defined words for input methods to use for predictive text input.
29  * Applications and input methods may add words into the dictionary. Words can have associated
30  * frequency information and locale information.
31  *
32  * <p><strong>NOTE: </strong>Starting on API 23, the user dictionary is only accessible through
33  * IME and spellchecker.
34  */
35 public class UserDictionary {
36 
37     /** Authority string for this provider. */
38     public static final String AUTHORITY = "user_dictionary";
39 
40     /**
41      * The content:// style URL for this provider
42      */
43     public static final Uri CONTENT_URI =
44         Uri.parse("content://" + AUTHORITY);
45 
46     private static final int FREQUENCY_MIN = 0;
47     private static final int FREQUENCY_MAX = 255;
48 
49     /**
50      * Contains the user defined words.
51      */
52     public static class Words implements BaseColumns {
53         /**
54          * The content:// style URL for this table
55          */
56         public static final Uri CONTENT_URI =
57                 Uri.parse("content://" + AUTHORITY + "/words");
58 
59         /**
60          * The MIME type of {@link #CONTENT_URI} providing a directory of words.
61          */
62         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.userword";
63 
64         /**
65          * The MIME type of a {@link #CONTENT_URI} sub-directory of a single word.
66          */
67         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.userword";
68 
69         public static final String _ID = BaseColumns._ID;
70 
71         /**
72          * The word column.
73          * <p>TYPE: TEXT</p>
74          */
75         public static final String WORD = "word";
76 
77         /**
78          * The frequency column. A value between 1 and 255. Higher values imply higher frequency.
79          * <p>TYPE: INTEGER</p>
80          */
81         public static final String FREQUENCY = "frequency";
82 
83         /**
84          * The locale that this word belongs to. Null if it pertains to all
85          * locales. Locale is as defined by the string returned by Locale.toString().
86          * <p>TYPE: TEXT</p>
87          */
88         public static final String LOCALE = "locale";
89 
90         /**
91          * The uid of the application that inserted the word.
92          * <p>TYPE: INTEGER</p>
93          */
94         public static final String APP_ID = "appid";
95 
96         /**
97          * An optional shortcut for this word. When the shortcut is typed, supporting IMEs should
98          * suggest the word in this row as an alternate spelling too.
99          */
100         public static final String SHORTCUT = "shortcut";
101 
102         /**
103          * @deprecated Use {@link #addWord(Context, String, int, String, Locale)}.
104          */
105         @Deprecated
106         public static final int LOCALE_TYPE_ALL = 0;
107 
108         /**
109          * @deprecated Use {@link #addWord(Context, String, int, String, Locale)}.
110          */
111         @Deprecated
112         public static final int LOCALE_TYPE_CURRENT = 1;
113 
114         /**
115          * Sort by descending order of frequency.
116          */
117         public static final String DEFAULT_SORT_ORDER = FREQUENCY + " DESC";
118 
119         /** Adds a word to the dictionary, with the given frequency and the specified
120          *  specified locale type.
121          *
122          *  @deprecated Please use
123          *  {@link #addWord(Context, String, int, String, Locale)} instead.
124          *
125          *  @param context the current application context
126          *  @param word the word to add to the dictionary. This should not be null or
127          *  empty.
128          *  @param localeType the locale type for this word. It should be one of
129          *  {@link #LOCALE_TYPE_ALL} or {@link #LOCALE_TYPE_CURRENT}.
130          */
131         @Deprecated
addWord(Context context, String word, int frequency, int localeType)132         public static void addWord(Context context, String word,
133                 int frequency, int localeType) {
134 
135             if (localeType != LOCALE_TYPE_ALL && localeType != LOCALE_TYPE_CURRENT) {
136                 return;
137             }
138 
139             final Locale locale;
140 
141             if (localeType == LOCALE_TYPE_CURRENT) {
142                 locale = Locale.getDefault();
143             } else {
144                 locale = null;
145             }
146 
147             addWord(context, word, frequency, null, locale);
148         }
149 
150         /** Adds a word to the dictionary, with the given frequency and the specified
151          *  locale type.
152          *
153          *  @param context the current application context
154          *  @param word the word to add to the dictionary. This should not be null or
155          *  empty.
156          *  @param shortcut optional shortcut spelling for this word. When the shortcut
157          *  is typed, the word may be suggested by applications that support it. May be null.
158          *  @param locale the locale to insert the word for, or null to insert the word
159          *  for all locales.
160          */
addWord(Context context, String word, int frequency, String shortcut, Locale locale)161         public static void addWord(Context context, String word,
162                 int frequency, String shortcut, Locale locale) {
163             final ContentResolver resolver = context.getContentResolver();
164 
165             if (TextUtils.isEmpty(word)) {
166                 return;
167             }
168 
169             if (frequency < FREQUENCY_MIN) frequency = FREQUENCY_MIN;
170             if (frequency > FREQUENCY_MAX) frequency = FREQUENCY_MAX;
171 
172             final int COLUMN_COUNT = 5;
173             ContentValues values = new ContentValues(COLUMN_COUNT);
174 
175             values.put(WORD, word);
176             values.put(FREQUENCY, frequency);
177             values.put(LOCALE, null == locale ? null : locale.toString());
178             values.put(APP_ID, 0); // TODO: Get App UID
179             values.put(SHORTCUT, shortcut);
180 
181             Uri result = resolver.insert(CONTENT_URI, values);
182             // It's ok if the insert doesn't succeed because the word
183             // already exists.
184         }
185     }
186 }
187