Java tutorial
package cc.metapro.openct.utils; /* * Copyright 2016 - 2017 OpenCT open source class table * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.Manifest; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.Environment; import android.os.Looper; import android.support.v4.content.ContextCompat; import android.util.Log; import android.widget.Toast; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import cc.metapro.openct.OpenCT; import cc.metapro.openct.R; public class CrashHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "OpenCT"; private static final String FILE_NAME = "openct-crash.txt"; private Thread.UncaughtExceptionHandler mDefaultHandler; private OpenCT mContext; private CrashHandler() { } public static CrashHandler initInstance(OpenCT context) { CrashHandler handler = new CrashHandler(); handler.init(context); return handler; } private void init(OpenCT context) { mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); mContext = context; } @Override public void uncaughtException(Thread thread, final Throwable ex) { if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { try { dumpExceptionToSDCard(ex); if (mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, R.string.crash_pop, Toast.LENGTH_LONG).show(); Looper.loop(); } }).start(); } catch (IOException e) { e.printStackTrace(); } } } private void dumpExceptionToSDCard(Throwable ex) throws IOException { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Log.w(TAG, "sdcard unmounted,skip dump exception"); } File file = new File(Environment.getExternalStorageDirectory(), FILE_NAME); try { PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file))); pw.println(new Date().toString()); dumpPhoneInfo(pw); pw.println(); ex.printStackTrace(pw); pw.close(); } catch (Exception e) { Log.e(TAG, "dump crash info failed"); } } private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); pw.print("OpenCT Version: "); pw.print(pi.versionName); pw.print("_"); pw.println(pi.versionCode); pw.print("OS Version: "); pw.print(Build.VERSION.RELEASE); pw.print("_"); pw.println(Build.VERSION.SDK_INT); pw.print("Vendor: "); pw.println(Build.MANUFACTURER); pw.print("Model: "); pw.println(Build.MODEL); } }