Tuesday 14 September 2010

Feedback

The Google Market has terrible search and filtering, only really works when you're browsing it on a phone using the Google Market app, and it's slow. But there's one thing it does right: It makes it really easy to leave comments and feedback on the applications you download. And for developers like me, that's a wonderful thing. Like, for example, this email I received the other day regarding my Notepad app.
This app is great. it really allows me to put all my Alchemy notes in one easy place and is just perfect for my research. thank you for making this app for us.
For me, feedback like this makes it worth all the time and effort I put into making my apps.

Even negative feedback is a wonderful thing, if it comes with an explanation of why. Like in this comment someone left in the Market:
Don't like that when you change your screens orientation it clears the screen and creates a new note (saves the text).
That one made me realize I wasn't handling orientation changes correctly, and led to the release of Notepad v1.03.

So if you find something wrong with any of my apps or have suggestions to improve them, please feel free to write me an email, or file an issue!

Friday 10 September 2010

Mobile Internet Device

Recently, I got an Eken M002 Android tablet. Or rather, I think it's a M002, since neither the device nor the manual contains any sort of brand or make markings except "MID".

It has a 7" screen, built-in webcam, microphone, speakers, tilt sensor and WiFi. There's hard buttons for power on, menu, volume + and volume -, and an iPad-like back button. On the bottom, MicroSD slot, 3.5mm headphone jack, a power jack for the included power adapter and a custom slot that fits a weird little expansion box with an ethernet port and two USB ports.

OS-wise, it runs Android 1.6, kernel version 2.6.29, build number 1.7.3. Reported memory size is 256 MB, and the model number is reported as "generic". It's got 1GB internal storage, called LocalDisk.

It has the default Android Alarm Clock, Browser, Calendar, Camera, Contacts, Email, Gallery and Maps apps. The device doesn't have any location sources, so that last one is of limited use.

Magic Album
In addition, there's a bunch of custom apps made by WonderMedia Technologies, including Magic Album, My Music, My Photo and My Video, plus a number of utilities: File Browser, PK Manager (manages packages), Picture Capture (takes screenshots) and YouTube, the latter definitely not the official YouTube app.

Magic Album is actually pretty nice. Displays the weather (defaulting to Beijing), time and date. And since it prevents the device from sleeping, it actually is useful as a calendar/clock.

Finally it has Apps Store, which is the Wonder App Store app. Looks nice, but a lot of the apps are Chinese, and I can't read Chinese.

Apps Store
Finally, it has a bunch of shortcut apps. "Gravity sensor setting" links to exactly that, "Ethernet" links to the system settings Configure ethernet page, "Settings" links directly to the overall system settings list, "Wi-Fi settings" links directly to that.

The device feels noticeably slow opening apps and the touch screen isn't of the highest quality, needing a delicate touch to prevent the first touch of a scroll swipe from being read as a press. Web browsing works acceptably. I mostly use it as a clock and weather station with Magic Album and occasionally as a digital photo frame and for that, it works very well.

And with the not too-recent version of Android and the hdpi screen, it's a very, very good platform for testing my apps on.

Wednesday 8 September 2010

Bad Sample Is Bad

If you look at Google's Note Pad sample application (and code based on it), you will find a pattern that goes something like this:

\samples\NotePad\src\com\example\android\notepad\NoteEditor.java:109

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final Intent intent = getIntent();
    final String action = intent.getAction();
    if (Intent.ACTION_EDIT.equals(action)) {
        mState = STATE_EDIT;
        mUri = intent.getData();
    } else if (Intent.ACTION_INSERT.equals(action)) {
        mState = STATE_INSERT;
        mUri = getContentResolver().insert(intent.getData(), null);
    }
    ...

This is bad and wrong.

The idea is entirely logical: You have an Activity that either loads an existing item or creates a new one depending on the action that's passed to it, and then lets the user edit what it has. The UI for 'fill out new item' and 'edit existing item' is the same so it makes sense to roll the two cases into one.

The catch is actually clearly pointed out in the Activity Lifecycle documentation: Android can completely stop and destroy your activity and then create it anew when the user moves back to it.

One place this happens is during configuration changes, like anytime the user tilts his phone to the side and the screen goes from portrait to landscape. The activity gets paused, gets a chance to save state, then stopped. And then it gets created again, with the saved state passed along.

And in the code above, that saved state is completely ignored and a new, empty item is cheerfully inserted into the database, loosing whatever the user had previously entered. Tilt the phone to and fro a few times and you end up with a whole bunch of blank items and a very confused, unhappy user.

The fix is to save the uri of the item that's being working on in onSaveInstanceState() and reload that item in onCreate(). During ACTION_INSERT, insert a new item only when savedInstanceState is null.

In my own code I create a new note only when no saved state is passed along. And I actually go one step further and save the entire original note so I can offer a 'Revert Edits' command.

Tuesday 7 September 2010

Devices and SDKs

My first real smart device was a Palm V. For its time, it was an amazing device and even today, the hardware looks gorgeous. I never managed to find an SDK for it, though.

After that I got a Sony Ericsson P800, and later upgraded to the P910. There is a Symbian/UIQ SDK, but I never got it to work. A humongous download, an ancient gcc toolset, separate emulator images, everything command-line and nothing documented.

Compared to that, the HTC TyTN II running Windows Mobile 5 (and later 6) I got after that was a delight to develop for. Full-featured, well-documented SDK, first-class emulator, everything integrated with Visual Studio, and you could use any .NET language or straight C to make apps. You can say about Microsoft what you want, but their developer support is still the best there is. I stuck with the .NET Compact Framework and made a game and a couple of quite useful apps.

And then Android appeared. Java-based SDK, which isn't my favorite, but entirely free-of-charge and integrated with a proper IDE, and excellent emulator support. Extensive API for various Google services. Windows Mobile wasn't really going anywhere, so when my contract was up, I got my current device, the HTC Hero. And I've been having tons of fun with it ever since.

You can tinker around with your own Android device as little or as much as you want, but on top of that, Google makes it really, really easy for you to take what you made and offer it to others in the form of the Android Market.

And, at the urging of friends, that's what I did. Currently, I have three apps available, a note-taking app, a file manager, and a running tasks app, which you can find on the market if you search for "banderlabs" and on the web on my Google Code page.

And at 113.395 downloads and 73.980 active installs, I'm rather happy. It's great seeing something I developed getting used and making people's life better. And I plan to keep refining my current apps and adding new ones, a few of which I'm already close to finishing.

Let's see how long I can keep it up. =)