mohd-faraz

_blogs

// blogs / 20260815.md

Dev Log: August 15 Wrap-up

2026-08-15
#android#kotlin#data-persistence#ui-ux

Overview

Today was one of those days where I bounced between big-picture features and those tiny, annoying UI bugs that you can't help but fix once you notice them. The highlight was finally getting a solid Backup & Restore system working without bloating the app with extra dependencies.

What I Worked On

Building a lightweight Backup & Restore

I’ve been meaning to add a way to export and import data for a while. Instead of pulling in a massive serialization library, I decided to stick with the standard org.json that comes with Android. The schema for this app is flat enough that hand-rolling the encoder and decoder was actually faster than setting up a full-blown library configuration.

One thing that tripped me up was the UX of importing. If a user imports data from six months ago while they’re looking at the current month’s dashboard, it looks like nothing happened. I ended up adding a timestamp return to the import logic so the app can automatically jump the view to the month where the new data actually lives. It’s a small touch, but it prevents that "Wait, did it work?" moment of confusion.

Refining the transaction matching

During the import process, I had to refine how we detect duplicate transactions. It’s not enough to just check the amount; you have to look at the payee too. But sometimes the payee names are just slightly different enough to fail a string match. I wrote a little helper to handle the logic for when payees actually "disagree":

/** 
 * Simple check to see if two transactions are actually different 
 * based on the reported names/entities.
 */
fun entries_conflict(parsed_name: String?, existing_name: String?): Boolean {
    if (parsed_name.isNullOrBlank() || existing_name.isNullOrBlank()) {
        return false // Not enough info to say they conflict
    }
    return !parsed_name.equals(existing_name, ignoreCase = true)
}

UI Polish: Chips and Navigation

I also spent some time fixing the "Add Transaction" screen. I noticed that if you typed a new category name but didn't "save" it yet, the UI didn't give you any feedback that it was selected. I fixed the chip logic so that a pending new category shows up visually just like the existing ones.

Also, navigation was losing the active filters when drilling down into category details. I updated the route arguments to pass the filter state along. It's much more seamless now—you don't feel like you're starting your search over every time you click a button.

It’s got a face now!

Finally, I stopped using the default Android robot icon. I put together a simple logo and updated the launcher background. It’s a small thing, but seeing a real icon on my home screen makes the project feel significantly more "real."

Wrapping Up

Persistence is solid, navigation is smarter, and the app looks better. Tomorrow, I think I’ll look into some edge cases in the SMS parsing logic—there are always a few weird bank formats that manage to break things. Catch you later.