前段时间做过一个反馈应用程序Bug的程序,今天和大家分享下
如果想要获取应用程序的出错信息则比较简单,只需要通过实现 UncaughtExceptionHandler就可以达到目的,那么如何获取Android OS 所有应用程序的出错信息,目前的方式只有通过修改框架层来达到此目的。
A) 继承UncaughtExceptionHandler的类
package org.winplus.getex;
import java.lang.Thread.UncaughtExceptionHandler;
import android.content.Context;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
public class CrashHandler implements UncaughtExceptionHandler {
private final static String TAG = "UncaughtExceptionHandler";
private Thread.UncaughtExceptionHandler mDefaultHandler;
private static CrashHandler mInstance;
private Context mContext;
private CrashHandler() {
}
/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
if (mInstance == null)
mInstance = new CrashHandler();
return mInstance;
}
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
if (!handleException(throwable) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, throwable);
} else {
// Sleep一会后结束程序
// 来让线程停止一会是为了显示Toast信息给用户,然后Kill程序
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Log.e(TAG, "Error : ", e);
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
}
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
final String msg = ex.getLocalizedMessage();
// 使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare();
Toast.makeText(mContext, "Exception:" + msg, Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
return true;
}
public void init(Context context) {
mContext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
}
B) 初始化并启动获取异常的线程类:CrashApplication
import android.app.Application;
public class CrashApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler crashHandler = CrashHandler.getInstance();
// 注册crashHandler
crashHandler.init(getApplicationContext());
}
}
D) 写一个用于测试的Activity
public class GetExceptionActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int i = 1/0;//除数不能为0 这里会抛出异常
}
}
系统出错时一般会弹出一个Dialog,这个Dialog是由frameworks\base\services\java\com\android\server\am\ActivityManagerService.java弹出的,具体的Dialog是frameworks\base\services\java\com\android\server\am\AppErrorDialog.java,所以在这里我们只需要将这个AppErrorDialog改掉,或者在AppErrorDialog中添加一个按钮用于来反馈出错信息的功能,简单的说就是在AppErrorDialog中添加一个按钮,这个按钮通过Intent打开相应的应用程序,并将错误信息发送到应用程序的Activity。
这里主要给出一个思路吧。
最后,如何发送邮件呢?Android有几种发送邮件的方式,一种是直接调用系统的邮件,第二种是通过Java Mail的方式发送邮件,第一种并不是我们所需要的,要通过javaMail发送邮件,但Android如何通过JavaMail的方式发送邮件呢?很好,以及有哥们帮我们做了,请看这个:http://code.google.com/p/javamail-android/,只需要下载下面3个Jar包即可:additionnal.jar mail.jar activation.jar
我们来看如何使用这些jar包发邮件
public class MailTool {
public static void sendMail(String subject, String content) throws MessagingException {
Properties props = new Properties();
props.put("mail.smtp.host", "mail.sina.cn");// 存储发送邮件服务器的信息
props.put("mail.smtp.auth", "true");// 同时通过验证
// 基本的邮件会话
Session session = Session.getInstance(props);
session.setDebug(true);// 设置调试标志
// 构造信息体
MimeMessage message = new MimeMessage(session);
// 发件地址
Address fromAddress = null;
fromAddress = new InternetAddress("[email protected]");
message.setFrom(fromAddress);
// 收件地址
Address toAddress = new InternetAddress("[email protected]");
message.addRecipient(Message.RecipientType.TO, toAddress);
// 解析邮件内容
message.setSubject(subject);// 设置信件的标题
message.setText(content);// 设置信件内容
message.saveChanges(); // implicit with send()//存储信息
// send e-mail message
Transport transport = null;
transport = session.getTransport("smtp");
transport.connect("mail.sina.cn", "[email protected]", "winplus.org");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
}
比如说需要发送接收gmail的邮件,要进行一下设置
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.gmail.com");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
原创文章,欢迎转载,转载请注明出处http://blog.csdn.net/tangcheng_ok