RSS Feed

GnucashMobile widgets and reusable PendingIntents on Android

Posted on Tuesday, August 21, 2012 in Coding

GnucashMobile for Android has a homescreen widget which displays an account summary (name + sum total of transactions) for any specified account. When you add the widget to the homescreen, you are asked which account you want to link to the widget. Any transaction changes with that account are then reflected in the widget.

gnucash_widget_config_activity

Android widgets rely on RemoteViews and support only a very limited set of views. Things like the EditText view are not supported, else I would give you the opportunity to directly input transactions from the widget. This is how the widget was originally envisioned in the planning documents for GnucashMobile. But now I know better.

The implementation as it is now just has a button which opens the TransactionActivity for the specified account and allows you to easily create a widget. If you click on the widget itself, you just go to the account overview with a listing of all the transactions for the particular account.

widget_preview.png

The Views in the RemoteViews which make up a widget on Android are bound to PendingIntents. So when you create a widget, you create a PendingIntent and assign it to be executed when, for example, a button is clicked. I guess the widgets run under a different process and using passing an Intent allows the action to be executed on behalf of your app.

GnucashMobile allows you to have multiple widgets for the different accounts you may have created. As you might imagine, this leads to a situation where the intents for opening a new transaction or viewing the account is very similar for the different widgets. The intents will only differ in the extras (account ID arguments) which they hold, but everything else is the same.

The catch is that on Android, PendingIntents are reused and the extras in an Intent are not enough to distinguish between the PendingIntents. This leads to a problem where once the first widget was added to the homescreen, any other subsequent widgets responded to click actions using the PendingIntent of the first widget. This meant the wrong account was opened and transsactions were always created in the first account. The PendingIntent of the first account was simply resused because in Android’s view, it was the same PendingIntent, never mind that the accoung ID argument was different.

How to fix this? It turns out that there is an argument when creating PendingIntents which the documentation claims not to use, but actually uses it to distinguish between PendingIntents. This is the requestCode argument in the method PendingIntent.getActivity(). If your PendingIntents differ only in the arguments, then make sure they also differ in the request code for Android to treat them differently.

Share and Enjoy:
  • Twitter
  • Google Bookmarks
  • Digg
  • del.icio.us
  • Facebook

Be the first to comment.

Leave a Reply