在Android APK中调用底层linux命令或者脚本

由于工作需要,接触到百度语音识别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灯的亮灭了,成功。~~

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值