The great thing about Android is also the same thing that annoys developers – the ability to run on multiple devices. When it comes to developing games or apps you need to think of how to incorporate the multiple screen resolutions so that it is compatible across the widest range of devices.
Tackling this problem it was, at first, the most confusing part of Android development. Even with a very thorough article on the development website (Multiple Screen Support), I still found it confusing. Let me walk you through how to setup your manifest and Eclipse workspace to achieve the desired results.
As mentioned in Part 1 of this article series, the way Android classifies different screen sizes are by pixel density. Once you’ve decided what your target hardware is, have a look again at the multiple screen guide. Make sure to pay attention to the differences between “px,” “dp,” and “sp.”
Now a higher screen density means you can display more information, or pixels, in a smaller space. For example, if you just develop your game or app for a HVGA screen, when you try and run in on a WVGA screen it will appear smaller. In order to correct this you must make 3 different sizes for each PNG image you use.
In your Android Project in Eclipse, under the “res” folder, you will find the “drawable” folder. In order for Android to tell which folder contains the correct density images you will need to use qualifiers. To do this, delete the drawable folder and recreate 3 new ones named “drawable-hdpi”, “drawable-mdpi”, and “drawable-ldpi”. These will contain your different sized images and the naming will tell Android which folder to use depending on which device is running your application.
If you develop your app or game using the HVGA screen size as recommended, to adjust your images you need to increase the image size by 1.5 times to get an HDPI image, and shrink it by 0.75 times to get a LDPI image. An example is the MDPI launcher icon. It is a 48×48 PNG file. Times the resolution by 1.5 to get 72×72, the size needed for a HDPI screen to display the icon at relatively the same size. And to get a LDPI image times the resolution by 0.75 to get 36×36. Once you have converted all of your graphics to the appropriate size, you need to modify the Android Manifest.
To tell Android how to handle multiple screens you need to go to the “Android Manifest” -> “Manifest extras” -> then add the “Support Screens” option. Under the attributes for “Support Screens” you have small screen, normal screens, large screens, resizable and any density. My recommendation is for you to focus on the majority of Android devices. 20 out of 22 Android devices have normal screens. It is up to you if you want to build for small or large screens.
Resizable basically means fit to screen. So if there is a resolution that is out of the norm for Android, devices like 640×480, then it will stretch the game to fit the screen. Otherwise it will just leave a black border.
If Any Density is false, then Android will only take resources from the “drawable-mdpi” and if the app is being run on a HDPI screen, it will auto convert the PNG up to the correct pixel density. I do not recommend doing this since it is not guaranteed to produce the desired results. Plus you want full control over your app and since we have already designated HDPI, MDPI, and LDPI folders we put Any Density to true meaning we can handling any density ourselves.
These are the setting that I usually use:
Small screens: false
Normal Screens: true
Large Screens: false
Any Density: true
The first step to proactively supporting screen sizes is to add the <supports-screens> element to your AndroidManifest.xml file. This specifies which screen sizes you explicitly support and which you do not.
Here is a manifest containing a <supports-screens> element:
Three of these attributes are almost self- explanatory: android:smallScreens, android:normalScreens, and android:largeScreens. Each take a boolean value indicating whether your application explicitly supports those screens (true) or requires “compatibility mode” assistance (false).
The android:anyDensity attribute indicates whether you are taking density into account in your calculations (true) or not (false). If false, Android will pretend as though all of your dimensions (e.g., 4px) are for a normal-density (160dpi) screen. If your application is running on a screen with lower or higher density, Android will scale your dimensions accordingly. If you indicate that android:anyDensity = “true”, you are telling Android not to do that, putting the onus on you to use density-independent units, such as dip, mm, or in.
Finding Your Size
If you need to take different actions in your Java code based on screen size or density, you have a few options. If there is something distinctive in your resource sets, you can “sniff” on that and branch accordingly in your code. For example, as will be seen in the code sample at the end of this chapter, you can have extra widgets in some layouts (e.g., res/layout-large/main.xml) — simply seeing if an extra widget exists will tell you if you are running a “large” screen or not.
You can also find out your screen size class via a Configuration object, typically obtained by an Activityvia getResources().getConfiguration().
A Configuration object has a public field named screenLayout that is a bitmask indicating the type of screen the application is running on. You can test to see if your screen is small, normal, or large, or if it is “long” or not (where “long” indicates a 16:9 or similar aspect ratio, compared to 4:3). For example, here we test to see if we are running on a large screen:
There appears to be no easy way to find out your screen density. If you absolutely need to know that, a “hack” would be to add a strings.xml file to res/values-ldpi/, res/values-mdpi/, and res/values-hdpi/ directories in your project. Put a string resource in strings.xml that has a common name across all three resource sets and has a distinctive value (e.g., name it ‘density’, with values of ldpi, mdpi, and hdpi, respectively). Then, test the value of the string resource at runtime. This is inelegant but should work.
To test out that this is working, make 3 Android Virtual Devices (AVD’s) and run your app. A WVGA or FWVGA, HVGA and QVGA should be good. I recommend making a specific PNG image in each density a different color, so you can tell if the right folder is being used.
If you read the article by Google linked at the beginning of this article it goes into more detail. Hope this makes sense and it helps you!
Leave a Reply