Android调用pm uninstall命令卸载应用报IOException权限错误怎么办
问题根因分析
- 参数格式错误:
Runtime.getRuntime().exec()传入的字符串数组要求每个命令参数单独作为数组元素,你将整条命令合并为一个字符串传入,同时参数中的短横线使用了全角长破折号,系统无法识别正确命令参数。 - 流程逻辑错误:
pro.waitFor()被放在读取输出的while循环内,会导致第一次读取输出行后就阻塞等待进程结束,无法读取剩余输出内容;且未读取进程错误流,进程异常输出会填满缓冲区导致阻塞。 - 权限不足:报错
error=13, Permission denied是核心问题,安卓系统默认限制第三方普通应用调用pm uninstall命令,该命令需要系统级权限才能执行。
修复方案
第一步:修正代码语法与逻辑
修正后的代码如下:
Process pro; StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); try { // 拆分每个参数为独立数组元素,替换全角符号为半角 pro = Runtime.getRuntime().exec(new String[]{"pm", "uninstall", "-k", "--user", "0", "com.google.android.gm"}); // 同时读取正常输出流和错误流 BufferedReader outputReader = new BufferedReader(new InputStreamReader(pro.getInputStream())); BufferedReader errorReader = new BufferedReader(new InputStreamReader(pro.getErrorStream())); String line; while ((line = outputReader.readLine()) != null) { output.append(line).append("\n"); } while ((line = errorReader.readLine()) != null) { error.append(line).append("\n"); } // 等待进程执行结束,放在流读取完成之后 int exitCode = pro.waitFor(); output.append("执行退出码:").append(exitCode); if (error.length() > 0) { output.append("\n错误信息:").append(error); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } String response = output.toString(); System.out.println(response); Log.d("log", response);
第二步:解决权限问题
根据你的使用场景选择对应方案:
- 如果你是开发系统级应用:给应用签系统级签名,在
AndroidManifest.xml中申请权限<uses-permission android:name="android.permission.DELETE_PACKAGES" />,即可正常调用命令。 - 如果设备已root:将执行的命令修改为通过su调用,把exec的参数替换为
new String[]{"su", "-c", "pm uninstall -k --user 0 com.google.android.gm"}即可。 - 如果是普通调试场景:不需要在应用内调用,直接连接设备到电脑,通过adb shell执行对应的pm卸载命令即可生效,普通第三方应用无法申请到卸载其他应用的权限。
内容的提问来源于stack exchange,提问作者Shubham Chakraborty
相关产品推荐
相关产品推荐

