Android一点 异常收集

1 篇文章 0 订阅
1 篇文章 0 订阅

异常捕捉有助于我们调试错误,但是app发布了自己看不到log怎么办?这时我们就需要AppException异常收集器了

异常的处理主要是实现UncaughtExceptionHandler这个接口,并重载uncaughtException方法,通过Throwable来获取异常的信息。不明白UncaughtExceptionHandler的可以百度查查

AppException

package com.example.test;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;

import org.json.JSONObject;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telephony.TelephonyManager;

public class AppException implements UncaughtExceptionHandler {
    /** 程序的Context对象 ,传入ApplicationContext */
    private Context context;
    private DeviceInfo devInfo;

    /** 系统默认的UncaughtException处理类 */
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    /** CrashHandler实例 */
    private static AppException appException;

    /** 保证只有一个CrashHandler实例 */
    private AppException() {
    }

    /** 获取CrashHandler实例 ,单例模式 */

    public static AppException getInstance() {

        if (appException == null) {
            appException = new AppException();
        }

        return appException;
    }

    /**
     * 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
     *
     * @param context
     */

    public void init(Context context) {

        this.context = context;
        devInfo=collectDeviceInfo();

        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();

        Thread.setDefaultUncaughtExceptionHandler(this);


    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {

        handleException(ex);
        if (mDefaultHandler != null) {
            // 如果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex);
        }
    }

    /**
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
     */
    public String handleException(Throwable e) {

        StringBuffer sb = new StringBuffer();

        // 获取classname、报错的哪一行等
        // String className = stacks[0].getFileName();
        // String methodName = stacks[0].getMethodName();
        // int lineNumber = stacks[0].getLineNumber();
        // System.out.println("ElementException:"+"className:"+className+" methodName:"+methodName+" lineNumber:"+lineNumber);

        // 获取具体的报错信息
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
//      System.out.println("crashMessage:" + sw.toString());

        // 直接定位报错信息
//      System.out.println("getCause:" + e.getMessage().toString());

        sb.append("sdkVersion:"+devInfo.getOsVersion()+"\n")
        .append("versionName:"+devInfo.getVersionName()+"\n")
        .append("versionCode:"+devInfo.getVersionCode()+"\n")
        .append("manufacturer:"+devInfo.getManufacturer()+"\n")
        .append("model:"+devInfo.getModel()+"\n")
        .append("deviceId:"+devInfo.getDeviceId()+"\n")
        .append("Exception:"+sw.toString());

        System.out.println("crashMessage:" + sb.toString());

        return sb.toString();
    }

    /**
     * 手机设备信息
     */
    public DeviceInfo collectDeviceInfo() {

        // TODO Auto-generated method stub
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (pi != null) {

                DeviceInfo devInfo=new DeviceInfo();

//              devInfo.setOsVersion(android.os.Build.VERSION.SDK);
                devInfo.setOsVersion(android.os.Build.VERSION.RELEASE);


                String versionName = pi.versionName == null ? "null": pi.versionName;
                String versionCode = pi.versionCode + "";

                devInfo.setVersionName(versionName);
                devInfo.setVersionCode(versionCode);

                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);  
                StringBuilder sb = new StringBuilder();  
                devInfo.setDeviceId(tm.getDeviceId());

                // 获取手机型号
                devInfo.setModel(android.os.Build.MODEL);
                //获取手机厂商:
                devInfo.setManufacturer(android.os.Build.MANUFACTURER);

                System.out.println("devInfo:"+devInfo);

                return devInfo;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;


    }

    /**
       * 获取手机的硬件信息
       * 
       * @return 
       */
      public String getMobileInfo() {
        JSONObject json = new JSONObject();
        // 通过反射获取系统的硬件信息

        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
          try {
            field.setAccessible(true);
            json.put(field.getName(), field.get(null).toString());

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

        System.out.println("getMobileInfo:"+json.toString());

        return json.toString();
      }


    public class DeviceInfo{
        private String osVersion;
        private String versionName;
        private String versionCode;
        private String deviceId;
        private String model;
        private String manufacturer;

        public String getOsVersion() {
            return osVersion;
        }
        public void setOsVersion(String osVersion) {
            this.osVersion = osVersion;
        }
        public String getVersionName() {
            return versionName;
        }
        public void setVersionName(String versionName) {
            this.versionName = versionName;
        }
        public String getVersionCode() {
            return versionCode;
        }
        public void setVersionCode(String versionCode) {
            this.versionCode = versionCode;
        }
        public String getDeviceId() {
            return deviceId;
        }
        public void setDeviceId(String deviceId) {
            this.deviceId = deviceId;
        }
        public String getModel() {
            return model;
        }
        public void setModel(String model) {
            this.model = model;
        }
        public String getManufacturer() {
            return manufacturer;
        }
        public void setManufacturer(String manufacturer) {
            this.manufacturer = manufacturer;
        }
        @Override
        public String toString() {
            return "DeviceInfo [osVersion=" + osVersion + ", versionName="
                    + versionName + ", versionCode=" + versionCode
                    + ", deviceId=" + deviceId + ", model=" + model
                    + ", manufacturer=" + manufacturer + "]";
        }

    }
}

获取设备信息还需要权限

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

使用的时候我们只要传入ApplicationContext

AppException.getInstance().init(getApplicationContext());

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值