Test version 2.0f - added email crash report functionality.

This commit is contained in:
Graham Jones
2016-03-28 20:48:17 +01:00
parent 4bd47afefa
commit ceb9fd7a0a
6 changed files with 195 additions and 1 deletions

View File

@@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.org.openseizuredetector"
android:versionCode="19"
android:versionName="2.0e" >
android:versionName="2.0f" >
<uses-sdk android:minSdkVersion="14" />
@@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-feature
android:name="android.hardware.telephony"

View File

@@ -83,6 +83,9 @@ public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set our custom uncaught exception handler to report issues.
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(MainActivity.this));
//int i = 5/0; // Force exception to test handler.
mUtil = new OsdUtil(this);
mConnection = new SdServiceConnection(this);

View File

@@ -0,0 +1,172 @@
package uk.org.openseizuredetector;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Looper;
import android.os.StatFs;
import android.util.Log;
import android.view.WindowManager;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Date;
import java.util.Locale;
/**
* Created by graham on 28/03/16.
* Based on http://www.coderzheaven.com/2013/03/13/customize-force-close-dialog-android/
*/
public class OsdUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
private Context mContext;
private static Context mStaticContext;
private static String reportEmail = "crashreports@openseizuredetector.org.uk";
public OsdUncaughtExceptionHandler(Context context) {
mContext = context;
mStaticContext = context;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
StringBuilder report = new StringBuilder();
Date curDate = new Date();
report.append("Error Report collected on : ")
.append(curDate.toString()).append('\n').append('\n');
report.append("System Information :").append('\n');
addInformation(report);
report.append('\n').append('\n');
report.append("Stack Trace:\n");
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
ex.printStackTrace(printWriter);
report.append(result.toString());
printWriter.close();
report.append('\n');
report.append("**** End of current Report ***");
Log.e(OsdUncaughtExceptionHandler.class.getName(),
"Crash Report: " + report);
sendErrorMail(report);
} catch (Throwable ignore) {
Log.e(OsdUncaughtExceptionHandler.class.getName(),
"Error while sending error e-mail", ignore);
}
}
private StatFs getStatFs() {
File path = Environment.getDataDirectory();
return new StatFs(path.getPath());
}
private long getAvailableInternalMemorySize(StatFs stat) {
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
private long getTotalInternalMemorySize(StatFs stat) {
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
}
private void addInformation(StringBuilder message) {
message.append("Locale: ").append(Locale.getDefault()).append('\n');
try {
PackageManager pm = mContext.getPackageManager();
PackageInfo pi;
pi = pm.getPackageInfo(mContext.getPackageName(), 0);
message.append("Version: ").append(pi.versionName).append('\n');
message.append("Package: ").append(pi.packageName).append('\n');
} catch (Exception e) {
Log.e("CustomExceptionHandler", "Error", e);
message.append("Could not get Version information for ").append(
mContext.getPackageName());
}
message.append("Phone Model: ").append(android.os.Build.MODEL)
.append('\n');
message.append("Android Version: ")
.append(android.os.Build.VERSION.RELEASE).append('\n');
message.append("Board: ").append(android.os.Build.BOARD).append('\n');
message.append("Brand: ").append(android.os.Build.BRAND).append('\n');
message.append("Device: ").append(android.os.Build.DEVICE).append('\n');
message.append("Host: ").append(android.os.Build.HOST).append('\n');
message.append("ID: ").append(android.os.Build.ID).append('\n');
message.append("Model: ").append(android.os.Build.MODEL).append('\n');
message.append("Product: ").append(android.os.Build.PRODUCT)
.append('\n');
message.append("Type: ").append(android.os.Build.TYPE).append('\n');
StatFs stat = getStatFs();
message.append("Total Internal memory: ")
.append(getTotalInternalMemorySize(stat)).append('\n');
message.append("Available Internal memory: ")
.append(getAvailableInternalMemorySize(stat)).append('\n');
}
/**
* This method for call alert dialog when application crashed!
*/
public void sendErrorMail(final StringBuilder errorContent) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
new Thread() {
@Override
public void run() {
Looper.prepare();
builder.setTitle("Sorry...OpenSeizureDetector Crashed!");
builder.create();
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
System.exit(0);
}
});
builder.setPositiveButton("Report by Email",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Intent sendIntent = new Intent(
Intent.ACTION_SEND);
sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String subject = "OpenSeizureDetector Crash report";
StringBuilder body = new StringBuilder("Crash Report:");
body.append('\n').append('\n');
body.append(errorContent).append('\n')
.append('\n');
// sendIntent.setType("text/plain");
sendIntent.setType("message/rfc822");
sendIntent.putExtra(Intent.EXTRA_EMAIL,
new String[]{reportEmail});
sendIntent.putExtra(Intent.EXTRA_TEXT,
body.toString());
sendIntent.putExtra(Intent.EXTRA_SUBJECT,
subject);
sendIntent.setType("message/rfc822");
Log.e("sendEmail", "starting activity...");
mStaticContext.startActivity(sendIntent);
Log.e("sendEmail", "exiting...");
System.exit(0);
}
});
builder.setMessage("Please report the " +
"problem by email using the button below so we can fix it.\n" +
"You can review the information being sent in the next screen:"+
"\n"+errorContent.toString());
Dialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
Looper.loop();
}
}.start();
}
}

View File

@@ -46,6 +46,12 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set our custom uncaught exception handler to report issues.
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(PrefActivity.this));
//int i = 5/0; // Force exception to test handler.
mUtil = new OsdUtil(getApplicationContext());
mContext = getApplicationContext();
}

View File

@@ -154,6 +154,13 @@ public class SdServer extends Service implements SdDataReceiver {
@Override
public void onCreate() {
Log.v(TAG, "onCreate()");
// Set our custom uncaught exception handler to report issues.
Thread.setDefaultUncaughtExceptionHandler(
new OsdUncaughtExceptionHandler(SdServer.this));
//int i = 5/0; // Force exception to test handler.
mHandler = new Handler();
mUtil = new OsdUtil(getApplicationContext());

View File

@@ -66,6 +66,11 @@ public class StartupActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set our custom uncaught exception handler to report issues.
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(StartupActivity.this));
//int i = 5/0; // Force exception to test handler.
setContentView(R.layout.startup_activity);
mUtil = new OsdUtil(this);