Thursday, September 30, 2010

More Countries, More sellers, More buyers

[This post is by Eric Chu, Android Developer Ecosystem. — Tim Bray]

Since we launched Android and Android Market, we have seen the population of Android users and devices expand into many countries. This widespread adoption has brought with it growing interest in Android Market’s support for the buying and selling of paid applications in these additional countries.

We have been hard at work on this and it is my pleasure to announce that effective today, developers from 20 more countries can now sell paid apps on Android Market. Additionally, over the next 2 weeks, users in 18 additional countries will be able to purchase paid apps from Android Market.

Support for paid application sales is now expanded to developers in 29 countries, with today’s additions of Argentina, Australia, Belgium, Brazil, Canada, Denmark, Finland, Hong Kong, Ireland, Israel, Mexico, New Zealand, Norway, Portugal, Russia, Singapore, South Korea, Sweden, Switzerland and Taiwan.

In addition, Android Market users from 32 countries will be able to buy apps, with the addition of Argentina, Belgium, Brazil, Czech Republic, Denmark, Finland, Hong Kong, India, Ireland, Israel, Mexico, Norway, Poland, Portugal, Russia, Singapore, Sweden, and Taiwan. No action is necessary if you have targeted your paid apps to be available to “All Locations” and would like to launch in these additional countries. If you have not selected “All Locations” and would like to target these additional countries, or if you have selected “All Locations” and do not want to launch your apps in these additional buyer countries, please visit the Android Market publisher site regularly over the next two weeks to make the necessary adjustments as the new buyer countries launch.

We remain committed to continuing to improve the buyer and seller experiences on Android Market. Among other initiatives, we look forward to bringing the Android Market paid apps ecosystem to even more countries in the coming months. Please stay tuned.

HTC HD2 Games: Spore Creatures v35.0.81







Your Spore Creatures are back and more evolved than ever! This innovative sequel to the award-winning Spore Origins has emerged from the ooze and onto solid ground.



Pick up where you left off in an all-new game designed exclusively for your mobile device. Attack or befriend other creatures and explore 12 exciting new levels.



Collect body parts and adapt yourself to complete challenges. Modify your creature with the Creature Creator to optimize its evolution and take it to the top of the food chain!



Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 1.90MB







Tuesday, September 28, 2010

Reflections on G-Kenya

[This post is by Reto Meier AKA @retomeier, who wrote the book on Android App development. — Tim Bray]

Recently I visited Kenya for the three-day G-Kenya event. I was there for two reasons:

  • To talk about Android and the emerging mobile opportunities for African developers.

  • To ask questions and find out more about the reality of mobiles and writing code from the people there.

Of the countries I’ve visited to talk about Android, nowhere have people had such a close connection to their mobile phones as in Africa. While most Kenyans own feature phones, those mobiles are already used as much more than simple phones. Mobile payments are already common, and cheap data plans mean that many people access the Internet exclusively through mobile handsets.

There were two Android announcements while I was in town: a new low-cost Android handset (the Huawei U8220), and Android Market access for Kenyans. I can’t wait to see the kind of apps that come from developers who live in an environment where mobile is so pervasive.

Day 1: Students

G-Kenya was set within the beautiful campus of the Strathmore Business School, so it was fitting that day one was addressed to students.

Of the three groups, the students where the most enthusiastic about Android. This was likely influenced by their confidence that by the time they graduate, modern smartphones in Africa will have become the norm.

I love talking to student developers — without the commercial pressures of finding customers or a monetization model — they're free to innovate on whatever technology platforms they think are interesting.

Day 2: Developers

Modern smartphones are not yet prevalent in Africa, so it wasn’t surprising that many of the developers are currently focusing on feature phones. That said, it was generally acknowledged that it was a question of when rather than if smartphones would come to dominate. The trick will be picking the right time to invest in Android so that they're ready to take advantage.

Plenty of developers believe that time is right now. It was a pleasure to meet the guys behind Ushahidi, creators of an Android app created to report and record incidents during the 2008 election violence. Since their launch they’ve expanded to offer a global platform for crowd-sourced news where timeliness is critical.

I love opportunity the Android Market delivers to developers like the idea of developers like Ushahidi and Little Fluffy Toys (of London Cycle Hire fame). An app the solves a problem for your local community can easily be expanded to offer solutions to similar problems across the world.

Developer focus in Kenya seemed to follow similar lines:

  • Create products and services targeted at local communities (such as the developers creating a distributed system to help health-care workers record medical information in the field.)

  • Build robust cloud-based services that provide access to users from any mobile platform.

  • Expand from feature phones to Android to incorporate features like GPS positioning, maps, and recording video and audio.

Day 3: Entrepreneurs and Marketers

No one was surprised to see a lot of the developers from the previous day return for entrepreneur day, and the apparent lack of Android questions from Day 2 was more than made up for on day 3; the “AppEngine Challenge” on Day 2 fielded a record 30 entries, so it seems everyone was working on their entries rather than asking questions!

I didn’t speak on Day 3, but spent all day fielding questions from eager mobile developers hoping to catch the Android wave as early innovators and first movers. That included a team who were working to provide real-time public transit tracking of Matatu via GPS and Android devices.

Reflections

It’s an exciting time to be a developer in Kenya. I regularly asked developers how long they thought it would take for Android devices to become common place. Many suggested if I came back this time next year I'd see a flood of Android devices. Even the more pessimistic predicted no more than 3 years.

As I traveled back towards Jomo Kenyatta International, listening to the radio offering a free Sony Ericsson X10 Mini to one lucky caller, the future didn’t seem very far away.

Sunday, September 26, 2010

HTC HD2 Games: Who Wants To Be A Millionaire 2010







Who Wants To Be A Millionaire 2010, challenges players to correctly answer 15 questions of increasing difficulty with the help of four lifelines - Ask the Audience, Phone a Friend and the newly added Double Dip and Ask the Expert.



Ten experts provide answers to the mobile game's nearly 1,000 questions. Just like on TV, players must answer before the game clock runs out, and any time remaining on the clock is banked for the million-dollar question.



Features:

-Authentic sounds and animations taken right from the show.

-Take the hot seat and test your knowledge with nearly 1,000 general knowledge questions.

-Climb your way to $1 Million with four different lifelines including: Phone a Friend, Ask The Audience and the new Double Dip and Ask The Expert.



* This version was ported from WQVGA so the game text is very small.





Download This HD2 Game Here:
















HD2Apps Facebook page
FileServing

cab file: 1.02MB







Saturday, September 25, 2010

HTC HD2 Apps: ListPro v.5.0.1.2019





 Create shopping lists, to do lists, checklists, or any list you need! ListPro makes it easy to organize and use your information however you want. Manage your time, remember all your errands, stay on track - and take your lists everywhere you go.



Features:



- Customize the Notes Pane for each item however you want. Format the text, insert images, and link to live web pages.



- Share lists, post them on websites, or turn lists into news feeds with our HTML and RSS/XML export options.



- Send lists and images to your Windows Mobile device instantly with one-click List Publishing.



- Get the most out of all your lists with options for alarms, item highlighting, indenting, outlining - plus, make any columns you want.



- Make lists easily and get organized fast with shopping list functions, built-in templates, and any of our free List Exchange lists.









Download This HD2 App Here:






















HD2Apps Facebook page
FileServing

zip file: 1.59MB







Tuesday, September 21, 2010

Proguard, Android, and the Licensing Server

[This post is by Dan Galpin, an Android Developer Advocate specializing in games and comics. — Tim Bray]

The Securing Android LVL Applications blog post makes it clear that an Android developer should use an obfuscation tool such as Proguard in order to help safeguard their applications when using License Server. Of course, this does present another question. How should one integrate such a tool with the Android build process? We’re specifically going to detail integrating Proguard in this post.

Before you Begin

You must be running the latest version of the Android SDK Tools (at least v7). The new Ant build rules file included with v7 contains hooks to support user-created pre and post compile steps in order to make it easier to integrate tools such as Proguard into an Android build. It also integrates a single rules file for building against all versions of the Android SDK.

Adding an Optimization Step to build.xml

First, you’ll have to get Proguard if you don’t yet have it.

If you’ve been using Eclipse to do your development, you’ll have to switch to using the command line. Android builds are done using Apache Ant. A version of Ant ships along with Eclipse, but I recommend installing your own version.

The Android SDK can build you a starter build.xml file. Here is how it’s done:

android update project --path ./MyAndroidAppProject

If all works well, you’ll have a shiny new build.xml file sitting in your path. Let’s try doing a build.

ant release

You should end up with an unsigned release build. The command-line tools can also sign your build for you. You’ll notice that the android tool created a local.properties file in your directory. It will contain the sdk.dir property. You can have it make you a signed build by adding the location of your keystore and alias to this file.

key.store=/Path/to/my/keystore/MyKeystore.ks
key.alias=myalias

So, now you have a signed build from the command line, but still no obfuscated build. To make things easy, you’re going to want to get two helper files: add-proguard-release.xml and procfg.txt.

Copy these files into your root directory (where the build.xml file sits). To add Proguard to your build, you first need to edit your local properties file to add the location of the directory that Proguard is installed in:

proguard.dir=/Directory/Proguard/Is/Installed/In

Finally... you need to add our script to your build file and have it override a few targets. To do this, we use the XML “entity” construct. At the top of your build.xml file, add an entity that references our script file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project [
<!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">
]>

You’re not done yet. Somewhere within the project tag add the reference to our entity to include our script.

<project name="MyProjectName" default="help">
&add-proguard-release;

That’s it! In many cases, calling

ant release

Will give you an obfuscated build. Now test and make sure that it hasn’t broken anything.

But Wait, My App is Crashing Now

Most crashes happen because Proguard has obfuscated away something that your application needs, such as a class that is referenced in the AndroidManifest or within a layout, or perhaps something called from JNI or reflection. The Proguard configuration provided here tries to avoid obfuscating most of these cases, but it’s still possible that in edge cases you’ll end up seeing something like a ClassNotFoundException.

You can make edits to the procfg.txt file to keep classes that have been obfuscated away. Adding:

-keep public class * [my classname]

should help. For more information about how to prevent Proguard from obfuscating specific things, see the Proguard manual. Specifically, the keep section. In the interest of security, try to keep as little of your application unobfuscated as possible.

The standard settings provided in procfg.txt will be good for many applications, and will catch many common cases, but they are by no means comprehensive. One of the things that we’ve done is had Proguard create a bunch of output files in the obf directory to help you debug these problems.

The mapping.txt file explains how your classes have been obfuscated. You’ll want to make sure to keep this around once you have submitted your build to Market, as you’ll need this to decipher your stack traces.

Conclusion

Tools such as Proguard make the binary of your application harder to understand, and make your application slightly smaller and more efficient at the same time, at the cost of making it slightly more challenging to debug problems in the field. For many applications, the tradeoff is more than worthwhile.

Monday, September 20, 2010

HTC HD2 Games: Monopoly Classic 3D v0.0.30











The iPhone version - Now on the HD2!

In the tradition of the original board game, it’s “GO” time on Windows Mobile! Buy, sell, and trade the famous properties.



See the game jump to life with animated features and intuitive gameplay. Customize the difficulty, number of players, and house rules.

Go against friends with Pass ‘n Play and own it all!







* This game has a conflict with some apps by Resco (G-sensor bug).

so "Shake To Roll" might not work.



Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 18.11MB







Sunday, September 19, 2010

HTC HD2 Games: The Sims 3 3D











The one from iPhone! - NOW ON Windows Mobile! Celebrate The Sims 10th Anniversary with this award-winning Sims experience. Choose your Sim’s appearance, clothing, and accessories.



Explore the amazing 3D open-world environment. Fulfill your Sim’s basic needs, while unlocking up to 73 goals and wishes to help your Sim reach its full potential.







Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 61.85MB







Saturday, September 18, 2010

HTC HD2 Apps: Slide 2 Play S2P v1.4







S2P is a finger friendly MP3/MP4/M4A/AAC/WMA/WAV/M3U/PLS/ASX player application. It simply lets you browse your music files & play. It fully integrates with S2U2 & supports A2DP & AVRCP.



v1.4 (14 September 2010):

* improved the responsiveness of the letter index bar.

* improved the album pic caching speed in the Albums list.

* auto hide MP4/M4A/AAC files if WMP does not have proper decoder built-in.

* fixed the start-up problem if the music library contained Nokia AAC ringtones.

* fixed the backward playback & repeat single did not work in v1.3.

* fixed an occasional start-up error if Bluetooth was already on.

* tuned down the scrolling sensitivity of all lists (again).

* a few minor bugs fixed.









Download This HD2 App Here:






















HD2Apps Facebook page
FileServing

zip file: 1.81MB







HTC HD2 Games: Star Trek v35.3.65







You are the captain of the USS Enterprise in this action-packed game. Fight valiantly alongside famous Star Trek ships and races. Get beamed up!



Soar through galaxies as you race to complete your campaigns. Pick up new weapons and fight valiantly alongside and against famous ships and races from the Star Trek Universe.



Collect power-ups to increase the abilities of your ship - including speed, energy and firepower. Explore the depth of the score system and get higher ratings on the high-score ladder. Get beamed up!











Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 1.64MB







Friday, September 17, 2010

HTC HD2 Games: Medieval Total War v35.1.31







The award-winning total war series wages its way onto the HD2! Command armies to battle in this real-time strategy game and lead them to victory!



Command a multitude of units, from infantry to artillery. Battle and capture towns to expand your troops and guide your faction to victory through strategic thinking.



Re-enact the famous battles of the 100 Years War in real-time, from the Battle of Agincourt to the Siege of Orleans. Choose from 6 different terrains like a desolate canyon or a crescent lake to create your own battlefield!







Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 1.18MB







Tuesday, September 14, 2010

Supporting the new music Voice Action

[This post is by Mike LeBeau, the Tech Lead and architect behind Voice Actions. — Tim Bray]

We recently launched Voice Actions in the new Google Voice Search for Android — an awesome new way to search, control, and communicate on your phone faster than ever before, by using your voice.

One of these new Voice Actions lets users find and automatically play music. By speaking something like “listen to They Might Be Giants” into the new Voice Search, users can quickly find the music they want online and play it, using any number of different apps. (Pandora, Last.fm, Spotify, mSpot, and Rdio are among the first apps to support this.)

To do this, we leveraged a very common little piece of Android magic: a new Intent. If you develop a music app that supports open-ended music search, you can make it work with users speaking “listen to” Voice Actions simply by registering for the new intent we’ve defined. This new intent isn’t defined as a constant in the SDK yet, but we wanted to make sure music app developers had all the information needed to use it right away.

Here’s all you should need to know:

  • In your AndroidManifest.xml, just register one of your activities for the new intent android.media.action.MEDIA_PLAY_FROM_SEARCH:

    <application android:label="@string/app_name" android:icon="@drawable/icon">
    <activity android:name="MusicActivity" android:label="@string/app_name">
    <intent-filter>
    <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
    <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    </activity>
    </application>
  • When your activity receives this intent, you can find the user’s search query inside the SearchManager.QUERY string extra:

    import android.app.Activity;
    import android.app.SearchManager;

    public class MusicActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String query = getIntent().getStringExtra(SearchManager.QUERY);
    // Do something with query...
    }
    }

    This will represent everything the user spoke after “listen to”. This is totally open-ended voice recognition, and it expects very flexible search — so, for example, the string could be the name of any artist (“they might be giants”), an album (“factory showroom”), a song (“metal detector”), or a combination of any of these (“metal detector by they might be giants”).

A few subtle details worth understanding about this intent:

  • Your app should do its best to quickly find and automatically play music corresponding to the user’s search query. The intention here is to get users to their desired result as fast as possible, and in this case, that means playing music quickly.

  • This will really only work well for music apps that can find music across a very large corpus of options. Because our voice recognition doesn’t currently support any way to provide a list of specific songs to be recognized, trying to use it against a small set of music choices will work poorly — things which are not in the set will be over-recognized, and things which are in the set may not be recognized well. So if you’re not the developer of a large-scale cloud music application, this intent is probably not for you.

We think you’ll find this new intent can greatly enhance your music app’s experience for users. And we hope you enjoy our new Voice Actions as much as we do!



HTC HD2 Games: EA Tetris v0.0.15







Tetris is one of the most popular games on mobile phones. What started as a simple Russian computer puzzle game became the addiction of millions of players worldwide. We started with one of the greatest games of all time and added the features to make it the perfect game for your mobile phone.



In addition to the classic Marathon mode, we have added two quick games, Ultra (how many lines can you clear in two minutes?) and Forty Line (How fast can you clear forty lines?) to fit the way people play games on phones.







Download This HD2 Game Here:






















HD2Apps Facebook page
FileServing

cab file: 7.50MB







HTC HD2 Apps: Resco Explorer v8.10







Resco Explorer - The best file explorer for your HD2. This is a must-have!



The ever popular file manager once again brings something new with the 2010 version, including the following functions:



Features:

- Upload to Social Network: Facebook, Flickr, Twitter, Picasa, MySpace and Photobucket

- Thumbnails View Mode: The new view mode displays previews of images

- Full Touch Optimization: Navigate through your files easily using your finger

- Letter Bar Navigation: Features the letter preview of the files you would like to access

- Virtual Folders For All Documents: Very useful when looking for files of the same type

- Quick Search Function: Instantly search for files you need by typing in the starting letters

- The Registry Editor: It allows you to export, import, view or modify the registry keys.

- ZIP Compression: Simplest and cheapest way to save significant amounts of storage space.

- The FTP Explorer: Gives the possibility to browse the FTP server's content directly in your device

- The Network Browser: Simply map the shared network folders

- Recycle Bin: Moves deleted files into a virtual folder "Recycle Bin" instead of immediate deletion





New features:

- Quick-search supports wildcards — the quick search tool supports “*” and “?” wildcards, you may now search for files and folders the way e.g. *pattern?.exe

- Improved Bluetooth features for Microsoft Bluetooth stack — Bluetooth transfer becomes 4 times faster + the discovery window shows the paired devices

- HW keyboard commands supported — commands such as Del, Tab, Ctrl+C, Ctr+V etc. are now supported on HW keyboard as well as on Soft keyboard

- Progress window is showing the remaining time

- Report view supports both directions scrolling (for longer columns) — in case the columns are wider than the display size, you may now scroll to the right/left as well



Smaller improvements:

- Paste shortcut for more files

- Properties window — file name and location is scrollable and supports context menu

- REG file import — silent import + key deletion ([-HKEY_...]) + comments are supported



*This download includes the registry editor plug-in. (second cab file)









Download This HD2 App Here:






















HD2Apps Facebook page
FileServing

zip file: 1.92MB







Monday, September 13, 2010

Screen Geometry Fun

The recent announcement of the Samsung Galaxy Tab should be a wake-up call for Android developers. What’s scary is that we’ve never seen a screen like this on an Android device before. What’s reassuring is that most apps Just Work (in fact, a lot of the ones I’ve tried so far have looked terrific) and the potential problems are easy to avoid. Here’s what you need to do to take advantage of not just the Tab, but all the new form factors that are coming down the pipe.

Let’s consider the Tab as a “teachable moment”:

  • Its screen is 1024x600; no compatible device’s screen has ever had a thousand pixels in any dimension before.

  • A lot of people are going to want to hold it sideways, in “landscape” mode, most of the time.

We recommend spending quality time with the Developers’-guide discussion of supporting multiple screens; we'll be revising that regularly when required as the device landscape changes. Also, this blog recently ran Dan Morrill’s One Screen Turn Deserves Another, which should help out in handling the landscape default.

What density means

When you build your app, you can provide layouts and assets (graphics) which vary by screen density, screen size, and landscape or portrait orientation. Clearly, pulling these together is not as much fun as designing groovy layouts and clever Intent filters; but there’s no way around it.

In this context, the Samsung has another little surprise: If you do the arithmetic, its screen has 170 DPI, which is far from the densest among Android devices. Still, it declares itself as “hdpi” (and as having a “large” screen size). The reason is simple: It looks better that way.

Samsung found that if you rendered your graphical resources bit-for-bit using medium-density sources, they looked great, but most large-screen designs ended up looking sparse, with too much space between buttons and icons. At high resolution, the framework scales up the resources an amount that turns out to be just enough.

As a photography hobbyist, I’m reminded of how you juggle aperture and shutter speed and ISO sensitivity. If, for example, you want a fast shutter speed to capture a dancer in mid-leap, you’d better compensate with a wider aperture or more sensitivity. Similarly, the Galaxy Tab’s screen is at the large end of “large”, so declaring it as high-density applies a useful compensation.

The good news is that the scaling code in the framework is smart enough and fast enough that it comes out well; the graphics in my own apps look remarkably good on the Tab. Here is the front page of my “LifeSaver 2” app; first the Nexus One, then the Galaxy Tab, resized for presentation here. Different densities, different geometries, and the only important difference is that the version on the big screen looks prettier.

Your take-away should be what I said above: Make sure you provide your graphics at all three resolutions, and chances are the Android framework will find a way to make them look great on a huge variety of devices.

Other Ways To Go Wrong

As I noted, most apps work just fine on this kind of device, out of the box, no changes required. However, we have run across a few Worst Practices that can make your app look dorky or even broken; for example:

  • Using AbsoluteLayout; this is a recipe for trouble.

  • Using absolute rather than density-independent pixels.

  • One member of my group ran across a couple of apps that suffered a Null Pointer Exception because they were calculating screen size when their Activity started, and doing their own resource loading rather than letting the framework take care of it. The problem was that they hadn't built in handling for the 1024x600 screen. The problem would vanish if they'd hand the work to the framework (or at least make sure that all their switch statements had default cases).

Escape the Shoebox

I've observed that a certain number of applications appear “shoeboxed”, running in a handset-like number of pixels in the center of the screen, surrounded by a wide black band. They work fine, but this is silly, and easy to avoid. It turns out that this happens when you have a targetSdkVersion value less than four; this is interpreted to mean that you’re targeting the legacy Cupcake flavor of Android, which only supported HVGA.

In any case, if you want to make 100% sure that your app doesn’t get pushed into the shoebox, the supports-screens element is your friend; here’s what we recommend:

<supports-screens android:largeScreens="true" android:anyDensity="true" />

(Both those attributes default to "false" for API levels less than 4.) Given a chance, the framework gets a good result on almost any Android screen imaginable.

Testing

When a device comes along that’s different in one way or another from what’s been available before, and you don’t have one, the only way to be sure your app will treat it properly is to run it on an Android emulator; the emulator code is flexible enough to model anything we’ve seen or know is coming down the pipe.

In the case of the Galaxy Tab, Samsung will be providing an add-on including a custom AVD and skin as an SDK add-on, to make your life easier; I used a pre-release to make the LifeSaver screenshot above.

Why All the Extra Work?

Because, as 2010 winds down, Android isn’t just for phones, and isn’t just for things that fit in your pocket. The minor effort required to deal with this should pay off big-time in terms of giving your apps access to a universe of new kinds of devices.

Thursday, September 9, 2010

One Screen Turn Deserves Another

[This post is by Dan Morrill, Open Source & Compatibility Program Manager. — Tim Bray]

Android has an API for accessing a variety of sensor types, such as an accelerometer or light sensor. Two of the most commonly-used sensors are accelerometers and magnetometers (that is, compasses.) Applications and devices frequently use these as forms of user input, and to determine which way to orient the screen.

However, there’s a new wrinkle: recently, a few devices have shipped (see here and here) that run Android on screens that are naturally landscape in their orientation. That is, when held in the default position, the screens are wider than they are tall. This introduces a few fairly subtle issues that we’ve noticed causing problems in some apps. Now, part of the reason for this is that the Android SDK docs on the sensor API left a couple things unsaid, leading many developers to use them incorrectly. Even a couple of our own samples did the wrong thing. Sorry about that!

Fortunately, using these APIs correctly is pretty simple, if you keep three rules in mind:

  • The sensor coordinate system used by the API for the natural orientation of the device does not change as the device moves, and is the same as the OpenGL coordinate system.

  • Applications must not assume that the natural orientation is portrait. That's not true on all devices.

  • Applications that match sensor data to on-screen display must always use android.view.Display.getRotation() to map sensor coordinates to screen coordinates — even if their manifest specifies portrait-only display.

If you have a strong background in math, the three rules above may be all you need to work out the rest. But if that’s not you, the rest of this post explains things step-by-step, and gives some tips for using sensors correctly.

The Basic Problem

Before we dive in, here’s a tip that I personally have found to be helpful: always remember that the sensor data’s coordinate system never changes. Ever. The rest of this post is going to talk about coordinate systems and rotations and so on. But sometimes when your head is deep in 3D transforms, you can get disoriented, so I’ve found it helps to frequently remind myself that no matter what is happening to the screen, the sensor coordinate system never changes.

Now with that tip in mind, we need an example to talk about. Let’s consider a simple app that draws an arrow that always points in the direction of gravity, animating the arrow as the user moves the phone around, like a plumb-bob. When a typical phone is held normally, the arrow points down, as shown in Figure A:

(Note: In the figures in this post, the letter “G” means the direction of gravity in the sensor coordinate system. In Figure A, for example, “G = -y” means that gravity is aligned with the device’s negative-Y axis, as measured by the accelerometer. And remember — the sensor coordinate system never changes!)

This app is pretty straightforward to implement in OpenGL: you simply need to draw an arrow on a GL SurfaceView, after rotating the coordinate space in response to the sensor data returned by the accelerometer. This “just works” because — in this basic case — the OpenGL screen coordinate system lines up with the sensor coordinate system.

So, this technique works, and the arrow will always point down — until you turn the phone too far.

So What’s the Problem?

Most Android devices use the accelerometer to detect when the device is being held sideways, and rotate the screen accordingly. This normally causes the apps to display horizontally, from the point of view of the user.

What this reorientation actually does is remap the X and Y axes, causing the app to draw itself horizontally. However, the Android sensor APIs define the sensor coordinate space to be relative to the top and side of the device — not the short and long sides. When the system reorients the screen in response to holding the phone sideways, the sensor coordinate system no longer lines up with the screen’s coordinate system, and you get unexpected rotations in the display of your app. Figure B shows an example:

There are are a couple different fixes for this problem that are commonly used today, but we’ve noticed that these often don’t work properly on landscape-default devices.

A common first attempt to solve the auto-rotation problem is to simply lock the screen to portrait mode, via the android:screenOrientation attribute in AndroidManifest.xml. This prevents the system from performing a screen coordinate system remap in response to device orientation, and so the sensor and screen coordinate systems remain in sync. However, locking the screen to portrait mode this way prevents the coordinate systems from getting out of sync on portrait-default devices, but causes them to become out of sync on landscape-default devices. This is because it forces a screen reorientation on those devices.

The second common technique is to detect when the device is in landscape mode, and compensate for it by adding a rotation to the graphics that are displayed. Unfortunately, this technique is often only a partial fix, because if you aren’t careful about detecting landscape mode, you will again cause an unnecessary compensation on landscape-default devices.

The Correct Fix

So what’s a poor developer to do? This seems like a catch-22: you can’t prevent screen reorientation, but you can’t compensate for it, either.

Or can you? Actually, you can compensate — you just have to make sure you’re correctly detecting when compensation is necessary. The question is, how does the device tell you that it’s been reoriented? And the answer is: android.view.Display.getRotation().

That method will return one of four values, indicating that either the device has not been reoriented (ROTATION_0), or that it has been reoriented by 90 degrees, 180 degrees, or 270 degrees (which respectively are ROTATION_90, ROTATION_180, and ROTATION_270.)

Pay special attention to those last two. ROTATION_180 and ROTATION_270 mean that each device actually has two portrait and two landscape modes: normal portrait and landscape, and the upside-down versions of each. Some Android devices that do “360 reorientation” will use these rotation modes as well, so you need to handle this generally, beyond just accounting for portrait or landscape mode.

Once you have the screen orientation info in hand, you can treat it as a rotation around the screen’s Z axis when rendering graphics. By applying the rotation to the values you get from your SensorEventListener, you can correctly and reliably compensate for screen reorientations on all devices.

Note that Display.getRotation() will tell you if the screen has been reoriented at all, not that it was reoriented specifically in response to the accelerometer. For example, even if you disable accelerometer-based reorientation by using android:screenOrientation=”nosensor", your app might still be reoriented if the user has opened a hard keyboard on the device.

Because handling all this involves some math that can be a bit of a chore, as a convenience we’ve provided the android.hardware.sensor.SensorManager.remapCoordinateSystem() method to do much of this remapping work for you. If you choose not to do use this method, you can achieve a similar effect by essentially swapping axes, along with the rule of thumb that 2 axis swaps requires that you negate the third axis. (Since this is a bit error-prone, we do recommend that you use remapCoordinateSystem() when you can.)

Recipes for Sensuous Delights

Okay, now we’ve got a technique that we can rely on to work on all devices. But how do you update your app? To give you a more explicit helping hand on how to fix your apps, I’ve whipped up a few recipes for updating your apps.

Apps That Never Draw Sensor Data

Apps that never display graphics derived from sensor data usually don’t need to make any changes. Examples of this type of app are those that detect for bumps to the device, those that use sensors for gesture input, apps that monitor g-forces (watching for free-fall or acceleration), and so on. These apps aren’t drawing images that vary according to the device’s orientation.

This isn’t a hard and fast rule; there probably are some apps out there that do need to take screen orientation into consideration, even though they don’t draw graphics depicting the sensor data. But, if your app just uses sensors in the background, there’s a good chance you won’t need to make any changes.

Apps That Work in Both Portrait and Landscape

Most Android apps work fine in both portrait and landscape, using the standard tools. If your app is one of these and you also use sensors, the only change your app probably requires is a tweak to use the behavior I outlined above. That is:

  • Don’t assume that portrait is the default mode.

  • Don’t assume that locking your app to portrait mode solves this issue.

  • Don’t assume that disabling sensor-based reorientation solves this issue (since reorientations also occur on some devices when the user opens a keyboard.)

  • Check for the current device orientation via getRotation(), and compensate accordingly, as detailed earlier.

Apps That Only Work in One Orientation

Some apps — notably, many games — only work well (or at all!) in either portrait or landscape mode. It’s perfectly okay, of course, for such apps to lock themselves to the appropriate mode, and doing so simplifies the sensors quite a bit.

However, because Android devices actually support two landscape and two portrait modes, these apps still need to check the current orientation. That is, if an app locks itself to landscape mode, it will need to perform a compensation on portrait-default devices, but not on landscape-default devices. And of course — are you sick of hearing this yet? — this can be accomplished by checking the result of getRotation().

Phew! Quite a mouthful for what is a fairly straightforward notion, once you understand what’s going on. But if I had to distill all that down into a single sentence, it would be this: android.view.Display.getRotation() is your friend.

I hope you’ve found this information useful; what’s more, I hope you’ve found it practical. We’ll keep improving our SDK and docs, and I hope you’ll keep improving your apps.

Happy coding!