Implement an AppWidget for BozaAlarm - Part I: Limitation

Today, I released BozaAlarm v4.10 to the Android Market. What's new in this version is the simple AppWidget to display the next enabled alarm.

Here, I'd like to talk about how I implemented this simple widget. Before I go too far, you probably need to take a look at least these two topics,

  1. AppWidgetProvider
  2. App Widget Design Guidelines
Just as I said before, there are some limitations in App Widget design and understand these should save you some time.

Basically, the Launcher process hosts AppWidgetHostView for each App Widget and talk with your process through RPC calls. You can image there are many RPC (binder) calls between Launcher and your process. That's why you will use RemoteViews to package your update actions in your process and apply them on the App Widget on the Launcher side. In fact, the RemoteViews is implemented as Command pattern in software terminology.

Now, you can imagine why AppWidget design is so restricted.

Moreover, because it's always unsafe to load classes from other process in a process, you're not allowed to use custom classes in your widget layout. Only built-in widget classes can be used in your layout xml file and only methods tagged by RemotableMethod in these classes are allowed.

Experiment the Tips for reducing APK file size

I came across this article: Tips for reducing APK file size at SonyEricsson Developer blog. Among them, the one I am aware of is the PNG file optimization. So, I took some time to experiment it.

First, I downloaded the GUI wrapper of command-line optimizer ImageOptim and optimize the PNG files at res/ directory. According to the result, it reduce total file size from 748K bytes to 700K bytes.

Second, I recompile the release binary of my application. But, the size of APK file remains the same as the one w/o PNG optimization.

Hmm. I repeated this process some times to make sure I didn't miss some important steps. While I was wondering, I noticed some messages spewed out during compilation like,
  [crunch] Processing image to cache: /Users/yenliangl/Work/Android/bozaalarm-android/res/drawable-hdpi/handler_app.png => /Users/yenliangl/Work/Android/bozaalarm-android/bin/res/drawable-hdpi/handler_app.png
Looks like PNG optimization has been included in the standard Android tool v14??

This should confirm my guess. From official site of Android tool, it says that in revision 14, aapt optimizes PNG during compilation.

png processing in aapt.
When aapt packages the resources, its main goal is to compile the XML to binary format and to create a resource table with all the resource values (string, color, ids, etc...). Additionally, it processes the png files to optimize them (for instance, pre-processing of 9-patches).
Because the aapt process is not incremental, this means every build goes through all png files and processes them always. For large projects with numerous (and/or large) png this process could take a long time.
Revision 14 now processes the png files outside of the aapt packaging step and caches them. Only modified png files are re-processed. 


TimePicker/DatePicker with keyboard input problem

I got some complaints from users saying they can't use keyboard to input in TimePicker or DatePicker widgets and found that this bug has been posted on Android developer forum for some time.

The quick workaround for this bug is,


Publish org to remote host through ssh

I've used Emacs org-mode to manage my personal notes and work stuff for a while. Its flexibility always amazes me.

Normally, I keep my personal notes in a Dropbox directory that are synced automatically. But, for work stuff, I created a local directory for them in intranet and published them to a secured remote host through ssh. The org-publish supports this feature well after you've configured ssh.

Customize Emacs compile

At work, I use M-x compile to build the project I'm working on. Chances are that default compile-command is not what you want. You can customize it and bind it to hotkeys as follows, 
Now, you can use F8, F9 to build the optimized and debug version.


Emacs server per workspace (GNU Screen)

I am a heavy user of GNU screen and Emacs at work and home. In the past, I created different GNU Screen instances for different projects and only one instance of Emacs server in one machine. For instance, you are aked to fix bugs in threee code branches and some fixes can't go into certain branches, I need to be very careful when I edit and switch buffers because only once emacs server out there.

What I really need to have setup like this,

Now, whenever you edit or switch files in a GNU screen by emacsclient, you can sit back and relax for a while. But, the problem is how do I make this a bit automatic? If you need to execute 'emacs --daemon=serverN' for every created GNU Screen, that will be very troublesome.
Here is what I have done to make this happen,

Now, when you instantiate GNU Screen by 'ws_XXX' aliases, an Emacs server identified by 'XXX' is created for you. And then you can use 'et' to edit a file in the proper Emacs server.

The only thing I don't like is that I am compelled to use another alias 'kill-emacs' to kill Emacs server. I often 'pkill' to kill process, but this will kill all Emacs servers in the same machine which is absolutely not the behavior I want.

The last thing to do is to patch the source code of emacsclient. In my experiment, emacsclient in the latest stable release (23.3b) doesn't pass correct argument for Emacs to start its daemon mode. So, I made minor changes to make it right.

After recompile and install, you can start using these two power tools in this way as I do.


Load machine-dependent bash setting

I own several computers and each is running different OS on it. We all know that maintaining different settings for different OS is very cumbersome. A simple solution for this is to separate common settings and machine-dependent settings into different files like this,
MNAME=`uname -s`
if [ -f $MBASHRC ]; then
    echo "==> loading $MBASHRC"
    . $MBASHRC
In this way, all you need to do is to write your machine-dependent settings in the bashrc.darwin or bashrc.linux.

MacOSX-like open command in Ubuntu and Windows/Cygwin.

I always find 'open' command in MacOSX is very useful for people always hanging around in the Terminal. To get the similar behavior in Ubuntu or other Linux system, we can create an alias such as,