• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.settings.inputmethod;
18 
19 import com.android.settings.R;
20 import com.android.settings.Settings.KeyboardLayoutPickerActivity;
21 import com.android.settings.Settings.SpellCheckersSettingsActivity;
22 import com.android.settings.SettingsPreferenceFragment;
23 import com.android.settings.Utils;
24 import com.android.settings.VoiceInputOutputSettings;
25 
26 import android.app.Activity;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.pm.PackageManager;
31 import android.content.res.Configuration;
32 import android.content.res.Resources;
33 import android.database.ContentObserver;
34 import android.hardware.input.InputManager;
35 import android.hardware.input.KeyboardLayout;
36 import android.os.Bundle;
37 import android.os.Handler;
38 import android.preference.CheckBoxPreference;
39 import android.preference.ListPreference;
40 import android.preference.Preference;
41 import android.preference.PreferenceCategory;
42 import android.preference.PreferenceScreen;
43 import android.provider.Settings;
44 import android.provider.Settings.System;
45 import android.text.TextUtils;
46 import android.view.InputDevice;
47 import android.view.inputmethod.InputMethodInfo;
48 import android.view.inputmethod.InputMethodManager;
49 
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.List;
53 import java.util.TreeSet;
54 
55 public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
56         implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener,
57         KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener {
58 
59     private static final String KEY_PHONE_LANGUAGE = "phone_language";
60     private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method";
61     private static final String KEY_INPUT_METHOD_SELECTOR = "input_method_selector";
62     private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
63     // false: on ICS or later
64     private static final boolean SHOW_INPUT_METHOD_SWITCHER_SETTINGS = false;
65 
66     private static final String[] sSystemSettingNames = {
67         System.TEXT_AUTO_REPLACE, System.TEXT_AUTO_CAPS, System.TEXT_AUTO_PUNCTUATE,
68     };
69 
70     private static final String[] sHardKeyboardKeys = {
71         "auto_replace", "auto_caps", "auto_punctuate",
72     };
73 
74     private int mDefaultInputMethodSelectorVisibility = 0;
75     private ListPreference mShowInputMethodSelectorPref;
76     private PreferenceCategory mKeyboardSettingsCategory;
77     private PreferenceCategory mHardKeyboardCategory;
78     private PreferenceCategory mGameControllerCategory;
79     private Preference mLanguagePref;
80     private final ArrayList<InputMethodPreference> mInputMethodPreferenceList =
81             new ArrayList<InputMethodPreference>();
82     private final ArrayList<PreferenceScreen> mHardKeyboardPreferenceList =
83             new ArrayList<PreferenceScreen>();
84     private InputManager mIm;
85     private InputMethodManager mImm;
86     private List<InputMethodInfo> mImis;
87     private boolean mIsOnlyImeSettings;
88     private Handler mHandler;
89     @SuppressWarnings("unused")
90     private SettingsObserver mSettingsObserver;
91     private Intent mIntentWaitingForResult;
92 
93     @Override
onCreate(Bundle icicle)94     public void onCreate(Bundle icicle) {
95         super.onCreate(icicle);
96 
97         addPreferencesFromResource(R.xml.language_settings);
98 
99         try {
100             mDefaultInputMethodSelectorVisibility = Integer.valueOf(
101                     getString(R.string.input_method_selector_visibility_default_value));
102         } catch (NumberFormatException e) {
103         }
104 
105         if (getActivity().getAssets().getLocales().length == 1) {
106             // No "Select language" pref if there's only one system locale available.
107             getPreferenceScreen().removePreference(findPreference(KEY_PHONE_LANGUAGE));
108         } else {
109             mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
110         }
111         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
112             mShowInputMethodSelectorPref = (ListPreference)findPreference(
113                     KEY_INPUT_METHOD_SELECTOR);
114             mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
115             // TODO: Update current input method name on summary
116             updateInputMethodSelectorSummary(loadInputMethodSelectorVisibility());
117         }
118 
119         new VoiceInputOutputSettings(this).onCreate();
120 
121         // Get references to dynamically constructed categories.
122         mHardKeyboardCategory = (PreferenceCategory)findPreference("hard_keyboard");
123         mKeyboardSettingsCategory = (PreferenceCategory)findPreference(
124                 "keyboard_settings_category");
125         mGameControllerCategory = (PreferenceCategory)findPreference(
126                 "game_controller_settings_category");
127 
128         // Filter out irrelevant features if invoked from IME settings button.
129         mIsOnlyImeSettings = Settings.ACTION_INPUT_METHOD_SETTINGS.equals(
130                 getActivity().getIntent().getAction());
131         getActivity().getIntent().setAction(null);
132         if (mIsOnlyImeSettings) {
133             getPreferenceScreen().removeAll();
134             getPreferenceScreen().addPreference(mHardKeyboardCategory);
135             if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
136                 getPreferenceScreen().addPreference(mShowInputMethodSelectorPref);
137             }
138             getPreferenceScreen().addPreference(mKeyboardSettingsCategory);
139         }
140 
141         // Build IME preference category.
142         mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
143         mImis = mImm.getInputMethodList();
144 
145         mKeyboardSettingsCategory.removeAll();
146         if (!mIsOnlyImeSettings) {
147             final PreferenceScreen currentIme = new PreferenceScreen(getActivity(), null);
148             currentIme.setKey(KEY_CURRENT_INPUT_METHOD);
149             currentIme.setTitle(getResources().getString(R.string.current_input_method));
150             mKeyboardSettingsCategory.addPreference(currentIme);
151         }
152 
153         mInputMethodPreferenceList.clear();
154         final int N = (mImis == null ? 0 : mImis.size());
155         for (int i = 0; i < N; ++i) {
156             final InputMethodInfo imi = mImis.get(i);
157             final InputMethodPreference pref = getInputMethodPreference(imi, N);
158             mInputMethodPreferenceList.add(pref);
159         }
160 
161         if (!mInputMethodPreferenceList.isEmpty()) {
162             Collections.sort(mInputMethodPreferenceList);
163             for (int i = 0; i < N; ++i) {
164                 mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i));
165             }
166         }
167 
168         // Build hard keyboard and game controller preference categories.
169         mIm = (InputManager)getActivity().getSystemService(Context.INPUT_SERVICE);
170         updateInputDevices();
171 
172         // Spell Checker
173         final Intent intent = new Intent(Intent.ACTION_MAIN);
174         intent.setClass(getActivity(), SpellCheckersSettingsActivity.class);
175         final SpellCheckersPreference scp = ((SpellCheckersPreference)findPreference(
176                 "spellcheckers_settings"));
177         if (scp != null) {
178             scp.setFragmentIntent(this, intent);
179         }
180 
181         mHandler = new Handler();
182         mSettingsObserver = new SettingsObserver(mHandler, getActivity());
183     }
184 
updateInputMethodSelectorSummary(int value)185     private void updateInputMethodSelectorSummary(int value) {
186         String[] inputMethodSelectorTitles = getResources().getStringArray(
187                 R.array.input_method_selector_titles);
188         if (inputMethodSelectorTitles.length > value) {
189             mShowInputMethodSelectorPref.setSummary(inputMethodSelectorTitles[value]);
190             mShowInputMethodSelectorPref.setValue(String.valueOf(value));
191         }
192     }
193 
updateUserDictionaryPreference(Preference userDictionaryPreference)194     private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
195         final Activity activity = getActivity();
196         final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
197         if (null == localeList) {
198             // The locale list is null if and only if the user dictionary service is
199             // not present or disabled. In this case we need to remove the preference.
200             getPreferenceScreen().removePreference(userDictionaryPreference);
201         } else if (localeList.size() <= 1) {
202             final Intent intent =
203                     new Intent(UserDictionaryList.USER_DICTIONARY_SETTINGS_INTENT_ACTION);
204             userDictionaryPreference.setTitle(R.string.user_dict_single_settings_title);
205             userDictionaryPreference.setIntent(intent);
206             userDictionaryPreference.setFragment(
207                     com.android.settings.UserDictionarySettings.class.getName());
208             // If the size of localeList is 0, we don't set the locale parameter in the
209             // extras. This will be interpreted by the UserDictionarySettings class as
210             // meaning "the current locale".
211             // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
212             // the locale list always has at least one element, since it always includes the current
213             // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
214             if (localeList.size() == 1) {
215                 final String locale = (String)localeList.toArray()[0];
216                 userDictionaryPreference.getExtras().putString("locale", locale);
217             }
218         } else {
219             userDictionaryPreference.setTitle(R.string.user_dict_multiple_settings_title);
220             userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
221         }
222     }
223 
224     @Override
onResume()225     public void onResume() {
226         super.onResume();
227 
228         mSettingsObserver.resume();
229         mIm.registerInputDeviceListener(this, null);
230 
231         if (!mIsOnlyImeSettings) {
232             if (mLanguagePref != null) {
233                 Configuration conf = getResources().getConfiguration();
234                 String language = conf.locale.getLanguage();
235                 String localeString;
236                 // TODO: This is not an accurate way to display the locale, as it is
237                 // just working around the fact that we support limited dialects
238                 // and want to pretend that the language is valid for all locales.
239                 // We need a way to support languages that aren't tied to a particular
240                 // locale instead of hiding the locale qualifier.
241                 if (language.equals("zz")) {
242                     String country = conf.locale.getCountry();
243                     if (country.equals("ZZ")) {
244                         localeString = "[Developer] Accented English (zz_ZZ)";
245                     } else if (country.equals("ZY")) {
246                         localeString = "[Developer] Fake Bi-Directional (zz_ZY)";
247                     } else {
248                         localeString = "";
249                     }
250                 } else if (hasOnlyOneLanguageInstance(language,
251                         Resources.getSystem().getAssets().getLocales())) {
252                     localeString = conf.locale.getDisplayLanguage(conf.locale);
253                 } else {
254                     localeString = conf.locale.getDisplayName(conf.locale);
255                 }
256                 if (localeString.length() > 1) {
257                     localeString = Character.toUpperCase(localeString.charAt(0))
258                             + localeString.substring(1);
259                     mLanguagePref.setSummary(localeString);
260                 }
261             }
262 
263             updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
264             if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
265                 mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
266             }
267         }
268 
269         // Hard keyboard
270         if (!mHardKeyboardPreferenceList.isEmpty()) {
271             for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
272                 CheckBoxPreference chkPref = (CheckBoxPreference)
273                         mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i]);
274                 chkPref.setChecked(
275                         System.getInt(getContentResolver(), sSystemSettingNames[i], 1) > 0);
276             }
277         }
278 
279         updateInputDevices();
280 
281         // IME
282         InputMethodAndSubtypeUtil.loadInputMethodSubtypeList(
283                 this, getContentResolver(), mImis, null);
284         updateActiveInputMethodsSummary();
285     }
286 
287     @Override
onPause()288     public void onPause() {
289         super.onPause();
290 
291         mIm.unregisterInputDeviceListener(this);
292         mSettingsObserver.pause();
293 
294         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
295             mShowInputMethodSelectorPref.setOnPreferenceChangeListener(null);
296         }
297         InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
298                 this, getContentResolver(), mImis, !mHardKeyboardPreferenceList.isEmpty());
299     }
300 
301     @Override
onInputDeviceAdded(int deviceId)302     public void onInputDeviceAdded(int deviceId) {
303         updateInputDevices();
304     }
305 
306     @Override
onInputDeviceChanged(int deviceId)307     public void onInputDeviceChanged(int deviceId) {
308         updateInputDevices();
309     }
310 
311     @Override
onInputDeviceRemoved(int deviceId)312     public void onInputDeviceRemoved(int deviceId) {
313         updateInputDevices();
314     }
315 
316     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)317     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
318         // Input Method stuff
319         if (Utils.isMonkeyRunning()) {
320             return false;
321         }
322         if (preference instanceof PreferenceScreen) {
323             if (preference.getFragment() != null) {
324                 // Fragment will be handled correctly by the super class.
325             } else if (KEY_CURRENT_INPUT_METHOD.equals(preference.getKey())) {
326                 final InputMethodManager imm = (InputMethodManager)
327                         getSystemService(Context.INPUT_METHOD_SERVICE);
328                 imm.showInputMethodPicker();
329             }
330         } else if (preference instanceof CheckBoxPreference) {
331             final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
332             if (!mHardKeyboardPreferenceList.isEmpty()) {
333                 for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
334                     if (chkPref == mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i])) {
335                         System.putInt(getContentResolver(), sSystemSettingNames[i],
336                                 chkPref.isChecked() ? 1 : 0);
337                         return true;
338                     }
339                 }
340             }
341             if (chkPref == mGameControllerCategory.findPreference("vibrate_input_devices")) {
342                 System.putInt(getContentResolver(), Settings.System.VIBRATE_INPUT_DEVICES,
343                         chkPref.isChecked() ? 1 : 0);
344                 return true;
345             }
346         }
347         return super.onPreferenceTreeClick(preferenceScreen, preference);
348     }
349 
hasOnlyOneLanguageInstance(String languageCode, String[] locales)350     private boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) {
351         int count = 0;
352         for (String localeCode : locales) {
353             if (localeCode.length() > 2
354                     && localeCode.startsWith(languageCode)) {
355                 count++;
356                 if (count > 1) {
357                     return false;
358                 }
359             }
360         }
361         return count == 1;
362     }
363 
saveInputMethodSelectorVisibility(String value)364     private void saveInputMethodSelectorVisibility(String value) {
365         try {
366             int intValue = Integer.valueOf(value);
367             Settings.Secure.putInt(getContentResolver(),
368                     Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, intValue);
369             updateInputMethodSelectorSummary(intValue);
370         } catch(NumberFormatException e) {
371         }
372     }
373 
loadInputMethodSelectorVisibility()374     private int loadInputMethodSelectorVisibility() {
375         return Settings.Secure.getInt(getContentResolver(),
376                 Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
377                 mDefaultInputMethodSelectorVisibility);
378     }
379 
380     @Override
onPreferenceChange(Preference preference, Object value)381     public boolean onPreferenceChange(Preference preference, Object value) {
382         if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) {
383             if (preference == mShowInputMethodSelectorPref) {
384                 if (value instanceof String) {
385                     saveInputMethodSelectorVisibility((String)value);
386                 }
387             }
388         }
389         return false;
390     }
391 
updateActiveInputMethodsSummary()392     private void updateActiveInputMethodsSummary() {
393         for (Preference pref : mInputMethodPreferenceList) {
394             if (pref instanceof InputMethodPreference) {
395                 ((InputMethodPreference)pref).updateSummary();
396             }
397         }
398         updateCurrentImeName();
399     }
400 
updateCurrentImeName()401     private void updateCurrentImeName() {
402         final Context context = getActivity();
403         if (context == null || mImm == null) return;
404         final Preference curPref = getPreferenceScreen().findPreference(KEY_CURRENT_INPUT_METHOD);
405         if (curPref != null) {
406             final CharSequence curIme = InputMethodAndSubtypeUtil.getCurrentInputMethodName(
407                     context, getContentResolver(), mImm, mImis, getPackageManager());
408             if (!TextUtils.isEmpty(curIme)) {
409                 synchronized(this) {
410                     curPref.setSummary(curIme);
411                 }
412             }
413         }
414     }
415 
getInputMethodPreference(InputMethodInfo imi, int imiSize)416     private InputMethodPreference getInputMethodPreference(InputMethodInfo imi, int imiSize) {
417         final PackageManager pm = getPackageManager();
418         final CharSequence label = imi.loadLabel(pm);
419         // IME settings
420         final Intent intent;
421         final String settingsActivity = imi.getSettingsActivity();
422         if (!TextUtils.isEmpty(settingsActivity)) {
423             intent = new Intent(Intent.ACTION_MAIN);
424             intent.setClassName(imi.getPackageName(), settingsActivity);
425         } else {
426             intent = null;
427         }
428 
429         // Add a check box for enabling/disabling IME
430         InputMethodPreference pref = new InputMethodPreference(this, intent, mImm, imi, imiSize);
431         pref.setKey(imi.getId());
432         pref.setTitle(label);
433         return pref;
434     }
435 
updateInputDevices()436     private void updateInputDevices() {
437         updateHardKeyboards();
438         updateGameControllers();
439     }
440 
updateHardKeyboards()441     private void updateHardKeyboards() {
442         mHardKeyboardPreferenceList.clear();
443         if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) {
444             final int[] devices = InputDevice.getDeviceIds();
445             for (int i = 0; i < devices.length; i++) {
446                 InputDevice device = InputDevice.getDevice(devices[i]);
447                 if (device != null
448                         && !device.isVirtual()
449                         && device.isFullKeyboard()) {
450                     final String inputDeviceDescriptor = device.getDescriptor();
451                     final String keyboardLayoutDescriptor =
452                             mIm.getCurrentKeyboardLayoutForInputDevice(inputDeviceDescriptor);
453                     final KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ?
454                             mIm.getKeyboardLayout(keyboardLayoutDescriptor) : null;
455 
456                     final PreferenceScreen pref = new PreferenceScreen(getActivity(), null);
457                     pref.setTitle(device.getName());
458                     if (keyboardLayout != null) {
459                         pref.setSummary(keyboardLayout.toString());
460                     } else {
461                         pref.setSummary(R.string.keyboard_layout_default_label);
462                     }
463                     pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
464                         @Override
465                         public boolean onPreferenceClick(Preference preference) {
466                             showKeyboardLayoutDialog(inputDeviceDescriptor);
467                             return true;
468                         }
469                     });
470                     mHardKeyboardPreferenceList.add(pref);
471                 }
472             }
473         }
474 
475         if (!mHardKeyboardPreferenceList.isEmpty()) {
476             for (int i = mHardKeyboardCategory.getPreferenceCount(); i-- > 0; ) {
477                 final Preference pref = mHardKeyboardCategory.getPreference(i);
478                 if (pref.getOrder() < 1000) {
479                     mHardKeyboardCategory.removePreference(pref);
480                 }
481             }
482 
483             Collections.sort(mHardKeyboardPreferenceList);
484             final int count = mHardKeyboardPreferenceList.size();
485             for (int i = 0; i < count; i++) {
486                 final Preference pref = mHardKeyboardPreferenceList.get(i);
487                 pref.setOrder(i);
488                 mHardKeyboardCategory.addPreference(pref);
489             }
490 
491             getPreferenceScreen().addPreference(mHardKeyboardCategory);
492         } else {
493             getPreferenceScreen().removePreference(mHardKeyboardCategory);
494         }
495     }
496 
showKeyboardLayoutDialog(String inputDeviceDescriptor)497     private void showKeyboardLayoutDialog(String inputDeviceDescriptor) {
498         KeyboardLayoutDialogFragment fragment =
499                 new KeyboardLayoutDialogFragment(inputDeviceDescriptor);
500         fragment.setTargetFragment(this, 0);
501         fragment.show(getActivity().getFragmentManager(), "keyboardLayout");
502     }
503 
504     @Override
onSetupKeyboardLayouts(String inputDeviceDescriptor)505     public void onSetupKeyboardLayouts(String inputDeviceDescriptor) {
506         final Intent intent = new Intent(Intent.ACTION_MAIN);
507         intent.setClass(getActivity(), KeyboardLayoutPickerActivity.class);
508         intent.putExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR,
509                 inputDeviceDescriptor);
510         mIntentWaitingForResult = intent;
511         startActivityForResult(intent, 0);
512     }
513 
514     @Override
onActivityResult(int requestCode, int resultCode, Intent data)515     public void onActivityResult(int requestCode, int resultCode, Intent data) {
516         super.onActivityResult(requestCode, resultCode, data);
517 
518         if (mIntentWaitingForResult != null) {
519             String inputDeviceDescriptor = mIntentWaitingForResult.getStringExtra(
520                     KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_DESCRIPTOR);
521             mIntentWaitingForResult = null;
522             showKeyboardLayoutDialog(inputDeviceDescriptor);
523         }
524     }
525 
updateGameControllers()526     private void updateGameControllers() {
527         if (haveInputDeviceWithVibrator()) {
528             getPreferenceScreen().addPreference(mGameControllerCategory);
529 
530             CheckBoxPreference chkPref = (CheckBoxPreference)
531                     mGameControllerCategory.findPreference("vibrate_input_devices");
532             chkPref.setChecked(System.getInt(getContentResolver(),
533                     Settings.System.VIBRATE_INPUT_DEVICES, 1) > 0);
534         } else {
535             getPreferenceScreen().removePreference(mGameControllerCategory);
536         }
537     }
538 
haveInputDeviceWithVibrator()539     private boolean haveInputDeviceWithVibrator() {
540         final int[] devices = InputDevice.getDeviceIds();
541         for (int i = 0; i < devices.length; i++) {
542             InputDevice device = InputDevice.getDevice(devices[i]);
543             if (device != null && !device.isVirtual() && device.getVibrator().hasVibrator()) {
544                 return true;
545             }
546         }
547         return false;
548     }
549 
550     private class SettingsObserver extends ContentObserver {
551         private Context mContext;
552 
SettingsObserver(Handler handler, Context context)553         public SettingsObserver(Handler handler, Context context) {
554             super(handler);
555             mContext = context;
556         }
557 
onChange(boolean selfChange)558         @Override public void onChange(boolean selfChange) {
559             updateCurrentImeName();
560         }
561 
resume()562         public void resume() {
563             final ContentResolver cr = mContext.getContentResolver();
564             cr.registerContentObserver(
565                     Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
566             cr.registerContentObserver(Settings.Secure.getUriFor(
567                     Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this);
568         }
569 
pause()570         public void pause() {
571             mContext.getContentResolver().unregisterContentObserver(this);
572         }
573     }
574 }
575