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:
parent
c315439763
commit
3108114b60
10 changed files with 100 additions and 11 deletions
|
@ -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)
|
|
@ -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
|
||||||
|
}
|
|
@ -1,16 +1,30 @@
|
||||||
package com.wbrawner.simplemarkdown.view.activity
|
package com.wbrawner.simplemarkdown.view.activity
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
|
||||||
|
import com.wbrawner.simplemarkdown.utility.init
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
||||||
|
private val analyticsHelper = AnalyticsHelper.init(this)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
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() {
|
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
|
||||||
|
)
|
|
@ -23,8 +23,10 @@ import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
|
||||||
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
||||||
|
import com.wbrawner.simplemarkdown.utility.init
|
||||||
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
||||||
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
||||||
import kotlinx.android.synthetic.main.fragment_main.*
|
import kotlinx.android.synthetic.main.fragment_main.*
|
||||||
|
@ -144,6 +146,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
AnalyticsHelper.init(requireContext()).trackPageView("Edit")
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
|
|
|
@ -13,15 +13,13 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
import com.wbrawner.simplemarkdown.utility.*
|
||||||
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
|
||||||
import com.wbrawner.simplemarkdown.utility.readAssetToString
|
|
||||||
import com.wbrawner.simplemarkdown.utility.toHtml
|
|
||||||
import kotlinx.android.synthetic.main.fragment_markdown_info.*
|
import kotlinx.android.synthetic.main.fragment_markdown_info.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class MarkdownInfoFragment : Fragment() {
|
class MarkdownInfoFragment : Fragment() {
|
||||||
private val errorHandler: ErrorHandler by errorHandlerImpl()
|
private val errorHandler: ErrorHandler by errorHandlerImpl()
|
||||||
|
private lateinit var analyticsHelper: AnalyticsHelper
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -74,6 +72,13 @@ class MarkdownInfoFragment : Fragment() {
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
arguments?.getString(EXTRA_FILE)?.let {
|
||||||
|
AnalyticsHelper.init(requireContext()).trackPageView(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FORMAT_CSS = "<style>" +
|
const val FORMAT_CSS = "<style>" +
|
||||||
"%s" +
|
"%s" +
|
||||||
|
|
|
@ -9,6 +9,8 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
|
||||||
|
import com.wbrawner.simplemarkdown.utility.init
|
||||||
import kotlinx.android.synthetic.main.fragment_settings.*
|
import kotlinx.android.synthetic.main.fragment_settings.*
|
||||||
|
|
||||||
class SettingsContainerFragment : Fragment() {
|
class SettingsContainerFragment : Fragment() {
|
||||||
|
@ -25,4 +27,9 @@ class SettingsContainerFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean = findNavController().navigateUp()
|
override fun onOptionsItemSelected(item: MenuItem): Boolean = findNavController().navigateUp()
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
AnalyticsHelper.init(requireContext()).trackPageView("Settings")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@ import androidx.lifecycle.Observer
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.utility.AnalyticsHelper
|
||||||
import com.wbrawner.simplemarkdown.utility.SupportLinkProvider
|
import com.wbrawner.simplemarkdown.utility.SupportLinkProvider
|
||||||
|
import com.wbrawner.simplemarkdown.utility.init
|
||||||
import kotlinx.android.synthetic.main.fragment_support.*
|
import kotlinx.android.synthetic.main.fragment_support.*
|
||||||
|
|
||||||
class SupportFragment : Fragment() {
|
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) {
|
// if (item.itemId == android.R.id.home) {
|
||||||
// findNavController().navigateUp()
|
// findNavController().navigateUp()
|
||||||
// return true
|
// return true
|
||||||
|
|
|
@ -17,12 +17,6 @@
|
||||||
android:defaultValue="@string/pref_key_dark_mode_auto"
|
android:defaultValue="@string/pref_key_dark_mode_auto"
|
||||||
android:key="@string/pref_key_dark_mode"
|
android:key="@string/pref_key_dark_mode"
|
||||||
android:title="@string/title_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
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="@string/readability_enabled"
|
android:key="@string/readability_enabled"
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_crashlytics_collection_enabled"
|
android:name="firebase_crashlytics_collection_enabled"
|
||||||
android:value="false" />
|
android:value="false" />
|
||||||
|
<meta-data
|
||||||
|
android:name="google_analytics_automatic_screen_reporting_enabled"
|
||||||
|
android:value="false" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -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)
|
Loading…
Reference in a new issue