[FAQ19122]Android N 首次开机不随sim卡自适应语言修改方案

来源:互联网 发布:sql语句union all 编辑:程序博客网 时间:2024/05/17 03:34
[DESCRIPTION]
 
           Android N和Android M上一样默认设计首次开机不会随Sim卡自适应语言,如要修改为随Sim卡自适应,可参考如下修改(Android N上language与M上有较大变化,可以同时选择多种语言,所以修改方案与M上也有所不同)。
           如果修改之后发现首次开机仍然无法自适应语言且版本是有安装GMS包, 请将下面的canUpdateLocale()函数中的“return !(userHasPersistedLocale() || isDeviceProvisioned(context));” 修改为"return !(userHasPersistedLocale() && isDeviceProvisioned(context));"
 
[SOLUTION]
/frameworks/opt/telephony/src/java/com/android/internal/telephony/MccTable.java
174 public static void updateMccMncConfiguration(Context context, String mccmnc,
175 boolean fromServiceState) {
176 Slog.d(LOG_TAG, "updateMccMncConfiguration mccmnc='" + mccmnc + "' fromServiceState=" + fromServiceState);
177
178 if (Build.IS_DEBUGGABLE) {
179 String overrideMcc = SystemProperties.get("persist.sys.override_mcc");
180 if (!TextUtils.isEmpty(overrideMcc)) {
181 mccmnc = overrideMcc;
182 Slog.d(LOG_TAG, "updateMccMncConfiguration overriding mccmnc='" + mccmnc + "'");
183 }
184 }
185
186 if (!TextUtils.isEmpty(mccmnc)) {
187 int mcc, mnc;
188
189 String defaultMccMnc = TelephonyManager.getDefault().getSimOperatorNumeric();
190 Slog.d(LOG_TAG, "updateMccMncConfiguration defaultMccMnc=" + defaultMccMnc);
191 //Update mccmnc only for default subscription in case of MultiSim.
192// if (!defaultMccMnc.equals(mccmnc)) {
193// Slog.d(LOG_TAG, "Not a Default subscription, ignoring mccmnc config update.");
194// return;
195// }
196
197 try {
198 mcc = Integer.parseInt(mccmnc.substring(0,3));
199 mnc = Integer.parseInt(mccmnc.substring(3));
200 } catch (NumberFormatException e) {
201 Slog.e(LOG_TAG, "Error parsing IMSI: " + mccmnc);
202 return;
203 }
204
205 Slog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
Locale mccLocale = null; //添加这行
206 if (mcc != 0) {
207 setTimezoneFromMccIfNeeded(context, mcc);
mccLocale = getLocaleFromMcc(context, mcc); //添加这行
208 }
209 if (fromServiceState) {
210 setWifiCountryCodeFromMcc(context, mcc);
211 } else {
212 // from SIM
213 try {
214 Configuration config = new Configuration();
215 boolean updateConfig = false;
216 if (mcc != 0) {
217 config.mcc = mcc;
218 config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc;
219 updateConfig = true;
220 }
221
if (mccLocale != null) { //添加这行
Configuration conLocale = new Configuration(); //添加这行
conLocale = ActivityManagerNative.getDefault().getConfiguration(); //添加这行
LocaleList userLocale = conLocale.getLocales(); //添加这行
LocaleList newUserLocale = new LocaleList(mccLocale,userLocale); //添加这行
config.setLocales(newUserLocale); //添加这行
updateConfig = true; //添加这行
} //添加这行

222 if (updateConfig) {
223 Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config);
224 ActivityManagerNative.getDefault().updateConfiguration(config);
225 } else {
226 Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
227 }
228 } catch (RemoteException e) {
229 Slog.e(LOG_TAG, "Can't update configuration", e);
230 }
231 }
232 } else {
233 if (fromServiceState) {
234 // an empty mccmnc means no signal - tell wifi we don't know
235 setWifiCountryCodeFromMcc(context, 0);
236 }
237 }
238 }


//添加下面函数
245 private static boolean canUpdateLocale(Context context) {
246 return !(userHasPersistedLocale() || isDeviceProvisioned(context));
247 }
248
249 private static boolean userHasPersistedLocale() {
250 String persistSysLanguage = SystemProperties.get("persist.sys.locale", "");
251 String persistSysCountry = SystemProperties.get("persist.sys.country", "");
252 return !(persistSysLanguage.isEmpty() && persistSysCountry.isEmpty());
253 }
254
255 private static boolean isDeviceProvisioned(Context context) {
256 try {
257 return Settings.Global.getInt(
258 context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED) != 0;
259 } catch (Settings.SettingNotFoundException e) {
260 return false;
261 }
262 }


284 private static Locale getLocaleForLanguageCountry(Context context, String language,
285 String country) {
286 if (language == null) {
287 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: skipping no language");
288 return null; // no match possible
289 }
290 if (country == null) {
291 country = ""; // The Locale constructor throws if passed null.
292 }

if(!canUpdateLocale()){ //添加这行
return null; //添加这行
} //添加这行
293
294 final Locale target = new Locale(language, country);
295 try {
296 String[] localeArray = context.getAssets().getLocales();
297 List<String> locales = new ArrayList<>(Arrays.asList(localeArray));
298
299 // Even in developer mode, you don't want the pseudolocales.
300 locales.remove("ar-XB");
301 locales.remove("en-XA");
302
303 List<Locale> languageMatches = new ArrayList<>();
304 for (String locale : locales) {
305 final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
306
307 // Only consider locales with both language and country.
308 if (l == null || "und".equals(l.getLanguage()) ||
309 l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
310 continue;
311 }
312 if (l.getLanguage().equals(target.getLanguage())) {
313 // If we got a perfect match, we're done.
314 if (l.getCountry().equals(target.getCountry())) {
315 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got perfect match: " +
316 l.toLanguageTag());
317 return l;
318 }
319
320 // We've only matched the language, not the country.
321 languageMatches.add(l);
322 }
323 }

325 Locale bestMatch = chooseBestFallback(target, languageMatches);
326 if (bestMatch != null) {
327 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got a language-only match: " +
328 bestMatch.toLanguageTag());
329 return bestMatch;
330 } else {
331 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: no locales for language " +
332 language);
333 }
334 } catch (Exception e) {
335 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: exception", e);
336 }
337
338 return null;
339 }
340



/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
19577 public void updateConfiguration(Configuration values) {
19578 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
19579 "updateConfiguration()");
19580
19581 synchronized(this) {
19582 if (values == null && mWindowManager != null) {
19583 // sentinel: fetch the current configuration from the window manager
19584 values = mWindowManager.computeNewConfiguration();
19585 }
19586
19587 if (mWindowManager != null) {
19588 mProcessList.applyDisplaySize(mWindowManager);
19589 }
19590
19591 final long origId = Binder.clearCallingIdentity();
19592 if (values != null) { //删除这行
19593 Settings.System.clearConfiguration(values); //删除这行
19594 } //删除这行
19595 updateConfigurationLocked(values, null, false);
19596 Binder.restoreCallingIdentity(origId);
19597 }
19598 }

19627 private boolean updateConfigurationLocked(Configuration values,
19628 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
...
19643 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { //删除这行
if (!initLocale && !values.getLocales().isEmpty()) { //添加这行
19644 final LocaleList locales = values.getLocales();
19645 int bestLocaleIndex = 0;
19646 if (locales.size() > 1) {
19647 if (mSupportedSystemLocales == null) {
19648 mSupportedSystemLocales =
19649 Resources.getSystem().getAssets().getLocales();
19650 }
19651 bestLocaleIndex = Math.max(0,
19652 locales.getFirstMatchIndex(mSupportedSystemLocales));
19653 }
if(values.userSetLocale){
SystemProperties.set("persist.sys.locale", //添加这行
locales.get(bestLocaleIndex).toLanguageTag()); //添加这行
}else{ //添加这行
SystemProperties.set("persist.sys.simLocale", //添加这行
locales.get(bestLocaleIndex).toLanguageTag()); //添加这行
} //添加这行
19654 SystemProperties.set("persist.sys.locale", //删除这行
19655 locales.get(bestLocaleIndex).toLanguageTag()); //删除这行
19656 LocaleList.setDefault(locales, bestLocaleIndex);
19657 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19658 locales.get(bestLocaleIndex)));
19659 }
...
}


/frameworks/base/core/jni/AndroidRuntime.cpp 
414const std::string readLocale()
415{
416 const std::string locale = getProperty("persist.sys.locale", "");
417 if (!locale.empty()) {
418 return locale;
419 }
420
421 const std::string language = getProperty("persist.sys.language", "");
422 if (!language.empty()) {
423 const std::string country = getProperty("persist.sys.country", "");
424 const std::string variant = getProperty("persist.sys.localevar", "");
425
426 std::string out = language;
427 if (!country.empty()) {
428 out = out + "-" + country;
429 }
430
431 if (!variant.empty()) {
432 out = out + "-" + variant;
433 }
434
435 return out;
436 }
437
const std::string simLocale = getProperty("persist.sys.simLocale", ""); //添加这行
if (!simLocale.empty()) { //添加这行
return simLocale; //添加这行
} //添加这行

438 const std::string productLocale = getProperty("ro.product.locale", "");
439 if (!productLocale.empty()) {
440 return productLocale;
441 }
442
443 // If persist.sys.locale and ro.product.locale are missing,
444 // construct a locale value from the individual locale components.
445 const std::string productLanguage = getProperty("ro.product.locale.language", "en");
446 const std::string productRegion = getProperty("ro.product.locale.region", "US");
447
448 return productLanguage + "-" + productRegion;
449}
  
阅读全文
0 0
原创粉丝点击