Capture uncaught exceptions on-device and let the user submit them, by hand, as a Gitea issue — no network access, no auto-upload (the app holds no INTERNET permission). Closes prod-readiness item 10; the issue templates also close item 7. - CrashReporter: uncaught-exception handler installed first in CalendulaApp.onCreate so startup crashes are caught too. Persists an allowlist-only report (app/Android/device version, locale, time, stack trace — nothing else) to filesDir/crash, then chains to the previous handler so the process still dies normally. Crash-loop detection + markHealthy reset. - buildCrashReport is pure/testable; CrashReportBuilderTest asserts the header is exactly the allowlisted lines (guards against PII creep). - Surfacing: next-launch dialog showing the full report verbatim (the privacy backstop) with a dismissed-marker so it doesn't nag; a Settings "Report a problem" row; and a minimal standalone CrashReportActivity that MainActivity routes to on a startup crash-loop, kept clear of the Hilt graph / DataStore theme. - submitCrashReport copies the report to the clipboard and opens the prefilled Gitea issues/new URL (long traces fall back to paste). - .gitea/ISSUE_TEMPLATE: crash_report, bug_report, feature_request. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21 lines
622 B
Kotlin
21 lines
622 B
Kotlin
package de.jeanlucmakiola.calendula
|
|
|
|
import android.app.Application
|
|
import dagger.hilt.android.HiltAndroidApp
|
|
import de.jeanlucmakiola.calendula.data.crash.CrashReporter
|
|
|
|
/**
|
|
* Application entry point. Registered as android:name=".CalendulaApp"
|
|
* in AndroidManifest.xml. Hilt initializes its component graph here.
|
|
*/
|
|
@HiltAndroidApp
|
|
class CalendulaApp : Application() {
|
|
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
// Install first thing so startup crashes are captured too (privacy-
|
|
// respecting, on-device; the user submits the report by hand).
|
|
CrashReporter.install(this)
|
|
}
|
|
}
|