android开发异常信息收集程序代码

2024-06-23 08:08

本文主要是介绍android开发异常信息收集程序代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先创建全局的Application ,此Application全局通用。

package com.demo.utils;import com.demo.exception.CrashHandler;
import android.app.Application;
/*** 全局的context,任意位置调用* @author Administrator**/
public class GlobalApplication extends Application
{private static GlobalApplication instance;public static GlobalApplication getInstance(){return instance;}@Overridepublic void onCreate(){super.onCreate();instance = this;CrashHandler crashHandler = CrashHandler.getInstance();//这是收集异常信息的单例类,具体代码请看下文crashHandler.init(getApplicationContext());//初始化}
}

注意:上面的代码需要在注册清单文件中注册。部分清单如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.demo.test"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="18" /><!-- 网络 --><uses-permission android:name="android.permission.INTERNET" /><!-- 访问sdcard --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><!-- 获取mac需要的网络状态 --><uses-permission android:name="andorid.permission.CHANGE_CONFIGURATION" /><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><applicationandroid:name="com.demo.utils.GlobalApplication"android:allowBackup="true"android:icon="@drawable/app_icon"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.demo.activity.MyActivity"android:launchMode="singleTask"android:screenOrientation="landscape"android:theme="@android:style/Theme.NoTitleBar" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></activity></application></manifest>

crashHandler

package com.demo.exception;import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Looper;import com.demo.utils.ConstantUtils;
import com.demo.utils.PathUtils;
import com.demo.utils.log.MyLog;/*** UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.* * @author user* 实现
UncaughtExceptionHandler接口*/
public class CrashHandler implements UncaughtExceptionHandler
{public static final String TAG = "bug";//系统默认的UncaughtException处理类 private Thread.UncaughtExceptionHandler mDefaultHandler;//CrashHandler实例private static CrashHandler INSTANCE = new CrashHandler();//程序的Context对象private Context mContext;//用来存储设备信息和异常信息private Map<String, String> infos = new HashMap<String, String>();//用于格式化日期,作为日志文件名的一部分private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");/** 保证只有一个CrashHandler实例 */private CrashHandler(){}/** 获取CrashHandler实例 ,单例模式 */public static CrashHandler getInstance(){return INSTANCE;}/*** 初始化* * @param context*/public void init(Context context){mContext = context;//获取系统默认的UncaughtException处理器mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();//设置该CrashHandler为程序的默认处理器Thread.setDefaultUncaughtExceptionHandler(this);}/*** 当UncaughtException发生时会转入该函数来处理*/@Overridepublic void uncaughtException(Thread thread, Throwable ex){if (!handleException(ex) && mDefaultHandler != null){//如果用户没有处理则让系统默认的异常处理器来处理mDefaultHandler.uncaughtException(thread, ex);}else{try{Thread.sleep(3000);}catch (InterruptedException e){MyLog.e(TAG, "error : ", e);}mDefaultHandler.uncaughtException(thread, ex);//退出程序//            android.os.Process.killProcess(android.os.Process.myPid());//            System.exit(1);}}/*** 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.* * @param ex* @return true:如果处理了该异常信息;否则返回false.*/private boolean handleException(Throwable ex){if (ex == null){return false;}//使用Toast来显示异常信息new Thread(){@Overridepublic void run(){Looper.prepare();//                Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();Looper.loop();}}.start();//收集设备参数信息 collectDeviceInfo(mContext);//保存日志文件 MyLog.i(TAG, "ex:" + ex.toString() + "--" + ex.getLocalizedMessage());saveCrashInfo2File(ex);return true;}/*** 收集设备参数信息* @param ctx*/public void collectDeviceInfo(Context ctx){try{PackageManager pm = ctx.getPackageManager();PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);if (pi != null){String versionName = pi.versionName == null ? "null" : pi.versionName;String versionCode = pi.versionCode + "";infos.put("versionName", versionName);infos.put("versionCode", versionCode);}}catch (NameNotFoundException e){MyLog.e(TAG, "an error occured when collect package info", e);}Field[] fields = Build.class.getDeclaredFields();for (Field field : fields){try{field.setAccessible(true);}catch (Exception e){MyLog.e(TAG, "an error occured when collect crash info", e);}}}/*** 保存错误信息到文件中* * @param ex* @return    返回文件名称,便于将文件传送到服务器*/private String saveCrashInfo2File(Throwable ex){StringBuffer sb = new StringBuffer();//        for (Map.Entry<String, String> entry : infos.entrySet())//        {//            String key = entry.getKey();//            String value = entry.getValue();//            sb.append(key + "=" + value + "\n");//        }Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);Throwable cause = ex.getCause();while (cause != null){MyLog.i(TAG, "cause:" + cause.toString() + "--");cause.printStackTrace(printWriter);cause = cause.getCause();}printWriter.close();String result = writer.toString();MyLog.i(TAG, "result:" + result);sb.append(result);try{long timestamp = System.currentTimeMillis();String time = formatter.format(new Date());String fileName = "crash-" + time + "-" + timestamp + ".log";if (ConstantUtils.isOnline){fileName = "crash-online.log";}String path = PathUtils.BUGPATH;FileOutputStream fos = new FileOutputStream(path + fileName);fos.write(sb.toString().getBytes());fos.close();return fileName;}catch (Exception e){MyLog.e(TAG, "an error occured while writing file...", e);}return null;}
}
上面信息涉及到下面的几个类ConstantUtils,PathUtils和MyLog

constantUtils

public class ConstantUtils
{/***是否上线版本***/public final static boolean isOnline = false;/**** 时间格式*/public static String timeFormat = "yyyy-MM-dd HH:mm:ss";
}

MyLog

package com.demo.utils.log;import java.text.SimpleDateFormat;
import java.util.Date;import android.util.Log;import com.demo.utils.ConstantUtils;
import com.demo.utils.PathUtils;public class MyLog
{private static String filename = "log.txt";/**** 打印日志* @param tag* @param msg*/public static void d(String tag, String msg){if (!ConstantUtils.isOnline){Log.d(tag, msg);}}/**** 打印日志* @param tag* @param msg*/public static void i(String tag, String msg){if (!ConstantUtils.isOnline){Log.i(tag, msg);}}/**** 打印日志* @param tag* @param msg*/public static void e(String tag, String msg){if (!ConstantUtils.isOnline){Log.e(tag, msg);}}/**** 打印日志* @param tag* @param msg*/public static void e(String tag, String msg, Throwable tr){if (!ConstantUtils.isOnline){Log.e(tag, msg, tr);}}/**** 打印日志* @param tag* @param msg*/public static void w(String tag, String msg){if (!ConstantUtils.isOnline){Log.w(tag, msg);}}/**** 写入文本到日志文件中* @param value*/public static void write(String value){if (!ConstantUtils.isOnline){String newValue = getDataFormat(System.currentTimeMillis()) + "  " + value;LogUtils.getInstances().write(PathUtils.LOGPATH, filename, newValue);}}/**** 获取当前时间* @param timeInMillis* @return*/private static String getDataFormat(long timeInMillis){SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return dataFormat.format(new Date(timeInMillis));}}

pathutils

package com.demo.utils;import java.io.File;import android.os.Environment;public class PathUtils
{public final static String sdcardPath = Environment.getExternalStorageDirectory() + "";public final static String PATH = sdcardPath + "/exception/" + AppUtils.getAppPackageName();public final static String BUGPATH = PATH + "/bug/";public final static String LOGPATH = PATH + "/log/";public PathUtils(){File PATH = new File(PathUtils.PATH);if (!PATH.exists()){PATH.mkdirs();}File LOGPATH = new File(PathUtils.LOGPATH);if (!LOGPATH.exists()){LOGPATH.mkdirs();}File BUGPATH = new File(PathUtils.BUGPATH);if (!BUGPATH.exists()){BUGPATH.mkdirs();}}
}



这篇关于android开发异常信息收集程序代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086603

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Python中异常类型ValueError使用方法与场景

《Python中异常类型ValueError使用方法与场景》:本文主要介绍Python中的ValueError异常类型,它在处理不合适的值时抛出,并提供如何有效使用ValueError的建议,文中... 目录前言什么是 ValueError?什么时候会用到 ValueError?场景 1: 转换数据类型场景