2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.pm.ApplicationInfo;
25 import android.content.res.Configuration;
26 import android.os.Bundle;
27 import android.preference.CheckBoxPreference;
28 import android.preference.Preference;
29 import android.preference.PreferenceGroup;
30 import android.preference.PreferenceScreen;
31 import android.provider.Settings;
32 import android.text.TextUtils;
33 import android.util.Log;
34 import android.view.inputmethod.InputMethodInfo;
35 import android.view.inputmethod.InputMethodManager;
37 import java.util.ArrayList;
38 import java.util.HashSet;
39 import java.util.List;
41 public class LanguageSettings extends SettingsPreferenceFragment {
42 private static final String TAG = LanguageSettings.class.getSimpleName();
44 private static final String KEY_PHONE_LANGUAGE = "phone_language";
45 private static final String KEY_INPUT_METHOD = "input_method";
46 private static final String KEY_KEYBOARD_SETTINGS_CATEGORY = "keyboard_settings_category";
47 private static final String KEY_HARDKEYBOARD_CATEGORY = "hardkeyboard_category";
48 private boolean mHaveHardKeyboard;
50 private List<InputMethodInfo> mInputMethodProperties;
51 private List<CheckBoxPreference> mCheckboxes;
52 private Preference mLanguagePref;
54 final TextUtils.SimpleStringSplitter mStringColonSplitter
55 = new TextUtils.SimpleStringSplitter(':');
57 private String mLastTickedInputMethodId;
59 private AlertDialog mDialog = null;
61 static public String getInputMethodIdFromKey(String key) {
66 public void onCreate(Bundle icicle) {
67 super.onCreate(icicle);
69 addPreferencesFromResource(R.xml.language_settings);
71 if (getActivity().getAssets().getLocales().length == 1) {
72 getPreferenceScreen().
73 removePreference(findPreference(KEY_PHONE_LANGUAGE));
75 mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
78 Configuration config = getResources().getConfiguration();
79 if (config.keyboard != Configuration.KEYBOARD_QWERTY) {
80 getPreferenceScreen().removePreference(
81 getPreferenceScreen().findPreference(KEY_HARDKEYBOARD_CATEGORY));
83 mHaveHardKeyboard = true;
85 mCheckboxes = new ArrayList<CheckBoxPreference>();
89 private boolean isSystemIme(InputMethodInfo property) {
90 return (property.getServiceInfo().applicationInfo.flags
91 & ApplicationInfo.FLAG_SYSTEM) != 0;
94 private void onCreateIMM() {
95 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
97 mInputMethodProperties = imm.getInputMethodList();
99 PreferenceGroup keyboardSettingsCategory = (PreferenceGroup) findPreference(
100 KEY_KEYBOARD_SETTINGS_CATEGORY);
102 int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
104 for (int i = 0; i < N; ++i) {
105 InputMethodInfo property = mInputMethodProperties.get(i);
106 String prefKey = property.getId();
108 CharSequence label = property.loadLabel(getActivity().getPackageManager());
109 boolean systemIME = isSystemIme(property);
111 // Don't show the toggle if it's the only keyboard in the system, or it's a system IME.
112 if (mHaveHardKeyboard || (N > 1 && !systemIME)) {
113 CheckBoxPreference chkbxPref = new CheckBoxPreference(getActivity());
114 chkbxPref.setKey(prefKey);
115 chkbxPref.setTitle(label);
116 keyboardSettingsCategory.addPreference(chkbxPref);
117 mCheckboxes.add(chkbxPref);
120 // If setting activity is available, add a setting screen entry.
121 if (null != property.getSettingsActivity()) {
122 PreferenceScreen prefScreen = new PreferenceScreen(getActivity(), null);
123 String settingsActivity = property.getSettingsActivity();
124 if (settingsActivity.lastIndexOf("/") < 0) {
125 settingsActivity = property.getPackageName() + "/" + settingsActivity;
127 prefScreen.setKey(settingsActivity);
128 prefScreen.setTitle(label);
130 prefScreen.setSummary(getResources().getString(
131 R.string.onscreen_keyboard_settings_summary));
133 CharSequence settingsLabel = getResources().getString(
134 R.string.input_methods_settings_label_format, label);
135 prefScreen.setSummary(settingsLabel);
137 keyboardSettingsCategory.addPreference(prefScreen);
143 public void onResume() {
146 final HashSet<String> enabled = new HashSet<String>();
147 String enabledStr = Settings.Secure.getString(getContentResolver(),
148 Settings.Secure.ENABLED_INPUT_METHODS);
149 if (enabledStr != null) {
150 final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
151 splitter.setString(enabledStr);
152 while (splitter.hasNext()) {
153 enabled.add(splitter.next());
157 // Update the statuses of the Check Boxes.
158 int N = mInputMethodProperties.size();
159 for (int i = 0; i < N; ++i) {
160 final String id = mInputMethodProperties.get(i).getId();
161 CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
164 pref.setChecked(enabled.contains(id));
167 mLastTickedInputMethodId = null;
169 if (mLanguagePref != null) {
170 Configuration conf = getResources().getConfiguration();
171 String locale = conf.locale.getDisplayName(conf.locale);
172 if (locale != null && locale.length() > 1) {
173 locale = Character.toUpperCase(locale.charAt(0)) + locale.substring(1);
174 mLanguagePref.setSummary(locale);
180 public void onPause() {
183 String lastInputMethodId = Settings.Secure.getString(getContentResolver(),
184 Settings.Secure.DEFAULT_INPUT_METHOD);
186 StringBuilder builder = new StringBuilder();
187 StringBuilder disabledSysImes = new StringBuilder();
189 int firstEnabled = -1;
190 int N = mInputMethodProperties.size();
191 for (int i = 0; i < N; ++i) {
192 final InputMethodInfo property = mInputMethodProperties.get(i);
193 final String id = property.getId();
194 CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
195 boolean hasIt = id.equals(lastInputMethodId);
196 boolean systemIme = isSystemIme(property);
197 if (((N == 1 || systemIme) && !mHaveHardKeyboard)
198 || (pref != null && pref.isChecked())) {
199 if (builder.length() > 0) builder.append(':');
201 if (firstEnabled < 0) {
205 lastInputMethodId = mLastTickedInputMethodId;
207 // If it's a disabled system ime, add it to the disabled list so that it
208 // doesn't get enabled automatically on any changes to the package list
209 if (pref != null && !pref.isChecked() && systemIme && mHaveHardKeyboard) {
210 if (disabledSysImes.length() > 0) disabledSysImes.append(":");
211 disabledSysImes.append(id);
215 // If the last input method is unset, set it as the first enabled one.
216 if (null == lastInputMethodId || "".equals(lastInputMethodId)) {
217 if (firstEnabled >= 0) {
218 lastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
220 lastInputMethodId = null;
224 Settings.Secure.putString(getContentResolver(),
225 Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
226 Settings.Secure.putString(getContentResolver(),
227 Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, disabledSysImes.toString());
228 Settings.Secure.putString(getContentResolver(),
229 Settings.Secure.DEFAULT_INPUT_METHOD,
230 lastInputMethodId != null ? lastInputMethodId : "");
234 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
236 // Input Method stuff
237 if (Utils.isMonkeyRunning()) {
241 if (preference instanceof CheckBoxPreference) {
242 final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
243 final String id = getInputMethodIdFromKey(chkPref.getKey());
244 if (chkPref.isChecked()) {
245 InputMethodInfo selImi = null;
246 final int N = mInputMethodProperties.size();
247 for (int i=0; i<N; i++) {
248 InputMethodInfo imi = mInputMethodProperties.get(i);
249 if (id.equals(imi.getId())) {
251 if (isSystemIme(imi)) {
252 // This is a built-in IME, so no need to warn.
253 mLastTickedInputMethodId = id;
254 return super.onPreferenceTreeClick(preferenceScreen, preference);
258 chkPref.setChecked(false);
259 if (selImi == null) {
260 return super.onPreferenceTreeClick(preferenceScreen, preference);
262 if (mDialog == null) {
263 // TODO: DialogFragment?
264 mDialog = (new AlertDialog.Builder(getActivity()))
265 .setTitle(android.R.string.dialog_alert_title)
266 .setIcon(android.R.drawable.ic_dialog_alert)
268 .setPositiveButton(android.R.string.ok,
269 new DialogInterface.OnClickListener() {
270 public void onClick(DialogInterface dialog, int which) {
271 chkPref.setChecked(true);
272 mLastTickedInputMethodId = id;
276 .setNegativeButton(android.R.string.cancel,
277 new DialogInterface.OnClickListener() {
278 public void onClick(DialogInterface dialog, int which) {
284 if (mDialog.isShowing()) {
288 mDialog.setMessage(getResources().getString(
289 R.string.ime_security_warning,
290 selImi.getServiceInfo().applicationInfo.loadLabel(getPackageManager())));
292 } else if (id.equals(mLastTickedInputMethodId)) {
293 mLastTickedInputMethodId = null;
295 } else if (preference instanceof PreferenceScreen) {
296 if (preference.getFragment() != null) {
297 // Fragment will be handled correctly by the super class.
298 } else if (KEY_INPUT_METHOD.equals(preference.getKey())) {
299 final InputMethodManager imm = (InputMethodManager)
300 getSystemService(Context.INPUT_METHOD_SERVICE);
301 imm.showInputMethodSubtypePicker();
302 } else if (preference.getIntent() == null) {
303 PreferenceScreen pref = (PreferenceScreen) preference;
304 String activityName = pref.getKey();
305 String packageName = activityName.substring(0, activityName
307 int slash = activityName.indexOf("/");
309 packageName = activityName.substring(0, slash);
310 activityName = activityName.substring(slash + 1);
312 if (activityName.length() > 0) {
313 Intent i = new Intent(Intent.ACTION_MAIN);
314 i.setClassName(packageName, activityName);
319 return super.onPreferenceTreeClick(preferenceScreen, preference);
323 public void onDestroy() {
325 if (mDialog != null) {