If you have yet to setup Crashlytics, refer to Setup Firebase Crashlytics On Android For Crash Reporting.
If are not familiar with Android settings UI using PreferenceFragment, refer to Android Settings Preference Using PreferenceFragmentCompat.
To allow runtime/user enable/disable Crashlytics, you must disable Crashlytics through AndroidManifest.xml
.
<manifest ...>
<application ...>
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
</application>
</manifest>
During application startup, check SharedPreference
value to enable Crashlytics if required.
class LuaApp : Application() { override fun onCreate() { super.onCreate() val context = this val settingsSharedPref = PreferenceManager.getDefaultSharedPreferences(context) val isEnablCrashReport = settingsSharedPref.getBoolean(context.getString(R.string.pref_key_enable_crash_report), true) /* if (isEnablCrashReport) { Fabric.with(this, Crashlytics()) } */ val crashlytics = Crashlytics.Builder() .core(CrashlyticsCore.Builder().disabled(!isEnablCrashReport).build()) .build() Fabric.with(this, crashlytics) }}
Edit your PreferenceFragment settings file (e.g. res/xml/pref_settings.xml
) to add SwitchPreference
for Crashlytics.
<PreferenceScreen ...>
<PreferenceCategory
android:title="Privacy"
android:key="pref_key_privacy_settings">
<SwitchPreference
android:key="@string/pref_key_enable_crash_report"
android:title="Enable Crash Report"
android:defaultValue="true"
/>
</PreferenceCategory>
</PreferenceScreen>
Edit your PreferenceFragment
in Activity.
class SettingsFragment: PreferenceFragmentCompat() { override fun onPreferenceTreeClick(preference: Preference): Boolean { return when (preference.key) { getString(R.string.pref_key_enable_crash_report) -> { val isEnablCrashReport = (preference as SwitchPreference).isChecked context?.also { context -> if (isEnablCrashReport) { Fabric.with(context, Crashlytics()) } else { AlertDialog.Builder(context) .setMessage("Need to restart app for changes to take effect.") .setPositiveButton(android.R.string.ok) { dialog, whichButton -> ProcessPhoenix.triggerRebirth(context) } .setNegativeButton(android.R.string.cancel, null) .show() } Log.d(TAG, "isEnableCrashReport=$isEnablCrashReport") } true } else -> { super.onPreferenceTreeClick(preference) } } }}
NOTE: Application restart is required to disable Crashlytics during runtime, where ProcessPhoenix is used.
If you bump into the following exception
java.lang.RuntimeException: Unable to create application com.luasoftware.luapass.LuaApp: io.fabric.sdk.android.services.concurrency.UnmetDependencyException: This app relies on Crashlytics. Please sign up for access at https://fabric.io/sign_up,
install an Android build tool and ask a team member to invite you to this app's organization.
Given that your previous Crashlytics is successful before:
- Don't use
ext.enableCrashlytics = false
in Modulebuild.gradle
'sbuildTypes
(bothdebug
andrelease
) - Don't enable Crashlytics in
AndroidManifest.xml
(make surefirebase_crashlytics_collection_enabled
isfalse
)
NOTE: Refer to Crashlytics Data Collection Policy
Caveats
If you disable Crashlytics
, calling Crashlytics.logException
or Crashlytics.getInstance
will cause the following exception.
java.lang.IllegalStateException: Must Initialize Fabric before using singleton()
at io.fabric.sdk.android.Fabric.singleton(Fabric.java:302)
As of version 2.9.8
, there is no way to check if Crashlytics
is enabled/initialized or not. Write a wrapper function instead.
fun logException(throwable: Throwable) { try { Crashlytics.logException(throwable) } // java.lang.IllegalStateException: Must Initialize Fabric before using singleton() when Crashlytics is disabled catch (e: Exception) { }}
NOTE: Exception log by Crashlytics.logException
is marked as Non-fatals
, where you need to adjust the Event type = "Non-fatals"
filter to view them in Firebase Console - Crashlytics.
UPDATE 2019-08-29:
To prevent Crashlytics.logException
from throwing exception when disabled, initialize with the following initialize with the following during application startup.
val crashlytics = Crashlytics.Builder() .core(CrashlyticsCore.Builder().disabled(true).build()) .build()Fabric.with(this, crashlytics)
References:
- https://firebase.google.com/docs/crashlytics/customize-crash-reports#enable_opt-in_reporting
- https://docs.fabric.io/apple/fabric/data-privacy.html#crashlytics
- Setup Firebase Crashlytics On Android For Crash Reporting
- Android Settings Preference Using PreferenceFragmentCompat
- How to Restart Android App Programmatically (ProcessPhoenix)