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.AlertDialog;
20 import android.app.Dialog;
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.os.Environment;
28 import android.os.SystemProperties;
29 import android.preference.CheckBoxPreference;
30 import android.preference.Preference;
31 import android.preference.PreferenceActivity;
32 import android.preference.PreferenceGroup;
33 import android.preference.PreferenceScreen;
34 import android.provider.Settings;
35 import android.text.TextUtils;
36 import android.view.View.OnClickListener;
37 import android.view.inputmethod.InputMethodInfo;
38 import android.view.inputmethod.InputMethodManager;
40 import java.util.ArrayList;
41 import java.util.HashSet;
42 import java.util.List;
44 public class LanguageSettings extends PreferenceActivity {
46 private static final String KEY_PHONE_LANGUAGE = "phone_language";
47 private static final String KEY_KEYBOARD_SETTINGS_CATEGORY = "keyboard_settings_category";
48 private static final String KEY_HARDKEYBOARD_CATEGORY = "hardkeyboard_category";
49 private boolean mHaveHardKeyboard;
51 private List<InputMethodInfo> mInputMethodProperties;
52 private List<CheckBoxPreference> mCheckboxes;
53 private Preference mLanguagePref;
55 final TextUtils.SimpleStringSplitter mStringColonSplitter
56 = new TextUtils.SimpleStringSplitter(':');
58 private String mLastInputMethodId;
59 private String mLastTickedInputMethodId;
61 private AlertDialog mDialog = null;
63 static public String getInputMethodIdFromKey(String key) {
68 protected void onCreate(Bundle icicle) {
69 super.onCreate(icicle);
71 addPreferencesFromResource(R.xml.language_settings);
73 if (getAssets().getLocales().length == 1) {
74 getPreferenceScreen().
75 removePreference(findPreference(KEY_PHONE_LANGUAGE));
77 mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
80 Configuration config = getResources().getConfiguration();
81 if (config.keyboard != Configuration.KEYBOARD_QWERTY) {
82 getPreferenceScreen().removePreference(
83 getPreferenceScreen().findPreference(KEY_HARDKEYBOARD_CATEGORY));
85 mHaveHardKeyboard = true;
87 mCheckboxes = new ArrayList<CheckBoxPreference>();
91 private boolean isSystemIme(InputMethodInfo property) {
92 return (property.getServiceInfo().applicationInfo.flags
93 & ApplicationInfo.FLAG_SYSTEM) != 0;
96 private void onCreateIMM() {
97 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
99 mInputMethodProperties = imm.getInputMethodList();
101 mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
102 Settings.Secure.DEFAULT_INPUT_METHOD);
104 PreferenceGroup keyboardSettingsCategory = (PreferenceGroup) findPreference(
105 KEY_KEYBOARD_SETTINGS_CATEGORY);
107 int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
109 for (int i = 0; i < N; ++i) {
110 InputMethodInfo property = mInputMethodProperties.get(i);
111 String prefKey = property.getId();
113 CharSequence label = property.loadLabel(getPackageManager());
114 boolean systemIME = isSystemIme(property);
116 // Don't show the toggle if it's the only keyboard in the system, or it's a system IME.
117 if (mHaveHardKeyboard || (N > 1 && !systemIME)) {
118 CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
119 chkbxPref.setKey(prefKey);
120 chkbxPref.setTitle(label);
121 keyboardSettingsCategory.addPreference(chkbxPref);
122 mCheckboxes.add(chkbxPref);
125 // If setting activity is available, add a setting screen entry.
126 if (null != property.getSettingsActivity()) {
127 PreferenceScreen prefScreen = new PreferenceScreen(this, null);
128 String settingsActivity = property.getSettingsActivity();
129 if (settingsActivity.lastIndexOf("/") < 0) {
130 settingsActivity = property.getPackageName() + "/" + settingsActivity;
132 prefScreen.setKey(settingsActivity);
133 prefScreen.setTitle(label);
135 prefScreen.setSummary(getString(R.string.onscreen_keyboard_settings_summary));
137 CharSequence settingsLabel = getResources().getString(
138 R.string.input_methods_settings_label_format, label);
139 prefScreen.setSummary(settingsLabel);
141 keyboardSettingsCategory.addPreference(prefScreen);
147 protected void onResume() {
150 final HashSet<String> enabled = new HashSet<String>();
151 String enabledStr = Settings.Secure.getString(getContentResolver(),
152 Settings.Secure.ENABLED_INPUT_METHODS);
153 if (enabledStr != null) {
154 final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
155 splitter.setString(enabledStr);
156 while (splitter.hasNext()) {
157 enabled.add(splitter.next());
161 // Update the statuses of the Check Boxes.
162 int N = mInputMethodProperties.size();
163 for (int i = 0; i < N; ++i) {
164 final String id = mInputMethodProperties.get(i).getId();
165 CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
168 pref.setChecked(enabled.contains(id));
171 mLastTickedInputMethodId = null;
173 if (mLanguagePref != null) {
174 Configuration conf = getResources().getConfiguration();
175 String locale = conf.locale.getDisplayName(conf.locale);
176 if (locale != null && locale.length() > 1) {
177 locale = Character.toUpperCase(locale.charAt(0)) + locale.substring(1);
178 mLanguagePref.setSummary(locale);
184 protected void onPause() {
187 StringBuilder builder = new StringBuilder(256);
188 StringBuilder disabledSysImes = new StringBuilder(256);
190 int firstEnabled = -1;
191 int N = mInputMethodProperties.size();
192 for (int i = 0; i < N; ++i) {
193 final InputMethodInfo property = mInputMethodProperties.get(i);
194 final String id = property.getId();
195 CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
196 boolean hasIt = id.equals(mLastInputMethodId);
197 boolean systemIme = isSystemIme(property);
198 if (((N == 1 || systemIme) && !mHaveHardKeyboard)
199 || (pref != null && pref.isChecked())) {
200 if (builder.length() > 0) builder.append(':');
202 if (firstEnabled < 0) {
206 mLastInputMethodId = mLastTickedInputMethodId;
208 // If it's a disabled system ime, add it to the disabled list so that it
209 // doesn't get enabled automatically on any changes to the package list
210 if (pref != null && !pref.isChecked() && systemIme && mHaveHardKeyboard) {
211 if (disabledSysImes.length() > 0) disabledSysImes.append(":");
212 disabledSysImes.append(id);
216 // If the last input method is unset, set it as the first enabled one.
217 if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) {
218 if (firstEnabled >= 0) {
219 mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
221 mLastInputMethodId = null;
225 Settings.Secure.putString(getContentResolver(),
226 Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
227 Settings.Secure.putString(getContentResolver(),
228 Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, disabledSysImes.toString());
229 Settings.Secure.putString(getContentResolver(),
230 Settings.Secure.DEFAULT_INPUT_METHOD,
231 mLastInputMethodId != null ? mLastInputMethodId : "");
235 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
237 // Input Method stuff
238 if (Utils.isMonkeyRunning()) {
242 if (preference instanceof CheckBoxPreference) {
243 final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
244 final String id = getInputMethodIdFromKey(chkPref.getKey());
245 if (chkPref.isChecked()) {
246 InputMethodInfo selImi = null;
247 final int N = mInputMethodProperties.size();
248 for (int i=0; i<N; i++) {
249 InputMethodInfo imi = mInputMethodProperties.get(i);
250 if (id.equals(imi.getId())) {
252 if (isSystemIme(imi)) {
253 // This is a built-in IME, so no need to warn.
254 mLastTickedInputMethodId = id;
255 return super.onPreferenceTreeClick(preferenceScreen, preference);
259 chkPref.setChecked(false);
260 if (selImi == null) {
261 return super.onPreferenceTreeClick(preferenceScreen, preference);
263 if (mDialog == null) {
264 mDialog = (new AlertDialog.Builder(this))
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(getString(R.string.ime_security_warning,
289 selImi.getServiceInfo().applicationInfo.loadLabel(
290 getPackageManager())));
292 } else if (id.equals(mLastTickedInputMethodId)) {
293 mLastTickedInputMethodId = null;
295 } else if (preference instanceof PreferenceScreen) {
296 if (preference.getIntent() == null) {
297 PreferenceScreen pref = (PreferenceScreen) preference;
298 String activityName = pref.getKey();
299 String packageName = activityName.substring(0, activityName
301 int slash = activityName.indexOf("/");
303 packageName = activityName.substring(0, slash);
304 activityName = activityName.substring(slash + 1);
306 if (activityName.length() > 0) {
307 Intent i = new Intent(Intent.ACTION_MAIN);
308 i.setClassName(packageName, activityName);
313 return super.onPreferenceTreeClick(preferenceScreen, preference);
317 protected void onDestroy() {
319 if (mDialog != null) {