InputMethodAndLanguageSettings.java revision a718832e28095219a897c6e95e903c1a3fe57c12
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 17package com.android.settings; 18 19import android.app.AlertDialog; 20import android.app.Dialog; 21import android.content.Context; 22import android.content.DialogInterface; 23import android.content.Intent; 24import android.content.pm.ApplicationInfo; 25import android.content.res.Configuration; 26import android.os.Bundle; 27import android.os.Environment; 28import android.os.SystemProperties; 29import android.preference.CheckBoxPreference; 30import android.preference.Preference; 31import android.preference.PreferenceActivity; 32import android.preference.PreferenceGroup; 33import android.preference.PreferenceScreen; 34import android.provider.Settings; 35import android.text.TextUtils; 36import android.view.View.OnClickListener; 37import android.view.inputmethod.InputMethodInfo; 38import android.view.inputmethod.InputMethodManager; 39 40import java.util.ArrayList; 41import java.util.HashSet; 42import java.util.List; 43 44public class LanguageSettings extends PreferenceActivity { 45 46 private boolean mHaveHardKeyboard; 47 48 private List<InputMethodInfo> mInputMethodProperties; 49 private List<CheckBoxPreference> mCheckboxes; 50 51 final TextUtils.SimpleStringSplitter mStringColonSplitter 52 = new TextUtils.SimpleStringSplitter(':'); 53 54 private String mLastInputMethodId; 55 private String mLastTickedInputMethodId; 56 57 static public String getInputMethodIdFromKey(String key) { 58 return key; 59 } 60 61 @Override 62 protected void onCreate(Bundle icicle) { 63 super.onCreate(icicle); 64 65 addPreferencesFromResource(R.xml.language_settings); 66 67 if (getAssets().getLocales().length == 1) { 68 getPreferenceScreen(). 69 removePreference(findPreference("language_category")); 70 } 71 72 Configuration config = getResources().getConfiguration(); 73 if (config.keyboard != Configuration.KEYBOARD_QWERTY) { 74 getPreferenceScreen().removePreference( 75 getPreferenceScreen().findPreference("hardkeyboard_category")); 76 } else { 77 mHaveHardKeyboard = true; 78 } 79 mCheckboxes = new ArrayList<CheckBoxPreference>(); 80 onCreateIMM(); 81 } 82 83 private boolean isSystemIme(InputMethodInfo property) { 84 return (property.getServiceInfo().applicationInfo.flags 85 & ApplicationInfo.FLAG_SYSTEM) != 0; 86 } 87 88 private void onCreateIMM() { 89 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 90 91 mInputMethodProperties = imm.getInputMethodList(); 92 93 mLastInputMethodId = Settings.Secure.getString(getContentResolver(), 94 Settings.Secure.DEFAULT_INPUT_METHOD); 95 96 PreferenceGroup textCategory = (PreferenceGroup) findPreference("text_category"); 97 98 int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties 99 .size()); 100 for (int i = 0; i < N; ++i) { 101 InputMethodInfo property = mInputMethodProperties.get(i); 102 String prefKey = property.getId(); 103 104 CharSequence label = property.loadLabel(getPackageManager()); 105 boolean systemIME = isSystemIme(property); 106 // Add a check box. 107 // Don't show the toggle if it's the only keyboard in the system, or it's a system IME. 108 if (mHaveHardKeyboard || (N > 1 && !systemIME)) { 109 CheckBoxPreference chkbxPref = new CheckBoxPreference(this); 110 chkbxPref.setKey(prefKey); 111 chkbxPref.setTitle(label); 112 textCategory.addPreference(chkbxPref); 113 mCheckboxes.add(chkbxPref); 114 } 115 116 // If setting activity is available, add a setting screen entry. 117 if (null != property.getSettingsActivity()) { 118 PreferenceScreen prefScreen = new PreferenceScreen(this, null); 119 prefScreen.setKey(property.getSettingsActivity()); 120 prefScreen.setTitle(label); 121 if (N == 1) { 122 prefScreen.setSummary(getString(R.string.onscreen_keyboard_settings_summary)); 123 } else { 124 CharSequence settingsLabel = getResources().getString( 125 R.string.input_methods_settings_label_format, label); 126 prefScreen.setSummary(settingsLabel); 127 } 128 textCategory.addPreference(prefScreen); 129 } 130 } 131 } 132 133 @Override 134 protected void onResume() { 135 super.onResume(); 136 137 final HashSet<String> enabled = new HashSet<String>(); 138 String enabledStr = Settings.Secure.getString(getContentResolver(), 139 Settings.Secure.ENABLED_INPUT_METHODS); 140 if (enabledStr != null) { 141 final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; 142 splitter.setString(enabledStr); 143 while (splitter.hasNext()) { 144 enabled.add(splitter.next()); 145 } 146 } 147 148 // Update the statuses of the Check Boxes. 149 int N = mInputMethodProperties.size(); 150 for (int i = 0; i < N; ++i) { 151 final String id = mInputMethodProperties.get(i).getId(); 152 CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties 153 .get(i).getId()); 154 if (pref != null) { 155 pref.setChecked(enabled.contains(id)); 156 } 157 } 158 mLastTickedInputMethodId = null; 159 } 160 161 @Override 162 protected void onPause() { 163 super.onPause(); 164 165 StringBuilder builder = new StringBuilder(256); 166 167 int firstEnabled = -1; 168 int N = mInputMethodProperties.size(); 169 for (int i = 0; i < N; ++i) { 170 final InputMethodInfo property = mInputMethodProperties.get(i); 171 final String id = property.getId(); 172 CheckBoxPreference pref = (CheckBoxPreference) findPreference(id); 173 boolean hasIt = id.equals(mLastInputMethodId); 174 boolean systemIme = isSystemIme(property); 175 if (((N == 1 || systemIme) && !mHaveHardKeyboard) 176 || (pref != null && pref.isChecked())) { 177 if (builder.length() > 0) builder.append(':'); 178 builder.append(id); 179 if (firstEnabled < 0) { 180 firstEnabled = i; 181 } 182 } else if (hasIt) { 183 mLastInputMethodId = mLastTickedInputMethodId; 184 } 185 } 186 187 // If the last input method is unset, set it as the first enabled one. 188 if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) { 189 if (firstEnabled >= 0) { 190 mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId(); 191 } else { 192 mLastInputMethodId = null; 193 } 194 } 195 196 Settings.Secure.putString(getContentResolver(), 197 Settings.Secure.ENABLED_INPUT_METHODS, builder.toString()); 198 Settings.Secure.putString(getContentResolver(), 199 Settings.Secure.DEFAULT_INPUT_METHOD, 200 mLastInputMethodId != null ? mLastInputMethodId : ""); 201 } 202 203 @Override 204 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 205 206 // Input Method stuff 207 if (Utils.isMonkeyRunning()) { 208 return false; 209 } 210 211 if (preference instanceof CheckBoxPreference) { 212 final CheckBoxPreference chkPref = (CheckBoxPreference) preference; 213 final String id = getInputMethodIdFromKey(chkPref.getKey()); 214 if (chkPref.isChecked()) { 215 InputMethodInfo selImi = null; 216 final int N = mInputMethodProperties.size(); 217 for (int i=0; i<N; i++) { 218 InputMethodInfo imi = mInputMethodProperties.get(i); 219 if (id.equals(imi.getId())) { 220 selImi = imi; 221 if (isSystemIme(imi)) { 222 // This is a built-in IME, so no need to warn. 223 mLastTickedInputMethodId = id; 224 return super.onPreferenceTreeClick(preferenceScreen, preference); 225 } 226 } 227 } 228 chkPref.setChecked(false); 229 if (selImi == null) { 230 return super.onPreferenceTreeClick(preferenceScreen, preference); 231 } 232 AlertDialog d = (new AlertDialog.Builder(this)) 233 .setTitle(android.R.string.dialog_alert_title) 234 .setIcon(android.R.drawable.ic_dialog_alert) 235 .setMessage(getString(R.string.ime_security_warning, 236 selImi.getServiceInfo().applicationInfo.loadLabel( 237 getPackageManager()))) 238 .setCancelable(true) 239 .setPositiveButton(android.R.string.ok, 240 new DialogInterface.OnClickListener() { 241 public void onClick(DialogInterface dialog, int which) { 242 chkPref.setChecked(true); 243 mLastTickedInputMethodId = id; 244 } 245 246 }) 247 .setNegativeButton(android.R.string.cancel, 248 new DialogInterface.OnClickListener() { 249 public void onClick(DialogInterface dialog, int which) { 250 } 251 252 }) 253 .create(); 254 d.show(); 255 } else if (id.equals(mLastTickedInputMethodId)) { 256 mLastTickedInputMethodId = null; 257 } 258 } else if (preference instanceof PreferenceScreen) { 259 if (preference.getIntent() == null) { 260 PreferenceScreen pref = (PreferenceScreen) preference; 261 String activityName = pref.getKey(); 262 String packageName = activityName.substring(0, activityName 263 .lastIndexOf(".")); 264 if (activityName.length() > 0) { 265 Intent i = new Intent(Intent.ACTION_MAIN); 266 i.setClassName(packageName, activityName); 267 startActivity(i); 268 } 269 } 270 } 271 return super.onPreferenceTreeClick(preferenceScreen, preference); 272 } 273 274} 275