Introduction to Android Application Development, Fourth Edition (2014)

Part IV. Android Application Design Essentials

Chapter 14. Designing Compatible Applications

There are now hundreds of different Android devices on the market worldwide—from smartphones to tablets and televisions. In this chapter, you learn how to design and develop Android applications that are compatible with a variety of devices despite differences in screen size, hardware, or platform version. We offer numerous tips for designing and developing your application to be compatible with many different devices. Finally, you learn how to internationalize your applications for foreign markets.

Maximizing Application Compatibility

With dozens of manufacturers developing Android devices, we’ve seen an explosion of different device models—each with its own market differentiators and unique characteristics. Users now have choices, but these choices come at a cost. This proliferation of devices has led to what some developers call fragmentation and others call compatibility issues. Terminology aside, it has become a challenging task to develop Android applications that support a broad range of devices. Developers must contend with devices that support different platform versions (see Figure 14.1), hardware configurations (including optional hardware features) such as OpenGL versions (see Figure 14.2), and variations in screen sizes and densities (see Figure 14.3). The list of device differentiators is lengthy, and it grows with each new device.

Image

Figure 14.1 Android device statistics regarding platform version (source: http://d.android.com/about/dashboards/index.html#Platform).

Image

Figure 14.2 Android device statistics regarding OpenGL versions (source: http://d.android.com/about/dashboards/index.html#OpenGL).

Image

Figure 14.3 Android device statistics regarding screen sizes and densities (source: http://d.android.com/about/dashboards/index.html#Screens).

Although fragmentation makes the Android app developer’s life more complicated, it’s still possible to develop for and support a variety of devices—even all devices—within a single application. When it comes to maximizing compatibility, you’ll always want to use the following strategies:

Image Whenever possible, choose the development option that is supported by the widest variety of devices. In many cases, you can detect device differences at runtime and provide different code paths to support different configurations. Just make sure you inform your quality assurance team of this sort of application logic so it can be understood and thoroughly tested.

Image Whenever a development decision limits the compatibility of your application (for example, using an API that was introduced in a later API level or introducing a hardware requirement such as camera support), assess the risk and document this limitation. Determine whether you are going to provide an alternative solution for devices that do not support this requirement.

Image Consider screen size and density differences when designing application user interfaces. It is often possible to design very flexible layouts that look reasonable in both portrait and landscape modes, as well as different screen resolutions and sizes. However, if you don’t consider these factors early, you will likely have to make changes (sometimes painful ones) later on to accommodate the differences.

Image Test on a wide range of devices early in the development process to avoid unpleasant surprises late in the game. Make sure the devices have different hardware and software, including different versions of the Android platform, different screen sizes, and different hardware capabilities.

Image Whenever necessary, provide alternative resources to help smooth over differences between device characteristics (we talk extensively about alternative resources later in this chapter).

Image If you do introduce software and hardware requirements to your application, make sure you register this information in the Android manifest file using the appropriate tags. These tags, used by the Android platform as well as third parties such as Google Play, help ensure that your application is installed only on devices that are capable of meeting its requirements.

Now let’s look at some of the strategies you can use to target different device configurations and languages.

Designing User Interfaces for Compatibility

Before we show you the many ways you can provide custom application resources and code to support specific device configurations, it’s important to remember that you can often avoid needing them in the first place. The trick is to design your initial default solution to be flexible enough to cover any variations. When it comes to user interfaces, keep them simple and don’t overcrowd them. Also, take advantage of the many powerful tools at your disposal:

Image As a rule of thumb, design for normal-size screens and medium resolution. Over time, devices trend toward larger screens with higher resolution.

Image Use fragments to keep your screen designs independent from your application Activity classes and provide for flexible workflows. Leverage the Android Support Library to provide newer support libraries to older platform versions.

Image For View and Layout control width and height attributes, use match_parent (also called the deprecated fill_parent) and wrap_content so that controls scale for different screen sizes and orientation changes, instead of using fixed pixel sizes.

Image For dimensions, use the flexible units, such as dp and sp, as opposed to fixed-unit types, such as px, mm, and in.

Image Avoid using AbsoluteLayout and other pixel-perfect settings and attributes.

Image Use flexible layout controls such as RelativeLayout, LinearLayout, TableLayout, and FrameLayout to design a screen that looks great in both portrait and landscape modes and on a variety of different screen sizes and resolutions. Try the “working square” principle for organizing screen content—we will talk more about this in a moment.

Image Encapsulate screen content in scalable container controls such as ScrollView and ListView. Generally, you should scale and grow screens in only one direction (vertically or horizontally), not both.

Image Don’t provide exact position values for screen elements, sizes, and dimensions. Instead, use relative positions, weights, and gravity. Spending time up front to get these right saves time later.

Image Provide application graphics of reasonable quality, and always keep the original (larger) sizes around in case you need different versions for different resolutions at a later time. There is always a trade-off in terms of graphics quality versus file size. Find the sweet spot where the graphic scales reasonably well for changes in screen characteristics, without bulking up your application or taking too long to display. Whenever possible, use stretchable graphics, such as Nine-Patch, which allow a graphic to change size based on the area in which it is displayed.


Image Tip

Looking for information about the device screen? Check out the DisplayMetrics utility class, which, when used in conjunction with the window manager, can determine all sorts of information about the display characteristics of the device at runtime:

DisplayMetrics currentMetrics = new DisplayMetrics();
WindowManager wm = getWindowManager();
wm.getDefaultDisplay().getMetrics(currentMetrics);


Working with Fragments

Fragments were discussed in detail in Chapter 9, “Partitioning the User Interface with Fragments,” but they deserve another mention here, in relation to designing compatible applications. All applications can benefit from the screen workflow flexibility provided by Fragment-based designs. By decoupling screen functionality from specific Activity classes, you have the option of pairing up that functionality in different ways, depending on the screen size, orientation, and other hardware configuration options. As new types of Android devices hit the market, you’ll be well placed for supporting them if you do this work up front—in short, future-proofing your user interfaces.


Image Tip

There’s little excuse not to use fragments, even if you are supporting legacy Android versions as far back as Android 1.6 (99% of the market). Simply use the Android Support Library to include these features in your legacy code. It’s just a right-click away in the Android IDE. With most non-Fragment-based APIs deprecated, it’s clearly the path along which the platform designers are leading developers.


Leveraging the Android Support Library

Fragments and several other new features of the Android SDK (such as loaders) are so important for future device compatibility that there are Android support libraries to bring these APIs to older device platform versions, as far back as Android 1.6. To use the Android Support Library with your application, take the following steps:

1. Use the Android SDK Manager to download the Android Support Library.

2. Find your project in the Package Explorer or Project Explorer.

3. Right-click the project and choose Android Tools, Add Support Library.... The most updated library will be downloaded, and your project settings will be modified to use the newest library.

4. Begin using the APIs available as part of the Android Support Library. For example, to create a class extending FragmentActivity, you need to import android.support.v4.app.FragmentActivity.

Supporting Specific Screen Types

Although you generally want to try to develop your applications to be screen independent (support all types of screens, small and large, high density and low), you can specify the types of screens your application can support explicitly when necessary in the Android manifest file. Here are some of the basics for supporting different screen types within your application:

Image Explicitly state which screen sizes your application supports using the <supports-screens> Android manifest file tag. For more information on this Android manifest tag, see http://d.android.com/guide/topics/manifest/supports-screens-element.html.

Image Design flexible layouts that work with different-size screens.

Image Provide the most flexible default resources you can, and add appropriate alternative layout and drawable resources for different screen sizes, densities, aspect ratios, and orientations as needed.

Image Test, test, test! Make sure you review how your application behaves on devices with different screen sizes, densities, aspect ratios, and orientations regularly as part of your quality assurance testing cycle.


Image Tip

For a very detailed discussion of how to support different types of screens, from the smallest smartphones to the largest tablets and televisions, see the Android Developer website: http://d.android.com/guide/practices/screens_support.html.


It’s also helpful to understand how legacy applications are automatically scaled for larger and newer devices using what is called screen compatibility mode. Depending on the version of the Android SDK that your application originally targeted, the behavior on newer platform versions may be subtly different. This mode is on by default but can be disabled by your application. Learn more about screen compatibility mode at the Android Developer website: http://d.android.com/guide/practices/screen-compat-mode.html.

Working with Nine-Patch Stretchable Graphics

Phone screens come in various dimensions. It can save you a lot of time to use stretchable graphics to enable a single graphic to scale appropriately for different screen sizes and orientations or different lengths of text. Android supports Nine-Patch Stretchable Graphics for this purpose. Nine-Patch Stretchable Graphics are simply PNG graphics that have patches, or areas of the image, defined to scale appropriately, instead of the entire image scaling as one unit. We discuss how to create stretchable graphics in Appendix A, “Mastering the Android Development Tools.”

Using the “Working Square” Principle

Another way to design for different screen orientations is to try to keep a “working square” area where most of your application’s user activity (meaning where users look and click on the screen) takes place. This area remains unchanged (or changes little beyond just rotating) when the screen orientation changes. Only functionality displayed outside the “working square” changes substantially when screen orientation changes (see Figure 14.4).

Image

Figure 14.4 The “working square” principle.

One example of a “working square” is the Camera application on the Nexus 4. In portrait mode, the camera controls are on the bottom of the viewfinder (see Figure 14.5, left); when the device is rotated clockwise into landscape mode, the camera controls stay in the same place but now they are on the right side of the viewfinder (see Figure 14.5, right). The viewfinder area would be considered the “working square”—the area that remains uncluttered. The controls are kept outside that area, so the user can compose his or her photos and videos.

Image

Figure 14.5 Nexus 4 Camera application using a form of the “working square” principle.

When you’re using the application, the rotation appears to have had little effect. The controls moved from being below the viewfinder to being to the right of the viewfinder. It just so happens, though, that they remain in the same location on the screen. This is part of the elegance of the “working square” principle.

Providing Alternative Application Resources

Few application user interfaces look perfect on every device. Most require some tweaking and some special case handling. The Android platform allows you to organize your project resources so that you can tailor your applications to specific device criteria. It can be useful to think of the resources stored at the top of the resource hierarchy naming scheme as default resources and the specialized versions of those resources as alternative resources.

Here are some reasons you might want to include alternative resources within your application:

Image To support different user languages and locales

Image To support different device screen sizes, densities, dimensions, orientations, and aspect ratios

Image To support different device docking modes

Image To support different device input methods

Image To provide different resources depending on the device’s Android platform version

Understanding How Resources Are Resolved

Here’s how it works. Each time a resource is requested within an Android application, the Android operating system attempts to find the resource that is the best possible match for the job. In many cases, applications provide only one set of resources. Developers can include alternative versions of those same resources as part of their application packages. The Android operating system always attempts to load the most specific resources available—the developer does not have to worry about determining which resources to load because the operating system handles this task.

There are four important rules to remember when creating alternative resources:

1. The Android platform always loads the most specific, most appropriate resource available. If an alternative resource does not exist, the default resource is used. Therefore, it’s important to know your target devices, design for the defaults, and add alternative resources judiciously in order to keep your projects manageable.

2. Alternative resources must always be named exactly the same as the default resources and stored in the appropriately named directory, as dictated by a special alternative resource qualifier. If a string is called strHelpText in the /res/values/strings.xml file, it must be named the same in the /res/values-fr/strings.xml (French) and /res/values-zh/strings.xml (Chinese) string files. The same goes for all other types of resources, such as graphics or layout files.

3. Good application design dictates that alternative resources should almost always have a default counterpart so that regardless of the device configuration, some version of the resource will always load. The only time you can get away without a default resource is when you provide every kind of alternative resource. One of the first steps the system takes when finding a best matching resource is to eliminate resources that are contradictory to the current configuration. For example, in portrait mode, the system would not even attempt to use a landscape resource, even if that is the only resource available. Keep in mind that new alternative resource qualifiers are added over time, so although you might think your application provides complete coverage of all alternatives now, it might not in the future.

4. Don’t go overboard creating alternative resources because they add to the size of your application package and can have performance implications. Instead, try to design your default resources to be flexible and scalable. For example, a good layout design can often support both landscape and portrait modes seamlessly—if you use appropriate layouts, user interface controls, and scalable graphics resources.

Organizing Alternative Resources with Qualifiers

Alternative resources can be created for many different criteria, including, but not limited to, screen characteristics, device input methods, and language or regional differences. These alternative resources are organized hierarchically within the /res resource project directory. You use directory qualifiers (in the form of directory name suffixes) to specify a resource as an alternative resource to load in specific situations.

A simple example might help to drive this concept home. The most common example of when alternative resources are used has to do with the default application icon resources created as part of a new Android project in the Android IDE. An application could simply provide a single application icon graphics resource, stored in the /res/drawable directory. However, different Android devices have different screen densities. Therefore, alternative resources are used instead: /res/drawable-hdpi/ic_launcher.png is an application icon suitable for high-density screens,/res/drawable-ldpi/ic_launcher.png is the application icon suitable for low-density screens, and so on. Note that in each case, the alternative resource is named the same. This is important. Alternative resources must use the same names as the default resources. This is how the Android system can match the appropriate resource to load—by its name.

Here are some additional important facts about alternative resources:

Image Alternative resource directory qualifiers are always applied to the default resource directory name, for example, /res/drawable-qualifier, /res/values-qualifier, /res/layout-qualifier.

Image Alternative resource directory qualifiers (and resource filenames) must always be lowercase, with one exception: region qualifiers.

Image Only one directory qualifier of a given type may be included in a resource directory name. Sometimes this has unfortunate consequences—you might be forced to include the same resource in multiple directories. For example, you cannot create an alternative resource directory called/res/drawable-ldpi-mdpi to share the same icon graphic. Instead, you must create two directories: /res/drawable-ldpi and /res/drawable-mdpi. Frankly, when you want different qualifiers to share resources instead of providing two copies of the same resource, you’re often better off making those your default resources and then providing alternative resources for those that do not match ldpi and mdpi—that is, hdpi. As we said, it’s up to you how you go about organizing your resources; these are just our suggestions for keeping things under control.

Image Alternative resource directory qualifiers can be combined or chained, with each qualifier separated from the next by a dash. This enables developers to create very specific directory names and therefore very specialized alternative resources. These qualifiers must be applied in a specific order, and the Android operating system always attempts to load the most specific resource (that is, the resource with the longest matching path). For example, you can create an alternative resource directory for French language (qualifier fr), Canadian region (qualifier rCA—CA is a region qualifier and is therefore capitalized) string resources (stored in the values directory) as follows: /res/values-fr-rCA/strings.xml.

Image You need to create alternative resources only for the specific resources you require—not every resource in a given file. If you need to translate only half the strings in the default strings.xml file, provide alternative strings only for those specific string resources. In other words, the default strings.xml resource file might contain a superset of string resources and the alternative string resource files a subset—only the strings requiring translation. Common examples of strings that do not get localized are company and brand names.

Image No custom directory names or qualifiers are allowed. You may use only the qualifiers defined as part of the Android SDK. These qualifiers are listed in Table 14.1.

Image

Image

Image

Image

Image

Table 14.1 Important Alternative Resource Qualifiers

Image Always try to include default resources—that is, those resources saved in directories without any qualifiers. These are the resources that the Android operating system will fall back on when no specific alternative resource matches the criteria. If you don’t, the system falls back on the closest matching resource based upon the directory qualifiers—one that might not make sense.

Now that you understand how alternative resources work, let’s look at some of the directory qualifiers you can use to store alternative resources for different purposes. Qualifiers are tacked onto the existing resource directory name in a strict order, shown in descending order in Table 14.1.

Good examples of alternative resource directories with qualifiers are

Image /res/values-en-rUS-port-finger

Image /res/drawables-en-rUS-land-mdpi

Image /res/values-en-qwerty

Bad examples of alternative resource directories with qualifiers are

Image /res/values-en-rUS-rGB

Image /res/values-en-rUS-port-FINGER-wheel

Image /res/values-en-rUS-port-finger-custom

Image /res/drawables-rUS-en

The first bad example does not work because you can have only one qualifier of a given type, and this one violates that rule by including both rUS and rGB. The second bad example violates the rule that qualifiers (with the exception of the region) are always lowercase. The third bad example includes a custom attribute defined by the developer, but these are not currently supported. The last bad example violates the order in which the qualifiers must be placed: language first, then region, and so on.

Providing Resources for Different Orientations

Let’s look at a very simple application that uses alternative resources to customize screen content for different orientations. The SimpleAltResources application (see the book’s sample code for a complete implementation) has no real code to speak of—check the Activity class if you don’t believe us. Instead, all interesting functionality depends on the resource folder qualifiers. These resources are as follows:

Image The default resources for this application include the application icon and a picture graphic stored in the /res/drawable directory, the layout file stored in the /res/layout directory, and the color and string resources stored in the /res/values directory. These resources are loaded whenever a more specific resource is not available to load. They are the fallbacks.

Image There is a portrait-mode alternative picture graphic stored in the /res/drawable-port directory. There are also portrait-mode-specific string and color resources stored in the /res/values-port directory. If the device is in portrait orientation, these resources—the portrait picture graphic, the strings, and the colors—are loaded and used by the default layout.

Image There is a landscape-mode alternative picture graphic stored in the /res/drawable-land directory. There are landscape-mode-specific string and color (basically reversed background and foreground colors) resources stored in the /res/values-land directory as well. If the device is in landscape orientation, these resources—the landscape picture graphic, the strings, and the colors—are loaded and used by the default layout.

Figure 14.6 illustrates how the application loads different resources based on the orientation of the device at runtime. This figure shows the project layout, in terms of resources, as well as what the screen looks like in different device orientations.

Image

Figure 14.6 Using alternative resources for portrait and landscape orientations.

Using Alternative Resources Programmatically

There is currently no easy way to request resources of a specific configuration programmatically. For example, the developer cannot programmatically request the French or English version of the string resource. Instead, the Android system determines the resource at runtime, and developers refer only to the general resource variable name.

Organizing Application Resources Efficiently

It’s easy to go too far with alternative resources. You could provide custom graphics for every different permutation of device screen, language, or input method. However, each time you include an application resource in your project, the size of your application package grows.

There are also performance issues with swapping out resources too frequently—generally when runtime configuration transitions occur. Each time a runtime event such as an orientation or keyboard state change occurs, the Android operating system restarts the underlying Activity and reloads the resources. If your application is loading a lot of resources and content, these changes come at a cost to application performance and responsiveness.

Choose your resource organization scheme carefully. Generally, you should make the most commonly used resources your defaults and then carefully overlay alternative resources only when necessary. For example, if you are writing an application that routinely shows videos or displays a game screen, you might want to make landscape mode resources your defaults and provide alternative portrait mode resources because they are not as likely to be used.

Retaining Data across Configuration Changes

An Activity can keep data around through these transitions by using the onRetainNonConfigurationInstance() method to save data and the getLastNonConfigurationInstance() method to restore this data after the transition. This functionality can be especially helpful when your Activity has a lot of setup or preloading to do. When using fragments, all you need to do is set a flag to retain a Fragment instance across these changes.

Handling Configuration Changes

In cases where your Activity does not need to reload alternative resources on a specific transition, you might want to consider having the Activity class handle the transition to avoid having your Activity restart. The Camera application mentioned earlier could use this technique to handle orientation changes without having to reinitialize the camera hardware internals, redisplay the viewfinder window, or redisplay the camera controls (the Button controls simply rotate in place to the new orientation—very slick).

For an Activity class to handle its own configuration changes, your application must

Image Update the <activity> tag in the Android manifest file for that specific Activity class to include the android:configChanges attribute. This attribute must specify the types of changes the Activity class handles itself.

Image Implement the onConfigurationChanged() method of the Activity class to handle the specific changes (by type).

Targeting Tablets, TVs, and Other New Devices

There has been tremendous growth in the types of devices supported by the Android platform. Whether we’re talking tablets, TVs, or toasters, there’s something for everyone. These new devices make for an exciting time for application developers. New devices mean new groups and demographics of users using the platform. These new types of Android devices, however, pose some unique challenges for Android developers.

Targeting Tablet Devices

Tablets come in a variety of sizes and default orientations, from many different manufacturers and carriers. Luckily, from a developer’s perspective, tablets can be considered just another Android device, provided that you haven’t made any unfortunate development assumptions.

Android tablets run the same platform versions that traditional smartphones do—there is nothing special. Most tablets these days run Android 4.0 and higher. Here are some tips for designing, developing, and publishing Android applications for tablet devices:

Image Design flexible user interfaces: Regardless of what devices your applications are targeting, use flexible layout designs. Use RelativeLayout to organize your user interfaces. Use relative dimension values such as dp instead of specific ones such as px. Use stretchable graphics such as Nine-Patch.

Image Take advantage of fragments: Fragments make for much more flexible user interface navigation by decoupling screen functionality from specific activities.

Image Leverage alternative resources: Provide alternative resources for various device screen sizes and densities.

Image Screen orientation: Tablets often default to landscape mode, but this is not always the case. Some tablets, especially smaller ones, use portrait defaults.

Image Input mode differentiators: Tablets often rely solely on touchscreen input. Some configurations also have a few other physical buttons, but this is unusual because Honeycomb, the first platform revision to truly support tablets, moved the typical hardware buttons to the touchscreen.

Image UI navigational differences: Users hold and tap on tablets in a different fashion from the way they do on smartphones. In portrait and landscape modes, tablet screens are substantially wider than their smartphone equivalents. Applications such as games that rely on the user cradling the device in his or her hands like a traditional game controller may struggle with all the extra room on a tablet. The user’s thumbs might easily reach or access the two halves of a smartphone screen but not be able to do the same on a tablet.

Image Feature support: Certain hardware and software features are not usually available on tablets. For example, telephony is not always available. This has implications for unique device identifiers; many used to rely on the telephony identifier that may not be present. The point is, hardware differences can also lead to other, less obvious impacts.

Targeting Google TV Devices

Google TV is another type of device that Android developers can target. Users can browse Google Play for compatible applications and download them much as they would to other Android devices.

In order to develop Google TV applications, developers use the Android SDK as well as a Google TV add-on, which can be downloaded using the Android SDK Manager.

There are some subtle differences between development for Google TV devices and targeting smartphones and tablets. Let’s look at some development tips for targeting Google TV devices:

Image Screen density and resolution: Google TV devices currently run at two resolutions. The first is 720p (aka “HD” and tvdpi), or 1280 × 720 pixels. The second is 1080p (aka “Full HD” and xhdpi), or 1920 × 1080 pixels. These correspond to large screen size.

Image Screen orientation: Google TV devices need only landscape-oriented layouts.

Image Not pixel perfect: One caveat regarding Google TV development is not to rely on the exact number of pixels on the screen. Televisions don’t always expose every single pixel. Therefore, your screen designs should be flexible enough to accommodate small adjustments when you’ve had a chance to test your applications on real Google TV devices. Use of RelativeLayout is highly recommended. See https://developers.google.com/tv/android/docs/gtv_displayguide#DisplayResolution for more information on this issue.

Image Input mode limitations: Unlike tablets or smartphones, Google TV devices are not within arm’s reach and do not have touchscreens. This means no gestures, no multitouch, and so on. The Google TV interface uses a directional pad (or D-pad)—that is, arrow keys for up, down, left, and right along with a Select button and media keys (“Play,” “Pause,” and so on). Some configurations also have a mouse or keyboard.

Image UI navigational differences: The input type limitations with Google TV devices may mean you need to make some changes to your application’s screen navigation. Users can’t easily skip over focusable items on the screen. For instance, if your UI has a row of items, with the two most common on the far left and far right for convenient access with thumb clicks, these items may be inconveniently separated for the average Google TV user.

Image Android manifest file settings: A number of Android manifest file settings should be configured appropriately for the Google TV. Review the Google TV documentation for details: https://developers.google.com/tv/android/docs/gtv_androidmanifest.

Image Google Play filters: Google Play uses Android manifest file settings to filter applications and provide them to the appropriate devices. Certain features, such as those defined using the <uses-feature> tag, may exclude your application from Google TV devices. One example of this is when applications require features such as touchscreen, camera, and telephony. For a complete list of features supported and unsupported by the Google TV, see the following page: https://developers.google.com/tv/android/docs/gtv_android_features.

Image Feature support: Certain hardware and software features (sensors, cameras, telephony, and so on) are not available on Google TV devices.

Image Native Development Kit: For Google TV devices based on Android 4.2.2, NDK support has been added. There is currently no NDK support for Google TV devices prior to Android 4.2.2.

Image Supported media formats: There are subtle differences between the media formats supported by the Android platform (http://d.android.com/guide/appendix/media-formats.html) and those supported on the Google TV platform (https://developers.google.com/tv/android/docs/gtv_media_formats).


Image Tip

For more information on developing for Google TV devices, see the Google TV Android Developers Guide at https://developers.google.com/tv/android/.


Targeting Google Chromecast Devices

Google Cast is a new screen-sharing feature introduced recently. Chromecast is an HDMI dongle that users connect to their TV and control with one of their devices, such as a smartphone, tablet, or computer.

Android 4.3 (API Level 18) received the MediaRouter APIs (android.media.MediaRouter) so developers can integrate screen-sharing capabilities into their applications. To learn more about the MediaRouter APIs, see http://developer.android.com/reference/android/media/MediaRouter.html. To learn more about Google Cast, see https://developers.google.com/cast/.

Summary

Compatibility is a vast topic, and we’ve given you a lot to think about. During design and implementation, always consider if your choices are going to introduce roadblocks to device compatibility. Quality assurance personnel should always vary the devices used for testing as much as possible—certainly don’t rely solely on emulator configurations for testing coverage. Use best practices that encourage compatibility, and do your best to keep compatibility-related resources and code streamlined and manageable.

If you take only two concepts away from this chapter, one should be that alternative resources and fragments can be used to great effect. They enable a flexibility that can go a long way toward achieving compatibility, whether it’s for screen differences or internationalization. The other is that certain Android manifest file tags can help ensure that your applications are installed only on devices that meet certain prerequisites, or requirements, such as a certain version of OpenGL ES or the availability of camera hardware.

Quiz Questions

1. True or false: To design user interfaces for compatibility, as a rule of thumb, design for normal-size screens and medium resolution.

2. What percentage of Android devices currently on the market support the use of fragments?

3. What manifest file tag is used to explicitly state which screen sizes your application supports?

4. True or false: The directory /res/drawables-rGB-MDPI is a good example of an alternative resource directory with a qualifier.

5. What are the possible values for the layout direction alternative resource directory qualifier?

6. True or false: You can request resources of a specific configuration programmatically.

7. What is the method call you should implement in your Activity class for handling configuration changes?

Exercises

1. Read through the “Best Practices” topic of the Android API Guides (http://d.android.com/guide/practices/index.html) to learn more about how to build apps that work for a wide range of devices.

2. Using the “Best Practices” Android API Guides, determine what the typical sizes in dp units are for small, normal, large, and xlarge screens.

3. Using the “Best Practices” Android API Guides, determine what scaling ratio you should follow between the four densities of low, medium, high, and extra-high.

References and More Information

Android SDK Reference regarding the application Dialog class:

http://d.android.com/reference/android/app/Dialog.html

Android SDK Reference regarding the Android Support Library:

http://d.android.com/tools/extras/support-library.html

Android API Guides: “Screen Compatibility Mode”:

http://d.android.com/guide/practices/screen-compat-mode.html

Android API Guides: “Providing Alternative Resources”:

http://d.android.com/guide/topics/resources/providing-resources.html#AlternativeResources

Android API Guides: “How Android Finds the Best-Matching Resource”:

http://d.android.com/guide/topics/resources/providing-resources.html#BestMatch

Android API Guides: “Handling Runtime Changes”:

http://d.android.com/guide/topics/resources/runtime-changes.html

Android API Guides: “Android Compatibility”:

http://d.android.com/guide/practices/compatibility.html

Android API Guides: “Supporting Multiple Screens”:

http://d.android.com/guide/practices/screens_support.html

ISO 639-2 languages:

http://www.loc.gov/standards/iso639-2/php/code_list.php

ISO 3166 country codes:

http://www.iso.org/iso/home/standards/country_codes.htm