android 接口 管理,Managing Network Usage | Android中文API

This lesson describes how to write applications that have fine-grained

control over their usage of network resources. If your application performs a

lot of network operations, you should provide user settings that allow users

to control your app’s data habits, such as how often your app syncs data,

whether to perform uploads/downloads only when on Wi-Fi, whether to use data

while roaming, and so on. With these controls available to them, users are much

less likely to disable your app’s access to background data when they approach their

limits, because they can instead precisely control how much data your app

uses.

For general guidelines on how to write apps that minimize the battery life

impact of downloads and network connections, see

Optimizing Battery Life

and 无耗电地传输数据.

Check a Device's Network Connection

A device can have various types of network connections. This lesson

focuses on using either a Wi-Fi or a mobile network connection. For the full

list of possible network types, see

Wi-Fi is typically faster. Also, mobile data is often metered, which can get

expensive.

A common strategy for apps is to only fetch large data

if a Wi-Fi network is available.

Before you perform network operations, it's good practice to check the state of

network connectivity. Among other things, this could prevent your app from inadvertently using

the wrong radio. If a network connection is unavailable, your application

should respond gracefully. To check the network connection, you typically use

the following classes:

This code snippet tests network connectivity for Wi-Fi and mobile. It

determines whether these network interfaces are available (that is, whether

network connectivity is possible) and/or connected (that is, whether network

connectivity exists and if it is possible to establish sockets and pass

data):

private static final String DEBUG_TAG = "NetworkStatusExample";

...

ConnectivityManager connMgr = (ConnectivityManager)

getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

boolean isWifiConn = networkInfo.isConnected();

networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

boolean isMobileConn = networkInfo.isConnected();

Log.d(DEBUG_TAG, "Wifi connected: " + isWifiConn);

Log.d(DEBUG_TAG, "Mobile connected: " + isMobileConn);

Note that you should not base decisions on whether a network is

"available." You should always check

A more concise way of checking whether a network interface is available is as

follows. The method null if none if the

interfaces is connected (meaning that an

internet connection is not available):

public boolean isOnline() {

ConnectivityManager connMgr = (ConnectivityManager)

getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

return (networkInfo != null && networkInfo.isConnected());

}

To query more fine-grained state you can use

Manage Network Usage

You can implement a preferences activity that gives users explicit control

over your app's usage of network resources. For

example:

You might allow users to upload videos only when the device is connected to a

Wi-Fi network.

You might sync (or not) depending on specific criteria such as network

availability, time interval, and so on.

To write an app that supports network access and managing

network usage, your manifest must have the right permissions and

intent filters.

The manifest excerpted below includes the following permissions:

You can declare the intent filter for the

SettingsActivity, which displays a preferences UI to let users

decide when to download a feed.

package="com.example.android.networkusage"

...>

android:targetSdkVersion="14" />

...>

...

Implement a Preferences Activity

As you can see in the manifest excerpt above, the sample app's activity

SettingsActivity has an intent filter for the SettingsActivity is a subclass of

Whether to display summaries for each XML feed entry, or just a link for

each entry.

Whether to download the XML feed if any network connection is available,

or only if Wi-Fi is available.

9ab90e2b0aaadf4dfccdd110e2846d98.png

b65025d270a067eb25ae8fc550b35d1c.png

Figure 1. Preferences activity.

Here is SettingsActivity. Note that it implements

refreshDisplay to true. This causes the display to refresh when the user

returns to the main activity:

public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Loads the XML preferences file

addPreferencesFromResource(R.xml.preferences);

}

@Override

protected void onResume() {

super.onResume();

// Registers a listener whenever a key changes

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

}

@Override

protected void onPause() {

super.onPause();

// Unregisters the listener set in onResume().

// It's best practice to unregister listeners when your app isn't using them to cut down on

// unnecessary system overhead. You do this in onPause().

getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);

}

// When the user changes the preferences selection,

// onSharedPreferenceChanged() restarts the main activity as a new

// task. Sets the the refreshDisplay flag to "true" to indicate that

// the main activity should update its display.

// The main activity queries the PreferenceManager to get the latest settings.

@Override

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

// Sets refreshDisplay to true so that when the user returns to the main

// activity, the display refreshes to reflect the new settings.

NetworkActivity.refreshDisplay = true;

}

}

Respond to Preference Changes

When the user changes preferences in the settings screen, it typically has

consequences for the app's behavior. In this snippet, the app checks the

preferences settings in onStart(). if there is a match between the setting and

the device's network connection (for example, if the setting is "Wi-Fi" and the

device has a Wi-Fi connection), the app downloads the feed and refreshes the

display.

public class NetworkActivity extends Activity {

public static final String WIFI = "Wi-Fi";

public static final String ANY = "Any";

private static final String URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";

// Whether there is a Wi-Fi connection.

private static boolean wifiConnected = false;

// Whether there is a mobile connection.

private static boolean mobileConnected = false;

// Whether the display should be refreshed.

public static boolean refreshDisplay = true;

// The user's current network preference setting.

public static String sPref = null;

// The BroadcastReceiver that tracks network connectivity changes.

private NetworkReceiver receiver = new NetworkReceiver();

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Registers BroadcastReceiver to track network connection changes.

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);

receiver = new NetworkReceiver();

this.registerReceiver(receiver, filter);

}

@Override

public void onDestroy() {

super.onDestroy();

// Unregisters BroadcastReceiver when app is destroyed.

if (receiver != null) {

this.unregisterReceiver(receiver);

}

}

// Refreshes the display if the network connection and the

// pref settings allow it.

@Override

public void onStart () {

super.onStart();

// Gets the user's network preference settings

SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

// Retrieves a string value for the preferences. The second parameter

// is the default value to use if a preference value is not found.

sPref = sharedPrefs.getString("listPref", "Wi-Fi");

updateConnectedFlags();

if(refreshDisplay){

loadPage();

}

}

// Checks the network connection and sets the wifiConnected and mobileConnected

// variables accordingly.

public void updateConnectedFlags() {

ConnectivityManager connMgr = (ConnectivityManager)

getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();

if (activeInfo != null && activeInfo.isConnected()) {

wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI;

mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE;

} else {

wifiConnected = false;

mobileConnected = false;

}

}

// Uses AsyncTask subclass to download the XML feed from stackoverflow.com.

public void loadPage() {

if (((sPref.equals(ANY)) && (wifiConnected || mobileConnected))

|| ((sPref.equals(WIFI)) && (wifiConnected))) {

// AsyncTask subclass

new DownloadXmlTask().execute(URL);

} else {

showErrorPage();

}

}

...

}

Detect Connection Changes

The final piece of the puzzle is the NetworkReceiver. When

the device's network connection changes, NetworkReceiver intercepts

the action wifiConnected and mobileConnected to true/false

accordingly. The upshot is that the next time the user returns to the app, the

app will only download the latest feed and update the display if

NetworkActivity.refreshDisplay is set to true.

Setting up a BroadcastReceiver that gets called unnecessarily can be a

drain on system resources.

The sample application registers the

NetworkReceiver in

in the manifest. When you declare a

in the manifest, it can wake up your app at any time,

even if you haven't run it for weeks. By registering and unregistering

NetworkReceiver within the main activity, you ensure that the app won't

be woken up after the user leaves the app.

If you do declare a in the manifest and you know exactly

where you need it, you can use

Here is NetworkReceiver:

public class NetworkReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

ConnectivityManager conn = (ConnectivityManager)

context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = conn.getActiveNetworkInfo();

// Checks the user prefs and the network connection. Based on the result, decides whether

// to refresh the display or keep the current display.

// If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.

if (WIFI.equals(sPref) && networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {

// If device has its Wi-Fi connection, sets refreshDisplay

// to true. This causes the display to be refreshed when the user

// returns to the app.

refreshDisplay = true;

Toast.makeText(context, R.string.wifi_connected, Toast.LENGTH_SHORT).show();

// If the setting is ANY network and there is a network connection

// (which by process of elimination would be mobile), sets refreshDisplay to true.

} else if (ANY.equals(sPref) && networkInfo != null) {

refreshDisplay = true;

// Otherwise, the app can't download content--either because there is no network

// connection (mobile or Wi-Fi), or because the pref setting is WIFI, and there

// is no Wi-Fi connection.

// Sets refreshDisplay to false.

} else {

refreshDisplay = false;

Toast.makeText(context, R.string.lost_connection, Toast.LENGTH_SHORT).show();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值