实例介绍
【实例简介】收集崩溃BUG发送到邮箱
【实例截图】
【核心代码】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | 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(); } } |
标签: 收集崩溃BUG发送到邮箱
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论