Replace Crashlytics with Sentry
Signed-off-by: William Brawner <me@wbrawner.com>
This commit is contained in:
parent
0e70364c6e
commit
1cc0063b15
11 changed files with 59 additions and 31 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@
|
||||||
*.log
|
*.log
|
||||||
keystore.properties
|
keystore.properties
|
||||||
*.jks
|
*.jks
|
||||||
|
sentry.properties
|
||||||
|
|
|
@ -3,7 +3,7 @@ apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
apply plugin: 'jacoco'
|
apply plugin: 'jacoco'
|
||||||
apply plugin: 'com.google.firebase.crashlytics'
|
apply plugin: 'io.sentry.android.gradle'
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
try {
|
try {
|
||||||
|
@ -44,6 +44,9 @@ android {
|
||||||
versionCode 26
|
versionCode 26
|
||||||
versionName "0.8.4"
|
versionName "0.8.4"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
manifestPlaceholders = [
|
||||||
|
sentryDsn: "https://399270639b2e4b10a028a2be9192d1d3@sentry.brawner.dev/2"
|
||||||
|
]
|
||||||
buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false"
|
buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false"
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
@ -99,11 +102,10 @@ dependencies {
|
||||||
implementation 'com.commonsware.cwac:anddown:0.3.0'
|
implementation 'com.commonsware.cwac:anddown:0.3.0'
|
||||||
implementation 'com.android.billingclient:billing:2.2.0'
|
implementation 'com.android.billingclient:billing:2.2.0'
|
||||||
implementation 'com.google.firebase:firebase-core:17.3.0'
|
implementation 'com.google.firebase:firebase-core:17.3.0'
|
||||||
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta04'
|
|
||||||
implementation 'com.google.firebase:firebase-analytics:17.3.0'
|
|
||||||
implementation "androidx.core:core-ktx:1.2.0"
|
implementation "androidx.core:core-ktx:1.2.0"
|
||||||
implementation 'androidx.browser:browser:1.2.0'
|
implementation 'androidx.browser:browser:1.2.0'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
implementation 'io.sentry:sentry-android:2.1.6'
|
||||||
def coroutines_version = "1.3.0-RC2"
|
def coroutines_version = "1.3.0-RC2"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
|
@ -117,6 +119,7 @@ dependencies {
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
jacoco {
|
jacoco {
|
||||||
|
|
|
@ -67,7 +67,10 @@
|
||||||
<activity android:name=".view.activity.SupportActivity" />
|
<activity android:name=".view.activity.SupportActivity" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_crashlytics_collection_enabled"
|
android:name="io.sentry.dsn"
|
||||||
|
android:value="${sentryDsn}" />
|
||||||
|
<meta-data
|
||||||
|
android:name="io.sentry.auto-init"
|
||||||
android:value="false" />
|
android:value="false" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
First and foremost, Simple Markdown DOES NOT collect any personally identifiable information. The
|
First and foremost, Simple Markdown DOES NOT collect any personally identifiable information. The
|
||||||
internet access permission is requested primarily for retrieving images from the internet in
|
internet access permission is requested primarily for retrieving images from the internet in
|
||||||
case you embed them in your markdown, but it also allows me to send automated error and crash
|
case you embed them in your markdown, but it also allows me to send automated error and crash
|
||||||
reports to myself whenever the app runs into an issue. These error reports are opt-out, and are
|
reports to myself whenever the app runs into an issue. These automated reports are powered by my own
|
||||||
powered by [Firebase Crashlytics] (https://firebase.google.com/docs/crashlytics/), which is a
|
self-hosted version of [Sentry] (https://sentry.io/), which is a free and open source error
|
||||||
free error reporting solution provided by Google. These error reports are used exclusively for
|
reporting solution. These error reports are used exclusively for fixing problems that occur while
|
||||||
fixing problems that occur while you're using the app, along with some analytics info like how
|
you're using the app. For more information on the kinds of data that may be sent in these automated
|
||||||
long you use the app for, how often, and which features of the app you use. This helps me to
|
error reports, please see the [relevant documentation](https://docs.sentry.io/platforms/android/#context)
|
||||||
determine how to spend my very limited time on building out new features. I'll have to defer to
|
on Sentry's website. If you would like to opt-out of these error reports, please visit the in-app
|
||||||
[Google's Privacy Policy](https://policies.google.com/privacy) to explain how they handle the
|
settings page to disable the toggle for error reports.
|
||||||
data. As for me, I don't knowingly or willingly sell or trade your data.
|
|
||||||
|
|
|
@ -2,15 +2,19 @@ package com.wbrawner.simplemarkdown
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.StrictMode
|
import android.os.StrictMode
|
||||||
import com.wbrawner.simplemarkdown.utility.CrashlyticsErrorHandler
|
import androidx.preference.PreferenceManager
|
||||||
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
|
import com.wbrawner.simplemarkdown.utility.SentryErrorHandler
|
||||||
|
|
||||||
class MarkdownApplication : Application() {
|
class MarkdownApplication : Application() {
|
||||||
val errorHandler: ErrorHandler by lazy {
|
val errorHandler: ErrorHandler by lazy {
|
||||||
CrashlyticsErrorHandler()
|
SentryErrorHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
.getBoolean(getString(R.string.error_reports_enabled), true)
|
||||||
|
errorHandler.init(this, enableErrorReports)
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
|
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
|
||||||
.detectAll()
|
.detectAll()
|
||||||
|
|
|
@ -1,27 +1,44 @@
|
||||||
package com.wbrawner.simplemarkdown.utility
|
package com.wbrawner.simplemarkdown.utility
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|
||||||
import com.wbrawner.simplemarkdown.BuildConfig
|
import com.wbrawner.simplemarkdown.BuildConfig
|
||||||
|
import io.sentry.android.core.SentryAndroid
|
||||||
|
import io.sentry.core.Sentry
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
interface ErrorHandler {
|
interface ErrorHandler {
|
||||||
|
fun init(context: Context, enable: Boolean)
|
||||||
fun enable(enable: Boolean)
|
fun enable(enable: Boolean)
|
||||||
fun reportException(t: Throwable, message: String? = null)
|
fun reportException(t: Throwable, message: String? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CrashlyticsErrorHandler : ErrorHandler {
|
class SentryErrorHandler : ErrorHandler {
|
||||||
private val crashlytics = FirebaseCrashlytics.getInstance()
|
private lateinit var enabled: AtomicBoolean
|
||||||
|
|
||||||
|
override fun init(context: Context, enable: Boolean) {
|
||||||
|
enabled = AtomicBoolean(enable)
|
||||||
|
SentryAndroid.init(context) { options ->
|
||||||
|
options.setBeforeSend { event, _ ->
|
||||||
|
if (enabled.get()) {
|
||||||
|
event
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun enable(enable: Boolean) {
|
override fun enable(enable: Boolean) {
|
||||||
crashlytics.setCrashlyticsCollectionEnabled(enable)
|
enabled.set(enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reportException(t: Throwable, message: String?) {
|
override fun reportException(t: Throwable, message: String?) {
|
||||||
@Suppress("ConstantConditionIf")
|
@Suppress("ConstantConditionIf")
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Log.e("CrashlyticsErrorHandler", "Caught exception: $message", t)
|
Log.e("SentryErrorHandler", "Caught exception: $message", t)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
crashlytics.recordException(t)
|
Sentry.captureException(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@ package com.wbrawner.simplemarkdown.view.activity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
|
||||||
class SettingsActivity : AppCompatActivity() {
|
class SettingsActivity : AppCompatActivity() {
|
||||||
|
@ -12,9 +11,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_settings)
|
setContentView(R.layout.activity_settings)
|
||||||
setSupportActionBar(findViewById(R.id.toolbar))
|
setSupportActionBar(findViewById(R.id.toolbar))
|
||||||
if (supportActionBar != null) {
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<string name="action_lock_swipe">Lock Swiping</string>
|
<string name="action_lock_swipe">Lock Swiping</string>
|
||||||
<string name="action_select">Select</string>
|
<string name="action_select">Select</string>
|
||||||
<string name="action_privacy">Privacy</string>
|
<string name="action_privacy">Privacy</string>
|
||||||
<string name="error_reports_enabled">crashlytics.enable</string>
|
<string name="error_reports_enabled">errors.enable</string>
|
||||||
<string name="pref_title_error_reports">Enable automated error reports</string>
|
<string name="pref_title_error_reports">Enable automated error reports</string>
|
||||||
<string name="pref_error_reports_off">Error reports will not be sent</string>
|
<string name="pref_error_reports_off">Error reports will not be sent</string>
|
||||||
<string name="pref_error_reports_on">Error reports will be sent</string>
|
<string name="pref_error_reports_on">Error reports will be sent</string>
|
||||||
|
|
|
@ -7,9 +7,9 @@ buildscript {
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||||
classpath 'com.google.gms:google-services:4.3.3'
|
classpath 'com.google.gms:google-services:4.3.3'
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta04'
|
classpath 'io.sentry:sentry-android-gradle-plugin:1.7.34'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
#Thu Mar 19 08:56:07 CST 2020
|
#Wed Jun 10 07:53:53 MST 2020
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||||
|
|
4
sentry.properties.sample
Normal file
4
sentry.properties.sample
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defaults.url=https://sentry.brawner.dev/
|
||||||
|
defaults.project=simplemarkdown
|
||||||
|
defaults.org=wbrawner
|
||||||
|
auth.token=
|
Loading…
Reference in a new issue