【带源码】我写了个局域网微信

2,067 阅读11分钟

在一次爬山途中,由于手机突然没有信号让我萌生了一个大胆的想法:能不能让手机之间直接连接并像微信一样通信呢?借离职后的自由时间,我决定挑战一下自己,开发一款小巧的设备间直连通信应用,在交互与功能层面尽量对齐微信,同时深度挖掘安卓系统底层能力,利用多种近场通信技术实现设备间的直接高效互联。

一、核心理念

  1. 去中心化: 摆脱服务器限制,探索设备间的直接互联。
  2. 多模态连接: 支持切换 Wi-FiWi-Fi直连蓝牙 等连接方式。
  3. 技术全栈化: 深度集成硬件调度、数据加密、文件传输及音视频通信等核心模块。

二、技术栈

技术选型说明
UI 框架Jetpack Compose构建响应式、现代化 UI
依赖注入Hilt模块化代码解耦
页面导航Navigation3类型安全的状态导航
数据持久化Room3, DataStore高效的本地数据缓存与配置管理
多媒体WebRTC, CameraX, MLKit, Coil3提供实时音视频及媒体处理能力
地图服务AMap可插拔架构,支持标准版/轻量版 SDK 自由切换
加好友BLE低功耗蓝牙
设备发现NSD局域网内服务注册、发现、解析
通信TCP Socket / RfcommSocket设备间连接的底层方案

均采用主流技术栈及最新版本


三、功能介绍

mindmap
      微信
          聊天
          联系人
          我
          设置
          登录
mindmap
      聊天
          聊天列表
              标为未读/已读
              置顶聊天
              不显示聊天
              删除聊天
              未读数显示
          消息类型
              文本
              语音
              表情
              图片
              视频
              位置
              文件
              音乐
              名片
          输入框
              文本输入
              表情输入
              全屏输入
              草稿消息
          通话
              视频通话
              语音通话
          对消息的操作
              复制
              转发
              删除
              撤回
              下载
              多选(批量转发、删除、下载)
              切换听筒/扬声器(语音消息)
          状态显示
              在线状态
              加密状态
              使用听筒播放语音
          聊天信息
              消息免打扰
              置顶聊天
              设置聊天背景
              清空聊天记录
mindmap
     联系人
         联系人列表
             新的朋友
             自己
             好友列表
             好友数量
             索引栏
             长按设置朋友资料
         联系人详情
             头像(点击查看大图)
             备注名
             昵称
             微信号
             性别
             个性签名
         朋友资料
             备注名
             备忘
             好友来源
             添加时间
         朋友设置
             设置朋友资料
             把他(她)推荐给朋友
             加入黑名单
             删除好友
mindmap
     个人资料
         头像
             预览
             修改
             保存
         名字
         性别
         微信号
         我的二维码
             二维码生成
             扫一扫
             换个样式
             保存图片
         个性签名
mindmap
     通知设置
        消息通知
        语音和视频通话通知
        通知显示内容
            仅显示「你收到了1条消息」
            显示朋友和群聊的名称
            显示朋友、群聊名称及消息内容
        系统通知设置入口
        聊天界面中的新消息通知
            声音控制
            振动控制
        消息提示音
            跟随系统
            内置提示音列表
            点击支持试听
        来电铃声
            跟随系统
            微信
            其他内置铃声列表
            点击支持试听
        呼叫我时朋友也可听见我的来电铃声
mindmap
     其他设置
         界面与显示
            深色模式
                跟随系统
                普通模式
                深色模式
            字体大小
                通过滑块调节字体大小
                实时预览
            多语言
                跟随系统
                简体中文
                English
        朋友权限
            加我为朋友时需要验证
            通讯录黑名单
        更多
            系统权限状态显示
        连接模式
            WiFi 局域网
            WiFi 直连
            蓝牙
        聊天
            全局聊天背景设置
            使用听筒播放语音消息
            使用独立的发送按钮
            端到端加密
        聊天记录管理
            清空全部聊天记录
        退出登录

四、功能说明

1. 经典启动页

启动页之后会进入欢迎页面,可以修改app语言,点击开始使用将进入登录页面

Screenrecorder-2026-03-26-08-59-23-991.gif

2. 登录页面

  • 也叫个人资料设置页面,设置头像和昵称后就能进入app。
  • 点击确定后将会自动生成微信号身份密钥
  • 私钥将被系统自动保存在硬件安全模块(TSS/SE)。公钥将随个人资料保存在DataStore

Screenrecorder-2026-03-26-09-08-03-915.gif

3. 个人资料页面

  • 头像可以预览、更换(裁剪)、保存到本地。
  • 名字、性别、签名等支持修改。
  • 微信号暂不支持修改。

Screenrecorder-2026-03-26-09-10-12-422.gif

二维码页面

  • 支持扫一扫、更换样式、保存图片

Screenrecorder-2026-03-26-09-12-43-699.gif


4. 添加朋友页面

扫一扫

  • 基于二维码

Screenrecorder-2026-03-26-09-15-03-936.gif

碰一碰

  • 基于NFC卡模拟/读卡

Screenrecorder-2026-03-26-09-17-57-519.gif

雷达

  • 基于UDP组播+轻量级HTTP头像服务器
  • 设备需要在同一Wi-Fi下

Screenrecorder-2026-03-26-09-20-56-311.gif

加好友逻辑

其实无论基于何种添加方式,上层都只是获取对方的ID,底层都是走的 BLE(低功耗蓝牙)去拉取对方的资料,以及发送和处理好友申请。选择 BLE 的主要原因包括:

  • 完全离线运行
  • 可以不配对直接交换信息
  • 可以在广播包中携带ID信息
  • 设备发现速度和资料交换速度都还可以

密钥

在对方同意好友申请后,双方将交换个人资料,包括各自的公钥,这时是唯一获取对方公钥的时机。以后几乎所有的消息都要通过各自的私钥对数据包中几乎所有的字段+时间戳进行签名,然后对方通过保存的对方的公钥进行验签。这主要是为了解决信任问题,防止篡改和伪造

好友资料更新机制

每次发送心跳包都会带一个基于时间戳的个人资料版本号,不是基于JSON,而是一个轻量级的二进制数据包,这样每次收到心跳,然后去和本地的好友的个人资料版本号进行比对,如果有更新就主动向对方发起拉取资料的请求。首次加好友后,一开始的头像其实是缩略图,因为蓝牙的带宽很小,但是如果他们在同一个Wi-Fi下,就会自动更新对方全量的资料。


5. 聊天页面

文本消息

  • 支持表情
  • 支持草稿消息
  • 超过3行后可以进入全屏输入框

*输入框自带的语音输入由于没有接入服务器,并不好用,可以忽略~

Screenrecorder-2026-03-26-09-56-32-873.gif

语音消息

Screenrecorder-2026-03-26-10-00-38-120.gif

表情消息

Screenrecorder-2026-03-26-10-02-52-791.gif

图片/视频消息

  • 支持实况图片
  • 支持显示上传进度
  • 大视频传输,支持双端进度显示,双端传输控制(暂停/继续/取消),且支持断点续传、秒传等
  • 点击将进入app自带的媒体选择器
  • 长按将进入系统自带的媒体选择器(部分手机自带的选择器可以选择擦除地理位置、相机参数等信息,以及获得更好的隐私保护)

Screenrecorder-2026-03-26-11-02-35-573.gif

相机

  • 支持对焦
  • 支持变焦
  • 支持长按录像
  • 支持切换摄像头
  • 支持开关闪光灯
  • 点击将进入app自带的相机
  • 长按将进入系统自带的相机(可选拍照/拍视频)

Screenrecorder-2026-03-26-11-22-11-442.gif

位置消息

  • 支持获取当前位置
  • 支持搜索位置
  • 支持位置快照
  • 支持拖动地图自动查询
  • 支持点击POI后聚焦及查询附近位置
  • 支持调起导航软件(将显示已安装的地图app列表供用户选择)

Screenrecorder-2026-03-26-11-31-03-491.gif

名片消息

Screenrecorder-2026-03-26-11-41-53-687.gif

文件消息

小文件会直传,大文件会先协商再传输

  • 支持大文件秒传
    • 先计算文件的SHA256哈希值
    • 发送文件元数据给对方
    • 对方查询该哈希值的文件是否存在
    • 已存在则回复AlreadyExists
    • 不存在则回复ReadyToReceive
  • 支持分片传输+断点续传
    • 不使用传统的保存若干个小分片文件,避免合并时的CPU与磁盘IO开销
    • 预创建一个和目标文件大小一致的空文件,该操作仅占用元数据空间,有效避免了写入过程中的频繁磁盘空间申请与文件碎片化。
    • 放弃传统的 FileOutputStreamRandomAccessFile 阻塞式写入,采用 FileChannel这种接近系统底层效率的API,利用 FileChannel.position(offset) 精确控制数据落盘位置,显著提升大文件在高并发写入时的吞吐量。
  • 支持并发传输
    • write时加锁避免数据污染
    • 每个分片数据包携带消息idoffset,准确写入指定消息文件的指定位置
    • 支持最多3个文件同时传输
    • 蓝牙模式下控制为1个
  • 实时发送进度显示
    • 蓝牙模式下进度更新间隔会变小,以实现更平滑的更新
  • 支持取消发送
  • 支持打开文件
  • 支持保存到本地
  • 支持转发文件
    • 转发的文件不重复保存,仅增加文件引用计数

Screenrecorder-2026-03-26-11-45-07-785.gif

发送app

  • 支持选择当前手机已安装的app
  • 同发送文件的逻辑

Screenrecorder-2026-03-26-11-50-44-129.gif

发送音乐

  • 列表支持点击预览播放/暂停
  • 音乐播放页面(参考的网易云音乐)
  • 暂停和播放时,唱片的启停模拟物理世界的惯性
  • 歌曲名支持循环滚动

Screenrecorder-2026-03-26-11-59-50-616.gif

通话

  • 支持语音通话
  • 支持视频通话
  • 支持麦克风/摄像头/扬声器开关或切换等
  • 支持切换小窗画面
  • 小窗支持拖动与自动吸附
  • 支持点击空白处收起控件
  • 因为不用考虑带宽的问题,默认超清画质+CD级音质
  • 支持完全无网环境接打电话,如:Wi-Fi直连、Wi-Fi热点模式
  • 支持自定义来电铃声;支持播放对方设置的铃声

*暂未支持悬浮窗、锁屏接听等

*蓝牙模式下支持交换信令,但不支持通话(带宽小且无IP地址)

Screenrecorder-2026-03-26-12-12-10-269.gif

Screenrecorder-2026-03-26-12-15-45-712.gif

聊天信息&列表页面

  • 消息免打扰
  • 置顶聊天
  • 设置聊天背景
  • 清空聊天记录
  • 置为未读/已读
  • 隐藏聊天

Screenrecorder-2026-03-26-15-45-13-904.gif

Screenrecorder-2026-03-26-15-49-27-73.gif


6. 联系人页面

联系人列表&新的朋友

Screenrecorder-2026-03-26-15-55-57-627.gif

联系人详情

  • 支持查看头像
  • 昵称、性别、个性签名显示
  • 支持设置备注名和备忘
  • 好友来源&添加时间显示

Screenrecorder-2026-03-26-16-03-55-538.gif

联系人设置

  • 加入黑名单
  • 删除好友

Screenrecorder-2026-03-26-16-53-35-100.gif


7. 设置页面

通知设置

  • 消息通知开关
  • 通话通知开关
  • 通知显示内容设置
  • 系统通知设置入口
  • 聊天界面的新消息通知设置
  • 消息提示音设置
  • 来电铃声设置
  • 呼叫我时朋友也可听见我的来电铃声开关

Screenrecorder-2026-03-26-17-00-05-107.gif

界面与显示设置

  • 深色模式
  • 字体大小
  • 多语言

Screenrecorder-2026-03-26-17-05-34-813.gif

朋友权限&更多设置

  • 加我为朋友时需要验证
  • 通讯录黑名单
  • 系统权限获取状态

Screenrecorder-2026-03-26-17-09-07-405.gif

连接模式&聊天&聊天记录管理

  • Wi-Fi/Wi-Fi Direct/蓝牙3种连接方式动态切换
  • 设置全局聊天背景
  • 使用听筒播放语音消息
  • 使用独立的发送按钮
  • 端到端加密:开启后将使用AES加密所有的数据包,无论是文本数据还是文件分块,且密钥由每次握手时协商,私钥仅存于内存
  • 清空全部聊天记录

Screenrecorder-2026-03-26-17-11-02-173.gif


8. 连接方式

无论底层基于何种连接方式,在上层都是一套ConnectionManager,抽象出了共同的方法:发送消息、接收消息和心跳机制等。他们的差异主要体现在发现设备、以及连接设备。像Wi-Fi和Wi-Fi Direct,他们可以基于共同的 TCPSocket,而蓝牙则是基于 RfcommSocket

Wi-Fi:需要设备在同一Wi-Fi下

  1. 什么是 NSD?

NSD (Network Service Discovery) 是 Android 系统提供的原生服务,基于 mDNS (Multicast DNS) 协议实现。它允许应用在局域网内进行服务的注册发现解析 ,无需手动输入 IP 地址即可实现设备互联。

  1. 局域网好友地址发现与连接机制

在 Wi-Fi 网络环境下,系统通过以下流程实现自动发现与通信:

  • 服务广播与发现:后台持续通过 NSD 协议在局域网内广播自身服务信息(包含 wxid 等标识符)。同时,监听网络中的其他广播包,解析出设备的 wxidHostPort 等关键元数据。

  • 连接握手与验证:当发现的设备 wxid 匹配好友列表时,系统自动发起 TCP 连接请求。

  • 连接池管理与持久化

    • 连接池:建立成功的连接实例以 wxid 为 Key 存入内存连接池。
    • 持久化:同步将最新的连接拓扑信息(IP/Port)写入本地数据库,以便在 App 重启或网络波动后快速恢复连接。
  • 消息发送逻辑:发送消息时,系统优先从内存连接池检索对应的 Socket 实例。若连接不存在或已失效,则利用数据库缓存的地址信息重新发起连接。

Wi-Fi直连:需要手动选择设备并配对,支持无网环境

  1. 协议原理:与传统 Wi-Fi 需要路由器作为中心节点不同,Wi-Fi Direct 允许设备间通过软件定义的“软 AP”直接建立连接。

    • 角色协商 :连接时,两台设备会通过协议协商谁充当 GO (Group Owner) ,谁充当 GC (Group Client) 。GO 负责管理 DHCP 分配 IP,GC 像连接普通 Wi-Fi 一样接入。
    • 与普通Wi-Fi模式下的通信逻辑基本共享。
  2. 技术优势

  • 支持无网环境:完全脱离路由器限制,在户外、偏远地区或公共场所(禁用局域网通信时)仍可实现高速互联。
  • 吞吐量极大:由于是点对点直连,减少了路由器中转的延迟和干扰。

MP4_20260326_194916VLOG.gif

可以看到Wi-Fi直连的传输速度是非常可观的

蓝牙:需要手动选择设备并配对,支持无网环境

  1. 采用 经典蓝牙 (RFCOMM)

  2. 技术优势

  • 稳定性较好
  • 安全性较高
  1. 限制与痛点
  • 传输速度慢
  • 传输距离近

Wi-Fi热点模式

  • 在户外环境,一个设备开热点,其他设备连接也是可以的,甚至可以打电话,和Wi-Fi直连类似。

五、源码&安装包

源码

安装包

注:可通过修改系统默认的省电策略为无限制来保持锁屏后的稳定连接。


六、结语

钟睒睒说:

我们要不断学习新的东西,打破自己原来知识结构的藩篱。

这个项目让我学到了很多东西,现在毫无保留的分享给大家,希望能帮到你~

完^_^