android 手写收集崩溃信息上传
我们要收集用户使用app时,异常崩溃的信息,网上有很多第三方的,今天我们就自己手动的写收集崩溃信息的功能。
我们要上传的有那些信息呢?
错误信息,app版本信息, 手机信息
我们怎么能监听到app崩溃,和在崩溃时保存错误信息呢?
这里我们使用的是Thread.UncaughtExceptionHandler接口,下面我们来一起看下代码:
public class ExpectionCrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG="ExpectionCrashHandler";
private volatile static ExpectionCrashHandler mInstance=null;
private Context mContext=null;
private Thread.UncaughtExceptionHandler mDefaultExceptionHandler=null;
private ExpectionCrashHandler(){
}
/**
* 单列
* @return
*/
public static ExpectionCrashHandler getInstance(){
if(mInstance==null){
synchronized (ExpectionCrashHandler.class){
if(mInstance==null){
mInstance=new ExpectionCrashHandler();
}
}
}
return mInstance;
}
/**
* 初始化
* @param context
*/
public void init(Context context){
mContext=context;
Thread.currentThread().setUncaughtExceptionHandler(this);
//系统默认处理类
mDefaultExceptionHandler = Thread.currentThread().getDefaultUncaughtExceptionHandler();
}
@Override
public void uncaughtException(Thread t, Throwable e) {
Log.e(TAG,"uncaughtException~~~~~");
//自定义处理
//错误信息
//应用信息 当前版本
//手机信息
//写到本地文件
String crashFileName = saveInfoToSD(e);
cacheCrashFile(crashFileName);
//默认处理
mDefaultExceptionHandler.uncaughtException(t,e);
}
private void cacheCrashFile(String crashFileName) {
SharedPreferences sp = mContext.getSharedPreferences("crash", Context.MODE_PRIVATE);
sp.edit().putString("CRASH_FILE_NAME",crashFileName).commit();
}
public File getCrashFile(){
SharedPreferences sp = mContext.getSharedPreferences("crash", Context.MODE_PRIVATE);
String crash_file_name = sp.getString("CRASH_FILE_NAME", null);
return new File(crash_file_name);
}
private String saveInfoToSD(Throwable ex) {
String fileName="";
StringBuffer sb =new StringBuffer();
FileOutputStream out = null;
HashMap<String, String> map = obtainSimpleInfo(mContext);
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key).append(" = ").append(value).append("\n");
}
sb.append(obtianExpectionInfo(ex));
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(mContext.getFilesDir() + File.separator + "crash" + File.separator);
if (!dir.exists()) {
dir.mkdirs();
}else {
deleteDir(dir);
}
try {
fileName = dir.getAbsolutePath() + File.separator + getAssignTime("yyyy_MM_dd_HH_mm") + ".txt";
out = new FileOutputStream(fileName);
out.write(sb.toString().getBytes());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
out = null;
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
}
return fileName;
}
private void deleteDir(File dir) {
File[] files = dir.listFiles();
for (File file : files) {
file.delete();
}
}
private String getAssignTime(String type) {
SimpleDateFormat format =new SimpleDateFormat(type);
String s = format.format(new Date());
return s;
}
private String obtianExpectionInfo(Throwable ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
pw.close();
return sw.toString();
}
private HashMap<String, String> obtainSimpleInfo(Context context) {
HashMap<String, String> map = new HashMap<>();
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo;
try {
packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
map.put("VersionName", packageInfo.versionName);
map.put("VersionCode", packageInfo.versionCode + "");
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
map.put("PRODUCT", Build.PRODUCT);
map.put("MODEL", Build.MODEL);
map.put("SDK_INT", Build.VERSION.SDK_INT + "");
map.put("MOBLE_INFO", getMobleInfo());
return map;
}
public String getMobleInfo() {
StringBuffer sb =new StringBuffer();
try {
Field[] fields = Build.class.getFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
String value = field.get(null).toString();
sb.append(name).append("=").append(value).append("\n");
}
}catch (Exception ex){
ex.printStackTrace();
}
return sb.toString();
}
}
这个还是很简单的,有了这个工具类,我们怎么使用呢?
public class BaseApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ExpectionCrashHandler.getInstance().init(this);
}
}
File crashFile =
ExpectionCrashHandler.getInstance().getCrashFile();
if(crashFile.exists()){
//上传到服务器
}
很简单吧,几行代码就搞定了。