Table Joins/Unions and ContentProviders: Reminderer

Ever since I wrote the new ContentProvider framework, Reminderer had this annoying bug where it wouldn’t auto-refresh the open tasks list whenever you added a new task. You added a task but the darn task wouldn’t show on the list until you rotated the phone.

The first approach was to force reload the Loader every time the fragment gets focus. While this hack works, its just that—a hack. This approach quickly becomes inefficient once the task list gets unduly large (as in hundreds of tasks). The second approach was to use a ContentObserver to listen for changes in the database. Fortunately, for some reason, as I’ll explain shortly, the content observer wouldn’t listen to changes in the table.

Continue reading


Off the Beaten Path: Reminderer

I’ve spent the past week fixing some persistent and annoying bugs. More on those later. Being a fan of the KISS principle, I think its better to polish what I have so far before adding more features rather than… adding a gazillion features that half work. So you can follow the latest progress in the dogFood branch.

The immediate goal is to make the “open tasks” activity more polished:

Continue reading


Rearrangeable List View Rows: Reminderer

Project View

I’ve been pretty busy at work, so I haven’t had as much time to work on Reminderer. The screenshot on the right shows the main page for Projects (aka categories)—you can now organize TODOs by project (1 project per TODO). Yes, the row height is too small to be user friendly but at this point I’m still working on the core functionality.

Rearrangeable List View Rows

One of the things that the UI will need is the ability to intuitively rearrange/reorder data, whether its projects or TODOs. Continue reading


End of Phase 1: Reminderer

first screenshot

I finally finished the first draft of the alarm system! Yay. Screenshot on the right.

“Wait,” you might be saying to yourself, “That app looks like crap.” And you’re right. I’ve been focusing strictly on the back end. With that out of the way, I can now dog food the app. Normally, I work from the outside in—create a UI first then add backend functionality as needed. In this case, the alarm system is so straightforward (yet interconnected) that it made more sense to complete it first.

What’s next?

The immediate next step is to add folders or categories. Each alarm can belong to one folder/category. Each folder/category has its own view. You’ll also be able to add an unlimited number of subtasks to a task, with unlimited hierarchy. Eventually there will also be tags to put tasks in multiple categories.

I’m also going to start surveying similar apps.


Roboelectric and ContentResolvers/ContentProviders

Setting up Roboelectric is dead simple. However, you may find that code like the one shown below doesn’t work:

//save using a task provider
Button saveButton = (Button) activity.findViewById(id.save_button);

//check that task was saved
ContentResolver resolver = activity.getContentResolver();
Cursor cursor = resolver.query(//...

assertTrue(cursor != null);

Nothing gets saved to the mock in-memory database. Your break points in the ContentProvider don’t get called.

What gives?

Register the ContentProvider

In Roboelectric, you need to manually register your content provider. The code below does the trick:

//instantiate the ContentProvider directly
TaskProvider taskProvider = new TaskProvider();

//register the ContentProvider
ShadowContentResolver.registerProvider(TaskProvider.AUTHORITY_NAME, taskProvider);

Thanks to Vardhan for the tip!

Unimplemented Methods

We’re almost there. The default mock in-memory database is pretty cool. For basic CRUD, it works pretty much like a real database except that everything is stored in memory.

However, you might find that queries don’t work. The reason is that as of 7/27/2013, Android API 16 (which is the default version Roboelectric uses) adds a new database method that Roboelectric hasn’t implemented yet.

The solution is to…implement the missing method yourself. You have two options:

  • Add the missing method directly to shadow class. (Requires that you work directly with the Roboelectric source code).
  • Create a custom class in your test and bind it at runtime to the framework. (I haven’t figure out how to do that yet in Roboelectric 2.)

The offending class is ShadowSqlLiteDatabase. Add this method and you should be good:

public Cursor rawQueryWithFactory (SQLiteDatabase.CursorFactory cursorFactory,
                                 String sql,
                                 String[] selectionArgs,
                                 String editTable,
                                 CancellationSignal cancellationSignal)
  return rawQueryWithFactory(cursorFactory,

Setup Roboelectric as a Submodule in Android Studio

Unit tests are awesome. In Android, the built-in unit tests are a kind of a drag because they require an emulator or a phone and APK deploys to the aforementioned device (in other words, they are slow). A popular alternative is Roboelectric. While it’s easy to add Roboelectric as a JAR or Maven dependency, it wasn’t so easy to add as a submodule.

“Why would you want Roboelectric as a submodule?” you ask.

Continue reading