Sunday, December 9, 2012

AnDevCon IV

It's AnDevCon time again! My Android Custom Components talk was really popular at AnDevCon III, so I decided to give it again. On top of that, I had to a two-part session to discuss Android UI, both lecture and hands-on workshop.

Murphy's Law

I prepared my talks a few weeks ahead of time, so I was pretty chill about the conference. But as Murphy's Law dictates, anything that can go wrong will go wrong. On Monday of the conference week, my laptop died. My talks were on Wednesday and Thursday. Needlessly to say, I was completely thrown off course. I was so stressed that I had nightmares on Monday night.

Tuesday I took the laptop to the Apple Store, and they had to ship it out for the repairs. My slides were all online, but I still needed a machine to project them. Fortunately I found a friend who lent me a laptop, and I installed Photoshop trial for the demo in my session.

Since I didn't want to install too many new programs on my friend's computer, I took a break from programming on Tuesday night. Instead, I baked cookies to bring to the conference.

Same as AnDevCon III, I gave away bugdroid-shaped cookies to encourage participation, and people loved it.

Beautiful Android on a Shoestring

My first session was Beautiful Android on a Shoestring. I shared my experience in creating beautiful Android apps without knowing how to draw, introducing concepts like xml drawable, text shadow, shaders, custom fonts etc. I am especially proud of using icon fonts for scalable icons, a concept I borrowed from the web.

After showing the Android techniques, I switched gears and showcased my favorite website to get color schemes, fonts, icons etc:

I recorded the talk with my phone:

Unfortunately the video did not capture the slides. But fear not, I used Popcorn.js to embed the video to the slide deck. Play the embedded video on the top right corner, and the slides will advance automatically to match. Check it out:

Hands-on Icon Creation

I led a hands-on Photoshop workshop right after Beautiful Android on a Shoestring. I know very little about Photoshop, but I felt that what I learnt from the Graphic Design for Engineers workshop was super useful, and I want to share that with other developers. I had a relatively small class, which was great because I could check and make sure everyone was following along.

Android Custom Components

The next day I gave my Android Custom Components talk. This is my fourth time giving this talk, so I was very comfortable with the material. Still, every talk is a live performance, and the audience is always different. I really enjoyed the interaction.

Since I already recorded the talk at AnDevCon III, I did not set up my video taping this time. Here is the recording from May:

Attending sessions

My three talks were clashing with a lot of the other sessions I wanted to attend, and I was a bit disappointed about it. Fortunately I managed to catch the Android concurrency talk, which was jam packed with information. I was live tweeting since it is too good to keep to myself! Here are a few of the tweets:

Great conference

Once again I had a great time at AnDevCon. It's really cool to hang out with so many Android developers. Definitely check it out if you work with Android!

Monday, December 3, 2012

Why Do I Speak At Conferences?

I have been asked by many people why I speak at conferences. I know I enjoy it tremendously, but it took me a while to pinpoint why. Here are my top three reasons.

Share Knowledge

First and foremost, I want to share what I know. As a developer I face new challenges every day, often scouring the internet for hours to figure out how to implement a new feature or get rid of that mysterious bug. I don't want my effects to go wasted. I keep a blog to share my findings, but sometimes I feel like I am talking to the void.

At a conference I have a live audience. I get instant feedback, perhaps a puzzled look that nudges me to explain in a different way, or a knowing smile that tells me I struck a chord. It is truly rewarding to see that sparkle of understanding, to know that you have made a difference.

Network effortlessly

After you give a talk, people come to you during lunch and coffee breaks. They heard you speak, thank you for the great talk, and want to discuss more. These conversations are way more interesting than your typical small talk, and I have met many wonderful people this way. As a speaker, networking becomes effortless because people come to me, and focused too, because they come to me knowing my interests. No more wandering aimlessly, shaking hands and collecting business cards without knowing why.

Be visible

As much as you would like to believe in a meritocratic society, unseen achievements are, by definition, not recognized. By stepping on stage and sharing your knowledge, you are seen as an expert. I know this at the back of my head, but I am still amazed by the wonderful opportunities that presented themselves to me since I started speaking.

One thing I did not expect about my visibility was that it was not just about me. I did not set out to defy the coder stereotype, but the truth is, I am not white, and I am not male. Every time I step on stage, I assert my identity as a software engineer, as a woman, as a speaker with a Cantonese-British-American accent, as someone who laughs at the smallest little thing, as myself. By being visible, I make it a bit easier for the next person who is working against the subconscious assumptions of what it means to be a software engineer, I push the envelope a little bit forward, towards a more diverse workforce in our industry.

Wanna speak?

I cannot believe that I only started speaking this year. And I cannot figure out why I never thought of doing it before. Perhaps you would like to give it a shot as well? Who knows, you may love it as much as I do.

There are many resources out there, We Are All Awesome and being two. I have given a talk on how to come up with talk topics, and also written a blog post on how to be a confident speaker. I'd love to share more, so let me know if there is something specific you want to hear about!

Technically Speaking

Edit: I started the Technically Speaking newsletter with Cate Huston two years after writing this blog post. Great resources delivered to your inbox every week!

View archive on TinyLetter

Thursday, November 22, 2012

Android: Jelly Bean forward locks paid apps

Today, a Monkey Write user complained that sound wasn't working on the workbooks he bought. I sell workbooks as separate paid apps on Google Play, which supplies data to the main app. Most of the data is retrieved via a ContentProvider, but for the sound the main app simply reaches out to the other apk and loads the sound file from its assets:

Context workbookContext = context.createPackageContext(
    packageName, 0);
AssetFileDescriptor afd = workbookContext.getAssets().openFd(
    "pronunciations/" + soundFile + ".ogg");

This depends on the resources and assets of an app being world-readable. But from the logcat, it seems that the main app could not find the sound file in the asset folder of the workbook app: pronunciations/kou3.ogg
 at android.content.res.AssetManager.openAssetFd(Native Method)
 at android.content.res.AssetManager.openFd(

I searched and searched on the internet to no avail, until I verified with the user that sound works fine for the free workbooks he downloaded. By including the word "paid" in my queries, I found a StackOverflow post with this critical bit of information:

Paid apps on JB devices are 'forward locked'. This means that the APK is split in two parts -- one with public resources, and one with private ones and code, which is not readable by other apps. I haven't looked into how files are split in detail, but the problem you are seeing suggests that assets are part of the private APK.

More importantly, he provided a way to test forward locking without going through Google Play: adb install -l myapp.apk

With that, I managed to reproduce and fix the problem. Since the assets of the paid app is no longer world-readable, I use a ContentProvider to read the sound file and have the main app query for it. The user has downloaded the updates from Google Play and verified that sound now works for paid workbooks. Yay!

Sunday, November 18, 2012


The grand finale for my Europe speaking tour is Devoxx. And grand is the right word for it.

A grand conference

Devoxx took place in Metropolis, the second largest cinema complex in Europe. The AV system is amazing. Gorgeous floor to ceiling projection with live video of the speaker on the left and slides on the right, plus a beautiful outer space background. Just stunning.

As if that is not grand enough, Stephan and team sprinkled the conference with panache. A troupe of Nao robots opened the conference with a dance, a motorcyle vroomed on stage in the middle of a keynote, celebrity speakers wearing giant hats... really good fun.

Nao robots

Java Posse with their signature hats

Android talks

I first heard about Devoxx from watching an Android talk on Parleys by Romain and Chet. Seems to cover many difference facets of Java, Android being one of them. In May I saw Romain and Chet in person at AnDevCon III, and asked them about Devoxx. That's when I decided to apply to speak there. Lo and behold, I got accepted!

Google delivered many awesome Android sessions at Devoxx, with Nick and Rich holding a hands-on workshop on the SDK, Romain and Chet talking about Jelly Bean, Xavier and Tor talking about the build system.

Chet and Romain talking about the developer options in Android 4.2

There were many great talks from non-Googlers as well. Pierre-Yves Ricau talked about Android Annotations, Jake Wharton showed us the open source libraries used at Square etc.

Jake talking about open source Android libraries

And then there is me, the ex-Googler! I talked about Android Custom Components, and people really liked it.

(Side note: did you know that Storify was started by Belgians?)

Awesome hallway

Although there were many wonderful Android talks, there were spread over 5 days, so for some time slots I ended up sitting out. Which is not a bad thing, because Devoxx has an awesome hallway setup.

There were two rows of tables with power strips in the middle. As we all know, developers swarm towards sockets to charge our gadgets, so this is like the well in the village square, where people gather and socialize. On top of that there was no special speaker preparation room, so everyone hang out here, igniting many interesting conversations. This is a brillant setup that every conference should copy!

Off-season Google I/O

As an Android developer, this tweet sums it up pretty well:

Great sessions, great people, great venue. Yes, it's far away, but I took advantage of that to enjoy some Belgian chocolate and beer. All in all, I'd love to speak at Devoxx again!

Tuesday, November 6, 2012

Droidcon Bucharest

After Droidcon London, I headed to Romania to speak at Droidcon Bucharest.

Droidcon Bucharest has a very strong community feel to it. There were about 80 people attending, and each of us introduced ourselves. It started in English, but then people slipped into Romanian. I could guess who were the students since the word in Romanian was really close to English, but it was great when they switched back to English.

From the introductions I gathered that Android is up and coming here in Romania, since there were quite a few student attendees. Around half of the audience said they have never done Android programming. I suppose they would be going to the 3-hour basic Android training in the afternoon.


Just like Droidcon London, we had Barcamp on the first day. I was a bit shocked when I saw the schedule.

15-minute per session? You need to run them with an iron fist to make sure everybody starts and ends on time. Turns out the schedule was merely a guideline. People talked for as long as they wanted, and the audience could asked as many questions as they had. And that's how a barcamp should be - it's over when it's over, no need to be fixated on the timing. I was just amused that they bothered printing time slots in the schedule when they had no plan to follow it.


Second day is conference day. I was the first speaker, and as usual I polled the audience before I started. Here only a few people made a custom view before, so I spent a lot of time covering the basics.

I noticed that Europeans are not as eager to shout from the audience when I ask questions, but I still wanted some participation, so I was throwing questions at them left and right. By the end they warmed up a bit, and I got a few people to answer loud and clear rather than mumble noncommittally. That made me happy, because it showed me that people are learning.

There was quite a variety of talks at the conference. I really enjoyed the UI makeover by Eugen Arbuleac and Andrei Catinean.

Roman Mazur gave an excellent talk on Android REST best practices. I will definitely be studying his open source project to learn a trick or two.

Regional event

At the end of Droidcon Bucharest the organizers gathered people from different cities to discuss how to foster the Android community in the region. There seems to be a lot of interests from students, and with some professional developers scattered here and there. With events like Droidcon bringing people together, I am sure the Eastern European Android community will flourish.

Here is a picture of me with some awesome Android ladies from Timişoara. It was great fun hanging out with them!

More Droidcon Bucharest coverage

Sunday, November 4, 2012

Droidcon London

The first stop of my European speaking tour is Droidcon London.

I absolutely loved the conference icons with the droid at London landmarks, and was very happy to see them adorning the venue.


The first day was Barcamp. I was astonished by the number of people that got on stage to propose a session. What was more amazing was that there were all super high quality. My experience at unconferences was that people come up with ideas on the spot, gather interested parties and hold an informal discussion. But at Droidcon London, people gave well-prepared, full-length presentations.

For instance I heard about RoboSpice, a library for asynchronous network requests. Stéphane brought a complete deck, pretty much treating it as a proper conference talk. I was impressed.


Second day was conference day, and once again it was jam-packed with great talks. There is a lot of tribal knowledge in Android, and at Droidcon London I felt that I was among the village elders, telling us creation myths and war stories.

SoundCloud jumped through lots of hoops to make streaming work

At my talk I shared my experience using custom components in Monkey Write. It was a mash-up from my Fluid Android Layouts and Android Custom Components talk, and I was very proud that I managed to trim the 1 hour and 45 minutes of material down to 45 minutes. Imagine my surprise when I got an email from the organizers a few days before the conference, informing us that our talks should be 35 minutes long. I stared at my presentation, unable to chop off any more slides, so I decided to go with the full deck.

Giving my talk. Photo credit: Alexandre Gherschon

At the beginning of my talk I polled the audience for their experience in custom components. As I expected most of them had written one already, allowing me to jump over the basics and went straight for the deep dive. I finished on time, and people came to me afterwards thanking me for sharing the advanced material. Yay!

Awesome people

As always my favorite part of conferences is meeting awesome people, and Droidcon London definitely delivered on that front. Most the attendees I met care deeply about perfecting their craft, and we had many interesting technical discussions in the hallway. I got to hang out with quite a few speakers as well. It was like going to Hollywood and casually chatting with celebrities. Totally awesome.

Droidcon London has a great vibe, and I attribute it to the enthusiastic organizers. The amazing lineup attracted developers from all over Europe, and it was rather magical to hang out with so many awesome people. Thank you very much for such a great conference!

Droidcon London organizers

Tuesday, October 9, 2012

Grace Hopper Celebration: Speaking and Connecting

Grace Hopper Celebration is my favorite conference of all times. Every time I go, I learn new things, make new friends, and come home energized. This year I am very honored to be accepted as a speaker, to share my experience as a female software engineer.

Letter to my younger self

The title of my talk is Letter to my younger self: Things I wish I knew when I first started working. I have made so many mistakes in my career that I wish I could go back and point myself in the right direction. Alas, I do not own a TARDIS, but I could pass the information to current students.

Once I came up with the talk idea, I invite two friends, Rupa Dachere and Christina Schulman, to present with me. They have quite a bit more experience than me, and we weave our stories together into the talk.

Me, Christina and Rupa
Me, Christina and Rupa

Speaking to a full house

When we got to the conference, we were rather surprised by the room assigned to our session. It was quite big, with 350 chairs (yes we counted). We anxiously watched people slowly filling the room, until all the chairs were all taken. Every single one of them. The ushers were actually turning people away!

View from the stage
View from the stage

We divided the talk into three parts: career, networking and negotiations. For negotiations, we lightened the mood quite a bit by demonstrating the techniques with skits. People loved it.

We were ruthless in cutting material from the talk to make sure we leave plenty of time for questions, for I always felt that is the best part of GHC sessions, the interaction at the end.

All in all the session went really well. It was a pity we didn't record the whole talk, but our session blogger, Lexy Holloway, types unbelievably quickly. She has a very comprehensive session report that is practically the transcript!

For more information on our talk, here is a collection of links:

Data science and cats

I was busy rehearsing all the way until our presentation, so I missed quite a lot of sessions. Now that I think about it, I only attended a single one during the whole conference. It was Short URLs, Big Data: Learning about the World in Realtime by Hilary Mason. What an outstanding talk! It was a great balance in technical details, insightful anecdotes, and humorous slides.

This slide, for instance, had me laughing uncontrollably. Hilary used it to illustrated that what we share is not what we click. People share links that reflects well on them, but privately they read very different things. Just like the cat dressing up as a chicken, we use sharing to groom a public appearance.

Hallway Track

Although I only went to a single session, I felt I benefited a lot from the conference nonetheless. I love to hang out in the hallway, wave at people I knew from previous conferences, and reconnect. We met over breakfast, lunch, dinner, drinks, even in the swimming pool. Each of us brought friends, made introductions, and expanded the circle of camaraderie.

I am actually very glad that I spent the majority of my time on the hallway track, to connect with women from all walks of technology, to support each other, to celebrate our achievements. This is the best part of Grace Hopper Celebration!

Monday, October 1, 2012

Europe Speaking Tour

When I set up my goal to be a public speaker, I had no idea that it will bring me to far away places like Amsterdam, where I gave a talk at Dutch Mobile Conference. I have applied to a few more European conferences, and to my surprise got accepted by all of them!

The conferences are quite close to each other in terms of time:

Oct 25 - 26 Droidcon London, UK
Nov 02 - 03 Droidcon Bucharest, Romania
Nov 12 - 16 Devoxx, Antwerp, Belgium

I was super excited about the acceptances, but it is taking me a long while to get all the logistics in place. With such long flights it makes more sense for me to stay in Europe, and do some sightseeing between the conferences.

For the week between the Romanian and Belgian conferences, I want to try something different. Instead of sightseeing, I am going to work remotely. I am looking into AirBnB for lodging right now, but it would be even more awesome if I can stay with a local developer. That way I can really get a feel of the tech scene over there, and live like a local.

The only problem is, I don't know anyone in Brussels. Or Gent. Or Bruges. Or Antwerp. Which is why I am writing this blog post right now. Do you know anyone in the greater Brussels area with a spare bed or sofa? I'll be repaying the kindness in Chinese language lessons or Android programming help, whichever is preferred :-)

Puzzle Pal: Substring extractor

I was at BANG 33 yesterday, and one of the puzzles involved extracting words out of other words. We did the extraction by hand at the game, but today I set down at my desk and added a substring extractor to Puzzle Pal.

While I was at it, I also bundled the wordlist into the main app, and updated the UI to use action bar.

If you find Puzzle Pal useful, please review it on Google Play. You can also leave a comment here if you have ideas for other solvers and decoders.

Happy puzzling!

Wednesday, September 19, 2012

Android: Swipe Image Viewer with ViewPager

A few months ago I complained that there is no standard widget for a swipe image viewer. I just asked about it on Twitter, and discovered that ViewPager is what I wanted.

I updated my github project with a ViewPager implementation, and it's so much simpler. On top of that, the images slide as your finger swipes across the screen, giving a much more satisfactory feedback.

Sunday, August 26, 2012

Browser extensions workshop

CodeChix held a Browser Extensions workshop, led by Sharon Minsuk. She described what browser extensions are, showed us a few demos, and then we had some hands-on coding exercises.

I toyed with browser extensions briefly, but stopped because I couldn't figure out how to include jquery. After the workshop today I got inspired again, and wrote my first extension to add tooltips for airport codes.

Say you are reading some forum post with lots of airport codes:

My extension will add an airplane icon after each 3-letter airport code. Hover over the airplane gives you the name and location of the airport:

The code is on github: You can also download the packaged extension directly.

The parsing is pretty crude, and I didn't use any jquery at the end.

It only took me an hour or so to make the extension, and I'm quite happy with the results. Thank you Sharon for the excellent workshop!

Saturday, August 25, 2012

Bash prompt

After attending the Cool Git Tricks talk by Carina Zona at Women Who Code Lightning Talk this Tuesday, I decided to add git status to my bash prompt.

Here is how it looks like in action:

chiuki@moomin 09:50 ~/github/android-square-view master $

  • username@hostname: Basic info.
  • Time: I show time in my prompt so I can start a long-running job and go to lunch. The prompt will be displayed the moment the job returns, so I can subtract and see how long it took.
  • Current directory: Gives me some context.
  • git branch: I show it in blue when I am in master, purple otherwise.
  • git status: I show a red star if the current directory is dirty.
  • $: The color indicates if the last command was successful. Green for success, red for failure.

So if I'm on the release branch, has pending changes, and the last command failed, my prompt would look like this:

chiuki@moomin 10:05 ~/github/android-square-view release* $

What do you show on your shell prompt?

Wednesday, August 22, 2012

Develop your voice

When I first started working, I was happily learning all kinds of new stuff: source control, working in a team, unit testing, etc, etc. After two years or so, I felt quite comfortable as a software engineer, but I had no idea how to grow further. I have since discovered that the most important thing is to develop your voice, and here is my lightning talk on the topic:


Voice is an interesting word, because it encompasses so many things. It's your vision, your direction, what you believe in and what you stand for. Voice also implies that it needs to projected, that you need to let other people know what you are trying to do.

Others don't know more than you

How many times were you in a conversation, forming an opinion, someone spoke and you discarded your thoughts? The distinguishing characteristic of someone who has found his voice is that he talks. He is using his voice, but that does not mean that he knows more than you. Be aware of that so you can listen critically and form your own opinion.

Delete "I think"

Email is a great way to build up your voice. Before you send out any emails, delete phrases like "I think", "I believe", "Maybe we should do it". They dampen your voice, and make you sound weaker than you actually are.

Reply to group emails

When someone poses a question to your team mailing list, reply. Don't go off and research for half an hour to come up with the perfect response. Just tell them the steps you were planning to take, and the expected outcome. As your name appears more and more on the mailing list, people think about you more, and will start asking for your opinion.

Sit at the table

Your team has regular meetings, right? Don't hide in the back row and bury your head behind your laptop. Sit at the table, and make a presence. Better yet, sit next to your boss. That takes courage, which sends a very strong signal. Also, your boss will probably turn around and ask you for your opinion, so you don't have to shout and wave to get your voice heard.

Learn to say no

To develop your voice, you need to focus on what matters the most, and stay on course. There are a million things that people want you to do, and you need to push back on the ones that don't matter. In the process you will learn to defend your position and vocalize your priorities.

Let your voice lead you

Realize that you have something to contribute, make a presence in emails and meetings, and defend your position. Slowly but surely your voice will emerge. Let that guide your career, with confidence and a sense of purpose.

Friday, August 17, 2012

That Conference

I have been actively seeking public speaking opportunities, which led me to places that I'll never visit otherwise. For instance, I was just in Wisconsin Dells, the venue of the inaugural That Conference.

Getting there

Since it was the first year, there wasn't much guideline for talk submission. The topic was "Web, Cloud and Mobile", so anything goes. I submitted a few Android talks, and got accepted. But since the conference has so many speakers, they don't have funds to cover the travel expense of the speakers. As an independent consultant, time is literally money, since I only bill the hours I work for my clients. To travel out-of-town and be at a conference is already quite expensive in terms of time, and I just couldn't get myself to pay for the flights and hotels as well.

I was going to withdraw from the speaker roster, then realized that I am probably not alone. I have been working hard to convince more women to step up and give tech talks, and I wonder how many of them hesitate because of travel costs. This is a problem money can solve, and a very concrete thing companies can do to support women in technology.

With that in mind, I started emailing various companies. I got worse than "no" for an answer, for they simply ignored me. Well, at least I tried, I told myself. Two months later, I got a response from Etsy Hacker Grants, saying that they would love to send women to speak at tech conferences! I was very pleasantly surprised.

At this point I have already given away my speaker slot at That Conference, but they are running Open Space sessions at the conference, and suggested that I came to present my Android talk there. Sure, I said, but I also asked them to put me on the backup speaker list in case there were cancellations. And sure enough, somebody cancelled, and I was back as a camp counselor aka official speaker.

The crowd

Given that the topics were "Web, Cloud and Mobile", I was really surprised that this turns out to be a very Microsoft heavy conference. I don't really get much exposure to Windows technologies in the Bay Area, so I took advantage of the situation and went to a session on building Metro applications. But as the day went on, I had this guilt feeling that I wasn't learning enough to justify taking time off to come to the conference.

That all changed in the evening. I went to dinner with a bunch of people, one of whom works on both iOS and Android. We discussed image caching on Android, geolocation on iOS, and just talked shop in general. And that was so much fun.

The next day I went to an Open Space session on Android game programming. I wanted to attend the session because of Android, but also because the guy who proposed the session shares a last name with a very good friend of mine back in the Bay Area. Turns out he is his brother!

I felt quite lonely as an Android developer in the sea of Windows folks, so this session was really cool. It brought the 8 of us together in this 600-person conference, and we had a great time exchanging tips on Android programming. Yay Open Space!

My talk was on the last day, and around 15 to 20 people attended, some from the Open Space session. I gave the same talk in Chicago already, but each crowd is different, and we drilled down to different parts of the talk. Overall it went really well.


That Conference was held in a waterpark, and it was reserved for the attendees on Tuesday night from 10:30pm to 1:30am. There was a long break from dinner until the waterpark party, so we went back to the Open Space room and played Race for the Galaxy.

It is a pretty hefty game to learn, but I had confidence in my fellow conference attendees, and I think everyone enjoyed the game.

10:30pm rolled along, and off to the waterpark we went. I haven't been to a waterpark for such a long time! I tried all the slides, and went on the vertical drop 3 times. It was tons of fun. I brought my diving camera and filmed one of the rides:


Overall I had a pretty good time at That Conference. The official sessions were not very appealing to me, but the people made up for it. I know I will be keeping in touch with a few of them, and that is what I call meaningful connections.

Saturday, August 4, 2012

Tally Counter for Smart Watch and Headset

I've been trying to come up with an app for my Sony Smart Wireless Headset pro, and like I mentioned in my Ignite talk, I often get new ideas when I swim. This time, however, it was quite literal. I was handing my pass to the clerk at the counter, and he clicked on his tally counter to keep track of how many people went swimming that day. That is perfect for the headset! It just needs one button to operate, which the headset has a big one in front, somewhere to show the counter, which the headset can do on its display.

After the made the app on the headset I decided to put it on the watch as well. Initially I used the same style, but then I realized the watch has a color screen, so I added some gradients to give it a background that looks like the dial on an odometer.

I did some user testing: gave the watch and headset to my husband to try. The headset was great, he said, because the button gave him tactile feedback, so he knew he clicked successfully without looking. Maybe I could add vibration to the watch? It was a really great idea. Besides giving tactile feedback, the vibration made a little buzz, and it happens to emulate the sound of a real tally counter. It was really satisfactory to tap on the watch and hear the count go up.

See it in action in this video:

Get this extension for free from Google Play: Tally Counter for SmartWatch.

Monday, July 30, 2012

Android: Swipe Image Viewer

EDIT: I have a much simpler implementation with ViewPager, and the github project has been updated. See post here.

I have a GrideView of images, which enlarges to full screen when you tap on any image. When I showed it to my friend he swiped to get to the next image, but that did not do anything because I was just using a plain old ImageView. I looked around for a standard widget to do that, and couldn't find any. So I unwillingly rolled my own solution:

I show the image in an ImageSwitcher. It contains two views, one displays the current image, and the other one holds the image to swap in. I lifted the gesture listener code from the Android Gallery app:

private class SwipeListener extends SimpleOnGestureListener {
  private static final int SWIPE_MIN_DISTANCE = 75;
  private static final int SWIPE_MAX_OFF_PATH = 250;
  private static final int SWIPE_THRESHOLD_VELOCITY = 200;

  public boolean onFling(MotionEvent e1, MotionEvent e2, 
      float velocityX, float velocityY) {
    try {
      if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
        return false;
      // right to left swipe
      if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
      } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    } catch (Exception e) {
      // nothing
    return false;

moveNextOrPrevious() swaps in the previous or next image with the appropriate animation:

private void moveNextOrPrevious(int delta) {
  int nextImagePos = mCurrentPosition + delta;
  if (nextImagePos < 0) {
  if (nextImagePos >= mImages.length) {

    delta > 0 ? mSlideInRight : mSlideInLeft);
    delta > 0 ? mSlideOutLeft : mSlideOutRight);

  mCurrentPosition = nextImagePos;

Notice how I show an overscroll grow when the user reaches the start or the end of the list of images. I make it visible immediately, and then use an animation to fade it away.

Right now all the logic is in MainActivity. I thought about encapsulating the viewer code into a custom view and bundling it into a jar file, but I am not sure how many people will find it useful, so laziness got the better of me. If you want to get a jar file to reuse this code, please let me know.

Until then, here is the source code:

Tuesday, July 24, 2012

#weareallawesome for public speaking

Every Tuesday at 1pm Pacific Time We Are All Awesome holds office hours on #weareallawesome on freenode. This week I asked Lorna Mitchell to share her experience at OSCON.

lornajane: I have never been to OSCON before, and I got two talks accepted that were kinda out of my league (I just submitted in the vague hope that something would happen)
chiuki: What do you mean by out of your league?
lornajane: both were scheduled on the same day - and they both went well!!! One of them was so full they shut the doors 5 minutes early
lornajane: chiuki: they were topics I didn't feel expert on
chiuki: ah
chiuki: but topics people want to hear
lornajane: yes, exactly
chiuki: what are the topics?
lornajane: I am very good at writing abstracts now - I have lots of practice at that! It was a PHP 5.4 talk (which actually was quite fun) and one about REST
lornajane: I am expert in REST but I hate speaking about it because it's contraversial and that part of the industry seems to make a habit of flaming and then I get upset
lornajane: the rest of my week was amazing, I've never been to Portland before and I loved it
chiuki: were there pointed questions at the REST talk?
lornajane: I met new friends and caught up with old ones, attended talks and tutorials in all kinds of technologies that I know nothing about, met loads of exhibitors and had fun at the parties
lornajane: chiuki: almost none. I mean, I got some questions laid down as a challenge, but I gave my (not-the textbook-version) opinion and the guy thanked me for my input
chiuki: cool
chiuki: so no flaming, then
lornajane: none!
lornajane: actually the OSCON crowd were all very friendly. I didn't know what to expect which was maybe fuelling my fears

I was curious about topics to submit, and Lorna has some insights:

chiuki: Any tips on submitting proposals to OSCON? What kind of topics go well?
lornajane: chiuki: it seems to be complicated, because there are tracks, so you're sort of submitting to subconferences
lornajane: so I aimed my talks firmly at the PHP track, and I know those people (and I stalked them on twitter!)
chiuki: That's a good way to look at it, to treat each track as a subconference
chiuki: I bet each track has its own review committee too
lornajane: chiuki: it exactly does
lornajane: I'm well-known in the PHP community so I pitched two talks to them (which they took) and one more general one (which didn't get in)
chiuki: the general one for a different track?
lornajane: yeah, it was like "algorithms for a geek lifestyle" or something like that
chiuki: oh I remember now
chiuki: I actually submitted something
lornajane: because I saw a few lifehacker type talks
chiuki: for being an indie developer
chiuki: but got rejected
lornajane: but mostly it was just good, clean tech all the way through
chiuki: next year I'll submit some hardcore Android talks for the mobile track
lornajane: chiuki: definitely do that!
chiuki: I think I got confused by the OS part of OSCON
chiuki: focusing too much on open source
chiuki: Android is open source, but that's not the part I work with
lornajane: they aren't militant about open source
chiuki: so I was trying too hard to cater to the OS part
chiuki: I'm looking at the program
chiuki: my existing Android talks will go really well

chiuki: I wonder if the twitter stalking helped you got your proposals accepted, lornajane :-)
cczona: what was the twitter stalking?
lornajane: chiuki: I don't know! I figured it didn't hurt :) Laura told me though that they had loved my proposals and that it was unusual to take two
lornajane: cczona: I know who runs the PHP track at OSCON so I tweeted at her when I submitted, just a little touch to remind her
cczona: Good idea.
chiuki: yeah, it's good to get your name in front of people

Rebecca Murphey, Carina Zona and Estelle Weyl chimed in when we discussed speaker packages:

lornajane: the main thing with oscon is that they have no speaker package
lornajane: so unless you work for a big company, it's hard to go
chiuki: no financial aid whatsoever?
lornajane: officially, not at all. In fact they can help out if you ask them, sometimes, but it seems a bit hit and miss
rmurphey: how much are oscon tickets and oscon sponsorships?
lornajane: rmurphey: I am not sure, I think the tickets are 1200 USD
chiuki: 1200USD????
chiuki: OMG
rmurphey: i am a tad bit puzzled as to why they can't cover speaker costs
rmurphey: sell one ticket per speaker, done
lornajane: rmurphey: the speakers are confused about that too
lornajane: rmurphey: most of them are big company people so it's no pain to them
lornajane: OSCON did cover my flight when I asked them to (I'm coming in from Europe and I'm self-employed)
rmurphey: good for you for asking lornajane :)
lornajane: rmurphey: actually, estellevw told me to
lornajane: and the devchix helped me find somewhere cheap to stay
lornajane: then the phpwomen helped me with my slides because it was all quite short notice
lornajane: hurrah for women in tech, is all I can say!
cczona: yeah
chiuki: hurray!
cczona: that's a great testament to the support available in the community
lornajane: *and* the systers had a lunch while we were there and I met more cool ladies doing amazing things. I felt so inspired by everyone's support
cczona: :-)
lornajane: oscon gives a pass, I should have said that. But nothing else
estellevw: O'Reilly does pay for some speakers. I assume if they want you to speak and don't think you can fund it thru a company.
rmurphey: if you would like to read a host of opinions on the topic,
rmurphey: but be warned
rmurphey: there are 181 comments

This is just a sample of the things we discuss on #weareallawesome. What do you want to talk about? Come join us some time!

Wednesday, July 18, 2012

Sony Smart Wireless Headset

I got a Sony SmartWatch from AnDevCon, and published two apps on Google Play:

Slideshow for SmartWatch

Fake Call for SmartWatch

I told Sony about my apps, and as a result they sent me a Sony Smart Wireless Headset to develop more apps!

I went to Google Play to get some apps for the headset, and there aren't many available. Here is the Twitter app:

The headset has a display, a microphone, and comes with an SD card to store your music. Besides playing music from the SD card, you can listen to the radio, and stream music from your phone or computer. It also has quite a few buttons:

  • Back key/Menu key
  • Previous key
  • Music key/Select key
  • Next key
  • Action key
  • Power key
  • Volume controls

With earphones and microphone, a display, and all these buttons, I'm sure there is a cool app waiting to be written. Guess it's time to study the SDK!

Sunday, July 1, 2012

Public speaking mid-year score card

Can you believe it's July already? I started the year with a resolution to be a public speaker, with the specific goal of giving 5 lightning talks and 3 full-length lectures. Let's see the mid-year score card!

Lightning talks

  1. April 2, 2012: Ignite Where 2012, San Francisco, CA
  2. June 28, 2012: Ignite Google I/O, San Francisco, CA

Full-length lectures

  1. April 6, 2012: Fluid Android Layouts, WindyCityGo, Chicago, IL
  2. April 11, 2012: Caching Strategies for Mobile Apps, Philly ETE, Philadelphia, PA
  3. April 17, 2012: Mobile Caching Strategies, Twitter Engineering Submit, San Francisco, CA
  4. May 16, 2012: Reusable Custom Components, AnDevCon III, Burlingame, CA
  5. June 8, 2012: Progressive enhancement for Android web apps, Dutch Mobile Conference, Amsterdam, the Netherlands

Looks like I'm coming short on the lightning talk side, which is quite surprising. I thought it would be more difficult to get accepted to give lectures. Also interesting that all my lightning talks were in Ignite talks, which is way more challenging than the speak-at-a-meetup quick talks I had in mind when I came up with the goals.

Ignite at Google I/O

Ignite talks are challenging because it follows a very specific format: 5 minutes, 20 slides, auto advancing. The auto-advancing slides is the trickiest bit, since you don't control the rhythm any more. I rehearse way more for Ignite than my full-length lectures, because I need to internalize the timing to sync my speech to my slides. It's almost like lip-syncing!

The first time I gave an Ignite talk was at Where 2012, to a crowd of 30 people or so. I was rather scared of the auto-advancing slides, but I found that I just need to wait until the next slide to appear before transitioning to a new topic.

Ironically, because I felt I did pretty well at my first Ignite, I was more nervous when preparing for my second one. I kept thinking that it was not quite as good. I mentioned that to my friend Julia, and did a practice run with her. She loved it! I notice that I really feed off the energy from the audience, even if only one person was listening. So the practice run was all I need to get back my confidence.

Ah, confidence is such a fragile thing. I walked into the room, and wow, it's big! It probably seats a thousand people. A thousand people! Plus the event was live streamed. I never spoke to such a large crowd, and I was so ridiculously nervous while waiting for the show to start. Fortunately once I got on stage I was back to my elements.

Here is the recording of the Ignite show at Google I/O. Let me know what you think!

Tuesday, June 19, 2012

How to be a confident speaker

Zach Holman posted an excellent article on tips and tricks for public speaking, which got me thinking about my own experience. I have given a few speeches now, and I'd say the most important thing is to be confident. I know, that's like saying you need to breathe in order to stay alive. So here are some practical tips.

Practice until you are comfortable, but not more

I have heard many contradicting advice on practicing: practice until you memorize your speech, don't memorize your slides because the presentation will be stiff, record your speech to find things to improve, etc etc. Truth is, everyone is different, so the rule of thumb is practice to the point you feel comfortable.

Personally I never write down what I plan to say, for I fear that I will miss a sentence when I'm on stage. Instead I use my slides as guidelines and talk over them. This gives spontaneity to my talks, makes them lively. I also don't do speaker notes, but some people swear by them. Again, do what's comfortable for you.

Have a mock session

Now, how do you make sure you don't over-practice until you beat the life out of your speech? Schedule a practice session! With a solid deadline you will have to stop practicing and actually give your speech.

When you give your mock session, do it for real: hook up your laptop to a projector, and speak to a live audience. This serves many purposes:

  • Time your speech. How many minutes do you take to go over a slide?
  • AV issues. How do you change the resolution of your laptop? If you are playing video, where does the sound go? How is the contrast on the images? Font size OK?
  • Learn to look at your audience. Connect with them, speak to them, clarify if they look confused. Chances are, you will feel encouraged by their approving nods, and forgot that you were nervous.
  • Stumble onto random problems, and recover from them. There is never a perfect speech, but knowing that you can get yourself out of a situation is very reassuring.

Most importantly, the practice session proves one thing: you can talk!

The audience assumes you know more than them

You've done your practice session, now you're ready for prime time. It's natural to be nervous, but remember, once you stepped on that stage, you are the expert. People come to listen to you because they want to learn from you. They could go to another talk, chat in the hallway, or stay home to watch TV. But no, they chose to come to your talk, because they believe you can teach them something.

The scale is tipped in your favor because you are on stage. Everybody wants you to shine, so whenever you have self-doubt, remember that.

It is okay to say I don't know

You gave your speech, and now comes the terrifying time: questions! I used to feel like if I don't know the answer I would disgrace myself in front of a crowd. But guess what, it's not a test! You are there to share what you know, not to be a walking encyclopedia. If you don't have a ready answer, just say so. Turn the question to the audience and ask if anyone knows. Usually an interesting discussion will unfold. If not, have them contact you afterwards, and promise to follow up.

Just do it

You cannot learn to ride the bicycle by reading a book. Start small, give a short talk at a local meetup. Be yourself, and go with the flow. You will be alright.

Tuesday, June 12, 2012

Dutch Mobile Conference

Ladies and gentlemen, I am proud to announce that I am now an international public speaker, for I just came back from Amsterdam after giving a talk at Dutch Mobile Conference.


Since I just got started in public speaking this year, I had no idea how conference proposals are selected, and I was submitting to pretty much every conference that I have something to share. Android conferences are obvious, but I even submitted something to Fluent Conf, a javascript conference. Now, the normal thing to do is to propose a javascript talk, since I did work on web development for a year and a half. But no, I ended up drafting a talk on embedding a WebView in an Android app and writing a javascript bridge to call native Android functions from a web page. I wasn't expecting it to be accepted, but I thought I'd try anyway.

Fast forward a few weeks, and I was browsing Lanyrd for Call for Speakers, and stumbled upon the call for Dutch Mobile Conference two days before the submission deadline. DMC focuses on mobile web apps, so a talk on bridging web and Android with a javascript bridge sounds pretty relevant. Copy-and-paste I went, submitting my Fluent Conf proposal. On a fine morning in February I got an email from the organizer for DMC. They accepted my proposal!


I did not prepare my talk until May, a few weeks before the conference. At the point I was panicking a little, because I don't use WebView in my day-to-day work, and I didn't feel comfortable giving a talk about it. I was speaking at AnDevCon III around then, and Stephan Branczyk asked me to repeat my session at his Android meetup. I told him that I'd rather give the DMC talk since I wanted to rehearse, and he liked the idea.

As I prepared the slides, I discovered that I am actually describing the Android implementation for PhoneGap. More panic ensued. After all, they could just use PhoneGap, so why bother listen to me explaining how to roll your own? I thought about not giving the talk at all, but flights and hotel have been booked months in advance, and I really couldn't get myself to give up the chance to see Amsterdam. I went ahead and give my talk at the Alameda Android meetup, and the audience found it interesting. One of them was using PhoneGap, and he was happy to learn the inner workings. That gave me back my confidence, knowing that I am still sharing valuable information.


Comes June, and off to Amsterdam I went. DMC ran alongside DPC, Dutch PHP Conference. The same conference pass was good for both conferences, and I ended up going to quite a few sessions on the PHP side. They were not strictly PHP talks though, but rather related technologies that are useful to PHP developers.

Scalability talk
Scalability talk

For instance, Thijs Feryn gave an overview of scalability, and many of the same technologies can be used for a Django or Rails server.

Frontend and backend
Frontend and backend

My talk was in the afternoon on the first day.

I reviewed my slides the night before my talk, and realized that I prepared it for the Android meetup, but this audience probably little or no experience in Android development. I did not really have time to prepare more slides to give an Android overview, so I just added a slide with the Android logo, and talked over it.

At the beginning of the session I warned the audience that it was going to be very heavy on the Android side, and invited them to ask me to clarify if anything was not clear. I was very happy when the questions got raised, because it meant people were following along. And they seemed to like the talk, according to feedbacks on Yay!


The organizer took great lengths to make sure that everyone enjoyed the conference. There was a social gathering for all the attendees at a bar after the first day, and I stayed until 3am, chatting with everyone.

As a speaker there were even more events. The day before the conference we met in the hotel bar to get to know each other, then went to dinner at a restaurant next door. On the first night there was a speaker dinner, where we were presented our speaker gift - an Arduino!

Arduino Uno
Arduino Uno

That was the perfect gift for techies like me. I have wanted to tinker with Arduino for a while, but didn't get around to order one. So I am very excited about this gift.

Overall the organizers took really good care of the speakers, and I had a wonderful time. A big thumbs up to the everyone running the conference!

Monday, May 28, 2012

Sony SmartWatch as name tag

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 = {
Cursor cursor = mContext.getContentResolver().query(
  MediaStore.Images.Media.DATA + " LIKE ?",
  new String[] { folder + "/%"},

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 : 

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:

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: If you do, ping me. I'm curious what you'll do with the SmartWatch!

Friday, May 25, 2012

Monkey Write: Now with pronunciations!

When I showed Monkey Write to new users, 8 out of 10 people would ask me, "why doesn't it pronounce the character?" My philosophy has always been "launch early, launch often", so I put Monkey Write on the market even though it was missing this obvious feature. Not any more - the latest version of Monkey Write includes pronunciations!

I recorded the characters over the weekend:

See the fancy microphone? My friend does voice-over for videos as a hobby, and I spotted the microphone when I went over to his place for board games. I borrowed it for the recording, and the sound was wonderful.

For software, I used Audacity. It was fun to see the sound wave of the characters. Look like tropical fish to me!

I sounded out all the characters in a workbook, usually twice per character, and then exported each character as a separate ogg file. Audacity made that pretty easy, which was a relief, since I always ended up yelling at iMovie whenever I needed to edit videos. A media editing UI that makes sense! Such a pleasure. If you know any one who worked on Audacity, please give them a pat on the shoulder from me.

Monkey Write pronounces the character automatically when you enter this screen. If you want to hear it again, press the sound button on the top right corner. When you are done writing the character, you will hear the character one more time.

The pronunciation-enabled version of Monkey Write is now available on Google Play Store, Amazon Appstore and the NOOK shop. Grab a copy, and let me know what you think. Will be great if you can write a review on the store too!

Thursday, May 17, 2012

AnDevCon III

When I decided to get onto the speaking circuit, my very first acceptance was my proposal to AnDevCon, way back in January. Four month later I suddenly realized that the conference was coming up in a week, and got really excited. The anticipation reminded me of the way I felt when I was going to visit an amusement park. But instead of roller coasters and free fall machines I was looking forward to tech talks and new gadgets. And AnDevCon did not disappoint.

Great talks

The speaker lineup was quite impressive:

  • My favorite talk was by Jake Wharton, the author of ActionBarSherlock. He showed us some powerful design patterns, each with a dead simple drop-in library for implementation. On top of that he was very candid, so his talk felt more like a friendly chat than a stiff lecture.
  • Saša Gargenta is so knowledgeable about the Android stack that my head was spinning just after a quick glance at his architectural diagrams. I learned a lot from his session.
  • I have watched Romain Guy and Chet Haase on video, but I had no idea that they are so funny in a live show!

My talk

I'm very honored to be speaking among such luminaries. Last month I read Confessions of a Public Speaker, and the author suggested bringing books as presents to encourage audience participations. I have not written any books, so instead I baked some Android cookies to give away.

I gave them to people who asked and answered questions, and I think that lightened the mood quite a bit. As the crowd warmed up we had a pretty good dialogue going, and I really enjoyed giving the talk.

Great discussions

Throughout the conference I got to geek out with my fellow Android developers, share our common frustrations over loading bitmaps, swap tips and tricks about xml declarations, and support each other in making outstanding applications. I am very happy that there was ample time between sessions for coffee breaks, where most of these conversations happened.

Great swags

The exhibition hall was a treasure trove. I got many t-shirts and fun little toys, but the exhibitors were also very generous in handing out devices to aid developers. I submitted a few app ideas to Sony and got a SmartWatch to develop them. The Blackberry folks was so impressed with Monkey Write that they gave me a Playbook to port it over. And on top of that, I won a Sony Xperia Arc S in the raffle!


Much like a visit to an amusement park, I am still abuzz with excitement from AnDevCon. I have quite a few new things to try for Monkey Write, and I may write an app or two for the SmartWatch too. I highly recommend AnDevCon to all Android developers.

More AnDevCon III coverage

Saturday, May 12, 2012

Popcorn.js with html5 slides

I heard about popcorn.js for a while, but did not have a chance to try it out. When the video of one of my talks became available, I knew I found a nail for this lovely hammer: I'll use popcorn.js to synchronize my slides to the video!

It only took a minute to embed the vimeo video. Next I wanted to change the size, so I added style="width: 160px; height: 120px" to the div container. No video. Baffled, I scoured the web for popcorn.js demos, and compared the source code with mine. By process of elimination I discovered that my html5 slides was to blame. The body tag has display: none so the unstyled articles tags do not show, but this means when popcorn.js cannot measure the size of the div container, it got zero width and height. As a work around, I added = "block" after the html5 slides are initialized, but before I create the popcorn object.

Next I annotated the slides with timings from the video. I extracted the timings and use the Code plugin to update the slide. The first jump worked. But when I added a second one, the slides were no longer moving.

My code looked like this:

for (var i = 0; i < articles.length; ++i) {
  var article = articles[i];
  var timing = getTiming(article);
    start: timing,
    onStart: function(options) {

After a lot of experimentation, I finally got it to work:

for (var i = 0; i < articles.length; ++i) {
  var article = articles[i];
  var timing = getTiming(article);
    start: timing,
    slideNumber: i,
    onStart: function(options) {

Notice how I stash away the value of i in the hash as slideNumber and grab it from the options inside the onStart callback. What happend was that when I use the variable i directly in the callback, its value has been changed by the for-loop when the callback is executed, so it ended up calling gotoSlide(article.length), which is not valid.

My slides now have a small video playing in the top right corner, which auto-advances the slides when you start watching. Have a look and let me know what you think!