Android NDK开发详解Wear之处理 Wear 上的数据层事件

2023-12-18


调用 Data Layer API 时,您可以在调用完成后收到调用状态。如果您的应用在 Wear OS by Google 谷歌网络上的任何位置进行了数据更改,您还可以监听因此而引发的数据事件。

注意:Data Layer API 只能发送消息并与 Android 手机或 Wear OS 手表同步数据。如果 Wear OS 设备已与 iOS 设备配对,Data Layer API 将无法正常运行。

因此,请不要使用 Data Layer API 作为与网络进行通信的主要方式。在 Wear OS 应用中,您应遵循与移动应用中的模式相同的模式,但二者有一些细微差异,详见 Wear OS 上的网络访问和同步。

如需查看有效使用 Data Layer API 的示例,请参考 Android DataLayer 示例应用。

等待数据层调用的状态

对 Data Layer API 的调用(例如使用 DataClient 类的 putDataItem 方法进行的调用)有时会返回 Task 对象。一旦创建了 Task 对象,操作便会在后台排队。如果在此之后您不再进行任何处理,则操作最终会以静默方式完成。

不过,您通常需要在操作完成后对结果进行某种处理,因此 Task 对象允许您以同步或异步方式等待结果状态。

异步调用

如果您的代码是在主界面线程上运行的,请勿对 Data Layer API 进行阻塞调用。您可以通过向 Task 对象添加回调方法来异步运行调用,该方法在操作完成时触发:

Kotlin

// Using Kotlin function references
task.addOnSuccessListener(::handleDataItem)
task.addOnFailureListener(::handleDataItemError)
task.addOnCompleteListener(::handleTaskComplete)
...
fun handleDataItem(dataItem: DataItem) { ... }
fun handleDataItemError(exception: Exception) { ... }
fun handleTaskComplete(task: Task<DataItem>) { ... }

Java

// Using Java 8 Lambdas.
task.addOnSuccessListener(dataItem -> handleDataItem(dataItem));
task.addOnFailureListener(exception -> handleDataItemError(exception));
task.addOnCompleteListener(task -> handleTaskComplete(task));

请参阅 Task API 以了解其他可能性,包括将不同任务的执行连接在一起。

同步调用

如果您的代码在后台服务(例如 WearableListenerService)中的单独处理程序线程上运行,则可以阻塞调用。在这种情况下,您可以对 Task 对象调用 Tasks.await(),从而使该调用阻塞,直到请求完成并返回 Result 对象,详见下例。

注意:切勿在主线程上调用此方法。

Kotlin

try {
    Tasks.await(dataItemTask).apply {
        Log.d(TAG, "Data item set: $uri")
    }
}
catch (e: ExecutionException) { ... }
catch (e: InterruptedException) { ... }

Java

try {
    DataItem item = Tasks.await(dataItemTask);
    Log.d(TAG, "Data item set: " + item.getUri());
} catch (ExecutionException | InterruptedException e) {
  ...
}

监听数据层事件

由于数据层会在手持式设备和穿戴式设备之间同步和发送数据,因此您通常需要监听一些重要事件,比如创建了数据项、接收了消息等。

如需监听数据层事件,您有两个选择:

创建扩展 WearableListenerService 的服务。
创建实现 DataClient.OnDataChangedListener 接口的 activity 或类。
无论选择哪一个,您都需要针对想要处理的事件,替换其数据事件回调方法。

注意:在选择监听器的实现方案时,请考虑应用的电池用量。WearableListenerService 是在应用的清单中注册的,可以在应用尚未运行时启动应用。如果您只需要在应用运行时监听事件(交互式应用通常就是如此),那么请不要使用 WearableListenerService。请改为注册实时监听器,例如使用 DataClient 类的 addListener 方法。这样可以减少系统上的负载并减少电池用量。

使用 WearableListenerService

您通常需要同时在穿戴式设备应用和手持式设备应用中创建 WearableListenerService 的实例。不过,如果您对其中一个应用中的数据事件不感兴趣,则无需在相应应用中实现该服务。

例如,您可以让手持式设备应用设置并获取数据项对象,而让穿戴式设备应用监听相应更新,以更新其界面。穿戴式设备应用从不更新任何数据项,因此手持式设备应用不会监听任何来自穿戴式设备应用的数据事件。

您可以使用 WearableListenerService 监听的部分事件如下:

onDataChanged():每当创建、删除或更改数据项对象时,系统都会在所有连接的节点上触发此回调。
onMessageReceived():从某个节点发送的消息会在目标节点上触发此回调。
onCapabilityChanged():当您的应用实例广播的某个功能发布到网络上时,该事件会触发此回调。如果您要寻找一个附近的节点,可以查询回调中提供的节点的 isNearby() 方法。
您还可以监听来自 ChannelClient.ChannelCallback 的事件,如 onChannelOpened()。

上述所有事件都在后台线程上执行,而不是在主线程上执行。

如需创建 WearableListenerService,请按以下步骤操作:

创建一个扩展 WearableListenerService 的类。
监听您感兴趣的事件,例如 onDataChanged()。
在 Android 清单中声明一个 intent 过滤器,以向系统通知您的 WearableListenerService。此声明使系统能根据需要绑定您的服务。
下例展示了如何实现一个简单的 WearableListenerService:

Kotlin

private const val TAG = "DataLayerSample"
private const val START_ACTIVITY_PATH = "/start-activity"
private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received"

class DataLayerListenerService : WearableListenerService() {

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: $dataEvents")
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        dataEvents.map { it.dataItem.uri }
                .forEach { uri ->
                    // Get the node ID from the host value of the URI.
                    val nodeId: String = uri.host
                    // Set the data of the message to be the bytes of the URI.
                    val payload: ByteArray = uri.toString().toByteArray()

                    // Send the RPC.
                    Wearable.getMessageClient(this)
                            .sendMessage(nodeId, DATA_ITEM_RECEIVED_PATH, payload)
                }
    }
}

Java

public class DataLayerListenerService extends WearableListenerService {
    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start-activity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: " + dataEvents);
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        for (DataEvent event : dataEvents) {
            Uri uri = event.getDataItem().getUri();

            // Get the node ID from the host value of the URI.
            String nodeId = uri.getHost();
            // Set the data of the message to be the bytes of the URI.
            byte[] payload = uri.toString().getBytes();

            // Send the RPC.
            Wearable.getMessageClient(this).sendMessage(
                  nodeId,  DATA_ITEM_RECEIVED_PATH, payload);
        }
    }
}

下一部分介绍如何对此监听器使用 intent 过滤器。

对 WearableListenerService 使用过滤器
上一部分中 WearableListenerService 示例的 intent 过滤器可能如下所示:

<service android:name=".DataLayerListenerService" android:exported="true" tools:ignore="ExportedService" >
  <intent-filter>
      <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
      <data android:scheme="wear" android:host="*"
               android:path="/start-activity" />
  </intent-filter>
</service>

在此过滤器中,DATA_CHANGED 操作取代了先前建议的 BIND_LISTENER 操作,使得只有特定事件才会唤醒或启动您的应用。这一变化可提高系统效率,并减少耗电量以及与您的应用有关的其他开销。在此示例中,手表会监听 /start-activity 数据项,并且手机会监听 /data-item-received 消息响应。

您需要遵守标准 Android 过滤器匹配规则。您可以为每个清单指定多项服务,为每项服务指定多个 intent 过滤器,为每个过滤器指定多项操作,并为每个过滤器指定多个数据 stanza。过滤器可以匹配通配符主机或特定主机。如需匹配通配符主机,请使用 host=“*”。如需匹配特定主机,请指定 host=<node_id>。

您还可以匹配字面量路径或路径前缀。为此,您必须指定通配符或特定主机。否则,系统将忽略您指定的路径。

如需详细了解 Wear OS 支持的过滤器类型,请参阅 WearableListenerService 的 API 参考文档。

如需详细了解数据过滤器和匹配规则,请参阅 清单元素的 API 参考文档。

在匹配 intent 过滤器时,请谨记两条重要规则:

如果没有为 intent 过滤器指定地址协议,系统会忽略其他所有 URI 属性。
如果没有为过滤器指定主机,系统会忽略所有路径属性。

使用实时监听器

如果您的应用只关心用户与应用互动时的数据层事件,则可能不需要长时间运行服务来处理每项数据更改。在这种情况下,您可以通过实现以下一个或多个接口来监听 activity 中的事件:

DataClient.OnDataChangedListener
MessageClient.OnMessageReceivedListener
CapabilityClient.OnCapabilityChangedListener
ChannelClient.ChannelCallback
如需创建用于监听数据事件的 activity,请执行以下操作:

实现所需接口。
在 onCreate() 或 onResume() 方法中,调用 Wearable.getDataClient(this).addListener()、MessageClient.addListener()、CapabilityClient.addListener() 或 ChannelClient.registerChannelCallback(),以通知 Google Play 服务您的 activity 想要监听数据层事件。
在 onStop() 或 onPause() 中,使用 DataClient.removeListener()、MessageClient.removeListener()、CapabilityClient.removeListener() 或 ChannelClient.unregisterChannelCallback() 取消注册任何监听器。
如果某个 activity 仅对具有特定路径前缀的事件感兴趣,您可以添加具有合适前缀过滤器的监听器,以便仅接收与当前应用状态有关的数据。
实现 onDataChanged()、onMessageReceived()、onCapabilityChanged() 或来自 ChannelClient.ChannelCallback 的方法,具体取决于您实现的接口。这些方法是在主线程上被调用的,或者您也可以使用 WearableOptions 来指定自定义 Looper。
下面是一个实现 DataClient.OnDataChangedListener 的示例:

Kotlin

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    public override fun onResume() {
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            if (event.type == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.dataItem.uri)
            } else if (event.type == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.dataItem.uri)
            }
        }
    }
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

    @Override
    public void onResume() {
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
            }
        }
    }
}

对实时监听器使用过滤器

如前所述,就像您可以为基于清单的 WearableListenerService 对象指定 intent 过滤器一样,您也可以在通过 Wearable API 注册实时监听器时使用 intent 过滤器。基于 API 的实时监听器和基于清单的监听器需遵守相同的规则。

常见的做法是在 activity 的 onResume() 方法中注册具有特定路径或路径前缀的监听器,然后在 activity 的 onPause() 方法中移除该监听器。以这种方式实现监听器,可以让您的应用更有选择性地接收事件,从而改进其设计和效率。

本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。

最后更新时间 (UTC):2023-11-20。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android NDK开发详解Wear之处理 Wear 上的数据层事件 的相关文章

随机推荐

  • linux路由

    网络拓扑 配置route主机 R1 网卡配置 eth0 TYPE Ethernet PROXY METHOD none BROWSER ONLY no BOOTPROTO static DEFROUTE yes IPV4 FAILURE F
  • 力扣每日一题:162. 寻找峰值(2023-12-18)

    力扣每日一题 题目 162 寻找峰值 日期 2023 12 18 用时 10 m 9 s 时间 0 ms 内存 40 54 MB 代码 class Solution public int findPeakElement int nums i
  • esProc SPL

    esProc SPL是一种用于数据处理的脚本语言 具有设计良好的丰富库函数和强大的语法 可以通过JDBC接口在Java程序中执行 并独立进行计算 Github地址 GitHub SPLWare esProc esProc SPL is a
  • ipfire

    安装 网卡地址配置 非常重要 配置不正确 影响ipfire正常工作 setup可以进入设置界面 配置 创建端口转发规则 设置端口转发是一项非常常见的任务 本指南解释了如何快速设置端口转发规则 请查看防火墙规则参考以了解更多说明 技术背景 端
  • JsonException: A possible object cycle was detected which is not supported 检测到可能的对象循环,这是不受支持的

    异常消息 JsonException A possible object cycle was detected which is not supported This can either be due to a cycle or if t
  • wget实现网站克隆

    这里写自定义目录标题 下载网站 WGET做镜像演示 wget用法说明 wget使用范例 下载网站 可以这样 wget r level 0 k p tries 0 https www django rest framework org 具体参
  • CSDN找到“仅我可见”内容

    有时候自己做一些笔记参考了他人的内容 所以想将文章转为 仅自己可见 仅作自用 记录一下CSDN找私密文章的方式 今天摸了好一会儿才找到哈哈哈 1 点击导航栏处的创作中心进入 2 查看更多 3 点击浏览就可以查看啦 来源 CSDN找到 仅我可
  • 工业数据的特殊性和安全防护体系探索思考

    随着工业互联网的发展 工业企业在生产运营管理过程中会产生各式各样数据 主要有研发设计数据 用户数据 生产运营数据 物流供应链数据等等 这样就形成了工业大数据 这些数据需要依赖企业的网络环境和应用系统进行内外部流通才能实现价值挖掘 如何高效安
  • 题解 | #火车进站#

    解约的同学看过来 提供一份解约思路 题解 火车进站 include
  • 20um尺度纳米机器人需要的条件

    制作出真正的智能纳米机器人需要什么条件 首先人类已经可以制作出一台符合人类需要的智能机器人了 即便不能生成出一台真正智能的机器人 但是半智能的机器人还是可以生产出来的 我认为半智能的机器人才是人类需要的 毕竟制作出一台可能不听话 失去控制的
  • 【二分查找】【z型搜索】LeetCode240:搜索二维矩阵

    LeetCoe240搜索矩阵 作者推荐 贪心算法 中位贪心 执行操作使频率分数最大 本文涉及的基础知识点 二分查找算法合集 题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 该矩阵具有以下特性 每
  • Minecraft服务器badly compressed packet报错解决方法

    此方法只在1 16 5Mohist端 Forege和水龙头 解决过 在其他版本不一定适用 1 报错信息 因为已经解决了问题所以懒得改回去截图了 随便找的网图 2 解决方案 在服务端和客户端都安装 XL数据包 MOD 虽然写着1 16 4但是
  • echarts漏斗图自定义漏斗颜色、粗细、大小、间隔缝隙

    echarts漏斗图自定义漏斗颜色 粗细 大小 间隔缝隙
  • 24届还有在看工作机会的吗,求求大家看下小米吧,HC非常多

    一定要反问HR的六个问题 offer比较 华为 vs OPPO 离谱的一周 百度裁应届 拼多多 非必要就别去了吧 阿里云25k gt 美团29k 实习转正啦 进来看耍猴 12 17更新 25届实习招聘信息汇总走起 策论 设计产出 Learn
  • sqlserver-事物日志

    前言 每个 SQL Server 数据库都有事务日志 用于记录所有事务以及每个事务所做的数据库修改 事务日志是数据库的一个关键组件 如果系统出现故障 你将需要依靠该日志将数据库恢复到一致的状态 有关事务日志体系结构和内部组件的详细信息 请参
  • Navicat关闭自动检查更新版本教程

    Navicat关闭自动检查更新版本教程 首先 点击菜单中的工具菜单 弹出了下拉菜单选中为选项 点击选项 首先 点击菜单中的工具菜单 弹出了下拉菜单选中为选项 点击选项 去掉勾选上在启动时自动检查更新选项
  • android无线调试连接

    开发时 遇到一些设备无法通过USB线连接adb时 可以尝试使用wifi无线调试 首先 要确保手机和电脑在同一个局域网内 再到开发者选项中打开无线调试 并进入子页面 如下 图一 无线调试设置界面 点击使用配对码配对设备 会弹出如下对话框 图二
  • ubantu22版本配置静态IP地址

    文章目录 编辑网络配置文件 应用网络配置 查看网络配置结果 编辑网络配置文件 在Ubuntu中配置静态IP地址可以通过以下步骤实现 打开终端 使用以下命令编辑网络配置文件 etc netplan 00 installer config ya
  • 【web网页制作】html+css网页制作游戏主题-王者荣耀(5页面)【附源码下载】

    涉及知识 游戏主题网页制作 王者荣耀网页制作成品 游戏网页制作成品 游戏主题web开发 期末网页大作业 网页作业成品 web前端源码实例 如何制作网页 网页设计思路 如何从零开始制作web页面 专栏 web前端大作业网页制作 关于我 一个持
  • Android NDK开发详解Wear之处理 Wear 上的数据层事件

    Android NDK开发详解Wear之处理 Wear 上的数据层事件 等待数据层调用的状态 异步调用 同步调用 监听数据层事件 使用 WearableListenerService