基本信息
源码名称:android 收集崩溃BUG发送到邮箱
源码大小:3.34KB
文件格式:.rar
开发语言:Java
更新时间:2015-06-13
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍

收集崩溃BUG发送到邮箱


package com.dubugutil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.yx.zhangyan.MainActivityf;

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

/**
 * 	在Application注册crashHandler  
 * 
	CrashHandler crashHandler = CrashHandler.getInstance();  
	crashHandler.setHost("smtp.163.com");邮箱服务
	crashHandler.setUserName("debugyx@163.com");发送日志的邮箱
	crashHandler.setUserPass("inioytzjssxorjspu");邮箱授权码
	crashHandler.setAddrTo("debugyx@163.com");收件箱
	crashHandler.init(getApplicationContext()); 初始化
 * 
 * 
 * 
 * 
 * **/


@SuppressLint("SimpleDateFormat")
public class CrashHandler implements UncaughtExceptionHandler {
	public static final String TAG = "CrashHandler";
	// 系统默认的UncaughtException处理�?
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	// CrashHandler实例
	private static CrashHandler INSTANCE = new CrashHandler();
	// 程序的Context对象
	private Context mContext;
	// 用来存储设备信息和异常信�?
	private Map<String, String> infos = new HashMap<String, String>();
	private String host, userName, userPass, AddrTo;
	// 用于格式化日�?作为日志文件名的�?���?
	private SimpleDateFormat formatter = new SimpleDateFormat(
			"yyyy-MM-dd-HH-mm-ss");

	/** 保证只有�?��CrashHandler实例 */
	private CrashHandler() {
	}

	/** 获取CrashHandler实例 ,单例模式 */
	public static CrashHandler getInstance() {
		return INSTANCE;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void setUserPass(String userPass) {
		this.userPass = userPass;
	}

	public void setAddrTo(String addrTo) {
		AddrTo = addrTo;
	}



	/**
	 * 初始�?
	 * 
	 * @param context
	 */
	public void init(Context context) {
		mContext = context;
		// 获取系统默认的UncaughtException处理�?
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		// 设置该CrashHandler为程序的默认处理�?
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	/**
	 * 当UncaughtException发生时会转入该函数来处理
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(ex) && mDefaultHandler != null) {
			// 如果用户没有处理则让系统默认的异常处理器来处�?
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				Log.e(TAG, "error : ", e);
			}
			// �?��程序
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(0);
		}

	}

	/**
	 * 自定义错误处�?收集错误信息 发�?错误报告等操作均在此完成.
	 * 
	 * @param ex
	 * @return true:如果处理了该异常信息;否则返回false.
	 */
	private boolean handleException(Throwable ex) {
		if (ex == null) {
			return false;
		}
		// 使用Toast来显示异常信�?
		
		try {
			
			new Thread() {
				@Override
				public void run() {
					Looper.prepare();
					Toast.makeText(mContext, "很抱歉,程序出现异常,我们尽快修复。",
							Toast.LENGTH_SHORT).show();
					
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						Log.e(TAG, "error : ", e);
					}
//					mContext.startActivity(new Intent(mContext,MainActivityf.class));
					android.os.Process.killProcess(android.os.Process.myPid());
					System.exit(0);  
					
					Looper.loop();
					
			
				}
			}.start();
		} catch (Exception e) {
			// TODO: handle exception
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(0);  
		}
		
	
		// 收集设备参数信息
		collectDeviceInfo(mContext);
		// 保存日志文件
		saveCrashInfo2File(ex);
		return true;
	}

	/**
	 * 收集设备参数信息
	 * 
	 * @param ctx
	 */
	public void collectDeviceInfo(Context ctx) {
		try {
			PackageManager pm = ctx.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
					PackageManager.GET_ACTIVITIES);
			if (pi != null) {
				String versionName = pi.versionName == null ? "null"
						: pi.versionName;
				String versionCode = pi.versionCode   "";
				infos.put("versionName", versionName);
				infos.put("versionCode", versionCode);
			}
		} catch (NameNotFoundException e) {
			Log.e(TAG, "an error occured when collect package info", e);
		}
		Field[] fields = Build.class.getDeclaredFields();
		for (Field field : fields) {
			try {
				field.setAccessible(true);
				infos.put(field.getName(), field.get(null).toString());
				Log.d(TAG, field.getName()   " : "   field.get(null));
			} catch (Exception e) {
				Log.e(TAG, "an error occured when collect crash info", e);
			}
		}
	}

	/**
	 * 保存错误信息到文件中
	 * 
	 * @param ex
	 * @return 返回文件名称,便于将文件传送到服务�?
	 */
	private String saveCrashInfo2File(Throwable ex) {
		StringBuffer sb = new StringBuffer();
		for (Map.Entry<String, String> entry : infos.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			sb.append(key   "="   value   "\n");
		}
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		sb.append(result);
		try {
			long timestamp = System.currentTimeMillis();
			String time = formatter.format(new Date());
			String fileName = "crash-"   time   "-"   timestamp   ".log";
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				String path = Environment.getExternalStorageDirectory()
						  "/crash/";
				File dir = new File(path);
				if (!dir.exists()) {
					dir.mkdirs();
				}
				send(sb.toString());
				FileOutputStream fos = new FileOutputStream(path   fileName);
				fos.write(sb.toString().getBytes());
				fos.close();
			}
			return fileName;
		} catch (Exception e) {
			Log.e(TAG, "an error occured while writing file...", e);
		}
		return null;
	}
	private void send(final String cuowu) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				Email email = new Email();
				email.setAddressTo(AddrTo);
				email.setHost(host);
				email.setPwd(userPass);
				email.setUserName(userName);
				try {
					email.send("【"   getAppName()   "】 手机厂商:"
							  android.os.Build.MANUFACTURER   "-手机型号:"
							  android.os.Build.MODEL   ",错误报告.", new String(
							cuowu.getBytes(), "UTF-8"));
					System.out.println("发送成功!");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	private String getAppName(){
		ApplicationInfo android = mContext.getApplicationInfo();
		return mContext.getString(android.labelRes);
	}
	
	   private void showDialog() {
	        new Thread() {
	            @Override
	            public void run() {
	                Looper.prepare();
	                new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false).setMessage("很抱歉,程序出现异常,异常已发送,我们尽快修复。")
	                        .setNeutralButton("我知道了", new OnClickListener() {
	                            @Override
	                            public void onClick(DialogInterface dialog, int which) {
//	                                System.exit(0);
	                        		Intent intent = new Intent(mContext.getApplicationContext(),MainActivityf.class);
	                	            PendingIntent restartIntent = PendingIntent.getActivity(
	                	            		mContext.getApplicationContext(), 0, intent,
	                	                    Intent.FLAG_ACTIVITY_NEW_TASK);
	                	            // 退出程序
	                	            AlarmManager mgr = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
	                	            mgr.set(AlarmManager.RTC, System.currentTimeMillis()   1000,restartIntent); // 1秒钟后重启应用
//	                	            mContext.finishActivity();
	                                 
	                            }
	                        }).create().show();
	                Looper.loop();
	            }
	        }.start();
	    }
	
	
}