欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

发送和接收信息

程序员文章站 2022-06-29 18:35:07
...

以下内容翻译自android wear的官方教程,本人水平有限,如有错误欢迎指出
home
以下正文


你可以通过 MessageApi
发送信息并将以下的项目附加到message上:

  • 一个任意的负载(payload)(可选的)
  • 一个唯一标识message 的路径(path)

message不同于data items,在手机和手表之间同步数据。Messages是一个单方向的通信机制,一般用于远程调用(RPC),比如发送一个message让手表启动一个activity。

多个手表可以被连接到用户的手机,每个连接的设备被当作一个网络节点。如果有多个设备,那么你就必须要考虑哪个设备接受message。比如在手表上的一个语音识别app在收到声音消息之后,你要想要发送一个message给能够处理这个声音的设备(计算能力和电池能力较强比如手机)。

注意:在7.3.0以下的Google Play ,只有一个手表能连接到手机上,你可能需要升级你的老代码来考虑多设备的情况。如果你不加以改变,你的message可能无法发送到想要的设备上。

发送Message

一个可穿戴的app可以为用户提供诸如语音识别的功能。用户可以对TA们的手表说话,然后被保存成一段文本。因为手表没有处理声音转换的能力,所以这个app应该将处理这个信息的任务交给其他更强的设备。

通知其他节点自己的能力

使用 MessageApi
启动一个请求,然后在手表上启动一个activity。因为多个设备可以被连接到手机上,所以手表上的app需要决定确定这个节点是否有能力启动activity。

为了确定能力( capabilities):

  1. res/value创建wear.xml配置文件
  2. 添加名为android_wear_capabilities的资源给wear.xml
  3. 定义设备所能提供的能力

注意:能力一般是string类型,并且你要确保它在你的app上是唯一的

下面的例子展示了怎样添加一个能力:

<resources>
    <string-array name="android_wear_capabilities">
        <item>voice_transcription</item>
    </string-array>
</resources>

通过能力(capabilities)来检索节点

通过 [CapabilityApi.getCapability()
](http://developer.android.youdaxue.com/reference/com/google/android/gms/wearable/CapabilityApi.html#getCapability(com.google.android.gms.common.api.GoogleApiClient, java.lang.String, int)) 方法你可以发现节点的能力。下面的例子展示了怎样检索有voice_transcription能力的节点

private static final String
        VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription";

private GoogleApiClient mGoogleApiClient;

...

private void setupVoiceTranscription() {
    CapabilityApi.GetCapabilityResult result =
            Wearable.CapabilityApi.getCapability(
                    mGoogleApiClient, VOICE_TRANSCRIPTION_CAPABILITY_NAME,
                    CapabilityApi.FILTER_REACHABLE).await();

    updateTranscriptionCapability(result.getCapability());}

为了发现有能力的节点,用 CapabilityApi.CapabilityListener()
实例在你的GoogleApiClient上登记。下面的例子展示了怎么登记一个listener并取回有voice_transcription的节点。

private void setupVoiceTranscription() {
    ...
    CapabilityApi.CapabilityListener capabilityListener =
            new CapabilityApi.CapabilityListener() {
                @Override
                public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
                    updateTranscriptionCapability(capabilityInfo);
                }
            };

    Wearable.CapabilityApi.addCapabilityListener(
            mGoogleApiClient,
            capabilityListener,
            VOICE_TRANSCRIPTION_CAPABILITY_NAME);
}

注意:当你继承了 WearableListenerService
来观察改变,你可能希望重写 onConnectedNodes()
方法来观察连通的细节,比如手表从wifi连接改变成蓝牙连接。更多的信息信息可以查看下一章的内容。

在发现了有能力的节点之后,决定给哪个节点发送信息。你应该检查节点最近的节点以减少传输数据经过的节点数目。一个近的节点意味着是直接连接到设备上的。用 Node.isNearby()
方法发现节点是否是直接连接的。

下面的例子展示你应该怎样发现最好用的节点:

private String transcriptionNodeId = null;

private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) {
    Set<Node> connectedNodes = capabilityInfo.getNodes();

    transcriptionNodeId = pickBestNodeId(connectedNodes);
}

private String pickBestNodeId(Set<Node> nodes) {
    String bestNodeId = null;
    // 发现一个节点或任意取一个
    for (Node node : nodes) {
        if (node.isNearby()) {
            return node.getId();
         }
         bestNodeId = node.getId();
    }
    return bestNodeId;
}

发送Message

一旦你发现了最佳的节点,用MessageApi来发送节点。

下面的例子将展示手表如何发送message给transcription-capable节点。确保节点在你发送之前是有效的。这个调用是同步的,处理会在系统将message排好发送队列之前阻塞。

注意:一个成功的结果码并不保证发送信息成功,如果你的app需要数据稳定,使用DataItem或CannelApi来发送数据。

public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription";
private void requestTranscription(byte[] voiceData) {
    if (transcriptionNodeId != null) {
        Wearable.MessageApi.sendMessage(googleApiClient, transcriptionNodeId,
            VOICE_TRANSCRIPTION_MESSAGE_PATH,voiceData).setResultCallback(
                  new ResultCallback() {
                      @Override
                      public void onResult(SendMessageResult sendMessageResult) {
                          if (!sendMessageResult.getStatus().isSuccess()) {
                              // 发送Message失败
                          }
                      }
                  }
            );
    } else {
        // 没有找到可以转换声音能力的节点
    }
}

注意:如果想要了解更多关于异步和同步调用Google Play 服务和在什么场景使用它们,可以查看 Communicate with Google Play Services

你也可以对所有连接的节点进行广播。为了检索所有可以发送信息的连接的节点,你可以实现下面的代码。

private Collection<String> getNodes() {
    HashSet <String>results = new HashSet<String>();
    NodeApi.GetConnectedNodesResult nodes =
            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
    for (Node node : nodes.getNodes()) {
        results.add(node.getId());
    }
    return results;
}

接收一个Message

实现 MessageListener
接口来监听收到信息的事件。将这个监听器用 [MessageApi.addListener()
](http://developer.android.youdaxue.com/reference/com/google/android/gms/wearable/MessageApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.MessageApi.MessageListener))方法注册,这个例子展示了一个实现监听VOICE_TRANSCRIPTION_MESSAGE_PATH,并启动activity来处理声音数据。

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    if (messageEvent.getPath().equals(VOICE_TRANSCRIPTION_MESSAGE_PATH)) {
        Intent startIntent = new Intent(this, MainActivity.class);
        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startIntent.putExtra("VOICE_DATA", messageEvent.getData());
        startActivity(startIntent);
    }
}

这只是一个小片段,下一章将会讲述更多关于监听数据变化事件的内容。