离线抓取并保存Android Logcat的工具

在工作中,会碰到一些设备上的原因,导致不能一直连着数据线抓logcat,这个时候需要一个能够离线抓取logcat的工具,有些芯片厂商提供的rom版本中自带这个工具,例如MTK的MTKLogger、高通的logcatuserdebug版本),这些工具都能够自动抓取logcat的内容

提示,制作抓取系统log的工具,需要将应用系统签名,否则只能拿到本应用的log

围绕抓取log过程中,产生了两个思路,但是思路一没有走通,如果想要直接使用的,请看思路二

 

思路一:logcat重定向,我们知道平时看logcat一般是在Android Studio中的界面中带工具可以查看,不过我们也可以在cmd中执行

adb logcat -v time > log.txt

这样就把logcat输出定向到了log.txt文件,不过这是在adb环境下通过连线输出到电脑上的重定向,跟机器本身的重定向不同,那么机器本身的重定向是怎么做的呢,我们进入到shell后执行下面的命令,其中&符号是linux中后台运行的命令

adb shell
logcat -v time > /sdcard/log.txt &

实际测试可以用,但是存在问题,重启后就又失效了,而我们有时候抓取log的时候就是为了抓启动界面的日志

所以我们需要一个apk执行这个命令,让apk在开机自启运行这段命令,有人会问那不是只能抓到这个apk启动之后的log么,其实logcat工具本身带有一些缓存,这也是我们有时候在调试应用的时候,出了问题之后再连上数据线也能看到出错日志的原因,所以利用这一点,再加上Runtime这个类,在apk中执行这段命令

    Runtime rt = Runtime.getRuntime();  
    Process proc = rt.exec("logcat -v time > /sdcard/log.txt &");  

但是这个时候我们就遇到了一个坑,Runtime.exec()不是命令解析器这段代码不会被执行,后面查了资料就有了思路二,我们自己读取logcat内容,自己写文件,而不是通过重定向让系统帮忙写,看来是不能省力了,还是要自己做

 

思路二:读取logcat中的内容,写入文件

如何直接读取logcat中的内容呢,使用下面的方法,使用这个代码的效果有点像在终端中输入命令cmd,结果会显示在终端中,不过这个不会显示在终端里面,需要我们自己读取里面的内容

 ProcessBuilder processBuilder = new ProcessBuilder(new String[]{"sh", "-c", cmd});
 processBuilder.redirectErrorStream(true);

先对processBuilder初始化,cmd中传入需要执行的命令

这里我们的cmd为

String cmd = "logcat -v time";

初始化之后,获取Process对象

        try {
            process = processBuilder.start();
            new ReadThread(process.getInputStream(), "InputStream").start();
            new ReadThread(process.getErrorStream(), "ErrorStream").start();
        } catch (IOException e) {
            e.printStackTrace();
        }

读取线程我是这样写的

 class ReadThread extends Thread {
        InputStream inputStream;
        int flag = OUTPUT;
        String name = "None Name";

        public ReadThread(InputStream inputStream, String name) {
            this.inputStream = inputStream;
            this.name = name;
        }

        @Override
        public void run() {
            super.run();
            try {
                byte[] buffer = new byte[1024 * 8];
                int length = 0;
                while (true) {
                    while ((length = inputStream.read(buffer)) != -1) {
                        byte[] tmp = new byte[length];
                        System.arraycopy(buffer, 0, tmp, 0, length);
                        Message message = handler.obtainMessage();
                        message.what = flag;
                        message.obj = new String(tmp);
                        handler.sendMessage(message);
                        buffer = new byte[1024 * 8];
                    }
                }


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

这就是读取logcat内容并写入文件的过程,做成app后还有很多工作,例如需要请求存储权限、开机自启、空间满了之后怎么处理、如何设定log大小循环写入等等等,这个属于业务上的内容了,就不另外扩展了

还有一点需要注意的是,需要设置systemuid以及系统签名

 

 

你可能感兴趣的:(Android)