Skip to content

Commit

Permalink
Bug: Google Drive API; retrofit2; tag colors
Browse files Browse the repository at this point in the history
Fixed bugs related with Google Drive API and retrofit2 in release builds.
Save hex colors instead of resource ids in the database
  • Loading branch information
ferrariofilippo committed May 17, 2024
1 parent fef24c0 commit 1a93a30
Show file tree
Hide file tree
Showing 28 changed files with 315 additions and 199 deletions.
9 changes: 5 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId "com.ferrariofilippo.saveapp"
minSdk 29
targetSdk 34
versionCode 6
versionName "1.07"
versionCode 9
versionName "1.09"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -58,8 +58,8 @@ dependencies {
implementation "androidx.core:core-ktx:1.13.1"
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "com.google.android.material:material:1.12.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0"
implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
implementation "androidx.compose.material3:material3:1.2.1"
Expand All @@ -71,6 +71,7 @@ dependencies {

implementation "com.squareup.moshi:moshi-kotlin:1.13.0"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
ksp "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"

implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"

Expand Down
9 changes: 8 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,11 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep class * extends com.google.api.client.json.GenericJson { *; }
-keep class com.google.api.services.drive.** { *; }
-keepclassmembers class * { @com.google.api.client.util.Key <fields>; }
Binary file modified app/release/app-release.apk
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 6,
"versionName": "1.07",
"versionCode": 9,
"versionName": "1.09",
"outputFile": "app-release.apk"
}
],
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/ferrariofilippo/saveapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.work.WorkManager
import com.ferrariofilippo.saveapp.model.enums.Currencies
import com.ferrariofilippo.saveapp.util.BudgetUtil
import com.ferrariofilippo.saveapp.util.CloudStorageUtil
import com.ferrariofilippo.saveapp.util.ColorUtil
import com.ferrariofilippo.saveapp.util.CurrencyUtil
import com.ferrariofilippo.saveapp.util.ImportExportUtil
import com.ferrariofilippo.saveapp.util.LogUtil
Expand Down Expand Up @@ -189,6 +190,7 @@ class MainActivity : AppCompatActivity() {
BudgetUtil.init(saveApp)
StatsUtil.init(saveApp)
SpacingUtil.init(saveApp)
ColorUtil.initColors(saveApp)

_restartFunction = { restartApplication() }
_checkpointFunction = { saveApp.utilRepository.checkpoint() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class SaveAppApplication : Application() {
LogUtil.logException(
e,
javaClass.kotlin.simpleName ?: "",
"defaultUncaughtExceptionHandler"
"defaultUncaughtExceptionHandler",
false
)
Runtime.getRuntime().exit(1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.view.View
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.ferrariofilippo.saveapp.R
import com.ferrariofilippo.saveapp.util.ColorUtil
import com.google.android.material.button.MaterialButton

@BindingAdapter("dynamicIcon")
Expand All @@ -33,11 +32,6 @@ fun View.setCollapsibleIcon(isCollapsed: Boolean) {
@BindingAdapter("dynamicTint")
fun View.setDynamicTint(value: Int?) {
value.let {
(this as ImageView).setColorFilter(
ColorUtil.getColorOrDefault(
context,
if (value == null || value == 0) R.color.emerald_500 else value
)
)
(this as ImageView).setColorFilter(value ?: context.getColor(R.color.emerald_500))
}
}
80 changes: 63 additions & 17 deletions app/src/main/java/com/ferrariofilippo/saveapp/data/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ import com.ferrariofilippo.saveapp.model.entities.Budget
import com.ferrariofilippo.saveapp.model.entities.Transaction
import com.ferrariofilippo.saveapp.model.entities.Subscription
import com.ferrariofilippo.saveapp.model.entities.Tag
import com.ferrariofilippo.saveapp.util.ColorUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

@Database(entities = [Budget::class, Transaction::class, Subscription::class, Tag::class], version = 3)
@Database(
entities = [Budget::class, Transaction::class, Subscription::class, Tag::class],
version = 4
)
abstract class AppDatabase : RoomDatabase() {
abstract fun budgetDao(): BudgetDao

Expand Down Expand Up @@ -58,74 +62,116 @@ abstract class AppDatabase : RoomDatabase() {
dao.deleteAll()

dao.insert(
Tag(0, cxt.getString(R.string.income), R.color.emerald_500, true)
Tag(0, cxt.getString(R.string.income), cxt.getColor(R.color.emerald_500), true)
)
dao.insert(
Tag(0, cxt.getString(R.string.bets), R.color.purple_200, false)
Tag(0, cxt.getString(R.string.bets), cxt.getColor(R.color.purple_200), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.clothes), R.color.emerald_200, false)
Tag(0, cxt.getString(R.string.clothes), cxt.getColor(R.color.emerald_200), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.culture), R.color.red_200, false)
Tag(0, cxt.getString(R.string.culture), cxt.getColor(R.color.red_200), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.entertainment), R.color.green_200, false)
Tag(
0,
cxt.getString(R.string.entertainment),
cxt.getColor(R.color.green_200),
false
)
)
dao.insert(
Tag(0, cxt.getString(R.string.food), R.color.cyan_200, false)
Tag(0, cxt.getString(R.string.food), cxt.getColor(R.color.cyan_200), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.gifts), R.color.blue_200, false)
Tag(0, cxt.getString(R.string.gifts), cxt.getColor(R.color.blue_200), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.holidays), R.color.purple_800, false)
Tag(0, cxt.getString(R.string.holidays), cxt.getColor(R.color.purple_800), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.personal_care), R.color.emerald_800, false)
Tag(
0,
cxt.getString(R.string.personal_care),
cxt.getColor(R.color.emerald_800),
false
)
)
dao.insert(
Tag(0, cxt.getString(R.string.others), R.color.red_800, false)
Tag(0, cxt.getString(R.string.others), cxt.getColor(R.color.red_800), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.sport), R.color.green_800, false)
Tag(0, cxt.getString(R.string.sport), cxt.getColor(R.color.green_800), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.tech), R.color.cyan_800, false)
Tag(0, cxt.getString(R.string.tech), cxt.getColor(R.color.cyan_800), false)
)
dao.insert(
Tag(0, cxt.getString(R.string.transports), R.color.blue_800, false)
Tag(0, cxt.getString(R.string.transports), cxt.getColor(R.color.blue_800), false)
)
}
}

companion object {
private val MIGRATION_1_2 = object: Migration(1, 2) {
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE tags ADD COLUMN isIncome INTEGER DEFAULT 0 NOT NULL")
db.execSQL("UPDATE tags SET isIncome = 1 WHERE id = 1")
}
}

private val MIGRATION_2_3 = object: Migration(2, 3) {
private val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE movements RENAME TO transactions")
}
}

private val MIGRATION_3_4 = object : Migration(3, 4) {
var ctx: Context? = null

override fun migrate(db: SupportSQLiteDatabase) {
if (ctx == null) {
return
}

try {
val localCtx = ctx!!
val tagsCursor = db.query("SELECT id, color FROM tags")
val idColorMap: MutableMap<Int, Int> = mutableMapOf()
tagsCursor.moveToFirst()
while (!tagsCursor.isLast) {
idColorMap[tagsCursor.getInt(0)] =
ColorUtil.getColorOrDefault(localCtx, tagsCursor.getInt(1))

tagsCursor.moveToNext()
}
tagsCursor.close()

for (id in idColorMap.keys) {
db.execSQL("UPDATE tags SET color = ${idColorMap[id]} WHERE id = $id")
}
} finally {
ctx = null
}
}
}

@Volatile
private var INSTANCE: AppDatabase? = null

const val DB_NAME = "saveapp_database"

fun getInstance(context: Context, scope: CoroutineScope): AppDatabase {
return INSTANCE ?: synchronized(this) {
MIGRATION_3_4.ctx = context

val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
DB_NAME
)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4)
.addCallback(AppDatabaseCallback(scope, context))
.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package com.ferrariofilippo.saveapp.model

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class CurrencyApiResponse(
@Json(name="amount") val amount: Int,
@Json(name="base") val base: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import com.google.android.material.snackbar.Snackbar
import com.google.api.services.drive.DriveScopes

object CloudStorageUtil {
private const val CLASS_NAME = "CloudStorageUtil"

private fun displayError(activity: Activity?, messageId: Int) {
if (activity == null)
return
Expand All @@ -38,6 +40,7 @@ object CloudStorageUtil {
}

private fun authorizeDownload(app: SaveAppApplication, result: AuthorizationResult) {
LogUtil.logInfo(CLASS_NAME, "authorizeDownload", "Authorizing download...")
if (result.hasResolution() && result.pendingIntent != null) {
try {
val intentSenderRequest =
Expand All @@ -53,14 +56,15 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "authorizeDownload")
LogUtil.logException(e, CLASS_NAME, "authorizeDownload")
}
} else {
enqueueDownload(app, result)
}
}

private fun authorizeUpload(app: SaveAppApplication, result: AuthorizationResult) {
LogUtil.logInfo(CLASS_NAME, "authorizeUpload", "Authorizing upload...")
if (result.hasResolution() && result.pendingIntent != null) {
try {
val intentSenderRequest =
Expand All @@ -76,7 +80,7 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "authorizeUpload")
LogUtil.logException(e, CLASS_NAME, "authorizeUpload")
}
} else {
enqueueUpload(app, result)
Expand All @@ -100,6 +104,7 @@ object CloudStorageUtil {
)
.build()

LogUtil.logInfo(CLASS_NAME, "enqueueDownload", "Starting backup download...")
WorkManager.getInstance(app).enqueue(downloadWorkRequest)
}

Expand All @@ -120,6 +125,7 @@ object CloudStorageUtil {
)
.build()

LogUtil.logInfo(CLASS_NAME, "enqueueUpload", "Starting backup upload...")
WorkManager.getInstance(app).enqueue(uploadWorkRequest)
}

Expand All @@ -143,7 +149,7 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(it, javaClass.kotlin.simpleName ?: "", "addOnFailureListener")
LogUtil.logException(it, CLASS_NAME, "addOnFailureListener")
}
}
}
Loading

0 comments on commit 1a93a30

Please sign in to comment.