崩溃日志显示Toast并输出至SD Card - 适配Android10
1、工具类
异常捕获Handler
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private Context mContext;
private Map<String, String> mInfo = new LinkedHashMap<>();
private Thread.UncaughtExceptionHandler mDefaultHandler;
private static CrashHandler instance = null;
private static final Object INSTANCE_LOCK = new Object();
public static CrashHandler getInstance() {
if (instance == null) {
synchronized (INSTANCE_LOCK) {
if (instance == null) {
instance = new CrashHandler();
}
}
}
return instance;
}
public void init(Context context) {
mContext = context.getApplicationContext();
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable ex) {
handleException(ex);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(t, ex);
} else {
System.exit(1);
}
}
private void handleException(Throwable ex) {
final Throwable e = ex;
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
Looper.loop();
}
}.start();
collectInfo();
AndroidUtils.saveErrInfoToGalleryByScopedStorage(mContext, outputErrorLogInfo(ex));
}
private String outputErrorLogInfo(Throwable ex) {
String deviceInfo = "";
for (String key : mInfo.keySet()) {
deviceInfo += key + " : " + mInfo.get(key) + "\n";
}
return "Error Info : \n" + ex.getLocalizedMessage() + "\n\n" + "Device Info : \n" + deviceInfo;
}
private void collectInfo() {
collectClassInfo(Build.VERSION.class);
collectClassInfo(Build.class);
}
private void collectClassInfo(Class cls) {
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
mInfo.put(field.getName(), field.get(null).toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
崩溃日志输出至sd card
public class AndroidUtils {
public static final String TAG = "AndroidUtils";
public static final String ERROR_LOG_FILE_PATH_1 = "Download/UAT Error Logs";
public static final String ERROR_LOG_FILE_PATH_2 = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "UAT Error Logs";
public static final String ERROR_LOG_FILE_NAME = "errLog";
public static boolean saveErrInfoToGalleryByScopedStorage(Context context, String logContent) {
long timestamp = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(timestamp));
String fileName = ERROR_LOG_FILE_NAME + "_" + time + ".txt";
FileOutputStream fos = null;
OutputStream os = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentValues values = new ContentValues();
values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
values.put(MediaStore.Downloads.MIME_TYPE, "text/plain");
values.put(MediaStore.Downloads.RELATIVE_PATH, ERROR_LOG_FILE_PATH_1);
Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
Uri uri = context.getContentResolver().insert(external, values);
if (uri != null) {
os = context.getContentResolver().openOutputStream(uri);
os.write(logContent.getBytes());
os.flush();
return true;
}
} else {
File dir = new File(ERROR_LOG_FILE_PATH_2);
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(dir, fileName);
if (!file.exists()) {
file.createNewFile();
}
fos = new FileOutputStream(file);
fos.write(logContent.getBytes());
fos.flush();
return true;
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, Log.getStackTraceString(e));
} finally {
closeIO(fos);
closeIO(os);
}
return false;
}
public static void closeIO(Closeable... closeables) {
if (null == closeables || closeables.length <= 0) {
return;
}
for (Closeable cb : closeables) {
try {
if (null == cb) {
continue;
}
cb.close();
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
}
}
2、使用
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().init(this);
}
}
程序崩溃闪退之后,在文件管理器中搜索UAT Error Logs文件夹
|