Improve analytics

- Automatic page view tracking wasn't helpful since it was based on the Activities viewed, and SimpleMarkdown is a single-Activity app, so page views are now tracked manually
- User preferences are now reported so I can remove preferences that aren't used and focus my time on features that are actively used
- Opting out of crash reports is no longer possible. I need crash reports to be able to improve the app. It would also simplify the code a bit to not need to take that into account. Existing opt-outs will be respected but moving forward, new users will need to download the app from Fdroid if they'd like to avoid interactions with Google.
This commit is contained in:
William Brawner 2022-10-23 23:44:02 -06:00
parent c315439763
commit 3108114b60
10 changed files with 100 additions and 11 deletions

View file

@ -0,0 +1,19 @@
package com.wbrawner.simplemarkdown.utility
import android.content.Context
import com.wbrawner.simplemarkdown.BuildConfig
import timber.log.Timber
class NoopAnalyticsHelper(context: Context): AnalyticsHelper() {
override fun setUserProperty(name: String, value: String) {
if (BuildConfig.DEBUG) {
Timber.tag("NoopAnalyticsHelper").d("setting user property $name to $value")
}
}
override fun trackPageView(name: String) {
Timber.tag("NoopAnalyticsHelper").d("user viewed $name page")
}
}
fun AnalyticsHelper.Companion.init(context: Context) = NoopAnalyticsHelper(context)

View file

@ -0,0 +1,8 @@
package com.wbrawner.simplemarkdown.utility
abstract class AnalyticsHelper {
abstract fun setUserProperty(name: String, value: String)
abstract fun trackPageView(name: String)
companion object
}

View file

@ -1,16 +1,30 @@
package com.wbrawner.simplemarkdown.view.activity
import android.content.Context
import android.os.Bundle
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
import com.wbrawner.simplemarkdown.utility.init
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
private val analyticsHelper = AnalyticsHelper.init(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
analyticsHelper.setUserProperty("autosave", sharedPreferences.getBoolean("autosave", true).toString())
val usingCustomCss = !getStringPref(R.string.pref_custom_css, null).isNullOrBlank()
analyticsHelper.setUserProperty("using_custom_css", usingCustomCss.toString())
val darkModeSetting = getStringPref(R.string.pref_key_dark_mode, "auto").toString()
analyticsHelper.setUserProperty("dark_mode", darkModeSetting)
analyticsHelper.setUserProperty("error_reports_enabled", getBooleanPref(R.string.pref_key_error_reports_enabled, true).toString())
analyticsHelper.setUserProperty("readability_enabled", getBooleanPref(R.string.readability_enabled, false).toString())
}
override fun onBackPressed() {
@ -19,3 +33,13 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
}
}
}
fun Context.getBooleanPref(@StringRes key: Int, defaultValue: Boolean) = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
getString(key),
defaultValue
)
fun Context.getStringPref(@StringRes key: Int, defaultValue: String?) = PreferenceManager.getDefaultSharedPreferences(this).getString(
getString(key),
defaultValue
)

View file

@ -23,8 +23,10 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
import com.wbrawner.simplemarkdown.utility.ErrorHandler
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
import com.wbrawner.simplemarkdown.utility.init
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
import kotlinx.android.synthetic.main.fragment_main.*
@ -144,6 +146,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
override fun onStart() {
super.onStart()
AnalyticsHelper.init(requireContext()).trackPageView("Edit")
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(requireContext())

View file

@ -13,15 +13,13 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.ErrorHandler
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
import com.wbrawner.simplemarkdown.utility.readAssetToString
import com.wbrawner.simplemarkdown.utility.toHtml
import com.wbrawner.simplemarkdown.utility.*
import kotlinx.android.synthetic.main.fragment_markdown_info.*
import kotlinx.coroutines.launch
class MarkdownInfoFragment : Fragment() {
private val errorHandler: ErrorHandler by errorHandlerImpl()
private lateinit var analyticsHelper: AnalyticsHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -74,6 +72,13 @@ class MarkdownInfoFragment : Fragment() {
return super.onOptionsItemSelected(item)
}
override fun onStart() {
super.onStart()
arguments?.getString(EXTRA_FILE)?.let {
AnalyticsHelper.init(requireContext()).trackPageView(it)
}
}
companion object {
const val FORMAT_CSS = "<style>" +
"%s" +

View file

@ -9,6 +9,8 @@ import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
import com.wbrawner.simplemarkdown.utility.init
import kotlinx.android.synthetic.main.fragment_settings.*
class SettingsContainerFragment : Fragment() {
@ -25,4 +27,9 @@ class SettingsContainerFragment : Fragment() {
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = findNavController().navigateUp()
override fun onStart() {
super.onStart()
AnalyticsHelper.init(requireContext()).trackPageView("Settings")
}
}

View file

@ -13,7 +13,9 @@ import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
import com.wbrawner.simplemarkdown.utility.SupportLinkProvider
import com.wbrawner.simplemarkdown.utility.init
import kotlinx.android.synthetic.main.fragment_support.*
class SupportFragment : Fragment() {
@ -51,7 +53,12 @@ class SupportFragment : Fragment() {
})
}
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun onStart() {
super.onStart()
AnalyticsHelper.init(requireContext()).trackPageView("Support")
}
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
// if (item.itemId == android.R.id.home) {
// findNavController().navigateUp()
// return true

View file

@ -17,12 +17,6 @@
android:defaultValue="@string/pref_key_dark_mode_auto"
android:key="@string/pref_key_dark_mode"
android:title="@string/title_dark_mode" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/pref_key_error_reports_enabled"
android:summaryOff="@string/pref_error_reports_off"
android:summaryOn="@string/pref_error_reports_on"
android:title="@string/pref_title_error_reports" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/readability_enabled"

View file

@ -8,6 +8,9 @@
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
<meta-data
android:name="google_analytics_automatic_screen_reporting_enabled"
android:value="false" />
</application>
</manifest>

View file

@ -0,0 +1,19 @@
package com.wbrawner.simplemarkdown.utility
import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
class FirebaseAnalyticsHelper(context: Context): AnalyticsHelper() {
private val firebaseAnalytics = FirebaseAnalytics.getInstance(context)
override fun setUserProperty(name: String, value: String) {
firebaseAnalytics.setUserProperty(name, value)
}
override fun trackPageView(name: String) {
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, Bundle().apply { putString(FirebaseAnalytics.Param.SCREEN_NAME, name) })
}
}
fun AnalyticsHelper.Companion.init(context: Context) = FirebaseAnalyticsHelper(context)