After several weeks on the Android Market, my State Capitals application is now free. I made ten sales. Of those ten, two were returned and one person’s credit card didn’t work.
At $2.00 for each of the seven completed sales, my app grossed $14. Subtract 30% for T-Mobile, and I get $9.80. Since I paid $25 to join the market, I am $15.20 in the red.
This is mildly disappointing, but I didn’t really expect to get rich selling state capital flash cards. I suppose I could try reducing the price to $0.99, but this feels like a dead end. I’d rather focus on game programming…and thus begins my next wild-goose chase.
I just added a new demo to my Android Game Examples project. This sample reacts to the accelerometer to control a ball. As you rotate the screen, the ball falls towards the earth. When it bounces off the edge of the screen, the phone vibrator kicks in for a few milliseconds.
If you follow me on Twitter (@burke_eric), you may have seen me commenting on accelerometer problems with my G1 phone. In the Labyrinth Lite game, the ball always pulls hard to the right, even after calibration. See this video:
I initially thought my phone was defective, because the same game works for other people. But another game, Papi Jump, works fine after calibration. Before calibration, that game also pulls hard to the right.
Accessing the Accelerometer
You access the accelerometer via the SensorManager:
That boolean result is true if the device supports the requested sensor, so it returns false on the emulator and true on the G1 phone.
The SensorListener has two methods: onAccuracyChanged(...) and onSensorChanged(...). My example updates the GUI whenever the sensor changes.
Disclaimer: if you update the GUI on every single event, your application will slow down, the garbage collector will kick in repeatedly, and your app will probably crash. The events from the sensor arrive very fast, faster than the GUI can display. If you check out the complete code, you’ll see I intentionally slow down the GUI updates to once every 100 milliseconds.
Calibration
The screen shot illustrates the “problem” with my phone and the Labyrinth Lite game. The X, Y, and Z values constantly change. When the phone rests on a level surface, X and Y should be around zero. On my phone, however, X is approximately 0.83.
My application stores three values representing the calibration. When you click the Calibrate button, I store the negative X, Y, and Z values in three variables: cx, cy, and cz. Those are the numbers shown in parenthesis. When I display the values for X, Y, and Z, I simply add cx, cy, and cz to the current sensor readings.
Papi Jump and Labyrinth
The Papi Jump game seems to calibrate just fine. I suspect they do exactly what I do: detect how far out of whack the phone’s sensor is, and apply that delta to the current sensor readings.
For whatever reason, Labyrinth fails to calibrate enough on my phone. I believe this is a bug in their application. Perhaps the phones they test with do not require as much calibration as my phone. I have read reports from several people who say Labyrinth works on their phones, and it works on my wife’s G1 as well.
G1 Tolerance?
My phone sensor clearly works, it just requires around -0.83 X-axis adjustment. Is this within acceptable tolerance? I do not know.
I do know, however, that game developers cannot assume all Android hardware is perfectly calibrated. Games like Labyrinth need to expect a wider range of hardware and adjust accordingly. Papi Jump does it, and my simple demo is able to calibrate with a trivial subtraction.
Source Code
The complete source code is available in my Android Game Examples project on GitHub.
Android devices like the G1 phone support different sensors. Tonight I wrote some code that reports which sensors your Android device supports. Unfortunately, the emulator supports none:
When I run this on my G1, the program reports true for these sensors:
While waiting for dinner earlier tonight, I installed Last.fm on my G1. I don’t have a Last.fm account, so I signed up for a new one. While waiting for a response from the server, the UI froze. This screen is never good:
Android programmers need to know this: Never make network calls on the main application thread.
The ability to install apps on the SD card, and make it obvious how to put SQLite DBs on the SD card.
More standard actions and reusable activities. For example, make it easy to select pictures from the filesystem, crop photos, etc. These pieces are all there, but not always included as public APIs. Over time, I hope to see more reusable building blocks, making application development easier.
A pre-built JAR file containing all the SDK sources, so I can download a single JAR and drop it into my IDE.
Improved navigation on the Reference Information web site. There are a large number of examples, but the web site is hard to navigate. At a minimum, some kind of breadcrumbs would be nice. It’s really easy to get lost on the current site.
Improved contact management. My main gripe is when editing contacts, I get duplicate email address conflicts, with no smart merging of the duplicate entries.
** Update: Flash support (see Michael’s comment below)
I suspect we’ll have most of these items sometime in 2009.
I finished a rough draft for an article on an Android threading technique. If you want to see the draft, or are interested in being a tech reviewer, here it is:
I zipped up my entire workspace and project, so I’m assuming you can simply open it up in Eclipse. I still need to try this on someone else’s computer to verify this works, I’m no Eclipse expert.
If you’ve never done anything with Android, this example is going to be challenging. You might want to go through the Notepad tutorial first.
Final publication is scheduled for Jan 2, so I’ll need any tech reviews a few days before that. Thanks!
The first 30 minutes of my OCI Java Lunch presentation on Android is on YouTube. We had to split it up into 3 10-minute segments due to YouTube size limits.
The remaining two segments are on the OCItv Channel.
I haven’t watched this myself…I think I was really nervous the first few minutes, but the talk really picked up steam in segments 2 and 3. The second part of the hour isn’t online yet. That’s when I did live demos with my G1, Eclipse, and the SDK. Mario is working on getting that online as well.
Yesterday I showed how lifecycle events fire in response to starting and stopping an Activity. Next, let’s see what happens when you change the display orientation:
That’s what happens without any customization. I marked two methods bold because they are different than yesterday’s diagram. See this comment from Ed Burnette for more details on customizing rotation behavior. Specifically, you can retain data by overriding onRetainNonConfigurationInstance(), or you can prevent activity destruction via the android:configChanges XML attribute.
Phone Call
Android is also useful as a telephone, believe it or not. This next diagram shows what happens when a phone call interrupts an Activity:
This is Part 1 of a multi-part series explaining how events, such as clicking the Home button, trigger transitions in the Android Activity lifecycle. You might want to refer back to this Activity Lifecycle Diagram I posted 20 days ago.
I like your diagram, the only thing its missing is what causes each transition to happen (i.e. User hits “back” button, user clicks “home” button etc…)
The activity lifecycle is a complicated state machine which cannot live completely in my head so i like having a diagram to reference, however without the transition events its not a complete reference.
This is indeed complex, and one diagram cannot capture all possible transitions. So I’ll split this up into several blog entries. Here is the first diagram I came up with:
To create this diagram, I wrote an Activity that overrides most of the onXXX() methods, writing log messages:
I then ran the Activity in Eclipse, viewing the log in the DDMS LogCat window. (NOTE: DDMS is an Eclipse perspective, the LogCat window is in that perspective). I created the diagram using OmniGraffle.
I hope to create additional diagrams showing the sequence of method calls for a variety of events, such as:
An incoming phone call
The user hits the Menu button
Showing a dialog
Navigating to a different view
The phone going to sleep after inactivity
etc…
I suspect that learning the Activity lifecycle is one of the more challenging aspects of Android development. I hope this and future diagrams help.