安卓手机通过 USB 为 MacBook 提供网络连接

实测环境:已 Root 的小米 10S、Android 12、Apple Silicon MacBook。

安卓手机默认通过 RNDIS 提供 USB 网络共享,而现代 macOS,尤其是 Apple Silicon MacBook,通常不能原生识别 RNDIS 网卡。

如果手机内核支持 CDC NCM,可在 Root 权限下把 USB Gadget 从 RNDIS 切换为 NCM。macOS 能原生识别 NCM,不需要:

  • 安装 HoRNDIS;
  • 安装第三方内核驱动;
  • 关闭 SIP;
  • 修改 Mac 系统内核。

本次小米 10S 实测结果:

  • 手机 USB 功能从 rndis 成功切换为 ncm;
  • macOS 创建了 Mi 10S 网络端口;
  • 网络接口为 en10;
  • Mac 获得 IPv4 地址 192.168.180.124;
  • NCM 枚举和 DHCP 地址分配均已成功。

完整链路如下:

text 复制代码
手机移动数据或 Wi-Fi
        ↓
Android Tethering + NAT + DHCP
        ↓
USB Gadget 使用 CDC NCM
        ↓
USB-C 数据线
        ↓
macOS 原生 USB 网络接口 enX
        ↓
MacBook 访问互联网

一:检查手机是否支持 NCM

1 确认 ADB 在线

bash 复制代码
adb devices

正常状态应为:

text 复制代码
device

如果显示 unauthorized,需要在手机上允许 USB 调试;如果显示 offline,可尝试重新插拔数据线或重启 ADB。

2 检查设备和内核

bash 复制代码
adb shell su -c 'getprop ro.product.device'
adb shell su -c 'getprop ro.build.version.release'
adb shell su -c 'uname -a'
adb shell su -c 'svc usb getFunctions'

3 检查 NCM 内核配置

bash 复制代码
adb shell su -c 'zcat /proc/config.gz 2>/dev/null | grep -E "USB_F_NCM|USB_CONFIGFS_NCM|USB_F_RNDIS|USB_CONFIGFS_RNDIS"'

本次小米 10S 的关键输出:

text 复制代码
CONFIG_USB_F_NCM=y
CONFIG_USB_F_RNDIS=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_RNDIS=y

其中最关键的是:

text 复制代码
CONFIG_USB_F_NCM=y
CONFIG_USB_CONFIGFS_NCM=y

如果 /proc/config.gz 不存在,不能直接判断手机不支持 NCM。仍可尝试切换,并以 Mac 是否出现新网络接口作为最终判断。

二:临时切换为 NCM

第一次测试建议先使用临时切换,确认手机、数据线和 Mac 能够完整工作后,再考虑持久化。

操作顺序

  1. 用数据线连接手机和 Mac。
  2. 执行 adb devices,确认手机在线。
  3. 在手机中打开"个人热点"或"便携式热点"。
  4. 开启"USB 网络共享"。
  5. 在 Mac 终端执行 NCM 切换命令。
bash 复制代码
adb shell su -c 'svc usb setFunctions ncm'

切换时 USB Gadget 会重新枚举,ADB 可能短暂断开,这是正常现象。等待 5 至 10 秒,必要时重新插拔数据线。

重新连接后检查当前 USB 功能:

bash 复制代码
adb shell su -c 'svc usb getFunctions'

成功结果:

text 复制代码
ncm

如果仍返回 rndis,说明 MIUI 或 USB 网络共享界面又把功能切回了 RNDIS。应先打开 USB 网络共享,再重新执行 NCM 切换命令。

三:可选的持久化配置

临时执行 svc usb setFunctions ncm 可能在以下操作后失效:

  • 手机重启;
  • 重新插拔数据线;
  • 关闭并重新打开 USB 网络共享;
  • MIUI 重新应用默认 USB 配置。

Android 12 可以尝试通过全局设置让 USB 网络共享优先使用 NCM:

bash 复制代码
adb shell su -c 'settings put global tether_force_usb_functions 1'
adb shell su -c 'settings get global tether_force_usb_functions'
adb reboot

重启后:

  1. 重新连接 Mac;
  2. 在手机中打开 USB 网络共享;
  3. 检查当前功能。
bash 复制代码
adb shell su -c 'svc usb getFunctions'

预期结果:

text 复制代码
ncm

不同厂商 ROM 可能忽略或覆盖该设置。如果仍返回 rndis,继续采用"先打开 USB 网络共享,再手动执行 NCM 切换"的方式。

四:成功判据

检查命令或位置 成功表现 失败时优先排查
svc usb getFunctions 返回 ncm 开启 USB 网络共享后重新强制 NCM
networksetup -listallhardwareports 出现手机名称和 enX 数据线、USB 授权、NCM 支持、重新插拔
ifconfig enX status: active Android Tethering、DHCP 和下游接口
ipconfig getifaddr enX 返回 192.168.x.x 重新申请 DHCP 或重启网络共享
ping 和 curl 能访问互联网 默认路由、DNS、上游网络、运营商限制

五:恢复 Android 默认配置

删除全局 NCM 强制设置:

bash 复制代码
adb shell su -c 'settings delete global tether_force_usb_functions'
adb reboot

在当前会话中切回 RNDIS:

bash 复制代码
adb shell su -c 'svc usb setFunctions rndis'

切换时 USB 会重新枚举,ADB 可能暂时断开。

最后:快速执行清单

对于已经确认内核支持 NCM 的 Root 手机,可以直接按下面顺序操作:

bash 复制代码
# 1. 确认 ADB
adb devices

# 2. 查看当前 USB 功能
adb shell su -c 'svc usb getFunctions'

# 3. 先在手机中打开 USB 网络共享

# 4. 强制切换为 NCM
adb shell su -c 'svc usb setFunctions ncm'

# 5. 确认切换结果
adb shell su -c 'svc usb getFunctions'

# 6. 查看 Mac 网络端口
networksetup -listallhardwareports
# 我这里是查到有一台小米10s的设备,网络接口是en10

# 7. 将 en10 替换为自己实际的 enX
ipconfig getifaddr en10

# 8. 验证公网访问
ping -c 4 1.1.1.1
curl -I https://www.apple.com

满足以下三个条件即可确认成功:

  • 手机端 getFunctions 返回 ncm;
  • Mac 出现手机网络端口,并获得 192.168.x.x 地址;
  • ping 和 curl 均能正常访问公网。
相关推荐
lpfasd12321 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Data analyse4561 天前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai1 天前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
环境栈笔记1 天前
指纹浏览器 WebRTC 怎么设置?从 ICE 候选、代理出口到功能验证
前端·人工智能·后端·自动化
赵大仁1 天前
官网性能优化实战:LCP 3.2s → 2.1s、CLS 0.107 → 0,以及被我推翻的 6 个判断
前端·性能优化·cls·lcp·core web vitals
xiancai_xianyu1 天前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
小羊没烦恼!1 天前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
史瓦辛格1 天前
给 DeepSeek Harness 写费用插件:把「这次会话花了多少钱」算准
前端·deepseek
星光不问赶路人1 天前
Vue 3 + TypeScript 中 enum 的使用实践
前端·vue.js
鸥梨菌Honevid1 天前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet