/
CrashPrinter.java
145 lines (121 loc) · 5.09 KB
/
CrashPrinter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package org.mym.prettylog;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.PrintStreamPrinter;
import org.mym.plog.Category;
import org.mym.plog.PrintLevel;
import org.mym.plog.printer.FilePrinter;
import java.io.File;
import java.util.Arrays;
/**
* This class provides a default(sample) crash file utility.
* Created by muyangmin on Jan 17, 2017.
*
* @since 2.0.0
*/
public class CrashPrinter extends FilePrinter {
public static final String CAT_CRASH = "crash";
private static volatile CrashPrinter sInstance = null;
private static String sExtraInfo;
private Context mApplicationContext;
private CrashPrinter(Context mContext) {
//Assume not null
//noinspection ConstantConditions
// super(getCrashFileDir(mContext).getAbsolutePath(),
super(mContext, DIR_EXT_FILES + "/crash",
new TimingFileNameGenerator(), 1024 * 1024L);
mApplicationContext = mContext.getApplicationContext();
}
public static CrashPrinter getInstance(Context context) {
//create a temp variable to improve performance for reading volatile field.
CrashPrinter instance = sInstance;
if (instance == null) {
synchronized (CrashPrinter.class) {
instance = sInstance;
//double check here
if (instance == null) {
instance = new CrashPrinter(context);
sInstance = instance;
}
}
}
return instance;
}
public static void setExtraInfo(@NonNull String extraInfo) {
sExtraInfo = extraInfo;
}
@Override
public boolean onIntercept(@PrintLevel int level, @NonNull String tag,
@Nullable Category category, @NonNull String msg) {
// accept only crash category!
// return !CRASH.equals(category);
return !(category != null && category.isSameAs(CAT_CRASH));
}
@Override
public void print(@PrintLevel int level, @NonNull String tag, @NonNull String msg) {
super.print(level, tag, msg);
//Only record one crash at a time.
close();
}
@Override
protected void printFileHeader(PrintStreamPrinter ps) {
//Print time and thread
// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss, z",
// Locale.getDefault());
// ps.println("CrashTime: " + format.format(timestamp));
// ps.println("CrashThread: " + thread + ", belong to group " + thread
// .getThreadGroup());
if (!TextUtils.isEmpty(sExtraInfo)) {
ps.println(sExtraInfo);
sExtraInfo = null;
}
//Print device info, app info, etc.
ps.println(createCrashHeaderStr(mApplicationContext));
//Print throwable, the core stacktrace
// ps.println(Log.getStackTraceString(throwable));
}
private String createCrashHeaderStr(Context context) {
StringBuilder sb = new StringBuilder(1024);
sb.append("Device Model: ").append(Build.MODEL).append("\n")
.append("Device Brand: ").append(Build.BRAND).append("\n")
.append("Device Manufacturer: ").append(Build.MANUFACTURER).append("\n")
.append("OS Version: ").append(Build.VERSION.SDK_INT).append("\n")
.append("OS Name: ").append(Build.VERSION.RELEASE).append("\n")
.append("CPU Hardware: ").append(Build.HARDWARE).append("\n");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
sb.append("CPU API: ").append(Arrays.toString(Build.SUPPORTED_ABIS)).append("\n");
}
//NOTE: 这里虽然列出了内存和外存的freeSpace, 但在测试设备 HUAWEI FRD-AL00上两者并不相同。
// 而外存的剩余大小和设置页里看到的存储空间数据一致。
try {
File intStore = context.getFilesDir();
File extStore = context.getExternalFilesDir(null);
sb.append("Internal Storage Free: ")
.append(Formatter.formatFileSize(context, intStore.getFreeSpace()))
.append("\n");
if (extStore != null) {
sb.append("External Storage Free: ")
.append(Formatter.formatFileSize(context, extStore.getFreeSpace()))
.append("\n");
}
} catch (SecurityException ignored) {
}
PackageInfo packageInfo = null;
try {
packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException ignored) {
//Empty
}
sb.append("App Version: ")
.append(packageInfo == null ? "N/A" : packageInfo.versionName)
.append("\n");
return sb.toString();
}
}