diff --git a/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java b/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java
index 1ed4e37f02..236221d11d 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java
@@ -1,17 +1,25 @@
package net.kdt.pojavlaunch;
+import android.app.*;
import android.content.*;
import android.os.*;
import android.support.v7.app.*;
+import android.util.*;
+import java.awt.*;
+import java.awt.datatransfer.*;
+
+import android.support.v7.app.AlertDialog;
public class FatalErrorActivity extends AppCompatActivity
{
- public static void showError(Context ctx, boolean isFatalErr, Throwable th) {
+ public static void showError(Context ctx, String savePath, boolean storageAllow, /* boolean isFatalErr, */ Throwable th) {
Intent ferrorIntent = new Intent(ctx, FatalErrorActivity.class);
ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ferrorIntent.putExtra("throwable", th);
- ferrorIntent.putExtra("isFatal", isFatalErr);
+ ferrorIntent.putExtra("savePath", savePath);
+ ferrorIntent.putExtra("storageAllow", storageAllow);
+ // ferrorIntent.putExtra("isFatal", isFatalErr);
ctx.startActivity(ferrorIntent);
}
@@ -20,9 +28,46 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
- Throwable th = (Throwable) extras.getSerializable("throwable");
- boolean isFatalError = extras.getBoolean("isFatal", false);
+ boolean storageAllow = extras.getBoolean("storageAllow");
+ final String strStackTrace = Log.getStackTraceString((Throwable) extras.getSerializable("throwable"));
+ String strSavePath = extras.getString("savePath");
+ String errHeader = storageAllow ?
+ "Crash stack trace saved to " + strSavePath + "." :
+ "Storage permission is required to save crash stack trace!";
+
+ // boolean isFatalError = extras.getBoolean("isFatal", false);
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.error_fatal)
+ .setMessage(errHeader + "\n\n" + strStackTrace)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ finish();
+ }
+ })
+ .setNegativeButton(R.string.global_restart, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ startActivity(new Intent(FatalErrorActivity.this, PojavLoginActivity.class));
+ }
+ })
+ .setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface p1, int p2) {
+ StringSelection errData = new StringSelection(strStackTrace);
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(errData, null);
+
+ finish();
+ }
+ })
+ //.setNegativeButton("Report (not available)", null)
+ .setCancelable(false)
+ .show();
- Tools.showError(this, isFatalError ? R.string.error_fatal : R.string.global_error, th, true);
+ // Tools.showError(this, isFatalError ? R.string.error_fatal : R.string.global_error, th, true);
}
}
diff --git a/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java b/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
index 84e46ff8b8..384ed1e22e 100644
--- a/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
+++ b/app/src/main/java/net/kdt/pojavlaunch/PojavApplication.java
@@ -9,16 +9,44 @@
import android.support.v7.preference.*;
import java.io.*;
import android.content.*;
+import android.support.v4.app.*;
+import android.util.*;
+import net.kdt.pojavlaunch.exit.*;
+import java.time.*;
+import java.text.*;
+import java.util.*;
public class PojavApplication extends Application
{
+ public static String CRASH_REPORT_TAG = "PojavCrashReport";
+
@Override
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread thread, Throwable th) {
- FatalErrorActivity.showError(PojavApplication.this, true, th);
- android.os.Process.killProcess(android.os.Process.myPid());
+ boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
+ File crashFile = new File(storagePermAllowed ? Tools.MAIN_PATH : Tools.datapath, "latestcrash.txt");
+ try {
+ // Write to file, since some devices may not able to show error
+ crashFile.createNewFile();
+ PrintStream crashStream = new PrintStream(crashFile);
+ crashStream.append("PojavLauncher crash report\n");
+ crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()));
+ crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL);
+ crashStream.append(" - Android version: " + Build.VERSION.RELEASE);
+ crashStream.append(" - Crash stack trace:");
+ crashStream.append(Log.getStackTraceString(th));
+ crashStream.close();
+ } catch (Throwable th2) {
+ Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", th2);
+ Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th);
+ }
+
+ FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th);
+ // android.os.Process.killProcess(android.os.Process.myPid());
+
+ MainActivity.fullyExit();
}
});
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2c8838fa7d..48f1390482 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -118,6 +118,7 @@
Load
Name
Remove
+ Restart
Save
This field can\'t be empty