diff --git a/app/src/main/java/com/github/libretube/MyApp.kt b/app/src/main/java/com/github/libretube/MyApp.kt index fbacea91a..d9e8dba76 100644 --- a/app/src/main/java/com/github/libretube/MyApp.kt +++ b/app/src/main/java/com/github/libretube/MyApp.kt @@ -9,6 +9,7 @@ import android.os.StrictMode.VmPolicy import androidx.work.ExistingPeriodicWorkPolicy import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceKeys +import com.github.libretube.util.ExceptionHandler import com.github.libretube.util.NotificationHelper import com.github.libretube.util.RetrofitInstance @@ -41,6 +42,12 @@ class MyApp : Application() { * initialize the notification listener in the background */ NotificationHelper.enqueueWork(this, ExistingPeriodicWorkPolicy.KEEP) + + /** + * Handler for uncaught exceptions + */ + val exceptionHandler = ExceptionHandler() + Thread.setDefaultUncaughtExceptionHandler(exceptionHandler) } /** diff --git a/app/src/main/java/com/github/libretube/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/activities/MainActivity.kt index b396050fb..d2e9f2b6b 100644 --- a/app/src/main/java/com/github/libretube/activities/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/activities/MainActivity.kt @@ -28,6 +28,7 @@ import coil.ImageLoader import com.github.libretube.Globals import com.github.libretube.R import com.github.libretube.databinding.ActivityMainBinding +import com.github.libretube.dialogs.ErrorDialog import com.github.libretube.fragments.PlayerFragment import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceKeys @@ -152,6 +153,12 @@ class MainActivity : AppCompatActivity() { binding.toolbar.title = ThemeHelper.getStyledAppName(this) } + + /** + * handle error logs + */ + val log = PreferenceHelper.getErrorLog() + if (log != "") ErrorDialog().show(supportFragmentManager, null) } private fun removeSearchFocus() { diff --git a/app/src/main/java/com/github/libretube/dialogs/ErrorDialog.kt b/app/src/main/java/com/github/libretube/dialogs/ErrorDialog.kt new file mode 100644 index 000000000..cd0ac0b01 --- /dev/null +++ b/app/src/main/java/com/github/libretube/dialogs/ErrorDialog.kt @@ -0,0 +1,36 @@ +package com.github.libretube.dialogs + +import android.app.Dialog +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.os.Bundle +import android.widget.Toast +import androidx.fragment.app.DialogFragment +import com.github.libretube.R +import com.github.libretube.preferences.PreferenceHelper +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +class ErrorDialog : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val errorLog = PreferenceHelper.getErrorLog() + // reset the error log + PreferenceHelper.saveErrorLog("") + + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.error_occurred) + .setMessage(errorLog) + .setNegativeButton(R.string.okay, null) + .setPositiveButton(R.string.copy) { _, _ -> + /** + * copy the error log to the clipboard + */ + val clipboard: ClipboardManager = + context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText(context?.getString(R.string.copied), errorLog) + clipboard.setPrimaryClip(clip) + Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show() + } + .show() + } +} diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt index a28ebc603..00e4800f0 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt @@ -227,6 +227,14 @@ object PreferenceHelper { return getString(PreferenceKeys.LAST_STREAM_VIDEO_ID, "") } + fun saveErrorLog(log: String) { + editor.putString(PreferenceKeys.ERROR_LOG, log).commit() + } + + fun getErrorLog(): String { + return getString(PreferenceKeys.ERROR_LOG, "") + } + private fun getDefaultSharedPreferences(context: Context): SharedPreferences { return PreferenceManager.getDefaultSharedPreferences(context) } diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt index 4220f29ac..820172302 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt @@ -81,4 +81,9 @@ object PreferenceKeys { const val CLEAR_SEARCH_HISTORY = "clear_search_history" const val CLEAR_WATCH_HISTORY = "clear_watch_history" const val CLEAR_WATCH_POSITIONS = "clear_watch_positions" + + /** + * Error logs + */ + const val ERROR_LOG = "error_log" } diff --git a/app/src/main/java/com/github/libretube/util/ExceptionHandler.kt b/app/src/main/java/com/github/libretube/util/ExceptionHandler.kt new file mode 100644 index 000000000..da2e17235 --- /dev/null +++ b/app/src/main/java/com/github/libretube/util/ExceptionHandler.kt @@ -0,0 +1,17 @@ +package com.github.libretube.util + +import android.util.Log +import com.github.libretube.preferences.PreferenceHelper +import kotlin.system.exitProcess + +class ExceptionHandler : Thread.UncaughtExceptionHandler { + override fun uncaughtException(thread: Thread, exc: Throwable) { + Log.e("bnyro", exc.stackTraceToString()) + // sav ethe error log + PreferenceHelper.saveErrorLog(exc.stackTraceToString()) + // finish the app + System.exit(0) + android.os.Process.killProcess(android.os.Process.myPid()) + exitProcess(0) + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 436dc8e71..763900e06 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,4 +287,6 @@ Translate Help by translating the app to the language you speak No results found. + Error occurred + Copied \ No newline at end of file