一、起点
我之前分享过WeUI,但其实在做WeUI之前,我就想做微信的,但那时确实能力不够,连很多UI效果都做不出来,便中途放弃了,选择做了相对容易些的WeUI组件库,准备积累一些经验后再做微信。这次离职后,原本计划在家“躺平”到年后,但是有一次爬山,觉得有点闲不住,就想着要做点什么,便想起了之前一直很想做的微信。
于是我开始思考:
- 我没有钱买服务器,能不能让手机之间直接互联?
- 能不能同时兼容多种连接方式?
- 能不能把 硬件、加密、文件传输、网络通信、音视频、地图、系统能力等 都玩一遍?
我快速问了 AI:
能否同时基于
Wi‑Fi LAN、Wi‑Fi Direct和蓝牙做一个安卓聊天 App?
答案是:完全可以。
然后,我给这个App取了个名字:WeChat Lan,于是这个项目就正式开始了。
二、技术选型
核心库均使用当前最新版本,构建响应式、现代化、高性能的 Android 应用。
-
UI 框架:Jetpack Compose 声明式 UI 全家桶,使用 Coil 3.x 实现图片异步加载。
-
开发语言:Kotlin 2.3 利用 Kotlin 新一代编译器特性,搭配 Serialization 进行高性能 JSON 解析。
-
依赖注入:Hilt 基于 Dagger 的标准依赖注入方案,深度集成 Navigation Compose,实现 ViewModel 的生命周期自动管理。
-
数据持久化:Room 使用 Jetpack 标准数据库组件,支持 Kotlin 协程与流式响应,配合 DataStore 处理轻量级键值对偏好设置和个人资料保存。
-
多媒体与交互:CameraX + WebRTC + MLKit 采用 CameraX 实现相机流控制,集成 WebRTC 支持实时通信,并利用 Google ML Kit 实现高效的二维码扫描识别。
-
地图:AMap的64KB对齐版本,还对地图模块进行了可插拔设计,理论上可以方便的切换到其他地图SDK,默认已经实现了高德地图的标准版SDK和轻量版SDK(通过选择Lite变体将自动切换)
-
项目采用模块化+领域驱动设计
三、功能介绍
mindmap
微信
聊天
联系人
我
设置
登录
mindmap
聊天
聊天列表
标为未读/已读
置顶聊天
不显示聊天
删除聊天
未读数显示
消息类型
文本
语音
表情
图片
视频
位置
文件
音乐
名片
输入框
文本输入
表情输入
全屏输入
草稿消息
通话
视频通话
语音通话
对消息的操作
复制
转发
删除
撤回
下载
多选(批量转发、删除、下载)
切换听筒/扬声器(语音消息)
状态显示
在线状态
加密状态
使用听筒播放语音
聊天信息
消息免打扰
置顶聊天
设置聊天背景
清空聊天记录
mindmap
联系人
联系人列表
新的朋友
自己
好友列表
好友数量
索引栏
长按设置朋友资料
联系人详情
头像(点击查看大图)
备注名
昵称
微信号
性别
个性签名
朋友资料
备注名
备忘
好友来源
添加时间
朋友设置
设置朋友资料
把他(她)推荐给朋友
加入黑名单
删除好友
mindmap
个人资料
头像
预览
修改
保存
名字
性别
微信号
我的二维码
二维码生成
扫一扫
换个样式
保存图片
个性签名
mindmap
通知设置
消息通知
语音和视频通话通知
通知显示内容
仅显示「你收到了1条消息」
显示朋友和群聊的名称
显示朋友、群聊名称及消息内容
系统通知设置入口
聊天界面中的新消息通知
声音控制
振动控制
消息提示音
跟随系统
内置提示音列表
点击支持试听
来电铃声
跟随系统
微信
其他内置铃声列表
点击支持试听
呼叫我时朋友也可听见我的来电铃声
mindmap
其他设置
界面与显示
深色模式
跟随系统
普通模式
深色模式
字体大小
通过滑块调节字体大小
实时预览
多语言
跟随系统
简体中文
English
朋友权限
加我为朋友时需要验证
通讯录黑名单
更多
系统权限状态显示
连接模式
WiFi 局域网
WiFi 直连
蓝牙
聊天
全局聊天背景设置
使用听筒播放语音消息
使用独立的发送按钮
端到端加密
聊天记录管理
清空全部聊天记录
退出登录
四、功能说明
1. 经典启动页
启动页之后会进入欢迎页面,可以修改app语言,点击开始使用将进入登录页面
2. 登录页面
- 也叫个人资料设置页面,设置头像和昵称后就能进入app。
- 点击确定后将会自动生成微信号和身份密钥。
- 私钥将被系统自动保存在硬件安全模块(TSS/SE)。公钥将随个人资料保存在DataStore。
3. 个人资料页面
- 头像可以预览、更换(裁剪)、保存到本地。
- 名字、性别、签名等支持修改。
- 微信号暂不支持修改。
二维码页面
- 支持扫一扫、更换样式、保存图片
4. 添加朋友页面
扫一扫
- 基于二维码
碰一碰
- 基于
NFC卡模拟/读卡
雷达
- 基于
UDP组播+轻量级HTTP头像服务器 - 设备需要在同一Wi-Fi下
加好友逻辑
其实无论基于何种添加方式,上层都只是获取对方的ID,底层都是走的 BLE(低功耗蓝牙)去拉取对方的资料,以及发送和处理好友申请。选择 BLE 的主要原因包括:
- 完全离线运行
- 可以不配对直接交换信息
- 可以在广播包中携带ID信息
- 设备发现速度和资料交换速度都还不错
密钥
在对方同意好友申请后,双方将交换个人资料,包括各自的公钥,这时是唯一获取对方公钥的时机。以后几乎所有的消息都要通过各自的私钥对数据包中几乎所有的字段+时间戳进行签名,然后对方通过保存的对方的公钥进行验签。这主要是为了解决信任问题,防止篡改和伪造。
好友资料更新机制
每次发送心跳包都会带一个基于时间戳的个人资料版本号,不是基于JSON,而是一个轻量级的二进制数据包,这样每次收到心跳,然后去和本地的好友的个人资料版本号进行比对,如果有更新就主动向对方发起拉取资料的请求。首次加好友后,一开始的头像其实是缩略图,因为蓝牙的带宽很小,但是如果他们在同一个Wi-Fi下,就会自动更新对方全量的资料。
5. 聊天页面
文本消息
- 支持表情
- 支持草稿消息
- 超过3行后可以进入全屏输入框
*输入框自带的语音输入由于没有接入服务器,并不好用,可以忽略~
语音消息
表情消息
图片/视频消息
- 支持实况图片
- 支持显示上传进度
- 大视频传输,支持双端进度显示,双端传输控制(暂停/继续/取消),且支持断点续传、秒传等
- 点击将进入app自带的媒体选择器
- 长按将进入系统自带的媒体选择器(部分手机自带的选择器可以选择擦除地理位置、相机参数等信息,以及获得更好的隐私保护)
相机
- 支持对焦
- 支持变焦
- 支持长按录像
- 支持切换摄像头
- 支持开关闪光灯
- 点击将进入app自带的相机
- 长按将进入系统自带的相机(可选拍照/拍视频)
位置消息
- 支持获取当前位置
- 支持搜索位置
- 支持位置快照
- 支持拖动地图自动查询
- 支持点击POI后聚焦及查询附近位置
- 支持调起导航软件(将显示已安装的地图app列表供用户选择)
名片消息
文件消息
*为支持高级传输功能,小文件将会直传,而大文件则会先协商再传输
- 支持大文件秒传
- 先计算文件的
SHA256哈希值 - 发送文件元数据给对方
- 对方查询该哈希值的文件是否存在
- 已存在则回复
AlreadyExists - 不存在则回复
ReadyToReceive
- 先计算文件的
- 支持分片传输+断点续传
- 不使用传统的保存若干个小分片文件,避免合并时的CPU与磁盘IO开销
- 预创建一个和目标文件大小一致的空文件,该操作仅占用元数据空间,有效避免了写入过程中的频繁磁盘空间申请与文件碎片化。
- 放弃传统的
FileOutputStream或RandomAccessFile阻塞式写入,而是采用FileChannel这种接近系统底层效率的API,利用FileChannel.position(offset)精确控制数据落盘位置,显著提升大文件在高并发写入时的吞吐量。
- 支持并发传输
- 在
write时加锁避免数据污染 - 每个分片数据包携带消息
id和offset,准确写入指定消息文件的指定位置 - 支持最多3个文件同时传输
- 蓝牙模式下控制为1个
- 在
- 实时发送进度显示
- 蓝牙模式下进度更新间隔会变小,以实现更平滑的更新
- 支持取消发送
- 支持打开文件
- 支持保存到本地
- 支持转发文件
- 转发的文件不会重复保存,仅增加文件引用计数
发送app
- 支持选择当前手机已安装的app
- 同发送文件的逻辑
发送音乐
- 列表支持点击预览播放/暂停
- 音乐播放页面(参考的网易云音乐)
- 暂停和播放时,唱片的启停模拟物理世界的惯性
- 歌曲名支持循环滚动
通话
- 支持语音通话
- 支持视频通话
- 支持麦克风/摄像头/扬声器开关或切换等
- 支持切换小窗画面
- 小窗支持拖动与自动吸附
- 支持点击空白处收起控件
- 因为不用考虑带宽的问题,默认超清画质+CD级音质
- 支持完全无网环境接打电话,如:Wi-Fi直连、Wi-Fi热点模式
- 支持自定义来电铃声;支持播放对方设置的铃声
*暂未支持悬浮窗、锁屏接听等
*蓝牙模式下支持交换信令,但不支持通话(带宽小且无IP地址)
聊天信息&列表页面
- 消息免打扰
- 置顶聊天
- 设置聊天背景
- 清空聊天记录
- 置为未读/已读
- 隐藏聊天
6. 联系人页面
联系人列表&新的朋友
联系人详情
- 支持查看头像
- 昵称、性别、个性签名显示
- 支持设置备注名和备忘
- 好友来源&添加时间显示
联系人设置
- 加入黑名单
- 删除好友
7. 设置页面
通知设置
- 消息通知开关
- 通话通知开关
- 通知显示内容设置
- 系统通知设置入口
- 聊天界面的新消息通知设置
- 消息提示音设置
- 来电铃声设置
- 呼叫我时朋友也可听见我的来电铃声开关
界面与显示设置
- 深色模式
- 字体大小
- 多语言
朋友权限&更多设置
- 加我为朋友时需要验证
- 通讯录黑名单
- 系统权限获取状态
连接模式&聊天&聊天记录管理
Wi-Fi Lan/Wi-Fi Direct/蓝牙3种连接方式动态切换- 设置全局聊天背景
- 使用听筒播放语音消息
- 使用独立的发送按钮
- 端到端加密:开启后将使用
AES加密所有的数据包,无论是文本数据还是文件分块,且密钥由每次握手时协商,私钥仅存于内存 - 清空全部聊天记录
8. 连接方式
Wi-Fi Lan:需要设备在同一Wi-Fi下
- 技术实现方案:安卓自带的NSD (Network Service Discovery)
- 协议栈深度集成:基于 mDNS (Multicast DNS) 协议,利用 UDP 端口 5353 进行多播。通过
NsdManager实现服务的注册、发现与解析,无需手动输入 IP 地址即可实现设备间的 “零配置”连接。 - 高效的服务交换:
- Service Broadcasting:设备通过多播宣告自身的存在及支持的通信协议。
- Dynamic Resolution:自动处理局域网内动态分配的 IP 变化,确保长效连接的稳定性。
- 局限性与风险
- AP 隔离 (AP Isolation) 限制:
- 在酒店、机场、公司等公共 Wi-Fi 环境中,路由器通常开启“AP 隔离”功能。此时,即便设备在同一 SSID 下,防火墙也会拦截设备间的 UDP 多播包,导致 NSD 无法发现彼此。
- 多播风暴抑制 (Multicast Filtering) :
- 部分企业级路由器为节省空口带宽,会主动丢弃或限制多播数据包频率。这会导致服务发现延迟高,或者在设备较多时出现“发现不稳定”的现象。
- 系统级休眠影响:
- Android 的 省电模式 可能会在屏幕关闭后限制网络活动或延迟 UDP 包的接收。需要通过前台服务(Foreground Service)或申请忽略电池优化来维持发现机制的活跃。
Wi-Fi Direct:需要手动选择设备并配对,支持无网环境
- 协议原理
- 基于 Wi-Fi Alliance P2P 标准。与传统 Wi-Fi 需要路由器(AP)作为中心节点不同,Wi-Fi Direct 允许设备间通过软件定义的“软 AP”(Group Owner, GO)直接建立连接。
- 角色协商 (Group Formation) :连接时,两台设备会通过协议协商谁充当 GO (Group Owner) ,谁充当 GC (Group Client) 。GO 负责管理 DHCP 分配 IP,GC 像连接普通 Wi-Fi 一样接入。
- 技术优势
- 支持无网环境:完全脱离路由器限制,在户外、偏远地区或公共场所(禁用局域网通信时)仍可实现高速互联。
- 吞吐量极大化:支持 802.11ac/ax 协议,理论带宽可达数百 Mbps。由于是点对点直连,减少了路由器中转的延迟和干扰。
- 安全性 (WPA2/WPA3) :连接过程强制使用 WPS 机制(如 PIN 码或 Push Button),确保物理隔离外的第三方无法监听传输内容。
可以看到Wi-Fi直连的传输速度是非常可观的,但这还不是最高速度,我的小米手机之间采用系统互传的速度可以超过100MB/s,所以一定还有更快的但相对复杂的传输逻辑。据说微信新推出的面对面传文件功能,在安卓端也用到了Wi-Fi Direct技术,不过不需要弹窗配对,应该还用到了其他思路,比如直接将GO的ssid和password通过网络等方式传给对方设备来连接。
蓝牙:需要手动选择设备并配对,支持无网环境
- 技术实现方案:经典蓝牙 (Bluetooth Classic / RFCOMM)
- 通过模拟串行端口(Serial Port Profile, SPP),提供相对稳定的流式传输。理论峰值速率约 2.1 Mbps,实测在 Android 设备间约为 100-200 KB/s。
- 技术优势
- 极强的抗干扰性:采用自适应跳频(AFH)技术,在 2.4GHz 拥挤的环境下(如展会、办公室),蓝牙的连接成功率通常高于 Wi-Fi Direct。
- 协议级普适性:不依赖路由器,不依赖 Wi-Fi 芯片状态(即使 Wi-Fi 正在连接热点,蓝牙也能并行工作),是真正的“全天候”连接手段。
- 限制与痛点
- 带宽瓶颈:
- 由于速率限制,传输一个 100MB 的视频可能需要 10 分钟以上。连传一个表情包可能都有点慢,大家可以试一下。
- 共存干扰 :
- 由于蓝牙和 Wi-Fi 共享天线和 2.4GHz 频段,在进行蓝牙大流量传输时,可能会导致 Wi-Fi 延迟剧增(Ping 值抖动)。
Wi-Fi热点模式
- 其实在户外环境,一个设备开热点,其他设备连接也是可以的,甚至可以打电话,和Wi-Fi Direct下类似,大家可以试一下~
五、源码&安装包
源码
安装包
六、结语
现在解决了有没有的问题,其实还有很多好不好的问题有待解决。可能还有兼容性问题,因为测试资源不够。还有一些功能如群聊还没做。反正真的去做了你会发现,微信的细节太多了,现在还远没有真正达到微信的体验。不过这个项目的目的并不是要超过谁,或者创造多大的商业价值,仅仅只是因为兴趣。我之前主要做Web前端,没有过实际的安卓工作经验,基本都是自学的,所以如果有写的不好甚至不对的地方,大家多多指正哈,一起让这个项目变得更好~
钟睒睒说:
我们要不断学习新的东西,打破自己原来知识结构的藩篱。
完^_^