As I mentioned earlier, I got a Sony SmartWatch at AnDevCon. I have been trying to come up with app ideas, but most of them didn't pass the "I can just pull out my phone" test. I was chatting with some friends, and one of them unclipped the watch from its strap and clipped it on his shirt. Now that's an awesome name tag!
I decided to write an app that reads images out of a folder on the SD card and show them on the watch as a slideshow. I first wrote a widget, but that did not work well because there was a loading screen between each refresh. I looked into the SDK some more, and decided to write a control instead. I refactored my widget code to add a control, but the control simply would not show up on the watch. I was studying the sample code very carefully and just could not figure out why. So I went to bed.
The next morning I started a fresh project to write the control. That worked. I then added a widget. Now the widget would not show up. It suddenly occurred to me that perhaps the LiveWare manager stored the app properties in a database, and did not reset the state when I reinstalled the app, so it did not recognize the additional control/widget.
To test that theory, I went to "Manage Applications" and cleared the data of the LiveWere manager. Well well, now it didn't even know about the SmartWatch! I uninstalled the SmartWatch app and reinstalled it from Google Play. And then I did the Bluetooth pairing again. Finally I installed my extension, and indeed, now my control showed up. That was really difficult to debug!
At this point the control was just displaying some hard-coded images. I swapped in a MediaStore
query to get images from the phone:
String[] projection = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION }; Cursor cursor = mContext.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, MediaStore.Images.Media.DATA + " LIKE ?", new String[] { folder + "/%"}, MediaStore.Images.Media.DATA);
A few notes here:
- I use
ORIENTATION
to rotate the image before displaying. - The "where" part of the query is specified by data binding. It is a safe way to say
MediaStore.Images.Media.DATA + " LIKE '" + folder + "/%'"
The SmartWatch dims the screen to save battery, but a dimmed name tag is a bit useless, so I added an option to leave the screen on.
setScreenState(alwaysOn ? Control.Intents.SCREEN_STATE_ON : Control.Intents.SCREEN_STATE_AUTO);
After adding the option to change the slide duration, I was ready to deploy. Very curiously, I got a fatal lint error, complaining that I did not localize my app to zh-rTW
and ja
. I could disable the lint, but as luck has it I speak both Chinese and Japanese, so I decided to localize the app!
The extension is now available on Google Play:
https://play.google.com/store/apps/details?id=com.sqisland.smartwatch.slideshow
You can also check out the Chinese and Japanese descriptions. I got lazy for Japanese, so I did not talk about selecting a folder or using it as a name tag. If you have a good translation, let me know!
The extension took me 2 days end to end. Overall it was a pretty good experience, except the part where I needed to clear data from the LiveWare manager when adding a control to an installed extension.
If you are an Android developer and you would like to get a SmartWatch for writing your own apps, you can submit a request to Sony using this link: https://www.surveymonkey.com/s/VT9D25X. If you do, ping me. I'm curious what you'll do with the SmartWatch!