当前位置: 首页 > news >正文

Android13 蓝牙协议属性配置详解

Android13 蓝牙协议属性配置详解

文章目录

  • Android13 蓝牙协议属性配置详解
    • 一、前言
    • 二、Android13 蓝牙协议属性配置
      • 1、Profile 属性和暴露接口的定义
      • 2、蓝牙协议属性定义
      • 3、系统代码中判断蓝牙协议是否使能的代码
    • 三、其他
      • 1、adb 窗口中查看蓝牙协议属性
      • 2、动态设置蓝牙prop协议属性有用吗
      • 3、opp协议为false时蓝牙文件传输相关日志
      • 4、Android11 蓝牙协议详解

一、前言

Android系统中蓝牙协议是否使能一般是通过一个属性值,如果这个属性值设置为false,

会导致这个协议的服务未启动,也就是说这个蓝牙功能会没有作用。

比如 Android 蓝牙传输文件协议是opp,如果opp未使能,那么整个系统是不支持蓝牙文件传输的。

在Android13之前的版本,我们可以通过 config.xml 中的 profile_supported_a2dp 属性控制蓝牙的某个协议是否使能。

比如Android13 以前的蓝牙协议使能属性:

    <bool name="profile_supported_a2dp">true</bool><bool name="profile_supported_a2dp_sink">true</bool><bool name="profile_supported_hs_hfp">true</bool><bool name="profile_supported_hfpclient">false</bool>

这些属性是res属性,只能在资源文件中修改,还不方便查询。

但是在Android13 或者更新的版本,很多属性都需要一个新的东西控制使能蓝牙协议了,那就是蓝牙属性profile属性。

Android13 以及更新的版本蓝牙协议使能属性:

bluetooth.profile.a2dp.source.enabled=true
bluetooth.profile.avrcp.target.enabled=true
...
bluetooth.profile.opp.enabled=true
bluetooth.profile.a2dp.sink.enabled=true

这些属性是prop属性,非常方便查询,直接修改的话,估计可以,但是重启会失效。

这个东西如果没有了解过,是无从下手的,蓝牙的profile属性读取和控制在Java代码中是找不到的。

如果想要学习了解,可以继续往下看看。

本文简单参考:https://blog.csdn.net/weixin_47456647/article/details/139493190

二、Android13 蓝牙协议属性配置

蓝牙的协议属性虽然都是prop属性,但是无法代码中并不是直接判断prop属性决定使能,

而是使用Profile提供的接口,判断蓝牙协议是否使能。

1、Profile 属性和暴露接口的定义

system\libsysprop\srcs\android\sysprop\BluetoothProperties.sysprop

注意,下面的代码只是定义蓝牙prop属性和关联Java Api方法的地方,具体赋值是在其他地方。

module: "android.sysprop.BluetoothProperties"
owner: Platform
...
# Whether the Advanced Audio Distribution Profile (A2DP) Sink role is enabled on this device.
# Set by vendors overlay, read at Bluetooth initialization
prop {api_name: "isProfileA2dpSinkEnabled" //暴露的apitype: Booleanscope: Publicaccess: Readonlyprop_name: "bluetooth.profile.a2dp.sink.enabled"
}//系统Java代码中调用 BluetoothProperties.isProfileA2dpSinkEnabled()就能查到对于的prop属性//这也是为啥Java代码中没有直接获取 bluetooth.profile 属性的原因。# Whether the Advanced Audio Distribution Profile (A2DP) Source role is enabled on this device.
# Set by vendors overlay, read at Bluetooth initialization
prop {api_name: "isProfileA2dpSourceEnabled"type: Booleanscope: Publicaccess: Readonlyprop_name: "bluetooth.profile.a2dp.source.enabled"
}# BR/EDR Page scan activity configuration
prop {api_name: "getClassicPageScanType"type: UIntscope: Internalaccess: Readonlyprop_name: "bluetooth.core.classic.page_scan_type"
}...

这个文件主要就是绑定某些api和prop属性的关联。

可以看到上面定义的access 都是只读,说明直接修改不一定有用。

在系统的java代码中,只要调用静态方法:BluetoothProperties.XXX()就可以判断某个协议属性是否使能了。

2、蓝牙协议属性定义

prop属性的默认值一般是通过XXX.mk文件进行设置默认值的

但是不同的供应商方案的系统可能定义的方式不一样。

比如 aml Android14 311D2方案 修改的路径:

PRODUCT_PROPERTY_OVERRIDES += \bluetooth.profile.asha.central.enabled=true \bluetooth.profile.gatt.enabled=true \bluetooth.profile.hid.host.enabled=true \bluetooth.profile.mcp.server.enabled=true \bluetooth.profile.opp.enabled=true \bluetooth.profile.pan.nap.enabled=true \bluetooth.profile.pan.panu.enabled=true

比如 mtk Android14 9679方案 修改的路径:

device\mediatek\mt5879\configs\bluetooth.prop

bluetooth.device.class_of_device=40,4,60
bluetooth.profile.a2dp.source.enabled?=false
bluetooth.profile.avrcp.target.enabled?=true
bluetooth.profile.bas.client.enabled?=true
···
bluetooth.profile.opp.enabled?=false  //默认为false,设置true才能正常传输文件

这种看起来是供应商自定义的,不像上面mk文件定义是原生的。

网上看有些mtk方案也有写在 device.mk里面定义prop属性的,还有些其他方案的会定义在其他xxx.mk

如果不确定定义在哪里,就在源码里面全局搜索一下吧,命令:

//搜索其中一个比较注意的prop属性关键字
grep -nr "bluetooth.profile.avrcp.target.enabled"
//或者
grep -nr "bluetooth.profile.opp.enabled"还可以搜索过来某些文件进行搜索
find . -name "*.mk" | xargs grep "bluetooth.profile.opp.enabled"
find . -name "*.prop" | xargs grep "bluetooth.profile.opp.enabled"

这样就能知道其他蓝牙协议属性定义的地方了。

大部分方案都是定义在 device、vendor目录下,也有小概率定义在package、hardware、framework、prebuilts等目录。

3、系统代码中判断蓝牙协议是否使能的代码

packages\modules\Bluetooth\android\app\src\com\android\bluetooth\a2dp\A2dpService.java

    //是否支持蓝牙声音功能,蓝牙连接耳机后声音从耳机发出public static boolean isEnabled() {return BluetoothProperties.isProfileA2dpSourceEnabled().orElse(false);}

每个蓝牙协议服务都在类似的判断静态方法,从而判断是否支持该协议。

其他的蓝牙协议服务也是类似的方式进行判断是否使能。

正式代码中未看到有直接判断prop 属性的方式,判断蓝牙是否使能的代码:

boolean isEnableXXX = SystemProperties.getBoolean("XXX", false);

全局搜索后,看到在某个Test的类中有这个使用。所以是不建议这样使用的。

但是也不是不能这样使用,特别是普通应用中,或没有导入framework Jar包的系统应用中都是有可能无法调用到 BluetoothProperties 这个类的,可以使用这个方法进行判断属性的方式判断蓝牙协议是否使能。

三、其他

1、adb 窗口中查看蓝牙协议属性

console:/ # getprop | grep  bluetooth.profile                                  
[bluetooth.profile.a2dp.source.enabled]: [true]
[bluetooth.profile.asha.central.enabled]: [true]
[bluetooth.profile.avrcp.target.enabled]: [true]
[bluetooth.profile.gatt.enabled]: [true]
[bluetooth.profile.hfp.ag.enabled]: [true]
[bluetooth.profile.hid.host.enabled]: [true]
[bluetooth.profile.mcp.server.enabled]: [true]
[bluetooth.profile.opp.enabled]: [true]
[bluetooth.profile.pan.nap.enabled]: [true]
[bluetooth.profile.pan.panu.enabled]: [true]
console:/ # 

getprop 过滤蓝牙相关prop,就能看到所有的蓝牙协议相关属性。

2、动态设置蓝牙prop协议属性有用吗

从打印日志看打开蓝牙的时候蓝牙相关的协议服务会进行重启,

关闭蓝牙蓝牙相关的协议服务会关闭。

所以理论上,动态修改蓝牙prop属性,在关开一次蓝牙,那么就会修改生效。

目前我只试过 bluetooth.profile.opp.enabled 确实是可以动态修改的,其他属性不确定。

3、opp协议为false时蓝牙文件传输相关日志

AML Android14 上 蓝牙相关日志:

06-14 16:22:49.238  8759  8791 I bluetooth: packages/modules/Bluetooth/system/gd/hci/hci_layer.cc:119 drop: Dropping event MAX_SLOTS_CHANGE
06-14 16:22:49.242  8759  8759 I BluetoothPhonePolicy: processDeviceConnected, device=XX:XX:XX:XX:16:0E
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: setConnection: device XX:XX:XX:XX:16:0E and isA2dpDevice=false
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: Updating last connected time for device: XX:XX:XX:XX:16:0E to 2
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: updateDatabase XX:XX:XX:XX:16:0E
06-14 16:22:49.248  8759  8791 I bluetooth: packages/modules/Bluetooth/system/main/shim/acl.cc:558 OnReadClockOffsetComplete: UNIMPLEMENTED
06-14 16:22:49.306  8759  8786 I l2c_csm : packages/modules/Bluetooth/system/stack/l2cap/l2c_csm.cc:338 l2c_csm_closed: Check security for psm 0x0001, status 0
06-14 16:22:49.320  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: PBAP PSE dynamic version upgrade is not enabled
06-14 16:22:49.325  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x42
06-14 16:22:49.334  8759  8786 I l2c_csm : packages/modules/Bluetooth/system/stack/l2cap/l2c_csm.cc:338 l2c_csm_closed: Check security for psm 0x0001, status 0
06-14 16:22:49.345  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: PBAP PSE dynamic version upgrade is not enabled
06-14 16:22:49.351  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x4306-14 16:22:53.352  8759  8786 W l2c_link: packages/modules/Bluetooth/system/stack/l2cap/l2c_link.cc:521 l2c_link_timeout: TODO: Remove this callback into bcm_sec_disconnect
06-14 16:22:53.352  8759  8786 I btm_acl : packages/modules/Bluetooth/system/stack/acl/btm_acl.cc:205 hci_btsnd_hcic_disconnect: Disconnecting peer:xx:xx:xx:xx:16:0e reason:HCI_ERR_PEER_USER comment:stack::l2cap::l2c_link::l2c_link_timeout All channels closed
06-14 16:22:53.438  8759  8786 E btm_sco : packages/modules/Bluetooth/system/stack/btm/btm_sco.cc:1137 btm_sco_on_disconnected: Unable to find sco connection
06-14 16:22:53.438  8759  8786 I btm_acl : packages/modules/Bluetooth/system/stack/acl/btm_acl.cc:2740 btm_acl_iso_disconnected: ISO disconnection from GD, handle: 0x0b, reason: 0x16
06-14 16:22:53.439  8759  8786 I btif_av : packages/modules/Bluetooth/system/btif/src/btif_av.cc:3565 btif_av_acl_disconnected: btif_av_acl_disconnected: Peer xx:xx:xx:xx:16:0e : ACL Disconnected

这是手机端发送后,接收端的蓝牙相关日志;

从日志未看出啥明显异常,也没有提示opp服务无法开启,但是只有ACL连接和断开的日志。

这里仅供参考。不同方案上可能有区别。

4、Android11 蓝牙协议详解

https://blog.csdn.net/wenzhi20102321/article/details/125826972

相关协议知识:

拨号网络配置文件 (DUN):
DUN 提供了通过 Bluetooth 无线技术接入 Internet 和其它拨号服务的标准。
最常见的情况是在手机上拨号,从膝上型计算机以无线方式接入 Internet。OPP:对象存储规范(Object Push Profile),最为常见的,文件的传输都是使用此协议。HFP:(Hands-free Profile),让蓝牙设备可以控制电话,如接听、挂断、拒接、语音拨号等,拒接、语音拨号要视蓝牙耳机及电话是否支持。HDP: HDP (Health Device Profile) 蓝牙医疗设备模式   可以创建支持蓝牙的医疗设备,使用蓝牙通信的应用程序,例如心率监视器,血液,温度计和秤。HID() 人机接口设备配置文件
HID 配置文件定义了 Bluetooth HID(如键盘、指向设备、游戏设备及远程监视设备)使用的协议、程序及功能HSP(Handset Profile)耳机模式 ,用于支持蓝牙耳机与移动电话之间使用A2DP: Advanced Audio Distribution Profile (A2DP) 高级音频传输模式  A2DP是能够采用耳机内的芯片来堆栈数据,达到声音的高清晰度。有A2DP的耳机就是蓝牙立体声耳机。
PAN:个人局域网(Personal Area Network)最新为了满足需求而出现的, 在小范围内能够将个人设备(自己的手机 电脑笔记本等)互联而组成的网络。DP( Service Discovery Protocol )服务发现协议
提供应用程序在蓝牙环境中发现哪个服务可用和决定那些可用服务的特征。GAP(Generic Access Profile)通用访问应用
一般访问应用规范定义了蓝牙设备如何发现和建立与其他设备的安全(或不安全)连接。
它处理一些一般模式的业务(如询问、命名和搜索)和一些安全性问 题(如担保),
同时还处理一些有关连接的业务(如链路建立、信道和连接建立)。GAP规定的是一些一般性的运行任务。
因此,它具有强制性,并作为所有其它 蓝牙应用规范的基础。

不同的Android版本对蓝牙协议的设置代码不同,但是蓝牙协议的基本知识是一样的。

相关文章:

Android13 蓝牙协议属性配置详解

Android13 蓝牙协议属性配置详解 文章目录 Android13 蓝牙协议属性配置详解一、前言二、Android13 蓝牙协议属性配置1、Profile 属性和暴露接口的定义2、蓝牙协议属性定义3、系统代码中判断蓝牙协议是否使能的代码 三、其他1、adb 窗口中查看蓝牙协议属性2、动态设置蓝牙prop协…...

南通国际高中有哪些?南通惠立学校高中部校长见面日重磅来袭

惠灵顿&#xff08;中国&#xff09;自2011年成立以来&#xff0c;一直坚持深耕国际与双语教育&#xff0c;拥有丰厚的办学经验。依托于集团化的深厚经验南通惠立学校于2024-2025学年开设9-11年级&#xff0c;这所南通国际高中为高中学生搭建一个集卓越升学成果、强大师资、纯正…...

Al智能图像处理APP,安卓手机专用一键优化工具资源合集下载

### 标题&#xff1a;Al智能图像处理APP&#xff0c;安卓手机专用一键优化工具资源合集下载 随着科技的进步&#xff0c;图像处理技术也在不断提升。为了满足用户对图像处理日益增长的需求&#xff0c;我们隆重推出了一款功能强大的图像处理工具——Al智能图像处理APP。这款安…...

Kettle根据分类实现Excel文件拆分——kettle开发31

将整理好的一份供应商付款明细Excel文件&#xff0c;按供应商拆分成多个Excel文件。 实现思路 本文我们首先将供应商付款明细表&#xff0c;按照“名称”拆分成多份Excel文件。拆分Excel文件打算用两个转换实现&#xff0c;一个用来将Excel数据读取到参数中&#xff0c;另外一…...

merkle tree中文

Merkle tree merkle tree中文文档英文文档 #include <cstdlib> #include <string> #include <bitcoin/bitcoin.hpp>BC_USE_LIBBITCOIN_MAINusing namespace bc;bc::hash_digest calculate_merkle_root(bc::hash_list &merkle);int bc::main(int argc, …...

制作自己的 @OnClick、@OnLongClick(告别 setOnClickListener,使用注解、反射和动态代理)

前言 前面我们说过 ButterKnife 这个库&#xff0c;这个库实现不仅实现了 View 的绑定&#xff0c;而且还提供了大量的注解如 BindView、OnClick、OnLongClick 等来简化开发过程中事件绑定。而这些功能的实现是通过 APT 也就是注解处理器&#xff0c;在编译期间生成 Java 代码…...

Android基础-RecyclerView的优点

一、引言 在Android开发中&#xff0c;RecyclerView是一个强大而灵活的控件&#xff0c;用于展示大量数据集合的视图。相比于传统的ListView和GridView&#xff0c;RecyclerView提供了更高的性能、更多的布局选择和更丰富的交互体验。本文将详细阐述RecyclerView的功能作用以及…...

C# Winform 用户控件,扩展控件,自定义控件综合实例

Control类是Windows窗体控件的基类&#xff0c;它提供了在 Windows 窗体应用程序中进行可视显示所需的基础结构&#xff0c;可以通过继承来扩展熟悉的用户控件和现有控件的功能。本列介绍三种不同自定义控件以及怎么创建他们。 自定义控件分类 用户控件&#xff1a;基本控件的…...

经济学和金融学有什么区别?

中文版 金融学和经济学是两个密切相关但有所不同的学科&#xff0c;它们各自侧重于不同的研究领域和方法。 经济学 (Economics) 经济学是研究如何配置有限资源以满足人类无限需求的学科。它可以分为两个主要分支&#xff1a; 宏观经济学 (Macroeconomics): 研究经济整体的行…...

Java课程设计:基于swing的学生信息管理系统

文章目录 一、项目介绍二、项目展示三、源码展示四、源码获取 一、项目介绍 这款Java swing实现的学生信息管理系统和jsp版本的功能很相似&#xff0c;简单的实现了班级信息的增删改查&#xff0c;学生信息的增删改查&#xff0c;数据库采用的是mysql&#xff0c;jdk版本不限&…...

【代码】3d->video

mesh->video import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib.animation import FuncAnimation import matplotlib.animation as animation from pywavefront import Wavefront import osnamedog # 读取OBJ文…...

算法01 递推算法及相关问题详解【C++实现】

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…...

自动化测试火狐下载文件

本篇文章介绍selenium中火狐浏览器如何下载文件。比如我想把这个MP4的视频文件下载下来。 点击之后查看下载的类型是video/mp4 指定使用火狐浏览器 profile webdriver.FirefoxOptions() # 设置firefox默认的下载路径&#xff0c;0表示桌面&#xff0c;1表示我的下载&#xf…...

基于JSP技术的定西扶贫惠农推介系统

开头语&#xff1a;你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;JSP 数据库&#xff1a;MySQL 技术&#xff1a;B/S架构、JSP技术 工具&#xff1a;Eclipse、MySQL、Tomcat 系统展示 首…...

Linux 终端窗口设置为透明

Linux 终端窗口设置为透明 打开终端 右键鼠标 选择Profile Preferences 点击Background 选择 Transparent background 拖动滑条调整透明度 完成。...

MySQL 中 Varchar(50) 和 varchar(500) 区别是什么?

一. 问题描述 我们在设计表结构的时候&#xff0c;设计规范里面有一条如下规则: 对于可变长度的字段&#xff0c;在满足条件的前提下&#xff0c;尽可能使用较短的变长字段长度。 为什么这么规定&#xff1f;我在网上查了一下&#xff0c;主要基于两个方面 基于存储空间的考…...

强化RAG:微调Embedding还是LLM?

为什么我们需要微调&#xff1f; 微调有利于提高模型的效率和有效性。它可以减少训练时间和成本&#xff0c;因为它不需要从头开始。此外&#xff0c;微调可以通过利用预训练模型的功能和知识来提高性能和准确性。它还提供对原本无法访问的任务和领域的访问&#xff0c;因为它…...

提取 Excel单元格文本下的超链接

在Excel中&#xff0c;可以使用内置的函数来提取单元格中的超链接地址。如果你有一个包含超链接的单元格&#xff0c;例如B1&#xff0c;你可以使用以下步骤来提取这个超链接&#xff1a; 在一个新的单元格&#xff08;例如C1&#xff09;中&#xff0c;输入以下公式&#xff…...

一键安全体检!亚信安全携手鼎捷软件推出企业安全体检活动 正式上线

亚信安全联合鼎捷软件股份有限公司&#xff08;以下简称“鼎捷软件”&#xff09;正式推出“一键安全体检”服务。亚信安全网络安全专家将携手鼎捷软件数据安全专家&#xff0c;围绕企业的数智安全状况&#xff0c;进行问题探索与治愈、新问题预测与预警&#xff0c;在全面筛查…...

numpy - array(1)

一维数据&#xff1a;向量 二位数据&#xff1a;矩阵 维度超过三维的数据&#xff1a;张量 这些数据在numpy中统称array (1)使用穷举法创建多为数据,接受列表或者元组类型的数据 a numpy.array([1, 2, 3]) b numpy.array([[1, 2, 3], (4, 5, 6), [7, 8, 9]]) (2)创建所有元…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...