android 收集错误日志 上传服务器

来源:互联网 发布:ubuntu pytorch 编辑:程序博客网 时间:2024/05/10 06:37
import android.app.Application;public class MyApp extends Application {    @Override    public void onCreate() {        super.onCreate();        CrashHandler.getInstance().init(this);    }}

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.ycfy.carsh">    <application        android:name=".MyApp"        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.GET_ACCOUNTS"/></manifest>
import android.Manifest;import android.content.pm.PackageManager;import android.os.Build;import android.os.Bundle;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;//http://m.blog.csdn.net/u013110195/article/details/76974022public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity ";    private Button btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn = (Button) findViewById(R.id.btn);        checkInitPermissions();        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                int i = Integer.parseInt("aa");//                throw new RuntimeException("这是自己定义的异常");            }        });    }    public static final int REQUEST_PERMISSION_CODE = 100;    private void checkInitPermissions(){        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            String[] permissions = new String[]{                    //放入需要授予的权限,例如需要写入的权限                    Manifest.permission.WRITE_EXTERNAL_STORAGE            };            if (ContextCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) {                if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])){                    ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSION_CODE);                }            }        } else {            handleAfterPermissions();        }    }    private void  handleAfterPermissions(){    }    @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == REQUEST_PERMISSION_CODE){            handleAfterPermissions();        }    }}

import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Build;import android.os.Environment;import android.os.Process;import android.util.Log;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;/** * function: 截获崩溃日志:当程序产生未捕获异常 * Created by lzq on 2017/8/10. */public class CrashHandler implements Thread.UncaughtExceptionHandler{    //手机存储路径    private final String logPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Crash";    private static final String TAG = CrashHandler.class.getSimpleName();    /** 系统默认的异常处理器(默认情况下,系统会终止当前的异常程序) */    private Thread.UncaughtExceptionHandler mDefaultCrashHandler;    private Context mContext;    private String mProcessName;    /** CrashHandler 实例 */    private static CrashHandler instance = new CrashHandler();    /** 私有构造 保证只有一个CrashHandler实例*/    private CrashHandler(){    }    /** 单例模式 */    public static CrashHandler getInstance(){        return instance;    }    /** 初始化 */    public void init(Context context){        mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();        //将当前实例设置为系统默认的异常处理器        Thread.setDefaultUncaughtExceptionHandler(this);        mContext = context.getApplicationContext();        mProcessName = context.getPackageName();    }    /** 用于格式化日期,作为日志文件名的一部分. */    private final DateFormat formatter = new SimpleDateFormat("MMdd-HH:mm:ss", Locale.getDefault());    @Override    public void uncaughtException(Thread thread, Throwable throwable) {        Log.e(TAG, "---------------uncaughtException start---------------\r\n");        try {            dumpExceptionToLocalFile(thread, throwable); //把异常日志在手机本地文件输出            uploadExceptionToServer();  //上传crash日志到服务器        } catch (IOException e) {            Log.e(TAG, "uncaughtException,ex:" + e.getMessage());            e.printStackTrace();        }        if (mDefaultCrashHandler != null){            mDefaultCrashHandler.uncaughtException(thread, throwable);        }else{            Process.killProcess(Process.myPid());        }        Log.e(TAG, "---------------uncaughtException end---------------\r\n");    }    /** dump UncaughtException into local file */    private void dumpExceptionToLocalFile(Thread thread, Throwable throwable) throws IOException{        //记录数量达到10个就清理数据        File logDir = new File(logPath);        if (logDir.exists()){            clearExLogWhenMax(logDir);        }else{            logDir.mkdirs();        }        //错误信息文件名        Date date = new Date();        String logFileName = formatter.format(date) + String.format("[%s]", thread.getName())+ ".txt";        File logExFile = new File(logDir, logFileName);        logExFile.createNewFile();        //写入信息到文件中        try {            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(logExFile)));            //时间戳            pw.println("Time stamp:" + date);            pw.println("Process[" + mProcessName + "," + Process.myPid() + "]");            pw.println();            //手机信息            dumpPhoneInfo(pw);            pw.println();            //导出异常调用栈信息            throwable.printStackTrace(pw);            pw.close();        }catch (IOException ex){            Log.e(TAG, "dump info failed");        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }    }    /**     * 设置最大日志数量 10     * @param logDir 日志目录     */    private void clearExLogWhenMax(File logDir){        File[] logFileList = logDir.listFiles();        if (logFileList == null || logFileList.length == 0){            return;        }        int length = logFileList.length;        if (length > 10){            for (File aFile : logFileList){                try {                    if (aFile.delete()){                        Log.d(TAG, "clearExLogWhenMax:" + aFile.getName());                    }                }catch (Exception ex){                    Log.d(TAG, "clearExLogWhenMax:" + ex);                }            }        }    }    private void dumpPhoneInfo(PrintWriter pw) throws IOException, PackageManager.NameNotFoundException {        PackageManager pm = mContext.getPackageManager();        PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);        pw.println("App Version:" + pi.packageName + "_" + pi.versionCode);        //Android版本号        pw.println("OS Version:" + Build.VERSION.RELEASE + "_" + Build.VERSION.SDK_INT);        //手机制造商        pw.println("Vendor:" + Build.MANUFACTURER);        //手机型号        pw.println("Model:" + Build.MODEL);        //CPU架构        pw.println("CPU ABI:" + Build.CPU_ABI);    }    private void uploadExceptionToServer() {        //TODO Upload Exception Message To Your Web Server    }}