Android11 车载 Framework PBAP同步电话
2022-05-17 本文已影响0人
程序员DS
Android11 车载 Framework PBAP同步电话簿如何添加姓名全拼和首字母的需求
原理分析
PBAP同步电话簿功能是
- 首先车机通过蓝牙连接手机。
- 车机会通过蓝牙建立的连接。
- 下载手机中的联系人到车机中的数据库去。
- 然后再由车机的蓝牙电话App查询数据库来显示电话。
这里只是大概介绍一下流程。详细的过程这里就不详细讲解了
数据库添加全拼和首字母这个需求,是在ContactsProvider这个app中修改 ContactsProvider保存联系人的App 好的 首先我们下载一下联系人的数据库 用如下的方法
- adb root
- adb remount
- adb pull /data/data/com.android.providers.contacts/databases/contacts2.db
打开数据库经过我长时间的分析,数据库中view_data视图中,sort_key字段,如果联系人名字是英文是有值的(值为英文名称),但是中文就没有值, phonebook_label也是英文就是首字母,中文同样没有值,这样我们确定了sort_key和phonebook_label是全拼和首字母,我们就可以写代码了 所以我们写入数据库的时候 中文给 sort_key和phonebook_label赋值就可以。
好了找代码的过程我就不讲了,很长的时间我找到了关键代码,是在
packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsDatabaseHelper.java
在方法
public void updateRawContactDisplayName(SQLiteDatabase db, long rawContactId) {
//displayNamePrimary 这个是联系人的名称 是用来做中文转英文的
bindString(rawContactDisplayNameUpdate, 2, displayNamePrimary);
......
//sortKeyPrimary 这个就是存储的名称全拼
bindString(rawContactDisplayNameUpdate, 6, sortKeyPrimary);
....
//phonebookLabelPrimary 这个存储的是名称首字母
bindString(rawContactDisplayNameUpdate, 7, phonebookLabelPrimary);
......................
}
实现过程
代码位于packages/providers/ContactsProvider
- 下载中文转英文的库,tinypinyin,需要两个库 ahocorasick-0.3.0.jar和tinypinyin-2.0.3.jar
下载地址 链接:pan.baidu.com/s/13TzWvMMw… 提取码:1234
- 把这个两个库放到ContactsProvider目录下的libs文件夹下(如果没有请新建libs目录)
- Android.bp文件增加如下代码:
java_import {
name: "tinypinyin-2.0.3",
jars: ["libs/tinypinyin-2.0.3.jar","libs/ahocorasick-0.3.0.jar"],
}
android_app {
...............
static_libs: [
"android-common",
"com.android.vcard",
"guava",
"tinypinyin-2.0.3"
],
.............
完整Android.bp代码如下:
Android.bp
java_import {
name: "tinypinyin-2.0.3",
jars: ["libs/tinypinyin-2.0.3.jar","libs/ahocorasick-0.3.0.jar"],
}
android_app {
name: "ContactsProvider",
// Only compile source java files in this apk.
srcs: [
"src/**/*.java",
"src/com/android/providers/contacts/EventLogTags.logtags",
],
libs: [
"ext"
],
static_libs: [
"android-common",
"com.android.vcard",
"guava",
"tinypinyin-2.0.3"
],
// The Jacoco tool analyzes code coverage when running unit tests on the
// application. This configuration line selects which packages will be analyzed,
// leaving out code which is tested by other means (e.g. static libraries) that
// would dilute the coverage results. These options do not affect regular
// production builds.
jacoco: {
include_filter: ["com.android.providers.contacts.*"],
},
platform_apis: true,
certificate: "shared",
privileged: true,
optimize: {
proguard_flags_files: ["proguard.flags"],
},
}
然后修改packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsDatabaseHelper.java中代码
//在ContactsDatabaseHelper.java中增加如下方法
ContactsDatabaseHelper.java
private void initPinyinConfig(){
// 添加自定义词典 因为库会把张转换成Chang 多音字 所以修改一下
Pinyin.init(Pinyin.newConfig()
.with(new PinyinMapDict() {
@Override
public Map<String, String[]> mapping() {
HashMap<String, String[]> map = new HashMap<String, String[]>();
map.put("长", new String[]{"CHANG"});
map.put("张", new String[]{"ZHANG"});
map.put("重", new String[]{"CHONG"});
return map;
}
}));
}
//构造方法调用一下
protected ContactsDatabaseHelper(
Context context, String databaseName, boolean optimizationEnabled,
boolean isTestInstance) {
........................
initPinyinConfig();
}
//然后在方法updateRawContactDisplayName实现该功能
public void updateRawContactDisplayName(SQLiteDatabase db, long rawContactId) {
.......................
//添加全拼和首字母start
//全拼
String fullpinyin = Pinyin.toPinyin(displayNamePrimary, "");
if (TextUtils.isEmpty(fullpinyin)) {
fullpinyin = "";
}else{
//由于英文转换后是小写 中文转换后为大写 为了保持一直 这里全部转大写
fullpinyin=fullpinyin.toUpperCase();
}
sortKeyPrimary=fullpinyin;
//首字母
String firstPinyin = "";
if (fullpinyin.length() > 0) {
firstPinyin = fullpinyin.substring(0, 1);
}
phonebookLabelPrimary = firstPinyin;
//添加全拼和首字母联系人end
//下面的代码是源码本身的不用修改,记得这个位置
final SQLiteStatement rawContactDisplayNameUpdate = db.compileStatement(
"UPDATE " + Tables.RAW_CONTACTS +
" SET " +
RawContacts.DISPLAY_NAME_SOURCE + "=?," +
RawContacts.DISPLAY_NAME_PRIMARY + "=?," +
RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," +
RawContacts.PHONETIC_NAME + "=?," +
RawContacts.PHONETIC_NAME_STYLE + "=?," +
RawContacts.SORT_KEY_PRIMARY + "=?," +
RawContactsColumns.PHONEBOOK_LABEL_PRIMARY + "=?," +
RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY + "=?," +
RawContacts.SORT_KEY_ALTERNATIVE + "=?," +
RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE + "=?," +
RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + "=?" +
" WHERE " + RawContacts._ID + "=?");
rawContactDisplayNameUpdate.bindLong(1, bestDisplayNameSource);
bindString(rawContactDisplayNameUpdate, 2, displayNamePrimary);
bindString(rawContactDisplayNameUpdate, 3, displayNameAlternative);
bindString(rawContactDisplayNameUpdate, 4, bestPhoneticName);
rawContactDisplayNameUpdate.bindLong(5, bestPhoneticNameStyle);
bindString(rawContactDisplayNameUpdate, 6, sortKeyPrimary);
bindString(rawContactDisplayNameUpdate, 7, phonebookLabelPrimary);
................................
}
记得引入包名
import java.util.List;
import java.util.ArrayList;
import com.github.promeg.pinyinhelper.Pinyin;
import com.github.promeg.pinyinhelper.PinyinMapDict;
import java.util.HashMap;
import java.util.Map;
然后使用mm编译后 找到这个编译出来的ContactsProvider.apk 通过
- adb root
- adb remount
- adb push ContactsProvider.apk /system/priv-app/ContactsProvider/ContactsProvider.apk
- adb reboot
这样就生效了