一、介绍
切换系统语言后,使用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存入的地址信息错误。
@Override
public 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 change
if (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);
}
}