Android中使用nanohttpd实现WiFi Direct聊天应用文件传输的开发指南问询
1. 前期权限配置
首先在AndroidManifest.xml中声明所需权限,注意区分不同Android版本的适配要求:
<!-- WiFi Direct基础权限 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <!-- Android 12+ 临近设备权限,替代旧版位置权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> <!-- Android 12及以下设备需额外声明位置权限,用于设备扫描 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="32" /> <!-- 文件读写权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
所有危险级权限必须在运行时动态申请,拿到用户授权后才能正常执行后续流程。
2. WiFi Direct连接建立流程
- 初始化核心组件:获取系统
WifiP2pManager实例,注册广播接收器监听以下事件:WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION:WiFi Direct开关状态变更WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION:周边可用设备列表更新WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION:连接状态变更WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:本机设备信息变更
- 设备搜索:调用
WifiP2pManager.discoverPeers()发起周边设备扫描,扫描到结果后通过WifiP2pManager.requestPeers()拿到设备列表,展示给用户选择连接目标。 - 建立连接:用户选择目标设备后构造
WifiP2pConfig,调用connect()方法发起配对。连接成功后通过requestConnectionInfo()回调获取群主(Group Owner)IP地址,默认IP为192.168.49.1,这是后续访问文件服务的核心地址。
3. 集成NanoHTTPD实现文件共享
3.1 引入依赖
在模块级build.gradle中添加NanoHTTPD依赖:
dependencies { implementation 'org.nanohttpd:nanohttpd:2.3.1' }
3.2 实现文件服务端
服务端默认运行在群主设备上,也可以两端都部署实现双向文件传输:
public class FileShareServer extends NanoHTTPD { // 自定义端口,建议使用1024以上的无冲突端口 private static final int PORT = 8080; public FileShareServer() { super(PORT); } @Override public Response serve(IHTTPSession session) { // 解析请求参数获取目标文件路径 String targetPath = session.getParms().get("path"); File targetFile = new File(targetPath); if (!targetFile.exists() || !targetFile.isFile()) { return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "文件不存在"); } try { FileInputStream fis = new FileInputStream(targetFile); return newFixedLengthResponse( Response.Status.OK, "application/octet-stream", fis, targetFile.length() ); } catch (FileNotFoundException e) { return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, "text/plain", "文件读取失败"); } } }
WiFi Direct连接成功后,在服务端执行new FileShareServer().start()启动服务即可。
3.3 客户端拉取文件
客户端拿到群主IP后,直接发起HTTP请求即可获取文件,示例请求格式:
http://192.168.49.1:8080?path=/sdcard/Download/xxx.mp4
请求返回的输入流直接写入本地存储,即可完成文件传输。
4. 常见注意事项
- 连接断开时要主动调用NanoHTTPD的
stop()方法释放端口,避免后续启动失败 - 大文件传输可在
serve方法中处理Range请求头,实现断点续传 - 聊天文本消息也可以通过这套HTTP接口传输,或者单独建立Socket通道,可按需选择
- 所有网络操作必须在子线程执行,避免阻塞主线程触发ANR
内容的提问来源于stack exchange,提问作者Shekhar Chauhan
相关产品推荐
相关产品推荐

