diff --git a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt
index 8c6a877a1..3c8c27d31 100644
--- a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt
@@ -20,8 +20,8 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.di.Injectable
-
import com.keylesspalace.tusky.util.NotificationHelper
+import net.accelf.yuito.CustomUncaughtExceptionHandler
import javax.inject.Inject
class SplashActivity : AppCompatActivity(), Injectable {
@@ -32,6 +32,9 @@ class SplashActivity : AppCompatActivity(), Injectable {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ val customUncaughtExceptionHandler = CustomUncaughtExceptionHandler(applicationContext)
+ Thread.setDefaultUncaughtExceptionHandler(customUncaughtExceptionHandler)
+
/** delete old notification channels */
NotificationHelper.deleteLegacyNotificationChannels(this, accountManager)
diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt
index 95b9251fc..ff3d3a69e 100644
--- a/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt
@@ -18,6 +18,7 @@ package com.keylesspalace.tusky.fragment.preference
import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
+import com.keylesspalace.tusky.ComposeActivity
import com.keylesspalace.tusky.PreferencesActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.util.ThemeUtils
@@ -73,6 +74,8 @@ class PreferencesFragment : PreferenceFragmentCompat() {
val botDrawable = botIndicatorPreference.context.getDrawable(R.drawable.ic_bot_24dp)
ThemeUtils.setDrawableTint(context, botDrawable, R.attr.toolbar_icon_tint)
botIndicatorPreference.icon = botDrawable
+
+ updateStackTracePreference()
}
override fun onResume() {
@@ -105,6 +108,36 @@ class PreferencesFragment : PreferenceFragmentCompat() {
}
+ private fun updateStackTracePreference() {
+
+ val stackTraceCategory = requirePreference("stackTraceCategory")
+
+ val sharedPreferences = preferenceManager.sharedPreferences
+ val stackTrace = sharedPreferences.getString("stack_trace", null)
+ if (stackTrace.isNullOrEmpty()) {
+ preferenceScreen.removePreference(stackTraceCategory)
+ } else {
+ val sendCrashReportPreference = requirePreference("sendCrashReport")
+ sendCrashReportPreference.setOnPreferenceClickListener {
+ activity?.let { activity ->
+ val intent = ComposeActivity.IntentBuilder()
+ .tootText("@ars42525@odakyu.app $stackTrace".substring(0, 400))
+ .contentWarning("Yuito StackTrace")
+ .build(activity)
+ activity.startActivity(intent)
+ sharedPreferences.edit()
+ .remove("stack_trace")
+ .apply()
+ }
+ true
+ }
+
+ val stackTracePreference = requirePreference("stackTrace")
+ stackTracePreference.summary = stackTrace
+ }
+
+ }
+
companion object {
fun newInstance(): PreferencesFragment {
return PreferencesFragment()
diff --git a/app/src/main/java/net/accelf/yuito/CustomUncaughtExceptionHandler.java b/app/src/main/java/net/accelf/yuito/CustomUncaughtExceptionHandler.java
new file mode 100644
index 000000000..4a67cb2f9
--- /dev/null
+++ b/app/src/main/java/net/accelf/yuito/CustomUncaughtExceptionHandler.java
@@ -0,0 +1,34 @@
+package net.accelf.yuito;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class CustomUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
+
+ private Context context;
+ private Thread.UncaughtExceptionHandler mDefaultUncaughtExceptionHandler;
+
+ public CustomUncaughtExceptionHandler(Context context) {
+ this.context = context;
+
+ mDefaultUncaughtExceptionHandler = Thread
+ .getDefaultUncaughtExceptionHandler();
+ }
+
+ @Override
+ public void uncaughtException(Thread thread, Throwable e) {
+ StringWriter stringWriter = new StringWriter();
+ e.printStackTrace(new PrintWriter(stringWriter));
+ String stackTrace = stringWriter.toString();
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ preferences.edit().putString("stack_trace", stackTrace).apply();
+
+ mDefaultUncaughtExceptionHandler.uncaughtException(thread, e);
+ }
+
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fd4aeab92..5022b33ee 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -224,6 +224,8 @@
Experimental Settings
Increase offscreenPageLimit of ViewPager
Use home timeline streaming
+ Stacktrace
+ Send crash report to developer
Dark
Light
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 69b44ae40..4d15a5005 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -125,4 +125,17 @@
android:key="useHTLStream"
android:title="@string/pref_title_experimental_htl_streaming" />
+
+
+
+
+
+
+