Android Allow User Settings to Disable Fabric/Firebase Crashlytics (GDPR)

September 28, 2018

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())
        }
    }
}

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 Module build.gradle’s buildTypes (both debug and release)
  • Don’t enable Crashlytics in AndroidManifest.xml (make sure firebase_crashlytics_collection_enabled is false)

NOTE: Refer to Crashlytics Data Collection Policy

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.