Networking

Many Android applications transfer data between the device and a server, or between devices. Like the battery state, applications may need to retrieve information about the network connections on the device. The ConnectivityManager class provides APIs applications can call to have access to the network information. Android devices often have multiple data connections available:

  • Bluetooth
  • Ethernet
  • Wi-Fi
  • WiMAX
  • Mobile (EDGE, UMTS, LTE)

Listing 7–6 shows how to retrieve information about the active connection as well as all the connections.

Listing 7–6. Network Information

    private void showNetworkInfoToast() {
        ConnectivityManager cm = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);

        // to show only the active connection
        NetworkInfo info = cm.getActiveNetworkInfo();
        if (info != null) {
            Toast.makeText(this, "Active: " + info.toString(),
Toast.LENGTH_LONG).show();
        }

        // to show all connections
        NetworkInfo[] array = cm.getAllNetworkInfo();
        if (array != null) {
            String s = "All: ";
            for (NetworkInfo i: array) {
                s += i.toString() + " ";
            }
            Toast.makeText(this, s, Toast.LENGTH_LONG).show();
        }
    }

NOTE: Your application needs the ACCESS_NETWORK_STATE permission to be able to retrieve the network information.

Since the focus is on maximizing the battery life, we need to be aware of certain things:

  • Background data setting
  • Data transfer rates

Background Data

Users have the ability to specify whether background data transfer is allowed or not in the settings, presumably to preserve battery life. If your application needs to perform data transfers when it is not the foreground application, it should check that flag, as shown in Listing 7–7. Services typically have to check that setting before initiating any transfer.

Listing 7–7. Checking Background Data Setting

    private void transferData(byte[] array) {
        ConnectivityManager cm = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean backgroundDataSetting = cm.getBackgroundDataSetting();
        if (backgroundDataSetting) {
            // transfer data
        } else {
            // honor setting and do not transfer data
        }
    }

Because this is a voluntary check, your application could actually ignore that setting and transfer data anyway. However, since it would go against the wish of the user, potentially slow down foreground data transfers, and impact battery life, such behavior would likely cause your application to be uninstalled by the user eventually.

To be notified when the background data setting changes, your application can register a broadcast receiver explicitly in the Java code using the ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED string to build the intent filter or android.net.conn.BACKGROUND_DATA_SETTING_CHANGED in the application's manifest file. Because this setting is to control background data transfer, it actually makes more sense to disable this broadcast receiver in onResume() and enable it again in onPause().

NOTE: The getBackgroundDataSetting() method is deprecated in Android 4.0 and will always return true. Instead, the network will appear disconnected when background data transfer is not available.

Data Transfer

Transfer rates can vary wildly, typically from less than 100 kilobits per second on a GPRS data connection to several megabits per second on an LTE or Wi-Fi connection. In addition to the connection type, the NetworkInfo class specifies the subtype of a connection. This is particularly important when the connection type is TYPE_MOBILE. Android defines the following connection subtypes (in the TelephonyManager class):

  • NETWORK_TYPE_GPRS           (API level 1)
  • NETWORK_TYPE_EDGE          (API level 1)
  • NETWORK_TYPE_UMTS          (API level 1)
  • NETWORK_TYPE_CDMA         (API level 4)
  • NETWORK_TYPE_EVDO_0     (API level 4)
  • NETWORK_TYPE_EVDO_A     (API level 4)
  • NETWORK_TYPE_1xRTT          (API level 4)
  • NETWORK_TYPE_HSDPA        (API level 5)
  • NETWORK_TYPE_HSUPA        (API level 5)
  • NETWORK_TYPE_HSPA           (API level 5)
  • NETWORK_TYPE_IDEN    (API level 8)
  • NETWORK_TYPE_EVDO_B    (API level 9)
  • NETWORK_TYPE_LTE    (API level 11)
  • NETWORK_TYPE_EHRPD    (API level 11)
  • NETWORK_TYPE_HSPAP    (API level 13)

Subtypes are added as new technologies are created and deployed. For example, the LTE subtype was added in API level 11, whereas the HSPAP subtype was added in API level 13. If your code depends on these values, make sure you handle the case where your application is presented with a new value it does not know about; otherwise it could result in your application not being able to transfer data. You should update your code when new subtypes are defined, so pay attention to each release of the Android SDK. A list of differences is available on http://d.android.com/sdk/api_diff/13/changes.html, for example.

Intuitively, your application should prefer faster connections. Even if the 3G radio chip consumes less power than the Wi-Fi radio chip, the Wi-Fi transfer rate may ultimately mean the Wi-Fi transfer reduces power consumption as the transfer can be completed in a shorter time.

NOTE: Since data plans now typically allow for a limited amount of data to be transferred (for example, $30 for 2GB a month), Wi-Fi connections are usually preferred. Also, your application can use NetworkInfo.isRoaming() to know if the device is currently roaming on the given network. Since this can incur additional cost, you should avoid transferring data when isRoaming() returns true.

Table 7–2 shows the memory consumption of various components on the T-Mobile G1 phone (also known as the HTC Dream, or Era G1). While the phone is somewhat old now (it was released in late 2008), the numbers still give a pretty good overview of how much power each component draws.

Image

While the exact numbers vary between devices, it is important to know roughly how much power your application would use. Since the G1 had a 1,150 mAh battery, an application that downloads and plays videos (for example, YouTube) would empty the battery in about three hours assuming it uses a 3G connection: 150mA for 3G, 90 mA for CPU, and 90mA for LCD would total 330 mA, or three and a half hours of usage (assuming nothing else runs on the phone).

If you have control over what kind of data gets transferred, then you should consider compressing the data before it is sent to the device. While the CPU will have to decompress the data before it can be used (and therefore more power will be needed for that purpose), the transfer will be faster and the radios (for example, 3G, Wi-Fi) can be turned off again faster, preserving battery life. The things to consider are:

  • Compress text data using GZIP and use the GZIPInputStream to access the data.
  • Use JPEG instead of PNG if possible.
  • Use assets that match the resolution of the device (for example, there is no need to download a 1920×1080 picture if it is going to be resized to 96×54).

The slower the connection (for example, EDGE) the more important compression is, as you want to reduce the time the radios are turned on.

Since Android is running on more and more devices, from cell phones to tablets, from set-top boxes to netbooks, generating assets for all these devices can become tedious. However, using the right assets can greatly improve the battery life and therefore make your application more desirable. In addition to saving power, faster downloads and uploads will make your application more responsive.

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

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