为什么 NetShare 不需要 Root 权限也能分享网络
Android 的权限护城河
Android 6 引入的运行时权限机制,加上从 Android 10 开始逐步收紧的网络 API 访问控制,让第三方应用直接调用系统热点接口变得越来越困难。运营商在 SIM 卡的 Carrier Config 里写入 tether_ap_required_authorization=true 后,任何尝试用 WifiManager.setWifiApEnabled() 开启热点的非白名单应用都会被静默拒绝。
更麻烦的是,即使应用拥有 CHANGE_WIFI_STATE 权限,原生热点在 Android 8 以上也已经变成了只能由系统设置进程调用的隐藏 API。谷歌通过 @hide 注解和白名单机制把第三方应用排除在外。这就是为什么市面上大量"一键热点"应用在 Android 12+ 上纷纷失效。
NetShare 的绕过策略
NetShare 没有试图和系统隐藏 API 死磕,而是换了一个思路:不创建"系统热点",创建"WiFi Direct 组主人(Group Owner)"。
WiFi Direct 是 Android 4.0 就内置的标准功能,从架构上它和传统热点的关系是:
| 特性 | 系统热点 | WiFi Direct 组主人 |
|---|---|---|
| 触发方式 | WifiManager 隐藏 API | WifiP2pManager 公开 API |
| 运营商控制 | 受 SIM 配置约束 | 完全不受 |
| 需要 Root | Android 12+ 基本需要 | 不需要 |
| 设备发现 | 扫描 WiFi SSID | WiFi Direct 服务发现 |
NetShare 内部调用的流程是:
- 调用
WifiP2pManager的createGroup()创建一个 P2P 网络,自己成为 Group Owner - 这个 P2P 网络会广播一个 SSID(就是应用界面上显示的名称),其他设备可以像连普通 WiFi 一样扫描到它
- 设备连接后,NetShare 在自己身上启动一个轻量的 HTTP 代理服务器(默认端口 8282)
- 代理服务器把接收到的请求转发到手机原本的网络接口(蜂窝数据或当前 WiFi)
本地代理为什么是必需的
Android 系统不允许 WiFi Direct 网络的流量直接转发到另一个网络接口——这是出于安全考虑的隔离机制。NetShare 必须在应用层自己做这件事:它启动的 HTTP 代理相当于一个中间人,接收来自连接设备的请求,再以自己的身份发出去,然后把响应原路返回。
这也是为什么接收端设备必须手动配置 HTTP 代理。系统无法自动完成这一步,因为自动代理配置本身也属于受限制的系统能力。NetShare 在应用界面上把代理地址和端口直接展示出来,用户抄过去填就行。
安全层面的考量
需要注意的是,NetShare 在连接设备上创建的是一个标准 HTTP 代理而非 SOCKS 代理。这意味着:
- 浏览器访问网页没问题(HTTP 和 HTTPS 都支持,后者走 CONNECT 隧道)
- 应用层自己实现代理支持的就能走(比如大多数桌面应用)
- 不走系统代理的应用(比如某些游戏、P2P 工具)可能连不上——这不是 NetShare 的 bug,而是那些应用无视系统代理设置