From: Damyan Ivanov Date: Mon, 11 Feb 2019 21:30:28 +0000 (+0200) Subject: add crash handling dialog with optional sending of the crash to the author X-Git-Tag: v0.7~83 X-Git-Url: https://git.ktnx.net/?p=mobile-ledger.git;a=commitdiff_plain;h=0974c053bfa714958b1ce911865907085232a6d9 add crash handling dialog with optional sending of the crash to the author --- diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/CrashReportDialogFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/CrashReportDialogFragment.java new file mode 100644 index 00000000..08756261 --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/ui/CrashReportDialogFragment.java @@ -0,0 +1,88 @@ +package net.ktnx.mobileledger.ui; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ScrollView; +import android.widget.TextView; + +import net.ktnx.mobileledger.R; +import net.ktnx.mobileledger.utils.Globals; + +public class CrashReportDialogFragment extends DialogFragment { + private String mCrashReportText; + private ScrollView repScroll = null; + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + + if (savedInstanceState != null) + mCrashReportText = savedInstanceState.getString("crash_text"); + + View view = inflater.inflate(R.layout.crash_dialog, null); + ((TextView) view.findViewById(R.id.textCrashReport)).setText(mCrashReportText); + repScroll = view.findViewById(R.id.scrollText); + builder.setTitle(R.string.crash_dialog_title).setView(view) + .setPositiveButton(R.string.btn_send_crash_report, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // still nothing + Intent email = new Intent(Intent.ACTION_SEND); + email.putExtra(Intent.EXTRA_EMAIL, + new String[]{Globals.developerEmail}); + email.putExtra(Intent.EXTRA_SUBJECT, "MoLe crash report"); + email.putExtra(Intent.EXTRA_TEXT, mCrashReportText); + email.setType("message/rfc822"); + startActivity(Intent.createChooser(email, + getResources().getString(R.string.send_crash_via))); + } + }) + .setNegativeButton(R.string.btn_not_now, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + CrashReportDialogFragment.this.getDialog().cancel(); + } + }) + .setNeutralButton(R.string.btn_show_report, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }); + + AlertDialog dialog = builder.create(); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogIinterface) { + dialog.getButton(AlertDialog.BUTTON_NEUTRAL) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (repScroll != null) { + repScroll.setVisibility(View.VISIBLE); + v.setVisibility(View.GONE); + } + } + }); + } + }); + return dialog; + } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString("crash_text", mCrashReportText); + } + public void setCrashReportText(String text) { + mCrashReportText = text; + } +} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/CrashReportingActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/CrashReportingActivity.java new file mode 100644 index 00000000..0d72499d --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/CrashReportingActivity.java @@ -0,0 +1,34 @@ +package net.ktnx.mobileledger.ui.activity; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +import net.ktnx.mobileledger.ui.CrashReportDialogFragment; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class CrashReportingActivity extends AppCompatActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + + Log.e(null, sw.toString()); + + CrashReportDialogFragment df = new CrashReportDialogFragment(); + df.setCrashReportText(sw.toString()); + df.show(getSupportFragmentManager(), "crash_report"); + } + }); + Log.d("crash", "Uncaught exception handler set"); + } +} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java index 0fe14026..02eb8096 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java @@ -30,7 +30,6 @@ import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewPager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; @@ -53,7 +52,7 @@ import java.lang.ref.WeakReference; import java.text.DateFormat; import java.util.Date; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends CrashReportingActivity { DrawerLayout drawer; private FragmentManager fragmentManager; private TextView tvLastUpdate; diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionActivity.java index c907b891..04cabd6b 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionActivity.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionActivity.java @@ -24,7 +24,6 @@ import android.support.design.widget.BaseTransientBottomBar; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.DialogFragment; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.InputType; @@ -73,7 +72,7 @@ import java.util.Objects; * TODO: nicer swiping removal with visual feedback * */ -public class NewTransactionActivity extends AppCompatActivity +public class NewTransactionActivity extends CrashReportingActivity implements TaskCallback, DescriptionSelectedCallback { private static SaveTransactionTask saver; private TableLayout table; diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java index dc36fc71..3a4a5154 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; @@ -51,7 +50,7 @@ import java.util.Collections; * item details. On tablets, the activity presents the list of items and * item details side-by-side using two vertical panes. */ -public class ProfileListActivity extends AppCompatActivity { +public class ProfileListActivity extends CrashReportingActivity { public static final String ARG_ACTION = "action"; public static final String ARG_PROFILE_INDEX = "profile_index"; diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java b/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java index ecbffda4..8a2c8366 100644 --- a/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java +++ b/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java @@ -39,6 +39,7 @@ public final class Globals { @ColorInt public static int primaryDark, defaultTextColor; public static String[] monthNames; + public static String developerEmail = "dam+mole-crash@ktnx.net"; private static SimpleDateFormat ledgerDateFormatter = new SimpleDateFormat("yyyy/MM/dd", Locale.US); private static Pattern reLedgerDate = diff --git a/app/src/main/res/layout/crash_dialog.xml b/app/src/main/res/layout/crash_dialog.xml new file mode 100644 index 00000000..2d4bb84f --- /dev/null +++ b/app/src/main/res/layout/crash_dialog.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index e735aed0..7a18b4da 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -88,5 +88,15 @@ Въвеждането на потребителско име е задължително когато се използва удостоверяване Паролата е задължителна Позволяване на добавянето на нови трансакции + Изпращане на доклада чрез: + Желаете ли да изпратите доклад за грешката на автора? Това ще помогне за диагностициране и отстраняване на проблема. + Срив + Не сега + Изпращане... + MoLe се срина + Съдържание на доклада: + (Само за преглед) + Потвърждаване на избора + Скриване на маркираните сметки diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fa60329e..54db4cc6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -133,4 +133,12 @@ Posting of new transactions enabled (Read only) + Crash report contents: + MoLe chashed + Send... + Not now + Crash + Would you like to send the crash report to the developer? This would help diagnosing and fixing the problem. + Send crash report via: + Show report