由于工作需要,接触到百度语音识别SDK移植,由于需要实现在APK里面控制物理硬件的效果,第一次接触到Runtime.getRuntime().exec方法。
通过网上查阅资料,得知Runtime.getRuntime().exec的使用方法,代码如下:
Runtime.getRuntime().exec(cmd);
很简单的使用方法,本来也以为就是这么简单,但是后面发现程序运行起来抛出异常:IOException: Working Directory: null Environment: null
折腾了半天,发现原来是权限的问题,各种查阅资料之后,找出了解决方法,执行proc必须是root用户,需要先添加su权限,代码如下:
try {
Process p = Runtime.getRuntime().exec("su");
p.getOutputStream().write(cmd.getBytes());
p.getOutputStream().flush();
} catch (IOException e) {
Log.e(TAG, "Runtime.getRuntime()");
}
测试了一下,依然是有问题,这次报错:java.io.IOException: write failed: EPIPE (Broken pipe);
然后继续找资料,将su改成sh,再进行测试,终于成功了,而需要改成sh的原因可能是因为执行shell命令需要shell用户权限。最后成功代码如下:
package com.baidu.android.voicedemo.util;
import java.io.DataOutputStream;
import java.io.IOException;
public class SystemFunction {
/**
* 行shell命令函数
*/
public String do_exec(String cmd) {
try {
Process exeEcho = Runtime.getRuntime().exec("sh");
DataOutputStream os = new DataOutputStream(exeEcho.getOutputStream());
os.writeBytes(cmd);
os.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cmd;
}
/**
* 点亮所有的蓝色灯
* 灯光级别为最暗
*/
public void lightOnAll(){
//R:00 G:00 B:00
//写蓝色到sys节点 0x00 00 01
int ledID;
Process exeEcho;
try {
exeEcho = Runtime.getRuntime().exec("sh");
DataOutputStream os = new DataOutputStream(exeEcho.getOutputStream());
for(ledID = 0; ledID < Const.LED_ID.LIGHT_LED_MAX.ordinal(); ledID++){
String ARGS = "echo 1 > " + Const.LedPath[ledID] + "\n";
String result = "";
os.writeBytes(ARGS);
//result = do_exec(ARGS);
System.out.println(result);
os.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 灭掉所有的灯
*/
public void lightOffAll(){
//写0到sys节点
int ledID;
Process exeEcho;
try {
exeEcho = Runtime.getRuntime().exec("sh");
DataOutputStream os = new DataOutputStream(exeEcho.getOutputStream());
for(ledID = 0; ledID < Const.LED_ID.LIGHT_LED_MAX.ordinal(); ledID++){
String ARGS = "echo 0 > " + Const.LedPath[ledID] + "\n";
String result = "";
os.writeBytes(ARGS);
//result = do_exec(ARGS);
System.out.println(result);
os.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里一定要注意,执行的cmd后面一定要接一个换行符”\n”,因为DataOutputStream并不能直接操作底层shell,所以需要”\n”来标志一条命令的结束。
好了,最后也能够通过APK控制LED灯的亮灭了,成功。~~