一、介绍
切换系统语言后,使用Dialer拨打电话后,通话记录显示的地址语言仍未原语言。
二、分析
- 发现并非翻译问题。
- 排查CallLog记录确定是写入的地理位置仍为原语言的值。
- 跟踪地址写入的位置,根据网上提供的通话记录写入流程,追踪logCall()插入方法,一直没有找到地理位置geoDescription的写入。
- 正确的根源在于地址信息来源,而不是写入的地方。
CallLog的数据库位置:
/data/user/0/com.android.providers.contacts
- 其中calls.db中的Calls.GEOCODED_LOCATION字段为号码归属地。
原因:
- 切换语言后,位置信息没有变,导致地理位置的值仍为原语言。
- 默认切换语言后,没有更新mLocate的值,导致写入通话记录的地理位置信息没有切换语言。
代码逻辑:
- addComputedValues()方法调用了getGeocodedLocationFor()
- 在getGeocodedLocationFor()中传入mLocate获取地理信息,此处影响获取的值的语言类型。
class DefaultCallLogInsertionHelper implements CallLogInsertionHelper {//...private final Locale mLocale;//切换语言时该值没有更新,仍为如下构建时的值//...private DefaultCallLogInsertionHelper(Context context) {mCountryMonitor = new CountryMonitor(context);mLocale = context.getResources().getConfiguration().locale;}//被addComputedValues()调用的方法,传入mLocate,该值不正确导致CallLog存入的地址信息错误。 @Overridepublic String getGeocodedLocationFor(String number, String countryIso) {PhoneNumber structuredPhoneNumber = parsePhoneNumber(number, countryIso);if (structuredPhoneNumber != null) {return getPhoneNumberOfflineGeocoder().getDescriptionForNumber(structuredPhoneNumber, mLocale);} else {return null;}}
}
三、解决
- 在ContactsProvider中解决。
- 在切换语言后,更新mLocate的取值。
packages\providers\ContactsProvider
1.DefaultCallLogInsertionHelper.java
//com\android\providers\contacts\DefaultCallLogInsertionHelper.java
class DefaultCallLogInsertionHelper implements CallLogInsertionHelper {//...private Locale mLocale;//删除final限制。//新增更新方法,在每次更新的时候触发。protected void updateLocale(Locale locale){mLocale = locale;}
}
2.ContactsProvider2.java
- 添加对DefaultCallLogInsertionHelper中updateLocale()方法的调用
//com\android\providers\contacts\ContactsProvider2.java
/*** Verifies that the contacts database is properly configured for the current locale.* If not, changes the database locale to the current locale using an asynchronous task.* This needs to be done asynchronously because the process involves rebuilding* large data structures (name lookup, sort keys), which can take minutes on* a large set of contacts.*/protected void updateLocaleInBackground() {// The process is already running - postpone the changeif (mProviderStatus == STATUS_CHANGING_LOCALE) {return;}final LocaleSet currentLocales = mCurrentLocales;final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());if (!needsToUpdateLocaleData(prefs, currentLocales, mContactsHelper, mProfileHelper)) {return;}int providerStatus = mProviderStatus;setProviderStatus(STATUS_CHANGING_LOCALE);mContactsHelper.setLocale(currentLocales);mProfileHelper.setLocale(currentLocales);mSearchIndexManager.updateIndex(true);prefs.edit().putString(PREF_LOCALE, currentLocales.toString()).commit();setProviderStatus(providerStatus);//新增的方法,更新mLocate。DefaultCallLogInsertionHelper.getInstance(getContext()).updateLocale(currentLocales.getPrimaryLocale());// The system locale set might have changed while we've being updating the locales.// So double check.if (!mCurrentLocales.isCurrent()) {scheduleBackgroundTask(BACKGROUND_TASK_CHANGE_LOCALE);}}