Friday, January 28, 2011

Zeemote controller on Android

This blog post is about Bluez IME for Android.

I have recently purchased a Zeemote JS 1 controller from Amazon. I wanted to use it with my HTC Desire phone, which is running Android 2.2.

Unfortunately the Zeemote came with no drivers, probably because it was priced at £3 and was shipped in a bubble wrap envelope :). This was a bit weird, because the Zeemote website claims that Android 1.6 to 2.0+.

Looking at the Android market, I could find two drivers. One was called something like Zeemote JS1, and did not work on the HTC Desire (it appears to have been removed). The other is called GamePro, and did work, but costs $10, which is more than twice the price of the controller itself. Besides, the whole purchase seems a bit dodgy with only a forum for a webpage. I also believe that this is not allowed due to Android Market publisher agreements 3.3.

So I set out figuring out how to implement a working Zeemote driver. First block in the road is that Android prevents emulated hardware keypresses for security reasons. This can be handled by creating a custom Input Method Editor (IME), which can then send key press events.

Next block was that I got no manual of any kind, so I could only pair with the device. Fortunately, there was a post here that explained how to connect to the Zeemote with Android Bluetooth, and it works for HTC Desire.

Upon connection, the device starts dumping some data, probably describing the device and its capabilities. After this, there is no communication until you activate the device. By looking at the transmitted data, I was able to guess the format. Doing this took about 3 hours, plus 2 hours for implementing the IME, so a total of 5 hours for getting a working Zeemote driver.

I then figured that others would probably have the same issues as I did, so I spent a few more hours, creating a settings interface.

I have also purchased a Bluetooth keyboard, which I am hoping to get working under the same framework, but no luck so far. The code is flexible enough to allow other devices to be supported.

Then I realized that if you search Android Market for Zeemote, most of the results are games claiming to support Zeemote. This seems to indicate that a lot of people have been through the same ordeal as me, and likely have to update their app to support whatever changes there are.

I then spent a few more hours isolating the core of the application as a service. The cool thing about this is that other apps can freely activate the service, and register for events. In effect, any app can support Zeemote just by invoking the service (provided that it is installed), and all updates can be done within the driver itself.

I have packaged the app up and published it on Android Market for free, just search for Bluez IME.

As always, I have released the source under LGPL. If you are interested in the source code, visit the android-bluez-ime site. You can also download the package from there but I recommend using Market if possible, as that will ensure that you are automatically updated.

On the android-bluez-ime site, you can also see the source code for a test application that uses the Bluez IME service. Note that the test application does not require Bluetooth permissions, as that is handled by the driver.

If you have questions or comments related to Bluez IME, please create an issue on the website.

2 comments:

Mark said...

Just what I was looking for! Many thanks for writing it up and offering the results for free.

Anonymous said...

Man, your software is great. Thank you very much. I used to have the other driver but had to rebuy it because my phone was flashed when I sent it for repair under warranty. Now I got yours.

One thing in my wish list is to emulate accelerator input with the driver. This would allow us to use it for games that don't support it but use the accelerator to capture input (a lot of driving games for example). I have no idea if it is possible, but I read it's been done in other operating systems.

Anyway, thanks for sharing your driver.