Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 968b5b7

Browse files
authored
Add bug report dialog on crash (#19)
* Add privacy policy dialog before sending report * Add share button to send stacktrace only * Set file chooser intent title * Fix typos in GDPR dialog and rename resources * Make important dialogs not cancelable
1 parent 9f3ec53 commit 968b5b7

9 files changed

Lines changed: 124 additions & 11 deletions

File tree

app/src/main/java/de/codebucket/mkkm/activity/CrashReportActivity.java

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
11
package de.codebucket.mkkm.activity;
22

3+
import android.app.AlertDialog;
4+
import android.content.ActivityNotFoundException;
5+
import android.content.DialogInterface;
36
import android.content.Intent;
7+
import android.net.Uri;
48
import android.os.Build;
59
import android.os.Bundle;
10+
import android.view.Menu;
11+
import android.view.MenuItem;
12+
import android.view.View;
13+
import android.widget.Button;
614
import android.widget.TextView;
15+
import android.widget.Toast;
716

817
import androidx.annotation.Nullable;
918

1019
import java.text.SimpleDateFormat;
1120
import java.util.Date;
1221

1322
import cat.ereza.customactivityoncrash.CustomActivityOnCrash;
23+
import cat.ereza.customactivityoncrash.config.CaocConfig;
1424

1525
import de.codebucket.mkkm.BuildConfig;
1626
import de.codebucket.mkkm.R;
1727

1828
public class CrashReportActivity extends ToolbarActivity {
1929

30+
public static final String REPORT_EMAIL_ADDRESS = "projects@codebucket.de";
31+
public static final String REPORT_EMAIL_SUBJECT = "Błąd w mobileKKM " + BuildConfig.VERSION_NAME;
32+
33+
private String mStacktrace;
34+
2035
@Override
2136
protected void onCreate(@Nullable Bundle savedInstanceState) {
2237
super.onCreate(savedInstanceState);
@@ -26,14 +41,87 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
2641
setupToolbar();
2742
setTitle(R.string.title_activity_crash);
2843

29-
TextView crashReport = findViewById(R.id.crash_report);
44+
mStacktrace = CustomActivityOnCrash.getStackTraceFromIntent(getIntent());
45+
46+
// Create crash report from stacktrace
47+
final CaocConfig caocConfig = CustomActivityOnCrash.getConfigFromIntent(getIntent());
48+
final String crashReport = createErrorReport(mStacktrace);
49+
50+
// Restart app on cancel
51+
Button cancelButton = findViewById(R.id.btn_cancel);
52+
cancelButton.setOnClickListener(new View.OnClickListener() {
53+
@Override
54+
public void onClick(View view) {
55+
Intent intent = new Intent(CrashReportActivity.this, SplashActivity.class);
56+
CustomActivityOnCrash.restartApplicationWithIntent(CrashReportActivity.this, intent, caocConfig);
57+
}
58+
});
59+
60+
// Send crash report to developer
61+
Button sendButton = findViewById(R.id.btn_send);
62+
sendButton.setOnClickListener(new View.OnClickListener() {
63+
@Override
64+
public void onClick(View view) {
65+
new AlertDialog.Builder(CrashReportActivity.this)
66+
.setTitle(R.string.privacy_policy_title)
67+
.setMessage(R.string.privacy_policy_body)
68+
.setCancelable(false)
69+
.setNeutralButton(R.string.read_privacy_policy, new DialogInterface.OnClickListener() {
70+
@Override
71+
public void onClick(DialogInterface dialog, int which) {
72+
try {
73+
// Open website with privacy policy
74+
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.codebucket.de/privacy-policy.html"));
75+
startActivity(intent);
76+
} catch (ActivityNotFoundException exc) {
77+
// Believe me, this actually happens.
78+
Toast.makeText(CrashReportActivity.this, R.string.no_browser_activity, Toast.LENGTH_SHORT).show();
79+
}
80+
}
81+
})
82+
.setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() {
83+
@Override
84+
public void onClick(DialogInterface dialog, int which) {
85+
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + REPORT_EMAIL_ADDRESS));
86+
intent.putExtra(Intent.EXTRA_SUBJECT, REPORT_EMAIL_SUBJECT);
87+
intent.putExtra(Intent.EXTRA_TEXT, crashReport);
88+
startActivity(Intent.createChooser(intent, getString(R.string.intent_chooser_email)));
89+
}
90+
})
91+
.setNegativeButton(R.string.decline, null)
92+
.show();
93+
}
94+
});
95+
96+
// Set report to textview
97+
TextView errorView = findViewById(R.id.crash_error);
3098
String report = getString(R.string.crash_apologise) + ":( \n";
3199
report += "-------------------------------------\n";
32-
report += createErrorReport(getIntent());
33-
crashReport.setText(report);
100+
report += crashReport;
101+
errorView.setText(report);
102+
}
103+
104+
@Override
105+
public boolean onCreateOptionsMenu(Menu menu) {
106+
// Inflate the menu; this adds items to the action bar if it is present.
107+
getMenuInflater().inflate(R.menu.share, menu);
108+
return true;
34109
}
35110

36-
private String createErrorReport(Intent intent) {
111+
@Override
112+
public boolean onOptionsItemSelected(MenuItem item) {
113+
if (item.getItemId() == R.id.action_share) {
114+
Intent intent = new Intent(Intent.ACTION_SEND);
115+
intent.putExtra(Intent.EXTRA_TEXT, mStacktrace);
116+
intent.setType("text/plain");
117+
startActivity(Intent.createChooser(intent, getString(R.string.intent_chooser_share)));
118+
return true;
119+
}
120+
121+
return super.onOptionsItemSelected(item);
122+
}
123+
124+
private String createErrorReport(String stacktrace) {
37125
String versionName = BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")";
38126
String details = "";
39127

@@ -60,8 +148,7 @@ private String createErrorReport(Intent intent) {
60148
details += "\n";
61149

62150
details += "--------- beginning of stacktrace\n";
63-
details += CustomActivityOnCrash.getStackTraceFromIntent(intent);
151+
details += stacktrace;
64152
return details;
65-
66153
}
67154
}

app/src/main/java/de/codebucket/mkkm/activity/LoginActivity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ private void showDisclaimer() {
272272
mAlertDialog = new AlertDialog.Builder(this)
273273
.setTitle(R.string.disclaimer_title)
274274
.setMessage(R.string.disclaimer_body)
275+
.setCancelable(false)
275276
.setNegativeButton(R.string.dialog_dont_show_again, new DialogInterface.OnClickListener() {
276277
@Override
277278
public void onClick(DialogInterface dialog, int which) {

app/src/main/java/de/codebucket/mkkm/activity/WebViewActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathC
111111
intent.addCategory(Intent.CATEGORY_OPENABLE);
112112
intent.setType("image/*");
113113

114-
startActivityForResult(Intent.createChooser(intent, null), FILE_CHOOSER_RESULT_CODE);
114+
startActivityForResult(Intent.createChooser(intent, getString(R.string.intent_chooser_file)), FILE_CHOOSER_RESULT_CODE);
115115
return true;
116116
}
117117
}
File renamed without changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:height="24dp"
3+
android:width="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24">
6+
<path android:fillColor="#fff" android:pathData="M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8A3,3 0 0,0 21,5A3,3 0 0,0 18,2A3,3 0 0,0 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9A3,3 0 0,0 3,12A3,3 0 0,0 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.34C15.11,18.55 15.08,18.77 15.08,19C15.08,20.61 16.39,21.91 18,21.91C19.61,21.91 20.92,20.61 20.92,19A2.92,2.92 0 0,0 18,16.08Z" />
7+
</vector>

app/src/main/res/layout/activity_crash.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
android:layout_height="wrap_content">
2121

2222
<TextView
23-
android:id="@+id/crash_report"
23+
android:id="@+id/crash_error"
2424
android:layout_width="wrap_content"
2525
android:layout_height="wrap_content"
2626
android:fontFamily="monospace"

app/src/main/res/menu/login.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<item
55
android:id="@+id/action_help"
66
android:orderInCategory="100"
7-
android:icon="@drawable/ic_menu_help_circle"
7+
android:icon="@drawable/ic_help_circle"
88
android:title="@string/action_help"
99
app:showAsAction="always" />
1010
</menu>

app/src/main/res/menu/share.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto">
4+
<item
5+
android:id="@+id/action_share"
6+
android:orderInCategory="100"
7+
android:icon="@drawable/ic_share"
8+
android:title="@string/action_share"
9+
app:showAsAction="always" />
10+
</menu>

app/src/main/res/values/strings.xml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@
9898
<!-- Strings related to crash report -->
9999
<string name="title_activity_crash">Raport błędu</string>
100100
<string name="crash_apologise">Wybacz mi, ale nastąpił problem!</string>
101-
<string name="crash_share">Udostępnij</string>
102101
<string name="crash_cancel">Anuluj</string>
103-
<string name="crash_send_report">Wyślij</string>
102+
<string name="crash_send_report">Zgłoś błąd</string>
103+
<string name="action_share">Udostępnij</string>
104104

105105
<!-- Strings related to dialogs -->
106106
<string name="dialog_logout_title">Wylogowanie</string>
@@ -117,6 +117,11 @@
117117
<!-- Disclaimer popup -->
118118
<string name="disclaimer_title">Przeczytaj uważnie!</string>
119119
<string name="disclaimer_body">mobileKKM jest <b>niezależnie od KKM i MPK Kraków opracowaną</b> aplikacją \"open-source\" z kodem zródłowym dostępnym na serwisie GitHub. Jej celem jest ułatwienie obsługi mobilnej wersji Krakowskiej Karty Miejskiej na urządzeniach mobilnych z systemem Android 5.0 lub wyżej.\n\nAplikacja <b>nie udostępnia</b> żadnych danych osobowych osobom trzecim, wszystkie dane są <b>bezpiecznie przesyłane</b> bezpośrednio do strony mobilnej KKM.\n\nKontakt do twórcy:\n<b>David Sn (@divadsn)\n<a href="mailto:projects@codebucket.de">projects@codebucket.de</a></b></string>
120+
<string name="privacy_policy_title">Polityka prywatności</string>
121+
<string name="privacy_policy_body">Ze względu na wprowadzenie Rozporządzenia o Ochronie Danych Osobowych (RODO) chcielibyśmy zwrócić Twoją uwagę na naszą politykę prywatności. Proszę przeczytaj ją uważnie.\n\nMusisz ją zaakceptować, aby przesyłać nam raporty o błędach.</string>
122+
<string name="read_privacy_policy">Przeczytaj politykę prywatności</string>
123+
<string name="accept">Akceptuj</string>
124+
<string name="decline">Odrzuć</string>
120125

121126
<!-- Other strings -->
122127
<string name="progress_login">Logowanie…</string>
@@ -128,4 +133,7 @@
128133
<string name="state_loading">Restartowanie aplikacji…</string>
129134
<string name="expiry_notification">Informacje o upływie ważności biletu</string>
130135
<string name="tickets_provider_name">Zapisane bilety</string>
136+
<string name="intent_chooser_file">Wybierz plik</string>
137+
<string name="intent_chooser_email">Wyślij e-mail</string>
138+
<string name="intent_chooser_share">Udostępnij przez</string>
131139
</resources>

0 commit comments

Comments
 (0)