开发者关系工程师
Googlebook 的推出为高保真、桌面级体验开辟了新天地。在本场专题演讲中,我们将深入幕后故事,与两位从零开始为该平台打造应用的先锋合作伙伴展开对话。
Notability 将分享他们使用 Jetpack Compose 创建桌面级 Android 应用的历程。了解他们从其他应用平台迁移到桌面设备优先的历程。其次,Logitech 将深入探讨硬件方面,讨论他们如何构建和定制外围设备,以便与 Googlebook 无缝集成。参加本专题演讲,获取有关优化输入、利用大屏 API 以及在软硬件之间提供优质、一致的用户体验的实用、真实见解。
转写文稿
大家好,我叫 Emilie Roberts,是一名开发技术推广工程师,从事笔记本电脑上的 Android 应用开发工作已有大约 9 年时间。
Googlebook 顺利发布。
耶!
我非常兴奋,我认为我们在笔记本电脑领域带来的创新非常酷。
我非常高兴能与两位开发者同台,他们投入了大量精力,让自己的应用在 Googlebook 上呈现出色的效果。
大家好!
我是 Notability 的 Ryan。
我是 Android 经理,这是一款我们刚刚在 Android 平台上推出的数字笔记本应用。
此功能还可在 iOS 设备、桌面设备以及 Googlebooks 上使用。
您好!
我是 Logitech 的 Joe,我们公司以出色的硬件和外围设备而闻名。
我将介绍我们如何将这些游戏引入新平台。
我要把它们推倒。
因此,Googlebooks 应运而生。
耶!
耶!
耶!
希望您有机会亲自体验这些功能,或者前往演示展台(位于当前楼层或上下楼层)进行体验。
当然,别忘了检查您的应用在这些设备上的显示效果。
我要说的是我的标准说辞,即 Android 生态系统正在不断发展。
我九年来一直这么说,现在依然如此。
应用也需要不断演进,以确保在所有这些屏幕尺寸和设备上满足用户的需求。
此时,拥有性能良好且行为良好的应用布局是标准做法。
而实现这一目标的最佳方式是使用 Jetpack Compose 和 Navigation 3。
输入也是如此。
应该可以正常运行。
当然,应用的架构和状态管理也属于布局和输入的一部分。
在 ADS 上,我们安排了多场演讲,介绍如何使用最新工具和最佳实践来实现这一目标。
不过,今天我们想借此机会,为那些从一开始就为 Googlebook 开发应用的开发者们留出一点空间,听听他们的故事。
Notability 是一款专为 Googlebook 打造的强大记事应用。
罗技不仅确保键盘、鼠标和其他外围设备能够正常工作,还确保它们在 Googlebook 上运行得非常出色,包括用户自定义功能。
Joe,抱歉抢了你的风头,但我们会详细介绍。
所以,这就足够了。
抱歉,这次没有说唱。
绝对不能再即兴发挥了。
总之,我们非常高兴能在 Googlebooks 上推出 Notability,接下来我将把遥控器交给 Ryan。
谢谢。
太棒了!
非常感谢,Em。
我们非常高兴能入驻 Googlebooks。
Notability 是数百万学生和专业人士记笔记的首选工具。
正如我之前提到的,它现已上架 Android,我将简要介绍一下我们是如何构建它的,以及如何正确地为 Android 构建应用,从而在应用发布之初就达到接近 Googlebook 的最佳效果。
首先,大约两年前我们启动这个项目时,我们非常希望确保我们不仅仅是移植 iOS 应用,然后将其提供给用户,并认为这样就足够了。
我们希望打造一款真正符合用户预期的原生应用,同时仍能提供完整的功能。
为此,我们使用了 Material Design 和组件,从头开始自定义所有界面。
此外,我们还确保了该库基于 Jetpack Compose 构建。
作为一款完全基于 Jetpack Compose 的原生 Android 应用,它能够支持各种硬件,不仅包括小型手机和低端设备,还包括高端、功能强大的大屏平板电脑、计算机、XR、汽车等,以及介于两者之间的所有设备。
Jetpack Compose 可让您轻松原生支持这些功能,而无需在界面中构建大量额外功能。
接下来是 Notability。
Notability 中的所有内容都是基于 Jetpack Compose 构建的。
界面在整个平台上保持一致,基本上只需构建一次,手机上显示的内容与最终在平板电脑和 Googlebook 等大屏设备上显示的内容之间没有实质性差异。
为此,Navigation 3 为我们提供了巨大的助力。
在 Google built-in 版本的 Notability 中,Navigation 3 的工作方式是,我们可以根据屏幕尺寸自定义布局,而无需担心该功能将如何呈现。
在此演示中,您可以看到,如果某个元素有空间打开侧边栏,它就会打开。
但如果不支持,则会以底部动作条的形式弹出。
那么,这在代码中是如何体现的呢?
在上面显示的代码中,您可以看到,侧边实际摘要面板有一个入口点,我们正在将其添加到返回堆栈中。
然后,我们的自定义场景策略会根据是否有空间,为该侧边栏选择布局。
因此,在平板电脑或 Googlebook 设备上,它会找到可用空间,并腾出空间,然后从右侧滑入该面板。
不过,在手机或可折叠设备等设备上,可能没有足够的空间来正确显示该面板,因此它会改为以底部动作条的形式弹出。
Notability 会根据窗口大小进行调整,而无需考虑设备类型,无论是手机、Googlebook、平板电脑、可折叠设备还是其他设备,我们的界面都能轻松自动适应用户的需求。
您可以在手机上看到,所有按钮和工具都会重新定位到拇指可以轻松触及的位置。
在平板电脑上,导航面板会显示在所有主要内容的旁边,因为平板电脑有更大的空间和更易于互动的屏幕。
在可折叠设备上,我们利用折叠功能提供独特的布局和界面,例如在学习测验中,用户可以在下半部分输入答案,在上半部分查看实际测验进度。
最后,在 Googlebooks 上,我们实际上可以顺畅地调整窗口大小。
因此,就像在桌面设备上使用任何其他普通窗口化应用一样,当您调整窗口大小时,Notability 会根据您的并排显示需求进行调整。
正如我之前提到的,我们构建的自适应界面几乎适用于 Googlebooks 上的整个完整桌面体验。
这会让你非常接近目标。
但如果您想获得桌面级体验,即真正非凡的体验,我们建议您执行以下操作。
首先,以键盘操作为主。
用户不会像在普通平板电脑或手机设备上那样对触控敏感,因此键盘快捷键和轻松访问 Android 快捷键列表的方式非常重要。
接下来,您有时可以设计功能,使其根据设备类型和可用的输入外围设备采用不同的布局。
当我们检测到笔记本电脑、外接键盘或鼠标等设备时,会在主屏幕上提供略有不同的界面,以便将用户重定向到我们认为他们更喜欢的工具,而不是平板电脑等设备,因为在平板电脑上,触控笔和自动手写笔笔记将是主要选项。
您还需要开始思考多个不同设备之间如何交互。
因此,Android 17 引入了“无缝流转”功能,让您能够将应用从一台设备无缝切换到另一台设备。
例如,在本例中,我们将手机上的记事转移到更大的桌面设备上。
只需快速同步备注 ID,并快速推进您在我们这边的进度,即可轻松完成。
因此,我们只需向 Googlebook 设备发送一个简单的应用 intent,即可轻松实现“继续”功能,让您从上次中断的位置继续操作。
对于桌面级设备,另一个需要考虑的因素是多输入支持模型。
因此,您不仅会拥有前面提到的键盘快捷键等功能,还会拥有与以前不同的缩放和滚动行为的触控板。
您可能还需要向用户提供之前没有的右键菜单。
此外,由于许多 Googlebook 设备仍是触摸屏设备,因此您需要确保当用户与该设备互动时,您不仅能针对触控笔和手指,还能针对触控板光标进行不同的输入识别,因为这三种输入方式应区别对待。
如果您对墨迹和书写笔记感兴趣(例如 Notability),我们建议您使用 Jetpack Ink。
因此,我们使用它来为墨水提供低延迟构建系统,而无需管理庞大、复杂的线程、渲染、缓冲区读取器以及其他各种组件,稍后我会向您展示这些组件。
但如果现在能用,我实际上可以向大家现场演示 Notability 应用,这要感谢 Logitech。
是的,完全正确。
好了,哎呀,快点。
好了,完美。
这就是我之前进行的测试。
但如您所见,我使用的是手指,因此它仍然可以识别手指输入,这很棒。
如果愿意,我也可以使用鼠标。
不过,我们目前已经能够构建一些 Android 专属的自定义画笔。
您可以看到,我在这里选择了彩虹和闪光效果,因此我们的输入或墨迹效果将受到底层 Jetpack Ink 库的影响。
在这里,我再写一次消息。
大家好。
然后,我们为最后一部分选择 Android 绿色。
很难正确触摸。
好了,Android 绿色。
然后,我们可以看到,实际颜色会根据您在此处选择的基础模型颜色而变化。
太好了。
因此,过去在构建此类画笔时,我们可能需要花费数月时间才能让所有自定义着色器、界面和所有内容都正确无误且美观。
现在,得益于 Jetpack Ink,借助 AI 和自定义笔刷构建器,实际用时可以缩短到一周以内。
因此,如果您想购买任何类型的墨水,请告诉他们。
这是一个非常棒的 API,为我们节省了大量时间。
太好了
正如我之前提到的,这就是它的样子。
因此,我们有一个所谓的湿墨层。
这是我们正在绘制的墨迹,需要非常非常灵敏,与干墨层不同。
从物理角度来看,这是合理的,您可以这样理解。
那是保存的墨水,已经完成了。
因此,交接工作过去完全由我们负责。
因此,我们必须进行线程处理,必须进行重绘和清理,必须将其交给干层,并确保这些层同步且不闪烁,还有所有这些复杂问题。
最后,我们必须应用 Notability 的独特之处,对吧?
我们有自己的曲线拟合模型,有办法让您的手写内容真正脱颖而出。
所以,您知道,那是旧模式。
得益于 Jetpack Ink,我们只需将曲线拟合输入到其自定义进度形状视图中,一切便可在 Android 上神奇地立即运行。
在讨论 Jetpack Ink 和其他 Google 库时,我们考虑的另一件事是 KMP。
因此,我们实际上是从查看已经构建的 iOS 代码开始,然后思考:“好吧,我们希望在 Android 和 iOS 之间共享一些逻辑。
我们有模型、有变化、有复杂的数学运算。
分享是明智之举。”
我们当时想,“C++,还有 Apple 的 Objective-C,我们就走这条路吧。”
事实证明,Kotlin Multiplatform 不仅更易于我们的 iOS 工程师实现,而且速度更快。
因此,使用 Kotlin 不仅让我们获得了更好的性能,而且我们可以复制大量 Android 代码,从长远来看,这对 iOS 来说也更容易。
因此,如果您想共享代码,我建议您了解一下 Kotlin Multiplatform。
目前,我们仍在评估该功能。
目前,我们还没有 100% 支持这一功能,因为不同的 AI 模型确实让作弊变得更容易了,只需将代码放在多个地方即可。但我们仍在积极研究这一功能,而且我非常看好它。
好了,现在来介绍一下 Notability 的一些特别功能。
如果您尝试在 Android 上构建一个可用的文本编辑器,可能会注意到,目前还没有一种很好的方法来构建一个大型、庞大的文档文本编辑器。
基本的 Android 编辑输入字段都是关于较小的界面、较小的 EditText、较短的内容。
我们最终不得不构建一个非常复杂的系统,它基本上运行在现有 Android API 之上,但能够同时处理大得多的文档,比如成千上万页的文本,并且支持协同编辑。这样,即使有其他用户在距离您 500 页之外的地方进行编辑,导致文档发生变化,也不会影响您正在进行的工作。
我们发现,实现这一目标的方法基本上是让按键操作通过两条路径进行。
第一种路径是,我们尽最大努力,让这个密钥出现在这里。
根据我们目前所能了解到的所有情况,我们认为这很好。
然后我们快速同步一下,对吧?
我们会去后端,检查我们的合作者,我们会说:“嘿,一切都好吗?
您明白了吗?
我们是否可靠?”
如果情况发生变化,它会及时调整。
您可以想象,如果两个用户在同一行上敲击按键,那么谁得到什么就会有点混乱。
但在大多数情况下,这种方法非常有效。
我之所以在这里提及这一点,是因为我们在这方面投入了大量工作,并且正在考虑将其开源。
因此,如果现场或线上有任何人想就此开展合作,并且认为这是一个好主意,请告诉我们。
我们正在讨论是否真的值得投入精力,但您知道,这对我们来说是一项巨大的工程,我们对结果感到非常自豪。
好的,接下来是墨水的工作原理。
因此,在协作模式方面,这更像是我们这边的一种直接运作方式。
如您所见,这里有三个步骤。
首先是触屏,我们会向所有已连接的设备(在本例中是 iPad)发送“嘿,顺便说一下,我们正在启动一个墨迹事件”的消息。
然后是实际绘制,因此可能会有 1 到数百万个这样的事件,具体取决于用户使用设备(即笔)绘制的时间。
希望不会太久。
我认为在某些情况下确实存在限制,但对于正常的使用场景,它已经足够好了。
然后是抬起事件。
因此,我们的管理方式是,在模型中保留一个临时对象。
这意味着,在 iPad 上,我们会说:“好吧,有一个笔画即将到来,但它还没有到达。
我们无法与之互动。
It's ephemeral."
只有在完成事件启动后,我们才会真正进入并说:“好的,太棒了。
现在,用一个对象替换整个内容,iOS 或任何其他客户端都可以直接获取该对象并与之交互。”
我们也在考虑将这个工具开源。
这不是我们的直接墨迹,而是一些临时内容,尤其是在文本层中。
太好了。
然后,是的。
我们还建议使用其他一些工具。
设备端 AI 非常出色。
我们将其用于文档扫描,因此您可以扫描文档、分析 PDF 文本、进行一些手写识别。
我们还使用 Gemini 等开放式云 AI 模型来帮助生成智能笔记,对用户的笔记进行分类、总结,然后以更优质、更具互动性的方式反馈给用户,从而优化学习模式。
所有这些功能结合在一起,确实让 Notability 感觉像是一款笔记本电脑应用,对吧?
这就是我们的最终目标。
我们有各种有趣的模型和功能,比如文本输入等,但关键在于:它给人的感觉是笔记本电脑应用,还是像在大屏幕上打开的“电话”应用,让人觉得有点别扭?
键盘、触控板、触控笔、窗口大小调整,这些都是需要重点关注的关键功能,以确保用户获得真正良好的体验。
不过,正如我之前提到的,Jetpack Compose、Navigation 3、Material Design 等技术都能解决这些问题。
因此,只要方法得当,其实并不需要投入太多精力。
这里很容易到达。
所以,是的。
以上就是我们的要点总结。
展望 Android 的未来,我认为不应再局限于设备本身。
我不会去想,这是手机、可折叠设备、XR 设备、桌面设备、笔记本电脑、平板电脑、车载设备还是电视。
而是要考虑:我可以使用多大的屏幕尺寸?用户可以使用哪些输入模态?
让我们为未来的用户提供尽可能优质的体验。
正如我在上一张幻灯片中提到的,Compose 和 Nav 3 确实让支持所有这些功能变得非常简单。
Google 每天都在推出新的、功能强大的 API,例如 Jetpack Ink 或 Gemini 端侧,以及各种各样的工具,让您能够轻松构建核心体验,然后专注于让您脱颖而出的独特魅力。
好的。
所以,
非常感谢。
以上就是我的演讲内容。
如果您有任何问题,可以稍后联系我,也可以随时联系 Notability。
这款应用大约两个月前才在 Android 平台上推出。
我们终于推出了正式版。
所以,欢迎大家试用。
欢迎提供反馈。
您也可以在身后的演示流程中通过 Googlebooks 找到它。
接下来,我将把时间交给 Logitech 的 Joe,由他继续介绍。
谢谢。
好了
谢谢 Ryan。
今天,好吧,抱歉。
我们来看一下幻灯片。
谢谢 Ryan。
今天,我将分享我们如何将外设自定义应用 Options+ 引入 Chromebook。
以及打造外围设备体验意味着什么?
我将介绍我们已经构建的内容、背后的一些工程亮点(没有低谷),以及我们接下来的发展方向。
罗技设备过去就支持 Android,大多数用户发现这些外围设备提高了无障碍性,尤其是在使用高端笔记本电脑以及连接了外接显示器的手机时。
说到这里,我刚才在楼下的 Googlebook 演示展位看到,他们把罗技游戏序列档挂在桌子上,用它来切换平板电脑上的不同屏幕。
就在这里。
这是一种使用方式。
哦,顺便说一下,法拉利不得不为他们的序列式变速箱额外收取 5 万欧元。
没错
正如 Ryan 刚才非常全面地提到的,在 Googlebook 上,我们有更多的空间可以利用。
如您所见,您可以根据需要调整屏幕大小,将其设置为横屏、竖屏或方形,这样您就有更多空间在应用之间进行操作。
您可以继续手头的工作,切换不同的应用,切换上下文,诸如此类。
这无疑改变了应用设计,布局需要在整个过程中保持实用性。
对于罗技来说,这看起来特别有趣,因为我们是一家在周边设备方面拥有丰富经验的公司,对吧?
我们为这项工作奠定了非常坚实的基础。
因此,我们认为,在这样的工作环境中,用户在整个工作日内都是通过鼠标或键盘进行互动的。
他们可以非常顺畅地进入工作流程。
毫不夸张地说,罗技将数十年的经验融入到了这项工作中。
我想我们本月初刚刚庆祝了 45 周年。
从罗技成立的第二年、第二天开始,我们就一直在制造鼠标。
因此,凭借这种经验,我们非常有信心进入这一领域。
更棒的是,ChromeOS 拥有悠久的历史。
过去,我们保证了与 ChromeOS 的出色兼容性。
现在,说了这么多,我们已经有了非常好的实践经验,打破了我们构建的硬件、我们不断创造的软件以及平台、操作系统、Googlebooks 之间的界限。
例如,用户按下一个按钮,就会看到可预测的结果。
这几乎就像是你们每个人都习以为常的事情。
但实际上,它们需要无缝的组件兼容性。
此外,人人都喜欢与自己的外围设备兼容。
例如,将灵敏度调整到恰到好处。
65 岁,不多不少。
因此,所有这些都需要在这三者之间实现非常良好的无缝兼容性集成。
现在,随着 Googlebooks 的推出,我们推出了适用于 Googlebooks 的 Options+。
因此,目前我们支持一系列鼠标和键盘,未来还会支持更多。
用户也可以在这里配置自己的设备。
正如我之前提到的,比如敏感度,诸如此类。
现在,场景变得越来越有趣了。
当我们谈论可配置性时,实际上是在谈论两个方面。
一方面是硬件和固件,这些功能在固件中实现。
另一端实际上是本演示和本演讲的重点,即操作系统端。
我想大家都知道,过去 Android 设备和大多数应用都位于各自的沙盒和用户空间中。
在许多情况下,您能做什么、不能做什么以及想要什么,都存在一定的限制。
对我们来说,这非常重要。
现在,我们来看一张屏幕截图,稍后我们会进行演示,但现在先看这张屏幕截图。
我们这里有一个鼠标,MX Master 4,它有很多功能。
对于了解外围设备领域的人来说,您会发现某些功能实际上是固件功能或设备功能。
而有些则不然。
对我们来说,我们正在努力让用户能够配置这两端。
我们的工作基本上是,首先让这些选项易于理解,并为用户提供完整的功能,然后针对操作系统和固件正确配置这些内容。
现在,我们来看一个简短演示。
这个演示非常精彩。
但下次,Ryan,请使用鼠标。
好了,我们开始吧。
这是我的设备屏幕。
您可以看到,我已连接了一个 MX Master 4 鼠标,就是这个。
我们开始吧。
我们将直接进入配置界面,如您之前所见,这里就是奇迹发生的地方。
现在,我们先将“圈定即搜”功能分配给拇指按钮。
然后,我们将魔力指针放入功能按钮中。
现在,我们开始。
我们打开一个浏览器。
前往此处。
在这里,我按下刚刚分配了“圈定即搜”功能的拇指按钮。
如您所见,我圈出了一个键盘。
瞧!
Google 只是显示有关此键盘的信息。
非常方便,而且非常流畅。
现在,我们来尝试一些不同的操作。
哦,抱歉。
让我倒回去。
我们来试试魔力指针。
我们来切换一下。
我可以按下功能按钮,标记这个设备,然后按下“这是什么设备?”
就是这样。
Google 开始搜索并显示结果。
因此,这种方式的好处在于,您可以将整个工作流程整合到单手操作中。
您预先分配功能,然后按下、圈出、点击,即可完成。
因此,我们相信这种操作将大大提高用户的无障碍体验和工作方式。
现在,我们回到幻灯片。
您可能会问,是什么导致了这种情况。
因为过去有很多事情是应用无法做到的。
Peripheral Customization API 闪亮登场!该 API 适用于 Googlebook 和 Android 设备。
不过,以下是 Google 提供的说明。
目前,此 API 仅向许可名单中的用户开放。
但我们计划在 2026 年第 4 季度(即本季度)随 Android 更新一起发布。
因此,我认为,一旦该功能发布,全球各地的开发者都将能够使用它。
现在,我们来了解一些技术方面的内容。
整个过程有三个关键组件:设备(这很好理解);触发器(可以是按键,也可以是预期的按钮);以及操作(在应用操作系统端)。
现在,我们来快速看一下这段代码。
在最顶部,我们使用供应商 ID 和产品 ID 定义设备。
// Vendor and product Information
const val VENDOR_ID = 1234
val pid = 123
// Use the mouse Middle Button as the trigger
val trigger = ButtonCustomizationTrigger(MotionEvent.BUTTON_TERTIARY)
// Set Voice Assistant as the action
val actionBuilder = AppCustomizationAction.Builder(component, ACTION_MAIN)
actionBuilder.setData(ActionId.ACTION_VOICE_ASSIST.actionId) // Action IDs are predefined
val action = actionBuilder.build()
val im = context.getSystemService(INPUT_SERVICE) as InputManager
im.addPeripheralCustomization(VENDOR_ID, pid, trigger, action)我们通常称之为 vid 和 pid。
向下移动,我们开始定义触发器。
在这里,如您所见,我们希望使用中间按钮作为触发器。
在这里,我们希望将中间按钮映射到操作系统功能的语音助理部分。
对吧?
这里有一个来自 AppCustomizationAction 的 actionBuilder,这里也有一个。
再往下看,这里注册了产品、设备、触发器和操作之间的映射关系。
当然,实际代码要比这复杂一些,但总体概念就是这样。
非常简单易用。
现在,我们来看看另一个非常酷且有趣的功能。
我在这里放了一个 GIF 文件,方便大家查看。
基本上,当有兼容且受支持的设备(在本例中为 Logitech Mobifold 鼠标)时,操作系统会触发标准通知,告诉您“嘿,您有适用于该设备的应用程序”。
告知用户“当然可以”。
点击后,您将直接进入 Play 商店,并可在其中直接安装。
这称为快速配对发现。
最后,我们来看看界面端。
Ryan 已经介绍了 Googlebook 的许多优点,以及如何设计界面,因此我在这里会讲得比较快。
如您所见,Options+ 可以在不同的平台上运行,包括 Windows、Mac,现在还支持 Chromebook。
因此,我们的目标实际上有两个:一是让它感觉像是平台专属的,但同时,我们希望让它在各个平台上感觉相似,这意味着一旦您在一个平台上熟悉了 Options+,您应该能够在另一个平台上顺利使用它。
这意味着,我们既要充分利用特定平台的优势,又要使用相同的设计语言。
如您所见,整个系列的设计语言保持一致。
正如我们之前讨论过的,Googlebook 用户往往会以更偏向笔记本电脑/桌面设备的方式使用 Googlebook。
因此,我们的应用本身(即使在 Googlebook 上)看起来也像桌面应用。
因此,应用本身的行为可能类似于桌面应用,并且在各种窗口尺寸、不同触控方式下都能正常运行,当然,您也可以控制使用鼠标和键盘。
好了,以上就是关于 Logitech 外围设备和 Options+ 在 Chromebook 上的简短故事。
效果非常好。
不过,这仅仅只是个开始。
我们有几个步骤:首先,我们希望将这种体验推广到更多设备、更多键盘、鼠标和其他外围设备,并且我们希望根据真实用户反馈来改进此应用。
当然,最重要的是,我们将在未来与 Google 进一步合作,并更深入地集成到新平台中。
因此,我们的最终目标是让外设自定义成为使用 Googlebook 时非常自然的体验,并帮助用户以自己想要的方式工作。
好的。
请务必前往楼下的展位,亲自体验 Options+ 和出色的罗技设备。
感谢我们的合作伙伴 Google,也感谢大家抽出宝贵时间。
非常感谢。
// Vendor and product Information
const val VENDOR_ID = 1234
val pid = 123
// Use the mouse Middle Button as the trigger
val trigger = ButtonCustomizationTrigger(MotionEvent.BUTTON_TERTIARY)
// Set Voice Assistant as the action
val actionBuilder = AppCustomizationAction.Builder(component, ACTION_MAIN)
actionBuilder.setData(ActionId.ACTION_VOICE_ASSIST.actionId) // Action IDs are predefined
val action = actionBuilder.build()
val im = context.getSystemService(INPUT_SERVICE) as InputManager
im.addPeripheralCustomization(VENDOR_ID, pid, trigger, action)