package com.secondworld.universalsdk; 
 | 
  
 | 
import android.content.Context; 
 | 
import android.content.pm.PackageInfo; 
 | 
import android.content.pm.PackageManager; 
 | 
import android.os.Build; 
 | 
import android.os.Looper; 
 | 
import android.os.SystemClock; 
 | 
import android.widget.Toast; 
 | 
  
 | 
import java.io.File; 
 | 
import java.io.FileOutputStream; 
 | 
import java.io.FilenameFilter; 
 | 
import java.io.PrintWriter; 
 | 
import java.io.StringWriter; 
 | 
import java.io.Writer; 
 | 
import java.text.DateFormat; 
 | 
import java.text.SimpleDateFormat; 
 | 
import java.util.Calendar; 
 | 
import java.util.Date; 
 | 
import java.util.HashMap; 
 | 
import java.util.Map; 
 | 
  
 | 
/** 
 | 
 * Created by Administrator on 2018/7/19 0019. 
 | 
 */ 
 | 
  
 | 
public class CrashCatchUtil implements Thread.UncaughtExceptionHandler 
 | 
{ 
 | 
    private static final String TAG = "CrashCatchUtil"; 
 | 
    private Context m_Context; 
 | 
    private Thread.UncaughtExceptionHandler m_UncaughtExceptionHandler; 
 | 
    private Map<String, String> m_DevicceInfo = new HashMap<>(); 
 | 
  
 | 
    private CrashCatchUtil() {} 
 | 
  
 | 
    private static CrashCatchUtil m_Instance; 
 | 
  
 | 
    public static CrashCatchUtil getInstance() 
 | 
    { 
 | 
        if (m_Instance == null) 
 | 
        { 
 | 
            m_Instance = new CrashCatchUtil(); 
 | 
        } 
 | 
        return m_Instance; 
 | 
    } 
 | 
  
 | 
    public void init(Context context) 
 | 
    { 
 | 
        m_Context = context; 
 | 
        m_UncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 
 | 
        Thread.setDefaultUncaughtExceptionHandler(this); 
 | 
        autoClear(5); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void uncaughtException(Thread thread, Throwable throwable) 
 | 
    { 
 | 
        if (!handleException(throwable) && m_UncaughtExceptionHandler != null) 
 | 
        { 
 | 
            m_UncaughtExceptionHandler.uncaughtException(thread, throwable); 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            SystemClock.sleep(3000); 
 | 
            android.os.Process.killProcess(android.os.Process.myPid()); 
 | 
            System.exit(1); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private void recordDeviceInfo() 
 | 
    { 
 | 
        m_DevicceInfo.clear(); 
 | 
        m_DevicceInfo.put("brand", Build.BRAND); 
 | 
        m_DevicceInfo.put("model", Build.MODEL); 
 | 
        m_DevicceInfo.put("android_version", String.valueOf(Build.VERSION.SDK_INT)); 
 | 
        try 
 | 
        { 
 | 
            PackageManager _pkgMgr = m_Context.getPackageManager(); 
 | 
            PackageInfo _pkgInfo = _pkgMgr.getPackageInfo(m_Context.getPackageName(), 
 | 
                                                          PackageManager.GET_ACTIVITIES); 
 | 
            if (_pkgInfo != null) 
 | 
            { 
 | 
                m_DevicceInfo.put("versionName", _pkgInfo.versionName); 
 | 
                m_DevicceInfo.put("versionCode", String.valueOf(_pkgInfo.versionCode)); 
 | 
            } 
 | 
        } catch (PackageManager.NameNotFoundException e) 
 | 
        { 
 | 
            e.printStackTrace(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private boolean handleException(Throwable throwable) 
 | 
    { 
 | 
        if (throwable == null) 
 | 
        { 
 | 
            return false; 
 | 
        } 
 | 
  
 | 
        try 
 | 
        { 
 | 
            new Thread(new Runnable() 
 | 
            { 
 | 
                @Override 
 | 
                public void run() 
 | 
                { 
 | 
                    Looper.prepare(); 
 | 
                    Toast.makeText(m_Context, "程序出现异常,即将重启", Toast.LENGTH_LONG).show(); 
 | 
                    Looper.loop(); 
 | 
                } 
 | 
            }).start(); 
 | 
  
 | 
            recordDeviceInfo(); 
 | 
  
 | 
            save(throwable); 
 | 
  
 | 
            SystemClock.sleep(3000); 
 | 
  
 | 
        } catch (Exception e) 
 | 
        { 
 | 
            e.printStackTrace(); 
 | 
        } 
 | 
        return true; 
 | 
    } 
 | 
  
 | 
    private String save(Throwable throwable) throws Exception 
 | 
    { 
 | 
        StringBuffer sb = new StringBuffer(); 
 | 
        try 
 | 
        { 
 | 
            SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 | 
            String date = sDateFormat.format(new Date()); 
 | 
            sb.append("\r\n" + date + "\n"); 
 | 
            for (Map.Entry<String, String> entry : m_DevicceInfo.entrySet()) 
 | 
            { 
 | 
                String key = entry.getKey(); 
 | 
                String value = entry.getValue(); 
 | 
                sb.append(key + "=" + value + "\n"); 
 | 
            } 
 | 
  
 | 
            Writer writer = new StringWriter(); 
 | 
            PrintWriter printWriter = new PrintWriter(writer); 
 | 
            throwable.printStackTrace(printWriter); 
 | 
            Throwable cause = throwable.getCause(); 
 | 
            while (cause != null) 
 | 
            { 
 | 
                cause.printStackTrace(printWriter); 
 | 
                cause = cause.getCause(); 
 | 
            } 
 | 
            printWriter.flush(); 
 | 
            printWriter.close(); 
 | 
            String result = writer.toString(); 
 | 
            sb.append(result); 
 | 
  
 | 
            String fileName = writeFile(sb.toString()); 
 | 
            return fileName; 
 | 
        } catch (Exception e) 
 | 
        { 
 | 
            sb.append("写入崩溃日志时, 出现了异常状况...\r\n"); 
 | 
            writeFile(sb.toString()); 
 | 
        } 
 | 
        return null; 
 | 
  
 | 
    } 
 | 
  
 | 
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); 
 | 
  
 | 
    private String writeFile(String sb) throws Exception 
 | 
    { 
 | 
        String time = formatter.format(new Date()); 
 | 
        String fileName = "crash-" + time + ".log"; 
 | 
        String path = getPath(); 
 | 
        File dir = new File(getPath()); 
 | 
        if (!dir.exists()) 
 | 
        { 
 | 
            dir.mkdirs(); 
 | 
        } 
 | 
        FileOutputStream fos = new FileOutputStream(path + fileName, true); 
 | 
        fos.write(sb.getBytes()); 
 | 
        fos.flush(); 
 | 
        fos.close(); 
 | 
        return fileName; 
 | 
    } 
 | 
  
 | 
    private String getPath() 
 | 
    { 
 | 
        return m_Context.getExternalFilesDir("").getAbsolutePath() 
 | 
                + File.separator 
 | 
                + "crash" 
 | 
                + File.separator; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 文件删除 
 | 
     * 
 | 
     * @param autoClearDay 文件保存天数 
 | 
     */ 
 | 
    public void autoClear(final int autoClearDay) 
 | 
    { 
 | 
        delete(getPath(), new FilenameFilter() 
 | 
        { 
 | 
            @Override 
 | 
            public boolean accept(File file, String filename) 
 | 
            { 
 | 
                String s = FileUtil.getFileNameWithoutExtension(filename); 
 | 
                int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay; 
 | 
                String date = "crash-" + getOtherDay(day); 
 | 
                return date.compareTo(s) >= 0; 
 | 
            } 
 | 
        }); 
 | 
    } 
 | 
  
 | 
    private void delete(String path, FilenameFilter filter) 
 | 
    { 
 | 
        File _file = new File(path); 
 | 
        if (!_file.exists()) 
 | 
        { 
 | 
            return; 
 | 
        } 
 | 
        File[] _files = _file.listFiles(filter); 
 | 
        for (int i = _files.length - 1; i >= 0; i--) 
 | 
        { 
 | 
            _files[i].delete(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private String getOtherDay(int offset) 
 | 
    { 
 | 
        Calendar _calendar = Calendar.getInstance(); 
 | 
        _calendar.add(Calendar.DATE, offset); 
 | 
        return formatter.format(_calendar.getTime()); 
 | 
    } 
 | 
} 
 |