Showing posts with label android SDK. Show all posts
Showing posts with label android SDK. Show all posts

Saturday, April 14, 2012

Complexities of Android development

As an indie mobile developer, I can personally attest that making things on Android - especially games - is pretty difficult.

I ran across this article about Battleheart's developer basically giving up on the Android platform as being "unsustainable" (original blog post by the developer here).

Now, this person has quite a lot of good points that works against Android devices in the business sense.  Why would you want to support something that takes a vast disproportionate amount of money to create?

Android has lots of problems for developers, and one of which is that simply Android users are generally more frugal with buying things (to include newer devices).  This means that as a developer, we should cater to old technology because a decent segment of the Android market are using old devices.

For example, I attempt to target Android 1.5 devices when and where possible so that, in theory, all newer devices should be able to run our games.  That sounds good at first, but this isn't always the reality, and this is where Battleheart's developer has a good point.  The only sure-fire way to guarantee that apps will work on a device is to physically test it on that device.

I wish it was an easy case were we can just load up our apps in an emulator, test, fix, deploy, but it definitely isn't that simple.  Each device manufacturer seems to have implemented various things about Android in their own way; forcing developers to cater to each device maker!

For example, only Android 2.1 allows for multitouch.  We created a virtual Dpad app that accepts user input on a circle (simulated analog dpad if you will) along with 2 virtual "buttons" - think like a Nintendo controller, but with a virtual directional pad.

After several days of developing and testing, it works 100% on our Motorola RAZR, but breaks horribly on Samsung Galaxy Tablet... and it all came down to the fact that Samsung implemented multitouch differently than Motorola (Motorola seemingly did it in accordance with the Android dev specs... Samsung apparently didn't?!).  As a developer, there would be no way for me to know this unless I physically had both of these devices... and this is a major problem with deploying games/apps on Android without having hundreds/thousands of Android devices to test against.  As a small indie shop, this means very unlikely to fork up all this cash for devices just to get meager amounts of downloads in Google Play market.

I can definitely feel what Mika Mobile is talking about as we've run in to these barriers as well.  It isn't impossible, but it sure raises the bar for "quality" (ie, not crashing/breaking) apps to have widespread deployment on the Android platform.

Wednesday, April 11, 2012

Getting the "density" of your Android device

This is one of those crazy small things you'll be needing sooner or later in game development on Android devices.

How to get the "density" of your device?  Or more specifically, how many physical pixels are there per inch, how big is my display?

Well, first of all, we need to get data from our device.

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

That will fill in everything we will need to know. From there, we can get all sorts of useful information.

How many pixels can we work with horizontally and vertically?  *Warning*: These are filled in based on the current orientation of the device!!!
xpixels = dm.widthPixels;
ypixels = dm.heightPixels;

How about pixels per inch on the display?
xpixelsPerInch = dm.xdpi;
ypixelsPerInch = dm.ydpi;

If we know how many pixels are given in a dimension, and how many pixels there are per inch, we can determine the exact inches of our display (more or less).
displayWidth = xpixels / xpixelsPerInch;
displayHeight = ypixels / ypixelsPerInch;

Now, for the part that can be a little bit more mysterious.  What about the actual "density"?  Well, in Android API 4+, our DisplayMetric (dm) has a property conveniently called "densityDpi".  This is well and good for Android 1.6 and beyond, but what about our poor Android 1.5 customers where this field didn't exist?  Fear not, we can still get this information!

There is a field called "density" which is a floating number based on the scaling factor of our pixels in comparison to a 160 DPI device.  In other words, if our device is "160 dpi", this scaling factor is 1 (160/160 = 1).

Common DPIs for Android devices are: 120, 160, 240, and 320.  Knowing this, we can now cater to Android 1.5's missing densityDpi field by making our own.
if (dm.density == 0.75)
    densityDpi = 120;
if (dm.density == 1.0)
    densityDpi = 160;
if (dm.density == 1.5)
    densityDpi = 240;
if (dm.density == 2)
    densityDpi = 320;

Normally it is NOT a good idea to do a straight floating point equality comparison check (rounding errors, precision point problems, etc), but in this case, there shouldn't be any issue.


Correction: Do not do it this way.  We recently received a problem report from a user with a 148 density, which is seemingly not standard.  I will leave this code in here for illustration and so that the reader gets an idea of catering to different hardware displays.

The following way is how you should calculate the density.

densityDpi = (int) (dm.density * 160.0f);

*Update* 4.29.2012 : Added the note about a user with a 148 density.