Android调用系统命令全攻略零基础手把手教你执行系统指令附权限处理避坑指南
📱Android调用系统命令全攻略|零基础手把手教你执行系统指令(附权限处理+避坑指南)
🔥Android调用系统命令|执行命令的5种方法+权限处理技巧(附实战案例)
💡一、为什么需要调用系统命令?
在Android开发中,调用系统命令能实现设备信息获取、文件操作、服务控制等核心功能。比如:
✅ 清理应用缓存(`pm clear com.example.app`)
✅ 获取设备MAC地址(`ipconfig`)
✅ 安装APK(`pm install`)
✅ 控制蓝牙/闪光灯(`bluetooth on/off`)
⚠️但新手常踩这些坑:
❌ 权限配置错误导致崩溃
❌ 未处理命令执行异常
❌ Android 10+版本权限限制
❌ 结果格式混乱
📌本文将手把手教你:
1️⃣ 5种调用命令的正规方法
2️⃣ 权限配置的完整方案
3️⃣ 异常处理与结果
4️⃣ 实战案例演示
5️⃣ Android 12+新特性适配
🛠️二、Android调用命令的5种方法
方法1:ProcessBuilder(推荐)
```java
Process process = new ProcessBuilder()
mand("su", "-c", "echo 'Hello Android'")
.redirectErrorStream(true)
.start();
try {
int exitCode = process.waitFor();
System.out.println("Exit code: " + exitCode);
byte[] output = new byte[1024];
process输出发送到output数组
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
```
🔧适用场景:需要标准输入输出的复杂命令
方法2:Runtime执行(基础版)
```java
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("sh");
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
```
⚠️注意:需处理子进程输出
方法3:Android 6.0+的Service执行
```java
startService(new Intent(this, CommandService.class));
Intent intent = new Intent(this, CommandService.class);
intent.putExtra("command", "pm list packages");
startActivity(intent);
```
🎯优势:适合后台持续执行
方法4:使用root权限(需设备支持)
```java
Process process = new ProcessBuilder()
mand("su")
.redirectErrorStream(true)
.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("root access granted")) {
// 执行敏感命令
}
}
```
⚠️注意:需处理设备无root的情况
方法5:使用第三方库(推荐)
```java
// 依赖implementation 'com.github.hitesh-pandya:command-executor:1.0.1'
CommandExecutor executor = new CommandExecutor();
String result = executor.executeCommand("ipconfig");
```
🌟优势:自动处理异常和重试
📌三、权限配置全
1. 基础权限(Android 8.0+)
```xml
```
2. 系统权限(需动态申请)
```java
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SCHEDULE_EXACT_ALARM)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SCHEDULE_EXACT_ALARM}, 1);
}
```
3. 自定义权限(Android 11+)
```xml
```
⚠️注意:Android 12+限制后台进程,建议:
- 使用前台服务
- 设置服务为高优先级
- 添加白名单豁免
📌四、实战案例演示
案例1:获取设备信息
```java
Process process = new ProcessBuilder()
mand("su", "-c", "getprop ro.build.version.sdk")
.redirectErrorStream(true)
.start();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = process.getInputStream().read(buffer)) != -1) {
String output = new String(buffer, 0, bytesRead);
if (output.contains("SDK")) {
// 处理设备信息
}
}
```
案例2:清理应用缓存
```java
String command = "pm clear " + packageManager.getPackageInfo("com.example.app", 0).packageName;
Process process = new ProcessBuilder()
mand("su", "-c", command)
.redirectErrorStream(true)
.start();
// 处理清理结果
```
案例3:安装APK(需root)
```java
Process process = new ProcessBuilder()
mand("su", "-c", "pm install /sdcard/app.apk")
.redirectErrorStream(true)
.start();
// 检查安装结果
```
📌五、异常处理指南
1. 常见异常类型:
1.jpg)
```java
// 权限不足
IOException: No space left on device
// 命令不存在
Exception: No such file or directory
// 子进程异常
ProcessException: Error starting process
```
2. 完整异常捕获:
```java
try {
Process process = new ProcessBuilder()mand("command").start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
} catch (IOException | InterruptedException e) {
if (e.getCause() instanceof ProcessExitException) {
System.out.println("命令执行失败:" + e.getCause().getMessage());
} else {
e.printStackTrace();
}
}
```
3. 重试机制:
```java
int maxAttempts = 3;
for (int i = 0; i < maxAttempts; i++) {
try {
// 执行命令
break;
} catch (Exception e) {
if (i == maxAttempts - 1) {
throw new RuntimeException("执行失败", e);
}
// 重试逻辑
}
}
```
1. 命令缓存:
```java
HashMap
String executeCommand(String cmd) {
if (commandCache.containsKey(cmd)) {
return commandCache.get(cmd);
}
// 执行命令并缓存结果
}
```
```java
BufferedInputStream bis = new BufferedInputStream(process.getInputStream());
int available = bis.available();
byte[] buffer = new byte[available];
bis.read(buffer, 0, available);
String output = new String(buffer);
```
3. 多线程处理:
```java
ExecutorService executor = Executors.newFixedThreadPool(3);
List
// 执行多个命令
List
.map(Future::get)
.collect(Collectors.toList());
```
📌七、Android 12+新特性适配
1. 系统命令白名单:
```java
// 在Android 12+中需要添加到白名单
Process process = new ProcessBuilder()
mand("su", "-c", "command")
.addArgument("--white-list", "com.example.app")
.start();
```
2. 使用ContentProvider执行命令:
```java
ContentValues values = new ContentValues();
values.put("command", "pm list packages");
Uri uri = Uri.parse("content://com.examplemandprovider");
ContentResolver resolver = getContentResolver();
resolver.insert(uri, values);
```
3. 使用Kotlin协程简化:
```kotlin
val process = ProcessBuilder(listOf("su", "-c", "command"))
.apply { redirectErrorStream = true }
.start()
val reader = BufferedReader(InputStreamReader(process.inputStream))
val output = reader.readLines().joinToString("\n")
```
📌八、常见问题Q&A
Q1:如何检测设备是否root?
A:执行`su -c "echo $root"`,若返回1则表示root
Q2:命令执行超时怎么办?
A:设置process.waitFor()的超时时间:
process.waitFor(10, TimeUnit.SECONDS)
Q3:如何处理中文命令?
A:使用双引号包裹命令:
.jpg)
new ProcessBuilder()mand("echo '你好,Android'")
Q4:为什么会出现"command not found"?
A:检查命令是否在设备环境变量中:
执行`env | grep PATH`
Q5:如何监控命令执行进度?
A:使用ProcessBuilder的redirectErrorStream参数
🔚
掌握Android系统命令调用需要:
1. 正确配置权限(基础权限+系统权限)
2. 选择合适的执行方式(ProcessBuilder/Service/第三方库)
3. 完善异常处理机制
4. 关注Android版本特性
附:完整代码仓库地址
GitHub:https://github/example/android-system-commands
📢互动话题:
你在开发中遇到过哪些系统命令相关的难题?
欢迎在评论区分享你的实战经验!
<< 上一篇
下一篇 >>