Fix StrictMode disk access violations
All checks were successful
Build & Test / Validate (pull_request) Successful in 23s
Build & Test / Run Unit Tests (pull_request) Successful in 9m58s
Build & Test / Run UI Tests (pull_request) Successful in 12m45s

This commit is contained in:
William Brawner 2024-08-22 16:59:04 -06:00
parent b1e698c9c9
commit e8f1f0abbf
Signed by: wbrawner
GPG key ID: 8FF12381C6C90D35
5 changed files with 23 additions and 11 deletions

View file

@ -38,7 +38,9 @@ class MarkdownApplication : Application() {
} }
} }
} }
Timber.plant(ErrorReporterTree.create(this)) coroutineScope.launch {
Timber.plant(ErrorReporterTree.create(this@MarkdownApplication))
}
super.onCreate() super.onCreate()
ReviewHelper.init(this) ReviewHelper.init(this)
fileHelper = AndroidFileHelper(this) fileHelper = AndroidFileHelper(this)

View file

@ -3,7 +3,6 @@ package com.wbrawner.simplemarkdown.utility
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Environment import android.os.Environment
import android.provider.MediaStore
import androidx.core.net.toUri import androidx.core.net.toUri
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -34,8 +33,10 @@ interface FileHelper {
} }
class AndroidFileHelper(private val context: Context) : FileHelper { class AndroidFileHelper(private val context: Context) : FileHelper {
override val defaultDirectory: File = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) override val defaultDirectory: File by lazy {
context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
?: context.filesDir ?: context.filesDir
}
override suspend fun open(source: URI): Pair<String, String>? = withContext(Dispatchers.IO) { override suspend fun open(source: URI): Pair<String, String>? = withContext(Dispatchers.IO) {
val uri = source.toString().toUri() val uri = source.toString().toUri()

View file

@ -19,10 +19,17 @@ interface PreferenceHelper {
} }
class AndroidPreferenceHelper(context: Context, private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)): PreferenceHelper { class AndroidPreferenceHelper(context: Context, private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)): PreferenceHelper {
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private val sharedPreferences by lazy {
private val states = Preference.entries.associateWith { MutableStateFlow(get(it)) } PreferenceManager.getDefaultSharedPreferences(context)
}
private val states by lazy {
val allPrefs: Map<String, Any?> = sharedPreferences.all
Preference.entries.associateWith { preference ->
MutableStateFlow(allPrefs[preference.key] ?: preference.default)
}
}
override fun get(preference: Preference): Any? = sharedPreferences.all[preference.key]?: preference.default override fun get(preference: Preference): Any? = states[preference]?.value
override fun set(preference: Preference, value: Any?) { override fun set(preference: Preference, value: Any?) {
sharedPreferences.edit { sharedPreferences.edit {

View file

@ -54,6 +54,7 @@ android {
} }
dependencies { dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.acra.core) implementation(libs.acra.core)
implementation(libs.acra.http) implementation(libs.acra.http)
runtimeOnly(libs.acra.limiter) runtimeOnly(libs.acra.limiter)

View file

@ -2,7 +2,8 @@ package com.wbrawner.simplemarkdown.core
import android.app.Application import android.app.Application
import android.util.Log import android.util.Log
import org.acra.ACRA import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.acra.config.httpSender import org.acra.config.httpSender
import org.acra.data.StringFormat import org.acra.data.StringFormat
import org.acra.ktx.initAcra import org.acra.ktx.initAcra
@ -17,18 +18,18 @@ class ErrorReporterTree private constructor(): Timber.Tree() {
} }
companion object { companion object {
fun create(application: Application): ErrorReporterTree { suspend fun create(application: Application): ErrorReporterTree {
application.createErrorReporterTree() application.createErrorReporterTree()
return ErrorReporterTree() return ErrorReporterTree()
} }
} }
} }
private fun Application.createErrorReporterTree() { private suspend fun Application.createErrorReporterTree() = withContext(Dispatchers.IO) {
initAcra { initAcra {
reportFormat = StringFormat.JSON reportFormat = StringFormat.JSON
httpSender { httpSender {
uri = "${BuildConfig.ACRA_URL}/report" /*best guess, you may need to adjust this*/ uri = "${BuildConfig.ACRA_URL}/report"
basicAuthLogin = BuildConfig.ACRA_USER basicAuthLogin = BuildConfig.ACRA_USER
basicAuthPassword = BuildConfig.ACRA_PASS basicAuthPassword = BuildConfig.ACRA_PASS
httpMethod = HttpSender.Method.POST httpMethod = HttpSender.Method.POST