如何使用NanoHTTPD实现已安装应用的APK提取与下载功能
实现APK下载功能的修改方案
你需要调整两部分逻辑:一是修改下载链接的规则,二是新增下载请求的处理逻辑。
1. 修正应用列表的链接格式
原来的href直接使用应用名作为路径,无法匹配到对应APK,调整为带包名参数的下载路径:
// 原列表生成代码替换为以下逻辑 answer += "<a href=\"/download?pkg=" + file.getPackageName() + "\" alt = \"\">" + file.getAppName() + "</a><br>";
2. 新增下载请求处理逻辑
在NanoHTTPD的GET请求判断分支中,先匹配下载请求路径,读取对应APK文件返回,完整的请求处理逻辑如下:
if (method.equals(Method.GET)) { String uri = session.getUri(); // 处理下载请求 if (uri.startsWith("/download")) { String pkgName = session.getParms().get("pkg"); if (pkgName == null || pkgName.isEmpty()) { return newFixedLengthResponse(Response.Status.BAD_REQUEST, "text/plain", "无效请求参数"); } // 匹配对应应用的APK路径 App targetApp = null; for (App app : apps) { if (app.getPackageName().equals(pkgName)) { targetApp = app; break; } } if (targetApp == null) { return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "未找到对应应用"); } File apkFile = new File(targetApp.getApkPath()); if (!apkFile.exists()) { return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "APK文件不存在"); } // 返回APK文件流触发下载 try { FileInputStream fis = new FileInputStream(apkFile); Response response = newFixedLengthResponse(Response.Status.OK, "application/vnd.android.package-archive", fis, apkFile.length()); // 处理中文文件名乱码问题 String fileName = URLEncoder.encode(targetApp.getAppName() + ".apk", "UTF-8").replaceAll("\\+", "%20"); response.addHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName); return response; } catch (Exception e) { e.printStackTrace(); return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, "text/plain", "文件读取失败"); } } // 原有应用列表返回逻辑 StringBuilder answer = new StringBuilder("<html><body><h3>已安装应用列表</h3>"); for (App file : apps) { answer.append("<a href=\"/download?pkg=") .append(file.getPackageName()) .append("\">") .append(file.getAppName()) .append("</a><br>"); } answer.append("</body></html>"); return newFixedLengthResponse(Response.Status.OK, "text/html", answer.toString()); }
注意事项
- 你原有代码中
packageManager.getInstalledApplications(PackageManager.GET_META_DATA;缺少右括号,修正为packageManager.getInstalledApplications(PackageManager.GET_META_DATA); - 不需要额外申请存储权限,系统默认允许应用读取已安装应用的APK源文件路径
- 文件名编码处理已适配中文场景,避免下载时文件名乱码
内容的提问来源于stack exchange,提问作者jcooli
相关产品推荐
相关产品推荐

