Save the date! Android Dev Summit is coming to Mountain View, CA on November 7-8, 2018.

优化网络流量消耗

在智能手机的整个生命周期,移动数据网络计划的成本通常会超出设备本身的成本。 从 Android 7.0(API 级别 24)开始,用户可以在整个设备上启用流量节省程序,以优化其设备的流量消耗,并减少流量消耗。 无论是在漫游、账单周期即将结束,还是使用少量的预付费数据包,此功能都特别有用。

当用户在 Settings 中启用流量节省程序且设备位于按流量计费的网络上时,系统屏蔽后台流量消耗,同时指示应用在前台尽可能使用较少的数据。 用户可以将特定应用加入白名单以允许后台按流量计费的流量消耗,即使在打开流量节省程序时也是如此。

N Developer Preview 扩展ConnectivityManager API,为应用提供检索用户的流量节省程序首选项监控首选项变更的方式。 这被认为是应用检查用户是否启用了流量节省程序并努力限制前台和后台流量消耗的有效方法。

检查流量节省程序首选项

在 N Developer Preview 中,应用可以使用 ConnectivityManager API 来确定正在应用的是哪些流量消耗限制。getRestrictBackgroundStatus() 方法返回下列值之一:

RESTRICT_BACKGROUND_STATUS_DISABLED
流量节省程序已停用。
RESTRICT_BACKGROUND_STATUS_ENABLED
用户已为此应用启用流量节省程序。应用应努力限制前台流量消耗,并妥善处理后台流量消耗限制。
RESTRICT_BACKGROUND_STATUS_WHITELISTED
用户已启用流量节省程序,但应用在白名单中。应用应努力限制前台和后台流量消耗。

这被认为是在设备连接到按流量计费的网络时限制流量消耗的有效方法,即使流量节省程序被停用或应用在白名单中。 以下示例代码使用 ConnectivityManager.isActiveNetworkMetered()ConnectivityManager.getRestrictBackgroundStatus() 来确定应用应使用多少数据:

ConnectivityManager connMgr = (ConnectivityManager)
        getSystemService(Context.CONNECTIVITY_SERVICE);
// Checks if the device is on a metered network
if (connMgr.isActiveNetworkMetered()) {
  // Checks user’s Data Saver settings.
  switch (connMgr.getRestrictBackgroundStatus()) {
    case RESTRICT_BACKGROUND_STATUS_ENABLED:
    // Background data usage is blocked for this app. Wherever possible,
    // the app should also use less data in the foreground.

    case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
    // The app is whitelisted. Wherever possible,
    // the app should use less data in the foreground and background.

    case RESTRICT_BACKGROUND_STATUS_DISABLED:
    // Data Saver is disabled. Since the device is connected to a
    // metered network, the app should use less data wherever possible.
  }
} else {
  // The device is not on a metered network.
  // Use data as required to perform syncs, downloads, and updates.
}

请求白名单权限

如果您的应用需要使用后台数据,它可以通过发送一项包含您的应用软件包名称的 URI 的 Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS Intent 来请求白名单权限:例如 package:MY_APP_ID

发送 Intent 和 URI 将启动 Settings 应用,还会显示您的应用的流量消耗设置。 用户随后可以决定是否启用应用的后台数据。 在您发送此 Intent 之前,先询问用户是否希望启用 Settings 应用,以启用后台流量消耗,这是一种有效的做法。

监控流量节省程序首选项变更

应用可以通过创建一个 BroadcastReceiver 以侦听 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED 以及使用 Context.registerReceiver() 动态注册接收器来监控流量节省程序首选项变更。当应用接收到这条广播时,应通过调用 ConnectivityManager.getRestrictBackgroundStatus()检查新的流量节省程序首选项是否会影响其权限

:系统只会向使用 Context.registerReceiver() 进行动态注册的应用发送此广播。在其清单中注册接收此广播的应用将不会收到它们。

使用 Android 调试桥命令测试

Android 调试桥 (ADB) 提供了多条命令,可用于在流量节省程序 条件下测试您的应用。您可以检查和配置网络权限或将无线网络设置为按流量计费,以便在无限流量网络上测试您的应用。

$ adb shell dumpsys netpolicy
生成包括当前全局后台网络限制设置、目前在白名单中的软件包 UID 以及其他已知软件包的权限的报告。
$ adb shell cmd netpolicy
显示网络政策管理器 (netpolicy) 命令的完整清单。
$ adb shell cmd netpolicy set restrict-background <boolean>
当分别传递 truefalse 时,启用或停用流量节省程序模式。
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
将指定软件包 UID 加入白名单,以允许后台按流量计费的流量消耗 。
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
从白名单中移除指定软件包 UID,以阻止当流量节省程序启用时后台按流量计费的流量消耗。
$ adb shell cmd netpolicy list wifi-networks
列出所有 WiFi 网络,显示它们是否按流量计费。
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
使用指定的 SSID 将 WiFi 设置为按流量计费,以便您在无限流量网络上模拟按流量计费的网络。