Android11 车载 Framework PBAP同步电话簿如何添加姓名全拼和首字母的需求

Android11 车载 Framework PBAP同步电话簿如何添加姓名全拼和首字母的需求

原理分析

PBAP同步电话簿功能是

  1. 首先车机通过蓝牙连接手机。
  2. 车机会通过蓝牙建立的连接。
  3. 下载手机中的联系人到车机中的数据库去。
  4. 然后再由车机的蓝牙电话App查询数据库来显示电话。

蓝牙下载联系人.drawio.png

这里只是大概介绍一下流程。详细的过程这里就不详细讲解了

数据库添加全拼和首字母这个需求,是在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

  • 把这个两个库放到ContactsProvider目录下的libs文件夹下(如果没有请新建libs目录)

1.jpg

  • 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

这样就生效了

文末

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android 11中,PBAP获取通讯录的方法与之前的版本略有不同。以下是使用PBAP获取通讯录的步骤: 1. 确保设备支持PBAP协议,并且已经连接到目标设备。可以使用BluetoothAdapter.getDefaultAdapter().getProfileProxy()方法获取PBAP代理对象。 2. 使用PBAP代理对象的requestPhonebook()方法请求电话簿。该方法需要传入一个电话簿类型参数,例如ContactsContract.PBAP_VCARD_TYPE。 3. PBAP代理对象会异步返回电话簿数据。可以使用ContentResolver.insert()方法将数据插入到设备的联系人数据库中。 以下是一个示例代码: ```java BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothPbapClient pbapClient = null; bluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if(profile == BluetoothProfile.PBAP_CLIENT) { pbapClient = (BluetoothPbapClient) proxy; pbapClient.start(); pbapClient.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); pbapClient.requestPhonebook(device, ContactsContract.PBAP_VCARD_TYPE); } } @Override public void onServiceDisconnected(int profile) { if(profile == BluetoothProfile.PBAP_CLIENT) { pbapClient = null; } } }); ContentValues values = new ContentValues(); values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, null); values.put(ContactsContract.RawContacts.ACCOUNT_NAME, null); Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values); long rawContactId = ContentUris.parseId(rawContactUri); String selectPhone = ContactsContract.Data.RAW_CONTACT_ID + " = " + rawContactId + " AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"; values.clear(); values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber); values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values); ``` 需要注意的是,Android 11中的PBAP获取通讯录需要用户授权。因此,在使用PBAP获取通讯录时,需要请求相应的权限。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值