项目中需要直接在APP中通过发送shell指令来控制lcd灯,其实按理说应该是方案公司在调好lcd灯驱动之后直接通过service送接口上来给APP,APP调用就可以控制了,这是正规流程,但我们项目的方案商用的mtk方案,方案公司又没人会改,只调好了驱动,让应用程序自己实现灯的控制,这不蛋疼嘛!!!!
发就发吧!
一、关于shell指令:
我们知道,shell指令是Linux里面带的指令,指令是分权限的,所以需要根据你的具体指令看需不需要有系统权限;
二、权限介绍:
如果不需要root权限的shell指令那可以直接通过Android提供的exec发送,如果需要root权限,有两种操作方式:
1、标准做法或者说是推荐做法:
a、为APP添加
android:sharedUserId="android.uid.system"
b、用系统签名签APP(关于如何签名,参考:http://gqdy365.iteye.com/blog/2111949)
c、将签名好的apppush到system/app/目录下,重启;
这里可以使用exec正常发送任何指令;
2、屌丝做法:
设备获取root权限,APP运行时授予root权限;
发送时用exec("su")发送;
这种方法在调试阶段是很有用的。第一种方法调试会很多蛋疼的;
三、参考代码:
Process process = null;
DataOutputStream os = null;
public void sendTest(String command){
if (command == null) {
return;
}
try {
if(null==process){
// process = Runtime.getRuntime().exec("sh");//系统签名,push到app目录下用这个这个
process = Runtime.getRuntime().exec("su");//有root权限的用这个;
os = new DataOutputStream(process.getOutputStream());
}
if (MyLog.isDyeLevel()) {
MyLog.log("lcd", MyLog.DYE_LOG_LEVEL, "execCommand :" + command);
}
os.write(command.getBytes());
os.writeBytes("\n");
os.flush();
}catch(Exception e){
e.printStackTrace();
}
}
上面代码记得在不发送时关闭流;
我程序中需要实时发送,所以定义了全局变量,大家可以如果不需要实时发送,就定义局部变量;
下面片段是摘自Trinea的博客(http://www.trinea.cn/android/android-java-execute-shell-commands/)但存在一个问题:阻塞式的,会造成系统卡顿,不推荐使用;
Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = null;
StringBuilder errorMsg = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command == null) {
continue;
}
// donnot use os.writeBytes(commmand), avoid chinese charset error
os.write(command.getBytes());
os.writeBytes(COMMAND_LINE_END);
os.flush();
try {
} catch (Exception e) {
e.printStackTrace();
}
}
os.writeBytes(COMMAND_EXIT);
os.flush();
result = process.waitFor();
// get command result
if (isNeedResultMsg) {
successMsg = new StringBuilder();
errorMsg = new StringBuilder();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}