2024

Extended ADB: En Vogue 💃

Last year, I wrote about an extended adb script. The idea of the script is to make it really easy to issue an adb command even if there are multiple devices attached by presenting a chooser. For example, if I have two physical devices and an emulator and I want to use my deeplink alias, I get presented with a device chooser:

➜  ~ deeplink https://zarah.dev
Multiple devices found:
1 - R5CR7039LBJ
2 - 39030FDJH01460
3 - emulator-5554
Select device: 
3 min read
Back to Top ↑

2023

Extending an Interactive ADB 🔀

A few weeks ago, I wrote about a script for making adb a little bit more interactive. The script makes the process of running an adb command much smoother if there are multiple devices attached by presenting a chooser. For example, when sending a deeplink:

➜  ~ deeplink https://zarah.dev
Multiple devices found:
1 - R5CR7039LBJ
2 - emulator-5554
3 - emulator-5556
Select device: 
4 min read

Making ADB a little bit dynamic 📱

Android has a lot of tools for developers and one that has been around for as long as I can remember is Android Debug Bridge (adb). It allows you to issue commands to an attached device, such as installing an app or starting an Activity.

5 min read

Bundling Things Nice and Pretty 💝

Of all the projects that I have worked on over the years, one thing they all have in common is the need to pass things around. Whether passing stuff to an Activity as Intent extras, a Fragment as arguments or its onSaveInstanceState, or even a ViewModel’s SavedStateHandle, the most common way to do it is through a Bundle.

5 min read
Back to Top ↑

2022

📣 PSA: Disabling mapping file uploads with Crashlytics

One of the more famous crash reporting tools used in Android development is probably Crashlytics. It offers up a lot of insight into an app’s performance – from device characteristics to insights on issue commonalities. If, like my current project, obfuscation is enabled in an app, Crashlytics has a Gradle plugin that uploads the mapping file so that we end up with readable crash reports.

~1 min read
Back to Top ↑

2021

Multi-module Lint Rules 🤹‍♀️

I have been learning a LOT about Lint the past year. Our team has grown 5x since I joined more than three years ago, and it became really obvious really quickly that we should be letting robots do a lot of the mundane and repetitive enforcement of our team’s code conventions.

13 min read
Back to Top ↑

2020

Enforcing Team Rules with Lint: Tests 🧐

A few months ago, my team came upon an agreement that when leaving a TODO anywhere in our code, we need to always provide several things:

  • the person who is expected to address the TODO
  • date when the TODO was left
  • a comment or explanation on what needs to be done
4 min read

Enforcing Team Rules with Lint: Detectors 🕵️

A few months ago, my team came upon an agreement that when leaving a TODO anywhere in our code, we need to always provide several things:

  • the person who is expected to address the TODO
  • date when the TODO was left
  • a comment or explanation on what needs to be done
12 min read

Enforcing Team Rules with Lint 👩‍🔧

A few months ago, my team came upon an agreement that when leaving a TODO anywhere in our code, we need to always provide several things:

  • the person who is expected to address the TODO
  • date when the TODO was left
  • a comment or explanation on what needs to be done
4 min read

Easy Navigation with Bookmarks

One of the things I find most challenging when learning a new part of a codebase is navigating through the data flow. In some areas of our app, following RX streams can be particularly… draining.

1 min read

Accurate Measurements With getTextBounds()

We have a few custom spans in our app and over the last few days I have been poring over one of them. I was trying to see if the implementation could be improved but before that could happen I needed to understand what it was trying to do first.

5 min read

//TODO Live Templates

Throughout my career, I have worked in projects of all sizes. I have taken part in greenfield projects and some that are a few years old. One of the lessons I have learned over the years is that no one ever goes back to fix the TODOs.

2 min read

Your Privilege is Showing

When I left the Philippines five years ago, I had a high-paying job at the heart of the country’s financial district. I was living a very comfortable life: I can afford an annual membership to a yoga studio, I bought an off-the-plan apartment with views of Manila Bay, I get to treat my parents to a holiday once in a while, I get to travel with my friends – we were even able to go abroad a couple of times!

4 min read

Which is Which: Named Breakpoints

I have always believed that one of the biggest factors that influence a person’s enjoyment and delight in doing their job are the tools. Having the right tools and using them the best way possible helps direct our energy on the what rather than the how.

1 min read
Back to Top ↑

2019

Scratch That Itch

One of the most useful things for me whilst I was learning Kotlin was TryKotlin. It gave me a quick way to test concepts, try new APIs, or just to get familiar with the syntax.

2 min read

On-Device Debugging Part V: Strut Your Stuff

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that help us:

  • figure out what’s going on without needing to be attached to a computer
  • test various configurations without re-installing
  • have a host for various experimentations we are trying to explore
2 min read

On-Device Debugging Part IV: Log All The Things!

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that help us:

  • figure out what’s going on without needing to be attached to a computer
  • test various configurations without re-installing
  • have a host for various experimentations we are trying to explore
3 min read

On-Device Debugging Part III: Inspect, Reset, Repeat

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that help us:

  • figure out what’s going on without needing to be attached to a computer
  • test various configurations without re-installing
  • have a host for various experimentations we are trying to explore
4 min read

On-Device Debugging Part II: Timbeeeeeeer!

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that aims to help us:

  • figure out what’s going on without needing to be attached to a computer
  • test various configurations without re-installing
  • have a host for various experimentations we are trying to explore
3 min read

On-Device Debugging Part I: Now It’s On, Now It’s Off

Over the past year, my team have been steadily building a Developer Options screen for our app. It is a simple PreferenceScreen available on debug builds that aims to help us:

  • figure out what’s going on without needing to be attached to a computer
  • test various configurations without re-installing
  • have a host for various experimentations we are trying to explore
4 min read

Shortcuts to Shortcuts

It has been a few years since I last looked at implementing app shortcuts, and lately I have been looking at them again. I remember implementing them the first time they were released for Android N, but as with life, things have changed a bit.

3 min read

Unwrapping Framework Binding Adapters

For the past year or so, my team has been all-in with data binding. And if you know me at all, it obviously makes me one happy duck!

3 min read
Back to Top ↑

2018

Ya Basic

Over the last year or so, we have been writing a lot of Kotlin at work. There is a consensus within the team that we all like working with the language. It really helps our productivity a lot by reducing a lot of boilerplate, we can actively enforce nullability rules that makes business logic obvious, and having the option to make extension functions offers a lot of flexibility.

2 min read

Selectively Resetting SharedPreferences

I have recently been working on a feature that has a bunch of pre-conditions. Things like the user must be logged in AND the feature flag has to be turned on AND it only appears the first time the user lands on the screen.

1 min read

Effectively Wrangling Together a Bunch of Views

One bit of task that I find myself doing over and over again is managing a bunch of Views and their visibility. In the olden days <insert old person handwave>, before there was ConstraintLayout, I have written my fair share of container_s to make this task manageable. Say we have to do something like this:

2 min read

Referencing IDs in Data Binding

Last week, I was talking to someone on my team and it became apparent that they weren’t aware of one super useful feature of data binding. If you know me at all, you know that I like love this library, and I would take every opportunity to spread the love around.

~1 min read

Next Move

Today is my last day at Domain. After three years, seven months, and three days, it is time to move out.

~1 min read

That Thing About Commit Messages

Last week, I was giving feedback to someone about improving the commit messages they write. I was very taken aback by their response – “it does not matter what the commit messages are”. Now this is confusing for me, mainly because I know from years of experience that having relevant commit messages is important.

1 min read
Back to Top ↑

2017

Parsing Data Binding Errors

Learning something new is always fun and exciting. That is, until seemingly cryptic error messages start creeping up.

1 min read

Binding to the H(eight)

As would probably be obvious by now, I have been investing a lot of time in learning and using data binding.

1 min read

I Like Walls

I have always been told I’m stubborn. And I am. So jumping off this post, I continued doing instant apps stuff and I learnt more things this week.

1 min read

Children, Respect Your Parent(s)

I was updating a bit of code the other day that involved dynamically inflating views into a LinearLayout using DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.row_related_property, container, false).

1 min read

There is Always Room for Improvement

During the beginning of my Android career, one of the things I had to do was to save some data to somewhere. I found out that for my purposes, I had to use an SQLite database. Reading through the docs, I was afraid. Petrified, even.

5 min read

@{app.plaid}

I gave a talk this morning in the first ever Droidcon Vietnam! It is about two of the things I love in Android – Plaid and data binding.

~1 min read

A note on giving back

Recently, there has been a spate of tweets about developers admitting their weaknesses. A bunch of people I know even made into the Moment created by @ThePracticalDev. And then there’s this tweet:

1 min read

:facepalm:

I just spent an hour debugging an issue that should have been a non-issue at all.

1 min read

Troubleshooting autoVerify

So you implement app links and you are 300% sure you have implemented everything correctly. The important thing to remember here is that verification is all or nothing. From the docs:

2 min read
Back to Top ↑

2016

The Quirks of Supporting SDK 25

The last developer preview of Android 7.1 has started shipping, which means APIs are (based on past experience) more or less stable. There is a very good write up on developer.android.com on how to get started with supporting these new features. I set about trying it out, and here’s what happened.

4 min read

A Little UX Love Goes A Long Way

Yesterday, my bank pushed a notification asking if I’m going to travel. Yes! I am! I filled up the form they asked me to fill up, and tapped Submit.

2 min read

Tools of the Trade: Unabridged

I gave an unabridged version of my last Android Meetup talk at this year’s YOW Conference. It has been an honour being part of this awesome conference!

~1 min read

Tools of the Trade

Here are the slides to my talk at the Android Meetup tonight.

~1 min read

String formatting and Lint

One piece of advice that we keep hearing over and over is to extract strings into resources. There really is no reason for you to hard code strings in code.

1 min read

A big step

Today was the day.

~1 min read

Stylish Dynamic Layouts

One of the things we are taught in Android is that we should gracefully handle different layouts based on screen sizes. With more and more things being not just screen size-specific but also OS version-specific, this is one thing I think a lot more devs need to pay attention to. Today was my turn to do just that.

2 min read

Using resource IDs in data binding layouts

I have been playing with data binding more and more over the last couple of weeks. This week, it’s all about creating a dialog with stuff dictated by a value from an enum.

2 min read

Snazzy git blaming

Sometimes, you can’t help it. You need to look at what happened in the past to understand what is happening in the present (wow).

1 min read

In which I was in a podcast

It has been a month since IO and in case you missed it, I got to chat with Kaushik of Fragmented. And by golly, I made it into an episode! At that point I was about to lose my voice, so I sound really husky. :p

~1 min read

Taking a closer look while debugging

One of the most common sources of bugs (at least of my bugs) is math. I have been working on dynamically resizing a View the past days, and it was driving me nuts! I needed to consider preserving aspect ratio, device density, original view size, etc etc. Math is hard guys!

4 min read

LinearLayouts, TextViews and Drawables

I sent out a series of tweets today about LinearLayouts and unexpectedly, quite a few people like them. I decided to get off my lazy ass and actually write it down in a post for easy reference.

2 min read

Squashing Bugs

This has been one hell of a busy week for me. I think you can sort of tell from my Tweets and G+ posts that I have been debugging A LOT.

1 min read
Back to Top ↑

2015

Annotating all (or most of) the things

If, like me, you are old and have been developing for Android for a while, you should, like me, appreciate the fact that the backwards compatibility of the OS has come a long way. Sure, they may toy with my feelings from time to time, but we all need a little excitement every now and then.

1 min read

NOT another day at the office

We had another round of Innovation Day at Domain last month, and I wrote about it. We started out dreaming up this ambitious project – too ambitious for two days! Here’s a partial list of what we had to do:

  • Build a wall
  • Stick devices on said wall
  • Make app that cycles through photos from listings
  • Load said app on those devices that we stuck to the wall
  • Figure out how to track people who get devices
  • What if someone just gets a device?!
  • Figure out how to let people give back devices
  • Oh! oh! oh! Wouldn’t it be cool if other devices cheer when one of them “comes home”?
  • How do we put new versions of the app on those devices?
  • Run tests, maybe?
  • What if the website team wants to test responsive designs?
  • Do they even charge????!!!
~1 min read

In Which Things Got Cheesy

Today, Android Developers published Domain’s Developer Story. In it, Gary and Rique talked about how the Domain Android app was rated very poorly and had all sorts of problems. Fast forward two years and it is now a highly-rated, top-ranked lifestyle app in Australia. You would think that going from a 2.8 star rating to 4.1 stars is all sorts of amazing. And it is!

2 min read

Raising Activities From the Dead

One of the scenarios I admittedly ~almost~ always forget to test is “What happens when my app goes into the background, then the OS kills is to claim memory, then I try to resume?” Usually it’s “Well, I handle onSavedInstanceState not being null, so I am great!” It is fine and dandy for simple apps; but once your Activity or Fragment gets beefier and you start relying on state for more and more things, it can get complicated pretty quickly (In my case, the Fragment has setRetainInstance(true)).

1 min read

Lies I’ve been told today

So I played around with data binding today. And these are the lies that the dev guide told me (explicitly or inferred):

  • There is a method `DataBindingUtil.bindTo(viewRoot, layoutId)
  • That this will work MyLayoutBinding.bind(viewRoot);
  • Android Studio has auto-complete
~1 min read

Pasting and Extracting Stuff

A lot of times, but especially when I am implementing some new logic, coding for me takes several steps:

  1. Write down what I have to do as comments
  2. Implement what I have written down
  3. Refactor and improve what I have implemented
1 min read

Stringy strings

While we are on the subject of strings, here are more ways of dealing with them in Android Studio. We all know that we should not hardcode strings in code, right? But sometimes, we forget and tend to do code first before defining them in strings.xml.

1 min read

Fixing a mistake in your git history

I have been using git for about five years now, but I definitely get stumped by it a lot. It is so powerful it’s daunting. There has been a couple lot of times where I had been too careless and reliant on my fingers’ add-commit-push muscle memory that I realised I have made a mistake too late. I have always been a proponent of clean, atomic commits, and when I find my commits all messed up, I hit myself in the head.

3 min read

On being material

In case you missed it, I made a blog post about updating our app to material design. In it I talk about what material design is and what we did to adopt it. I hope you enjoy reading it as much as I did writing it. :) Head on over to Domain’s tech blog for the details.

~1 min read

SQLiteAssetHelper + ORMLite

I recently had cause to use Jeff Gilfelt’s SQLite Asset Helper library. For those unfamiliar, it is a library that can help with including a pre-populated SQLite database with your Android application. It is extremely convenient with unbundling a potentially huge database you would want to ship.

2 min read
Back to Top ↑

2014

AutoCompleteTextView Hell

Today, I ran into a weird “feature” of Android. I was working on an AutoCompleteTextView with the dropdown list having section dividers. It all works well in portrait mode, but gets all messed up in landscape.

2 min read

Swipe, not Pull, to Refresh

I have recently came across this new View in the support library package that allows your app to have built-in support for pull swipe to refresh. This is pretty cool, since we don’t have to use any of the libraries out there. Admittedly, very little customization can be done, but then what else can we customize, right?

1 min read

Quick Tip: Understanding Alternate Resources

Trying to support as many devices as possible the best way possible is a very daunting task indeed. You will usually need to provide a lot of different layouts, strings, or dimensions (among others) to make your app look great whatever the user’s device is. And then you start chaining resource qualifiers and testing which resource is being loaded by the OS can become a nightmare very quickly.

1 min read

Adding attributes to a custom view

There are times when using the default Android Views just doesn’t cut it and you need to create your own version of a View. So how exactly do you do that? It’s as simple as subclassing the View! But what if you want to add customizable attributes? Here’s how.

3 min read

Quick Tip: git Auto-complete

When I started using git, it peeved me that there is no auto-complete. More so when you have to manually do a git add manually.

~1 min read

Setting up the SeekBar

So we want to use the SeekBar. We want the minimum value to be 10 and the maximum value to be 100, and it should increment by 10.

1 min read
Back to Top ↑

2013

Back to Top ↑

2012

Quick Tip: Pulling an SQLite db file from device

I have always thought that you would need root access to pull an SQLite file from a non-rooted Android device. Turns out I thought wrong! Here’s how you do it:

$ adb -d shell
$ run-as your.package.name
$ cat /data/data/your.package.name/databases/yourdatabasename  >/sdcard/yourdatabasename
~1 min read

I Can Haz Internetz!

Last week, I was exploring connectivity monitoring and came up with a small app for demo. The app listens for connectivity changes and sends a notification to the user informing them of the change.

3 min read

Making ActionBarSherlock and ViewPagerIndicator play nice

EDIT (20121227): I made a new post on changing the tab selector underline.
EDIT (20121014): I received feedback from the comments that rotating the device will cause the tab contents to revert to the default text. In essence, the adapter “loses” the contents of the tabs. I have corrected this in the example below as well as in github.
EDIT (20120905): The full sample source code is now in github.

3 min read

Cloning a remote branch in git

My current project at work uses git, and I have always been a CVS/SVN baby so I’m still trying to find my way around it. Today I wanted to clone a remote branch to my local computer. This remote branch also has submodules, so I want to get those too.

~1 min read

Eclipse-ception

Guys!! Eclipse just went all Inception on me!

~1 min read

Adding a float value to your resources

Earlier today, I was trying to figure out how to add a float value to constants file. What I used to do was add a string value in my strings.xml, retrieve the string value, and convert it to float.

float floatFromFile = Float.valueOf(getResources().getString(R.string.my_float));
~1 min read

Quick Tip: git cloning

A user-friendly way of cloning a git repo is through the eGit plug-in in Eclipse. But sometimes, especially on Windows machines, Eclipse has trouble cleaning up after itself after completing a clone operation. The best workaround for this is to clone the repo from git bash and then import the repo in Eclipse.

default@ZDOMINGUEZ-T420 ~
$ git clone git@github.com:<your git repo> <local folder to check out to>
~1 min read

Selenium and File Downloads

Lately, one of my tasks has been to automate regression tests on one of our apps. Since this is a web app, we are using Selenium. Here, I enumerate the steps to configure Firefox for file downloading using Selenium and JUnit by foregoing the downloads dialog box.

4 min read
Back to Top ↑

2011

MongoDB and Authentication

By default, MongoDB allows access to the database without authentication. Adding a user with a username/password is easy, but authenticating might be a bit tricky since the official documentation does not say the command directly.

1 min read

Hello, it’s me again.

To my two readers out there, hello! It’s been a while since I posted here. I was transferred to another (non-Android) project and lost all my Internet privileges, hence the silence. I still can’t believe almost every other site is blocked by the office firewall! Makes software development ten times harder. Ugh.

~1 min read

Where’s my R.java?

This afternoon, I tried importing an existing project into Eclipse. Doing a Project > Clean usually clears up the R.java not found errors, but this time it didn’t work. I tried re-importing the project, copy-and-pasting it into a new workspace, restarting Eclipse, but the error is still there.

~1 min read

A break: When I grow up

Tearing my hair out on my latest project. So here’s some Garbage to cheer me up.

~1 min read

Passing complex objects to another Activity

Several months ago, I was faced with a problem of passing a complex object to another Activity. There are several ways of doing this:

  • “Deconstructing” the complex object to simple data types and passing them as extras through putExtra()
  • Making the object Parcelable
  • Making the object Serializable
6 min read

Dreaming of Google I/O: ADT preview

It is my dream to one day attend Google I/O. But seeing as I’m from a Third World country where everyday is a practice in cost-cutting, it is very unlikely that I would fulfill that dream anytime soon. I haven’t sat down and computed the actual cost, but thinking about it makes my head spin. Off the top of my head:

  • US Visa application = P6500 (~USD150)
  • Round trip plane fare ticket = P90,000 (~USD2000, if I’m lucky)-
  • Google I/O ticket = P21,000 (~USD450, if my research is correct)
5 min read

Changing a button’s text color

There are times that when changing a button’s background color, we also want to change the text’s color. There is a method setTextColor(int color) specifically for this purpose. Seems pretty straightforward enough, but it took me a few tries to get it right the first time I tried using it. Documenting it here so that I wouldn’t forget.

~1 min read

Using CWAC’s EndlessAdapter with a custom adapter

In one of my projects, the app has the potential to display a very, and I mean very, long list. To minimize the loading time of the app, I limit the number of items initially included in the list and then add to it as the user scrolls down.

6 min read

My EditText is cut off by the on-screen keyboard!

With clients demanding left and right that my app should look like an iPhone app, I tend to be unappreciative of the way Android natively handles UI interactions and such. Notice how the screen automagically scrolls up when you click on an EditText? It turns out that in iPhone development, the developer does this manually (indicate how much the view should scroll when the on-screen keyboard appears, then scroll it back down afterwards). HA!

~1 min read

Using a custom font in WebView

In one of my projects, I needed to display some special characters that the Android OS by itself cannot seem to render. I figured that I would need to provide a custom font that includes the characters that I needed.

1 min read

It never ends!

Been ultra super busy the past few weeks. Also learning a lot of new things. And renewing my battle with orientation change, AsyncTasks and dialog boxes.

~1 min read

stealth ninja mode on

Over the past couple of weeks, this blog has been getting unusually high traffic. Which means I get more than one hit per week.

~1 min read

That damn seekbar thumb

If you have ever needed to use a SeekBar, you definitely would have noticed how hard it is to move the slider (aka thumb) when it is set to the minimum or maximum value. The slider tends to be cut in half, and fitting your finger into it to press it becomes a test of patience.

1 min read

Enabling/disabling menu items on the fly

In one of my applications, I want to disable some menu entries if the database is not valid or is not present at all. To do that, I make use of the onPrepareOptionsMenu() API.

1 min read

Just wondering

You know those postscripts that Google engineers have on their posts in forums? I wonder if they have a sort of “standards body” that came up with it. They all sound like this:

~1 min read
Back to Top ↑

2010

Quick tip: Quick Formatting of Android XML Files

One of the most useful tools in Android’s Eclipse plug-in is the Layout Editor. It is easy to experiment with layouts using the drag-and-drop enabled editor without having to worry about the correct syntax or if you are using the correct attribute name.

~1 min read

What happened to my layout editor?

There you are, happily creating your layout files in the Eclipse plug-in’s layout editor. Dragging and dropping is a breeze. But then one day, you open a layout XML file and boom! No UI! All you see is the XML tree with all the nodes and attributes. What happened?

1 min read

What grammar?

My OC side was alarmed when suddenly, my Problems view in Eclipse was filled with warnings on my XML files. Each of my XML files had a warning with it, and that little yellow exclamation mark on the side:

~1 min read

TextView and MaxLines

I have a TextView (who doesn’t?) and I want to adjust its height automatically, depending on the length of the text it will contain. Should be easy. It was, but it took me a couple of minutes to figure it out.

~1 min read

Missing hierarchyviewer in SDK 7

If you have SDK version 7, you are most probably missing the hierarchyviewer from your /tools folder. To check your SDK version, launch the SDK manager UI from your installation path, usually C:\android-sdk-windows, then click About.

~1 min read

More plurals: decimal values

In my previous post, I showed you how to set string plurals. If you noticed, the methods to get the plurals strings only accept ints. What if (like me) you want to display a decimal value? I am getting my raw value from a progress bar with a range of 1-10, with 0.1 increments.

1 min read

String Pluralization

Last week, I discovered Android’s support for plural strings by accident. And a good accident it was since I am working on an app that will display a float to the user. I used to display:

1 min read

It’s so fluffyyyyyyyyy!!!

<img src=http://www.despicable.me/pops/minionMaker/userpics/910156207.jpg width=”380” height=”473” alt=”I’ve created a Minion to join Gru’s Minion army.” />

~1 min read

Quick string resource formatting

Sooner or later, you would want to display a message to your user with dynamic content. This may be the number of results, the user’s name, etc.

~1 min read

A test, a test

I was thinking of starting a quick-tips style blog for software development (mostly for myself, since I tend to forget stuff a lot recently).

~1 min read
Back to Top ↑