diff --git a/.gitignore b/.gitignore
index 07544b8..6a955c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
*.log
keystore.properties
*.jks
+sentry.properties
diff --git a/app/build.gradle b/app/build.gradle
index a5fb7f6..e9a91d7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'jacoco'
-apply plugin: 'com.google.firebase.crashlytics'
+apply plugin: 'io.sentry.android.gradle'
def keystoreProperties = new Properties()
try {
@@ -44,6 +44,9 @@ android {
versionCode 26
versionName "0.8.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ manifestPlaceholders = [
+ sentryDsn: "https://399270639b2e4b10a028a2be9192d1d3@sentry.brawner.dev/2"
+ ]
buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false"
}
signingConfigs {
@@ -99,11 +102,10 @@ dependencies {
implementation 'com.commonsware.cwac:anddown:0.3.0'
implementation 'com.android.billingclient:billing:2.2.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.browser:browser:1.2.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'io.sentry:sentry-android:2.1.6'
def coroutines_version = "1.3.0-RC2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
@@ -117,6 +119,7 @@ dependencies {
apply plugin: 'com.google.gms.google-services'
repositories {
mavenCentral()
+ jcenter()
}
jacoco {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 44868d3..46a1d34 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -67,7 +67,10 @@
+
diff --git a/app/src/main/assets/Privacy Policy.md b/app/src/main/assets/Privacy Policy.md
index a542f31..b631fca 100644
--- a/app/src/main/assets/Privacy Policy.md
+++ b/app/src/main/assets/Privacy Policy.md
@@ -1,13 +1,12 @@
## Privacy Policy
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
- 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
- powered by [Firebase Crashlytics] (https://firebase.google.com/docs/crashlytics/), which is a
- free error reporting solution provided by Google. These error reports are used exclusively for
- fixing problems that occur while you're using the app, along with some analytics info like how
- long you use the app for, how often, and which features of the app you use. This helps me to
- determine how to spend my very limited time on building out new features. I'll have to defer to
- [Google's Privacy Policy](https://policies.google.com/privacy) to explain how they handle the
- data. As for me, I don't knowingly or willingly sell or trade your data.
+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
+reports to myself whenever the app runs into an issue. These automated reports are powered by my own
+self-hosted version of [Sentry] (https://sentry.io/), which is a free and open source error
+reporting solution. These error reports are used exclusively for fixing problems that occur while
+you're using the app. For more information on the kinds of data that may be sent in these automated
+error reports, please see the [relevant documentation](https://docs.sentry.io/platforms/android/#context)
+on Sentry's website. If you would like to opt-out of these error reports, please visit the in-app
+settings page to disable the toggle for error reports.
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt
index 9de53cc..ab44f35 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt
@@ -2,15 +2,19 @@ package com.wbrawner.simplemarkdown
import android.app.Application
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.SentryErrorHandler
class MarkdownApplication : Application() {
val errorHandler: ErrorHandler by lazy {
- CrashlyticsErrorHandler()
+ SentryErrorHandler()
}
override fun onCreate() {
+ val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(this)
+ .getBoolean(getString(R.string.error_reports_enabled), true)
+ errorHandler.init(this, enableErrorReports)
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt b/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt
index 4ee20dd..fbdd3d5 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt
@@ -1,27 +1,44 @@
package com.wbrawner.simplemarkdown.utility
+import android.content.Context
import android.util.Log
-import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.wbrawner.simplemarkdown.BuildConfig
+import io.sentry.android.core.SentryAndroid
+import io.sentry.core.Sentry
+import java.util.concurrent.atomic.AtomicBoolean
interface ErrorHandler {
+ fun init(context: Context, enable: Boolean)
fun enable(enable: Boolean)
fun reportException(t: Throwable, message: String? = null)
}
-class CrashlyticsErrorHandler : ErrorHandler {
- private val crashlytics = FirebaseCrashlytics.getInstance()
+class SentryErrorHandler : ErrorHandler {
+ 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) {
- crashlytics.setCrashlyticsCollectionEnabled(enable)
+ enabled.set(enable)
}
override fun reportException(t: Throwable, message: String?) {
@Suppress("ConstantConditionIf")
if (BuildConfig.DEBUG) {
- Log.e("CrashlyticsErrorHandler", "Caught exception: $message", t)
+ Log.e("SentryErrorHandler", "Caught exception: $message", t)
return
}
- crashlytics.recordException(t)
+ Sentry.captureException(t)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SettingsActivity.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SettingsActivity.kt
index 1cb3b05..a76d449 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SettingsActivity.kt
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SettingsActivity.kt
@@ -3,7 +3,6 @@ package com.wbrawner.simplemarkdown.view.activity
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
-
import com.wbrawner.simplemarkdown.R
class SettingsActivity : AppCompatActivity() {
@@ -12,9 +11,7 @@ class SettingsActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
setSupportActionBar(findViewById(R.id.toolbar))
- if (supportActionBar != null) {
- supportActionBar!!.setDisplayHomeAsUpEnabled(true)
- }
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 499ba52..9c19fa9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -34,7 +34,7 @@
Lock Swiping
Select
Privacy
- crashlytics.enable
+ errors.enable
Enable automated error reports
Error reports will not be sent
Error reports will be sent
diff --git a/build.gradle b/build.gradle
index f3727a0..7ba4586 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,9 +7,9 @@ buildscript {
google()
}
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.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"
}
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1da66c8..7730d7d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Mar 19 08:56:07 CST 2020
+#Wed Jun 10 07:53:53 MST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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
diff --git a/sentry.properties.sample b/sentry.properties.sample
new file mode 100644
index 0000000..243594f
--- /dev/null
+++ b/sentry.properties.sample
@@ -0,0 +1,4 @@
+defaults.url=https://sentry.brawner.dev/
+defaults.project=simplemarkdown
+defaults.org=wbrawner
+auth.token=