Skip to content

Most visited

Recently visited

navigation

网络访问和同步

有了 Android Wear 2.0,手表无需访问 Android 或 iOS 手机,即可直接与网络通信。这种直接网络访问取代了使用 Data Layer API(Wear 1.x 中)连接网络。

网络访问

Android Wear 应用可进行网络请求。当手表可通过蓝牙连接到手机时,手表的网络流量通常由手机代理。当手机不可用时,可根据硬件使用 WLAN 和蜂窝网络。Wear 平台可处理网络之间的转换。

您可以使用 HTTP、TCP 和 UDP 等协议。不过,不能使用 android.webkit API(包括 CookieManager 类)。您可以通过读取和写入请求和响应的标题来使用 Cookie。

此外,我们建议使用以下 API:

高带宽网络访问

Android Wear 平台管理网络连接的目标是提供最佳的整体用户体验。此平台通过平衡以下两个因素来选择默认活动网络:

当节省电池电量优先时,活动网络可能没有足够的带宽来执行需要高带宽的网络任务,如传输大型文件或流媒体。

本部分将指导您如何使用 ConnectivityManager 类以确保为应用提供必需的网络带宽。如需有关精细控制网络资源的一般信息,请参阅管理网络使用情况

另请参阅下文所述的演示做法的示例

获取高带宽网络

在 Android Wear 上,请勿假设高带宽网络始终可用。对于需要高带宽网络访问的用例,如传输大型文件或流媒体,我们建议采取以下步骤:

  1. 检查活动网络,如果有活动网络,则检查其带宽。
  2. 如果没有活动网络或其带宽不足,则请求访问无限流量的 WLAN 或蜂窝网络。

您可以使用 ConnectivityManager 类检查是否存在活动网络以及是否具有足够的带宽:

int MIN_BANDWIDTH_KBPS = 320;
mConnectivityManager =
  (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = mConnectivityManager.getActiveNetwork();

if (activeNetwork != null) {
  int bandwidth =
    mConnectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();

  if (bandwidth < MIN_BANDWIDTH_KBPS) {
    // Request a high-bandwidth network
  }
} else {
  // You already are on a high-bandwidth network, so start your network request
}

您可以使用 ConnectivityManager 请求无限流量的高带宽网络。对于单次网络请求,您可以请求无限流量的 WLAN 或蜂窝网络。当网络准备就绪时(例如,设备的 WLAN 无线装置连接至保存的网络),调用 NetworkCallback 实例的 onAvailable() 函数。如果未找到适合的网络,则不会调用 onAvailable() 函数。因此,您应手动将您的请求设置为超时;请参阅等待网络可用

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    if (bindProcessToNetwork(network)) {
      // socket connections will now use this network
    } else {
      // app doesn't have android.permission.INTERNET permission
    }
  }
};

NetworkRequest request = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
  .build();

mConnectivityManager.requestNetwork(request, mNetworkCallback);

释放网络

当您的应用不再需要高带宽网络时,必须使用 ConnectivityManager 类释放网络以确保平台可以恢复网络访问的管理。

mConnectivityManager.bindProcessToNetwork(null);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);

为了优化电池消耗,网络连接应仅在 Activity 持续时间保持注册状态。因此,您应考虑在 Activity 的 onStop() 函数中释放网络。

等待网络可用

可能无法瞬间获取网络,因为手表的 WLAN 或蜂窝无线装置可能处于关闭状态以节省电池。此外,如果手表无法连接至网络,则不会调用 NetworkCallback 实例的 onAvailable() 函数。因此,在预先确定的时间长度后,您应将请求设置为超时并释放所有关联资源。

int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
long NETWORK_CONNECTIVITY_TIMEOUT_MS = 10000

mHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
    switch (msg.what) {
      case MESSAGE_CONNECTIVITY_TIMEOUT:
        // unregister the network
        break;
    }
  }
};

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    mHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
    ...
  }
};

mConnectivityManager.requestNetwork(request, mNetworkCallback);

mHandler.sendMessageDelayed(
  mHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT),
  NETWORK_CONNECTIVITY_TIMEOUT_MS);

监控网络状态

NetworkCallback 接口具有用于监控所绑定网络的状态变化(如带宽发生变化和连接丢失)的函数。

mNetworkCallback = ConnectivityManager.NetworkCallback {
  @Override
  public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
    int bandwidth =
      mConnectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();

      if (bandwidth < MIN_BANDWIDTH.KBPS) {
        // handle insufficient network bandwidth
      }
  }

  @Override
  public void onLost(Network network) {
    // handle network loss
  }
}

启动 WLAN 设置 Activity

请求 WLAN 网络时,系统尝试连接至已保存的网络,前提是保存的网络已配置且在范围之内。不过,如果没有可用的已保存 WLAN 网络,则系统绝不会调用 NetworkCallback 实例的 onAvailable() 回调函数。如果您使用 Handler 将网络请求设置为超时,那么,在出现超时时,您可以指示用户添加一个 WLAN 网络。您可以直接将用户转到 Activity,以使用以下 Intent 添加 WLAN 网络:

context.startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));

要启动设置 Activity,您的应用必须具有以下权限:android.permission.CHANGE_WIFI_STATE

界面注意事项

如果应用需要连接至新的 WLAN 网络以进行高带宽操作,请确保在启动 WLAN 设置之前先向用户清晰阐明连接的原因。仅在需要高带宽网络时才请求用户添加新的 WLAN 网络。请勿阻止用户访问不需要高带宽网络的应用功能。

例如,图 1 显示的是一个音乐应用。此应用应允许用户浏览音乐,且仅在用户需要下载或流式传输音乐时才要求用户添加新的 WLAN 网络。

音乐下载

图 1. 用于下载音乐的音乐应用流程。

如果您的应用需要高带宽网络才能运行,在要求用户添加新的 WLAN 网络前,应先向用户阐述明确的理由。另外,对于长时间运行的网络操作,如下载用户的媒体播放列表,您应显示一个进度指示器,说明正在执行的操作。

图 2 显示的是音乐应用的流式传输音乐流程。如果用户想要流式传输音乐并且需要高带宽网络,在将用户转到 WLAN 设置之前,应用应清晰阐述为什么需要新的 WLAN 网络。

音乐流式传输

图 2. 用于流式传输音乐的音乐应用流程。

云消息传递

对于发送通知,应用可以直接使用 Firebase 云消息传递 (FCM),其取代了 Google Cloud Messaging (GCM)。Wear 2.0 支持 FCM,但不支持 GCM。

没有特定于 Android Wear 的网络访问 API 或 FCM。请参阅有关连接至网络云消息传递的现有文档。

FCM 在低电耗模式下能够顺畅运行,因此,建议通过 FCM 将通知发送到手表。

在 Wear 应用运行时,通过收集设备的注册令牌从 FCM 提供消息。然后,当服务器将消息发送至 FCM REST 端点时,添加令牌作为目的地的一部分。FCM 将消息发送至由令牌标识的设备。

FCM 消息采用 JSON 格式,并且可以包含以下一个或两个负载:

如需了解详细信息和负载示例,请参阅关于 FCM 消息

默认情况下,从手机应用将通知桥接(共享)到手表。如果您具有独立的 Wear 应用和对应的手机应用,则可能会出现重复的通知。例如,手机和手表从 FCM 接收的相同通知可单独在这两个设备上显示。

使用后台 Service

要确保后台任务得到正确执行,必须考虑到低电耗模式。在 Android 6.0 中,低电耗模式和应用待机模式可增加电池续航时间。

在 Android Nougat 和 Android Wear 2.0 中对低电耗模式进行了增强。当屏幕关闭或进入微光模式的时间足够长时,设备在特定时间段会部分进入低电耗模式,且后台任务可能会延迟。之后,如果设备长时间处于静止状态,则将进入常规低电耗模式。

您应使用 JobScheduler API 计划作业,您的应用可通过它注册在低电耗模式下安全的代码执行。计划作业时,您可以选择约束条件,如定期执行、需要连接或设备充电。采用不会对电池续航时间产生不利影响的方式配置作业。作业应使用 JobInfo.Builder 对象提供约束条件和元数据,例如,针对任务使用以下一个或多个函数:

请注意,Bluetooth LE 等一些低带宽网络被视为按流量计费的网络。

使用约束条件进行计划

您可以计划需要约束条件的任务。在以下示例中,当符合以下约束条件时,JobScheduler 对象将激活 MyJobService

您可以使用构建器函数 setExtras 将一个应用特定的元数据捆绑包附加到作业请求中。在执行作业时,为作业 Service 提供此捆绑包。请注意传递到 JobInfo.Builder 构造函数的 MY_JOB_ID 值。这个 MY_JOB_ID 值是应用提供的标识符。取消后续调用并使用同一个值创建后续作业,这将更新现有作业:

JobInfo jobInfo = new JobInfo.Builder(MY_JOB_ID,
        new ComponentName(this, MyJobService.class))
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
        .setRequiresCharging(true)
        .setExtras(extras)
        .build();
((JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE))
        .schedule(jobInfo);

下面是 JobService 的一个实现,用于处理上述作业。执行作业时,将 JobParameters 对象传递到 onStartJob 函数。在计划作业时,您可以通过 JobParameters 对象获取作业 ID 值以及提供的任何额外的 extra。将会在主应用线程上调用 onStartJob 函数,因此,任何开销大的逻辑都应从其他线程运行。在此示例中,使用 AsyncTask 在后台运行代码。完成工作后,您应调用 jobFinished 函数以通知 JobScheduler 任务已完成:

public class MyJobService extends JobService {
    @Override public boolean onStartJob(JobParameters params) {
        new JobAsyncTask().execute(params);
        return true;
    }

    private class JobAsyncTask extends AsyncTask
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)