--- /dev/null
+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;
+ }
+}
--- /dev/null
+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");
+ }
+}
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;
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;
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;
* 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;
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;
* 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";
@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 =
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingStart="8dp"
+ android:paddingTop="8dp"
+ android:paddingEnd="8dp">
+
+ <ScrollView
+ android:id="@+id/scrollText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="9"
+ android:background="@color/table_row_light_bg"
+ android:scrollbars="horizontal|vertical"
+ android:visibility="gone">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="8dp">
+
+ <TextView
+ android:id="@+id/textCrashReport"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Example crash report text goes here"
+ tools:ignore="HardcodedText" />
+ </LinearLayout>
+ </ScrollView>
+
+ <TextView
+ android:id="@+id/textView7"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/crash_send_question" />
+
+</LinearLayout>
\ No newline at end of file
<string name="err_profile_user_name_empty">Въвеждането на потребителско име е задължително когато се използва удостоверяване</string>
<string name="err_profile_password_empty">Паролата е задължителна</string>
<string name="posting_permitted">Позволяване на добавянето на нови трансакции</string>
+ <string name="send_crash_via">Изпращане на доклада чрез:</string>
+ <string name="crash_send_question">Желаете ли да изпратите доклад за грешката на автора? Това ще помогне за диагностициране и отстраняване на проблема.</string>
+ <string name="crash_app_condensed_label">Срив</string>
+ <string name="btn_not_now">Не сега</string>
+ <string name="btn_send_crash_report">Изпращане...</string>
+ <string name="crash_dialog_title">MoLe се срина</string>
+ <string name="crash_report_contents_label">Съдържание на доклада:</string>
+ <string name="profile_subitlte_read_only">(Само за преглед)</string>
+ <string name="menu_acc_summary_confirm_selection_title">Потвърждаване на избора</string>
+ <string name="menu_acc_summary_hide_selected_title">Скриване на маркираните сметки</string>
</resources>
</string-array>
<string name="posting_permitted">Posting of new transactions enabled</string>
<string name="profile_subitlte_read_only">(Read only)</string>
+ <string name="crash_report_contents_label">Crash report contents:</string>
+ <string name="crash_dialog_title">MoLe chashed</string>
+ <string name="btn_send_crash_report">Send...</string>
+ <string name="btn_not_now">Not now</string>
+ <string name="crash_app_condensed_label">Crash</string>
+ <string name="crash_send_question">Would you like to send the crash report to the developer? This would help diagnosing and fixing the problem.</string>
+ <string name="send_crash_via">Send crash report via:</string>
+ <string name="btn_show_report">Show report</string>
</resources>