android 收集错误日志 上传服务器
2017-11-13 10:44
357 查看
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/76974022 public 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
}
}
相关文章推荐
- 将android客户端的错误日志压缩上传到服务器
- Android中错误异常日志管理(上传服务器)
- Android自定义错误日志收集
- android 崩溃日志收集与上传
- 好记性不如烂笔头------使用Acra+Android-Email实现错误日志上传
- 错误收集(本地Log日志)错误上传
- Android APP崩溃上传日志到服务器并且重启!
- android收集bug(异常)信息,上传至服务器
- android app崩溃日志收集以及上传
- Android项目的错误异常收集日志记录
- android--app崩溃日志收集以及上传
- Android logcat保存当前应用程序的日志并上传服务器或指定邮箱
- Android开发之app崩溃日志收集以及上传
- android怎样实时上传崩溃日志到服务器
- android app崩溃日志收集以及上传
- Android APP崩溃上传日志到服务器并且重启!
- android 通过UncaughtExceptionHandler处理和上传错误日志
- android抓取错误日志并上报到服务器
- android app崩溃日志收集以及上传
- android自定义异常处理与错误日志上传