13. Designing Compatible Applications

According to the MOVR Mobile Overview Report, January–March 2015, by ScientiaMobile, Inc., in the first quarter of 2015 there were over 5,600 different Android devices on the market worldwide—just from smartphones, tablets, and feature phones. 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.

Maximizing Application Compatibility

With dozens of manufacturers developing Android devices, we’ve seen an explosion of different device models and form factors—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, even when the devices are of the same form factor. Developers must contend with devices that support different platform versions (see Figure 13.1), hardware configurations (including optional hardware features) such as OpenGL versions (see Figure 13.2), and variations in screen sizes and densities (see Figure 13.3). The list of differentiators is lengthy and it grows with each new device.

Image

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

Image

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

Image

Figure 13.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 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 on different screen resolutions and sizes, as well as in both portrait and landscape modes for mobile, and on round and rectangle Wear screens. However, if you don’t consider these factors early on, you will likely have to make changes (sometimes painful ones) later 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 hardware and software 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 their use 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.

Image Leverage the various Android Support Library APIs 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 pt, 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, FrameLayout, or a custom layout to design a screen that looks great in both portrait and landscape modes, as well as on a variety of different screen sizes and resolutions.

Image Encapsulate screen content in scalable container controls such as ViewPager, ScrollView, ListView, and RecyclerView. 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 this 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, as shown here:

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

You may also learn about a device configuration and user configurations, such as input modes, screen size and orientations, locales, and scaling at runtime, through the Configuration class as follows:

Configuration config = getResources().getConfiguration();


Working with Fragments

Fragments were discussed in detail in Chapter 9, “Partitioning 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 (nearly 100% of the market). Simply use the Android Support Library to include these features in your legacy code. With most non-Fragment-based APIs deprecated, it’s clearly the path along which the platform designers are leading developers.


Leveraging the Various Android Support Library APIs

In addition to fragments, several other new features of the Android SDK are so important for future device compatibility that there are Android support libraries to bring these APIs to older device platform versions, some as far back as Android 1.6. In addition, there are certain modern features such as the RecyclerView that are only available through the support library, so even if you are not interested in targeting older devices, to implement newer features may require adding the appropriate support libraries. To use the Android Support Library APIs with your application, take the following steps:

1. Use the Android SDK Manager to download the Android Support Repository for Android Studio.

2. View your project in the Android view of Android Studio, and open the appropriate build.gradle module file.

3. Add the appropriate support libraries to the dependencies declaration with the version target to the build.gradle file.

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.

For a full list of the available APIs in the Android Support Library, see http://d.android.com/tools/support-library/features.html.

Supporting Specific Screen Types

Although you generally want to try to develop your applications to be screen independent (supporting all types of screens, small and large, high density and low), when necessary you can explicitly specify the types of screens your application can support 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 regularly review how your application behaves on devices with different screen sizes, densities, aspect ratios, and orientations 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 watches 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

Screens come in various dimensions. It can save you a lot of time if you 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 D, “Mastery: Android SDK Tools.”

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, to design for the defaults, and to 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 must be 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 do so 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 Android Studio. An application could simply provide a single application icon graphics resource, stored in the res/mipmap/ directory. However, different Android devices have different screen densities. Therefore, alternative resources are used instead: res/mipmap-hdpi/ic_launcher.png is an application icon suitable for high-density screens, res/mipmap-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 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 the shared resources your default resources, and then providing alternative resources for those resources that do not match ldpi and mdpi—such as, 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 (and resource filenames) must always be lowercase, with one exception: region qualifiers.

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 the French language (qualifier fr) in the Canadian region (qualifier rCACA 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 for 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 would contain 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 13.1.

Image
Image
Image
Image
Image

Table 13.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, which could be 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 13.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 sample code for this chapter found on the book’s website, http://introductiontoandroid.blogspot.com, for a complete implementation) has very little custom code to speak of (check the Activity class if you don’t believe us); there were two lines of code written for adding the Android Design Support library ToolBar as the ActionBar, and rather than SimpleAltResourcesActivity extending Activity, we extend AppCompatActivity. Here are the two lines of code we added to the onCreate() method:

toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

The interesting functionality depends on the resource folder qualifiers. These resources are as follows:

Image The default resources for this application include the application icon in the res/mipmap/ directory; a picture graphic stored in the res/drawable/ directory; the layout file stored in the res/layout/ directory; and the color, dimension, string, and style 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 13.4 (left) shows the Android project view of Android Studio, with the res/ directory fully expanded, revealing the different symbolic resource file names and subdirectories for different configurations. Note that these directories are only symbolic representations of their names, not their actual file system location. The Android project view shows how easy it is to determine what configuration a particular resource is for by displaying the appropriate resource qualifiers to the right of the filename in parentheses, even though these are only symbolic representations of the project hierarchy. For example, we see three pic.jpg files—the first has no qualifier, so that is the default pic.jpg resource, the second pic.jpg has the (land) qualifier to the right, and the third pic.jpg has the (port) qualifier to the right. Figure 13.4 (right) shows the traditional Project view of Android Studio, expanded to reveal the res/ directory showing the actual file system names and locations of these directories. Rather than displaying a symbolic (land) file representation, the actual directory name contains the qualifier—for example, values-land and values-port—each of which contains a colors.xml file and strings.xml file (those files not shown for the traditional Project view).

Image

Figure 13.4 An expanded Android project view of Android Studio reveals the alternative resource files within the res/ subdirectories by their symbolic name and project hierarchy location (left), and shows the traditional Project view that displays the res/ subdirectories with their actual file system name and location (right).

Figure 13.5 illustrates how SimpleAltResources loads different resources based on the portrait orientation of the application at runtime. This figure shows the rendered resources, with a unique blue, white, and black color palette for the status bar, TextView, ToolBar, and navigation bar, and a unique image for the ImageView.

Image

Figure 13.5 Using alternative resources for portrait orientation in the SimpleAltResources application.

Figure 13.6 illustrates how SimpleAltResources loads different resources based on the landscape orientation of the application at runtime. This figure shows the rendered resources, with a unique red and black color palette for the status bar, ToolBar, TextView, and navigation bar, and a unique image for the ImageView.

Image

Figure 13.6 Using alternative resources for landscape orientation in the SimpleAltResources application.

Using Alternative Resources Programmatically

Currently, there is 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—usually 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 use the setRetainInstance() method 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. A camera application 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 and TVs

There has been tremendous growth in the types of devices supported by the Android platform. Whether we’re talking tablets or TVs, there is something for everyone. These devices make for an exciting time for application developers. More devices mean more user groups and demographics are using the platform. These 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 that they require. These days, most tablets run Android Jelly Bean 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 values 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’s 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 typical hardware buttons have moved 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 cannot 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 developers used to rely on the telephony identifier that may not be present on tablets. The point is, hardware differences can also lead to other, less obvious impacts.

Targeting TV Devices

Android 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 Android TV applications, developers use the Android SDK as well as the add-on for Android TV, which can be downloaded using the Android SDK Manager.

Android TV applications have a similar structure to smartphone and tablet applications, although there are some subtle differences between targeting Android TV devices and targeting smartphones and tablets. Let’s look at some development tips for targeting Android TV devices:

Image Screen density and resolution: Android TV applications should target resolutions of 1920 x 1080 pixels and allow the system to automatically resize the resources for you if your user should have a TV with a lower resolution.

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

Image Overscan margins: Screen clipping can occur on Android TVs due to overscan. If you are using the v17 Leanback support classes, you have nothing to worry about; however, if you are not using those classes, be sure to define a 10% margin for your layouts so your screen elements are not affected by overscan clipping.

Image Not pixel perfect: One caveat regarding Android 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 Android TV devices.

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

Image UI navigational differences: The input type limitations with Android 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 Android TV user.

Image Android manifest file settings: A number of Android manifest file settings should be configured appropriately for the Android TV. Review the Android TV training for details: http://d.android.com/training/tv/start/start.html.

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 Android TV devices. If you have built a game, you should set the android:isGame attribute of the <application> tag in your manifest file so your app will be listed in the games section. 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 Android TV, see “Handling TV Hardware”: http://d.android.com/training/tv/start/hardware.html.

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


Image Tip

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


Extending Your Application to Watches and Cars

With Android Wear and Android Auto being specialized versions of Android—Wear for running on watches, and Auto for running on dashboard console devices—there are many application compatibility differences when comparing a Wear or Auto application to one for smartphones, tablets, and TVs, or when comparing a Wear application to an Auto application.

Wear and Auto applications are designed to act as an extension to a handheld device—a smartphone or tablet. Integration with Wear may be performed with an application extension that gets installed on the Wear device. The extension is packaged with your handheld application and installed at the same time the handheld application installs. Integration also may not have an application extension to be installed on the Wear device; instead, the handheld device relays messages that are displayed on the screen of the Wear device in the form of a Notification using the NotificationCompat class.

There are minimal compatibility issues when your handheld application is only used to relay notifications for display on the Wear device; if those notifications contain icon images, resolution may need to be considered, but you must ensure the APIs used on the handheld remain compatible with the Android Wear API version paired with the handheld.

On the other hand, if the Wear integration requires a separate Wear application to be installed on the Wear device itself, you are now challenged with ensuring application compatibility across Wear devices, so things like layouts or device configurations are now more of an issue to contend with—in addition to compatibility issues you must maintain across handheld devices such as smartphones and tablets. The good news is that there are very few Android Wear devices on the market as of this writing, but this is surely going to change as more manufacturers move into the wearable device market.

For Android Auto, the dashboard console device acts as an extension to your handheld application and relays messages and audio, or allows for voice interaction or button presses on the console device, which means there is no application that needs to be installed on the console device. As of now, there are minimal compatibility issues to contend with, but make sure the APIs in your handheld application match up properly with the console device APIs.


Image Tip

To learn more about building applications for Android Wear, see http://d.android.com/wear/index.html. To learn more about building applications for Android Auto, see http://d.android.com/auto/index.html.


Ensuring Compatibility with SafetyNet

Even if you have implemented all of these compatibility design techniques, it does not mean your application is guaranteed to run as expected on the device on which it has been installed. How could this be, you may ask? Because Android is open source, anyone capable of building a hardware device could use Android as the operating system, without needing to pass any quality or compatibility requirements before going to market. In addition, you may come across a customer who replaced the stock Android of their device. This means you cannot guarantee that your application will perform as expected in this situation, even if you adhere to all of these compatibility recommendations.

With this in mind, Google Play has a service you can access called SafetyNet that will help you determine if a device is capable of running your application as intended. The AOSP does recommend to all hardware manufacturers that they build compatible devices, but that does not mean they will comply. In the hope that they do build compatible hardware devices, the AOSP has created the Compatibility Test Suite that allows manufacturers to check their device for compatibility against a series of manual or automatic tests. If a manufacturer passes these tests, Google records a profile for the device. That means the device is most likely configured to maintain compatibility for running your application as intended for the requirements you have specified in that application.

In order for you, the application developer, to use SafetyNet, you must agree to the Google API’s Terms of Service. Once you have done so, you may make requests to the SafetyNet API to check if the device profile your application has been installed on matches the profile of a device that has passed the Compatibility Test Suite. If there is no match, you application may have problems running correctly—but maybe not; there really is no way to tell until the user reaches a part of your code that triggers an error. Unfortunately, there is nothing you can do in this situation until after the fact. On the other hand, if there is a profile match, your application may just run as expected, but really there are no guarantees other than that the device your application is running on is a match to a device profile that has passed the Compatibility Test Suite.


Image Tip

For more information on the SafetyNet API service, see http://d.android.com/training/safetynet/index.html. For more information about Compatibility and the AOSP, see https://source.android.com/compatibility/index.html.


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. The other is that certain Android manifest file tags can help ensure that your applications are installed only on devices that meet certain requirements. In addition, you learned about the compatibility similarities between smartphones, tablets, and TVs, and you should understand the differences in compatibility between handhelds and Wear, and handhelds and TV. Finally, to help you further determine if your application may work properly on the given device, you learned about a Google Play service that allows you to make API requests to determine if a device matches a compatibility profile that has passed the AOSP Compatibility Test Suite.

Quiz Questions

1. True or false: As a rule of thumb, to design user interfaces for compatibility, 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’s 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?

8. True or false: Your Android Auto applications are installed on a car’s dashboard console device.

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, xlarge, xxlarge, and xxxlarge screens.

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

4. Using the online documentation, determine the name of the SafetyNet attribute returned from the getJwsResult() method that tells you whether the device your application is being installed on matches a device profile that has passed the AOSP Compatibility Test Suite.

References and More Information

ScientiaMobile: Mobile Overview Report (MOVR) 2015 Q1:

http://data.wurfl.io/MOVR/pdf/2015_q1/MOVR_2015_q1.pdf

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: “Device 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

Android Training: “Building Apps for TV”:

http://d.android.com/training/tv/index.html

Android Training: “Building Apps for Wearables”:

http://d.android.com/training/building-wearables.html

Android Training: “Building Apps for Auto”:

http://d.android.com/training/auto/index.html

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.15.99