Android Uncaught Exception Handler邮件发送错误日志

 

原创  Android Uncaught Exception Handler邮件发送错误日志 

http://blog.blackmoonit.com/2010/02/android-postmortem-reports-via-email.html

 

http://blog.csdn.net/vzq4815/archive/2010/11/18/6018431.aspx

 

收藏

Use for "Force Close".

//close the activity immediately.

android.os.Process.killProcess(android.os.Process.myPid());

System.exit(0);

Post from:

http://blog.blackmoonit.com/2010/02/android-postmortem-reports-via-email.html

 

  1. package com.myapp;  
  2. import java.io.BufferedReader;  
  3. import java.io.FileNotFoundException;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.lang.Thread.UncaughtExceptionHandler;  
  8. import java.lang.reflect.Field;  
  9. import java.text.DecimalFormat;  
  10. import java.text.NumberFormat;  
  11. import java.text.SimpleDateFormat;  
  12. import java.util.Date;  
  13. import android.app.Activity;  
  14. import android.content.Context;  
  15. import android.content.Intent;  
  16. import android.content.pm.PackageInfo;  
  17. import android.content.pm.PackageManager;  
  18. import android.content.pm.PackageManager.NameNotFoundException;  
  19. import android.os.Build;  
  20. public class PostMortemReportExceptionHandler implements UncaughtExceptionHandler, Runnable {  
  21.     public static final String ExceptionReportFilename = "postmortem.trace";  
  22.       
  23.     private static final String MSG_SUBJECT_TAG = "Exception Report"//"app title + this tag" = email subject  
  24.     private static final String MSG_SENDTO = "support@mysite.com";    //email will be sent to this account  
  25.     //the following may be something you wish to consider localizing  
  26.     private static final String MSG_BODY = "Please help by sending this email. "+  
  27.         "No personal information is being sent (you can check by reading the rest of the email).";  
  28.       
  29.     private Thread.UncaughtExceptionHandler mDefaultUEH;  
  30.     private Activity mApp = null;  
  31.    
  32.     public PostMortemReportExceptionHandler(Activity aApp) {  
  33.         mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();  
  34.         mApp = aApp;  
  35.     }  
  36.     @Override  
  37.     protected void finalize() throws Throwable {  
  38.         if (Thread.getDefaultUncaughtExceptionHandler().equals(this))  
  39.             Thread.setDefaultUncaughtExceptionHandler(mDefaultUEH);  
  40.         super.finalize();  
  41.     }  
  42.     @Override  
  43.     public void uncaughtException(Thread t, Throwable e) {  
  44.         submit(e);  
  45.         //do not forget to pass this exception through up the chain  
  46.         if (mDefaultUEH!=null)  
  47.             mDefaultUEH.uncaughtException(t,e);  
  48.     }  
  49.       
  50.     public String getDebugReport(Throwable aException) {  
  51.         NumberFormat theFormatter = new DecimalFormat("#0.");  
  52.         String theErrReport = "";  
  53.           
  54.         theErrReport += mApp.getPackageName()+" generated the following exception:/n";  
  55.         theErrReport += aException.toString()+"/n/n";  
  56.           
  57.         //stack trace  
  58.         StackTraceElement[] theStackTrace = aException.getStackTrace();  
  59.         if (theStackTrace.length>0) {  
  60.             theErrReport += "--------- Stack trace ---------/n";  
  61.             for (int i=0; i<theStackTrace.length; i++) {  
  62.                 theErrReport += theFormatter.format(i+1)+"/t"+theStackTrace[i].toString()+"/n";  
  63.             }//for  
  64.             theErrReport += "-------------------------------/n/n";  
  65.         }  
  66.           
  67.         //if the exception was thrown in a background thread inside  
  68.         //AsyncTask, then the actual exception can be found with getCause  
  69.         Throwable theCause = aException.getCause();  
  70.         if (theCause!=null) {  
  71.             theErrReport += "----------- Cause -----------/n";  
  72.             theErrReport += theCause.toString() + "/n/n";  
  73.             theStackTrace = theCause.getStackTrace();  
  74.             for (int i=0; i<theStackTrace.length; i++) {  
  75.                 theErrReport += theFormatter.format(i+1)+"/t"+theStackTrace[i].toString()+"/n";  
  76.             }//for  
  77.             theErrReport += "-----------------------------/n/n";  
  78.         }//if  
  79.           
  80.         //app environment  
  81.         PackageManager pm = mApp.getPackageManager();  
  82.         PackageInfo pi;  
  83.         try {  
  84.             pi = pm.getPackageInfo(mApp.getPackageName(), 0);  
  85.         } catch (NameNotFoundException eNnf) {  
  86.             //doubt this will ever run since we want info about our own package  
  87.             pi = new PackageInfo();  
  88.             pi.versionName = "unknown";  
  89.             pi.versionCode = 69;  
  90.         }  
  91.         Date theDate = new Date();  
  92.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss_zzz");  
  93.         theErrReport += "-------- Environment --------/n";  
  94.         theErrReport += "Time/t="+sdf.format(theDate)+"/n";  
  95.         theErrReport += "Device/t="+Build.FINGERPRINT+"/n";  
  96.         try {  
  97.             Field theMfrField = Build.class.getField("MANUFACTURER");  
  98.             theErrReport += "Make/t="+theMfrField.get(null)+"/n";  
  99.         } catch (SecurityException e) {  
  100.         } catch (NoSuchFieldException e) {  
  101.         } catch (IllegalArgumentException e) {  
  102.         } catch (IllegalAccessException e) {  
  103.         }  
  104.         theErrReport += "Model/t="+Build.MODEL+"/n";  
  105.         theErrReport += "Product/t="+Build.PRODUCT+"/n";  
  106.         theErrReport += "App/t/t="+mApp.getPackageName()+", version "+pi.versionName+" (build "+pi.versionCode+")/n";  
  107.         theErrReport += "Locale="+mApp.getResources().getConfiguration().locale.getDisplayName()+"/n";  
  108.         theErrReport += "-----------------------------/n/n";  
  109.       
  110.         theErrReport += "END REPORT.";  
  111.         return theErrReport;  
  112.     }  
  113.       
  114.     protected void saveDebugReport(String aReport) {  
  115.         //save report to file  
  116.         try {  
  117.             FileOutputStream theFile = mApp.openFileOutput(ExceptionReportFilename, Context.MODE_PRIVATE);  
  118.             theFile.write(aReport.getBytes());  
  119.             theFile.close();  
  120.         } catch(IOException ioe) {  
  121.             //error during error report needs to be ignored, do not wish to start infinite loop  
  122.         }         
  123.     }  
  124.       
  125.     public void sendDebugReportToAuthor() {  
  126.         String theLine = "";  
  127.         String theTrace = "";  
  128.         try {  
  129.             BufferedReader theReader = new BufferedReader(  
  130.                     new InputStreamReader(mApp.openFileInput(ExceptionReportFilename)));  
  131.             while ((theLine = theReader.readLine())!=null) {  
  132.                 theTrace += theLine+"/n";  
  133.             }  
  134.             if (sendDebugReportToAuthor(theTrace)) {  
  135.                 mApp.deleteFile(ExceptionReportFilename);  
  136.             }  
  137.         } catch (FileNotFoundException eFnf) {  
  138.             // nothing to do  
  139.         } catch(IOException eIo) {  
  140.             // not going to report  
  141.         }         
  142.     }  
  143.       
  144.     public Boolean sendDebugReportToAuthor(String aReport) {  
  145.         if (aReport!=null) {  
  146.             Intent theIntent = new Intent(Intent.ACTION_SEND);  
  147.             String theSubject = mApp.getTitle()+" "+MSG_SUBJECT_TAG;  
  148.             String theBody = "/n"+MSG_BODY+"/n/n"+aReport+"/n/n";  
  149.             theIntent.putExtra(Intent.EXTRA_EMAIL,new String[] {MSG_SENDTO});  
  150.             theIntent.putExtra(Intent.EXTRA_TEXT, theBody);  
  151.             theIntent.putExtra(Intent.EXTRA_SUBJECT, theSubject);  
  152.             theIntent.setType("message/rfc822");  
  153.             Boolean hasSendRecipients = (mApp.getPackageManager().queryIntentActivities(theIntent,0).size()>0);  
  154.             if (hasSendRecipients) {  
  155.                 mApp.startActivity(theIntent);  
  156.                 return true;  
  157.             } else {  
  158.                 return false;  
  159.             }  
  160.         } else {  
  161.             return true;  
  162.         }  
  163.     }  
  164.       
  165.     @Override  
  166.     public void run() {  
  167.         sendDebugReportToAuthor();  
  168.     }  
  169.       
  170.     public void submit(Throwable e) {  
  171.         String theErrReport = getDebugReport(e);  
  172.         saveDebugReport(theErrReport);  
  173.         //try to send file contents via email (need to do so via the UI thread)  
  174.         mApp.runOnUiThread(this);                 
  175.     }  
  176. }  
 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值