android实用方法----代码中抓取log

最近在公司中遇到一个需求,客户的手机出现bug但是我们复现不出来,所以我们主管让我写个抓log的apk。
思路很简单,开启一个服务,然后用Runtime.getRuntime().exec(String [] cmdArray);方法调用命令行执行adb命令就好。
给大家贴上代码LogObserverService

package com.kukool.game.Service;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.kukool.game.ddz.MainActivity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 抓log的服务
 */
public class LogObserverService extends Service implements Runnable {
    private String TAG = "LogObserverService";
    private boolean isObserverLog = false;
    private StringBuffer logContent = null;
    private Bundle mBundle = null;
    private Intent mIntent = null;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.v("TrafficService","startCommand");
//START_STICKY是service被kill掉后自动重写创建
        flags =  START_STICKY;
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG,"onCreate");
        mIntent = new Intent();
        mBundle = new Bundle();
        logContent = new StringBuffer();
        startLogObserver();
    }

    /**
     * 开启检测日志
     */
    public void startLogObserver() {
        Log.i(TAG,"startObserverLog");
        isObserverLog = true;
        Thread mTherad = new Thread(this);
        mTherad.start();
    }

    /**
     * 关闭检测日志
     */
    public void stopLogObserver() {
        isObserverLog = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopLogObserver();
    }

    /**
     * 发送log内容
     * @param logContent
     */
    private void sendLogContent(String logContent){
        mBundle.putString("log",logContent);
        mIntent.putExtras(mBundle);
        mIntent.setAction(MainActivity.LOG_ACTION);
        sendBroadcast(mIntent);
    }


    @Override
    public void run() {
        Process pro = null;
        BufferedReader bufferedReader = null;
        try {
            String[] running=new String[]{ "logcat","|find","cocos2d-x debug" };
//          pro = Runtime.getRuntime().exec("logcat");
            pro = Runtime.getRuntime().exec(running);
//          Runtime.getRuntime().exec("logcat -c").waitFor();
            bufferedReader = new BufferedReader(new InputStreamReader(
                    pro.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //筛选需要的字串
        String strFilter="cocos2d-x debug";
        String line = null;
            try {
                Log.e("走到这里没","走到这里没");
                System.out.println(bufferedReader.readLine());
                while ((line =bufferedReader.readLine()) != null) {

                    Log.e("走到这里没","走到这里没");
                    if (line.indexOf(strFilter) >=0) {
                        //读出每行log信息
                        System.out.println(line);
                        logContent.delete(0,logContent.length());
                        logContent.append(line);
                        logContent.append("\n");
                        //发送log内容
                        sendLogContent(logContent.toString());
                        Thread.yield();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
}

别忘了在清单文件中加上

       <service android:name=".LogObserverService" />

还有权限

  <uses-permission android:name="android.permission.READ_LOGS" />

然后是测试代码,具体你们可以改动

package com.example.admin.logobserver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;

public class MainActivity extends AppCompatActivity {

    private String TAG = "LogObserverActivity";
    public static String LOG_ACTION = "com.example.admin.logobserver.LOG_ACTION";
    private TextView logContent = null;
    private Button start = null;
    private Intent logObserverIntent = null;
    private LogBroadcastReceiver mLogBroadcastReceiver = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化视图
        initView();
        //注册log广播接收者
        registerLogBroadcastReceiver();

    }

    private void initView() {
        logContent = (TextView) findViewById(R.id.logContent);
        logContent.setText("show log");
        start = (Button)findViewById(R.id.start);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startLogObserverService();
                start.setEnabled(false);
            }
        });
    }

    private void startLogObserverService() {
        logObserverIntent = new Intent(this, LogObserverService.class);
        startService(logObserverIntent);
    }

    /**
     * 注册log广播接收者
     */
    private void registerLogBroadcastReceiver(){
        mLogBroadcastReceiver = new LogBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(LOG_ACTION);
        registerReceiver(mLogBroadcastReceiver, filter);
    }

    /**
     * log 广播接收者
     * @author zhangyg
     *
     */
    private class LogBroadcastReceiver extends BroadcastReceiver {
        private String action = null;
        private Bundle mBundle = null;
        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if(LOG_ACTION.equals(action)){
                mBundle = intent.getExtras();
                Log.e("log接收","log&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
                logContent.setText(mBundle.getString("log"));
                writeToSdCard(mBundle.getString("log"));
            }
        }
    }


    //写数据
    public void writeToSdCard(String string){
        //1、判断sd卡是否可用
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            //sd卡可用
            //2、获取sd卡路径
            File sdFile=Environment.getExternalStorageDirectory();
            File path=new File(sdFile,"360/a.txt");//sd卡下面的a.txt文件  参数 前面 是目录 后面是文件
            try {
                FileOutputStream fileOutputStream=new FileOutputStream(path,true);
                fileOutputStream.write(string.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (logObserverIntent!=null){
            stopService(logObserverIntent);
        }
        if (mLogBroadcastReceiver!=null){
            unregisterReceiver(mLogBroadcastReceiver);
        }

    }
}

这就可以了,但是这个只能嵌套在你项目中不能做成APK因为只能获取自己项目的log,原因是 android.permission.READ_LOGS:app读取日志权限,android 4.1之前版本通过申请READ_LOGS权限就可以读取其他应用的log了。但是谷歌发现这样存在安全风险,于是android 4.1以及之后版本,即使申请了READ_LOGS权限也无法读取其他应用的日志信息了。4.1版本中 Logcat的签名变为 “signature|system|development”了,这意味着只有系统签名的app或者root权限的app才能使用该权限。普通用户可以通过ADB查看所有日志。

简单说就是谷歌觉得危险干掉了,你又不可能叫客户刷机,所以就是嵌套在你的项目中。

对了过滤我用的 adb logcat |find “保留的log”
还可以用 adb logcat -s 你想看的类的log

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值