安卓手机APP开发__构建通话应用

安卓手机APP开发__构建通话应用

目录

概述

依赖项和权限

注册应用

平台集成

注册通话

添加通话

接听来电

拒接来电

去电

将通话置于保持状态

断开连接

转接音频

前台支持

Surface 支持


概述

使用 Telecom Jetpack 库为用户提供最佳视频和音频体验。借助
Telecom 框架,您可以获得通话和通知管理、前台支持等。
新的 Jetpack 库增加了对以下内容的支持:

    通话流式传输和转接
    Android Auto 和 Wear OS 集成
    向后兼容性

如需详细了解如何使用 Telecom 库构建通话应用,请参阅 Telecom 指南。
支持的电信设备

从 Android 7(API 级别 21)开始,大多数手机都支持 Telecom 框架,
必须支持 Telecom 框架,基于 SIM 卡的通话功能才能正常运行。对于
通常不需要电话实现的设备(例如平板电脑),Android 14(API 级别 34)
引入了新要求,以强制要求支持 VoIP 的平板电脑采用适当的
Telecom 框架实现。

使用 PackageManager 检查设备是否支持电信:

packagemanager.hasSystemFeature(PackageManager.FEATURE_TELECOM)

新的 Android Telecom Jetpack 库可让您轻松告知平台您的通话处于何种状态。

依赖项和权限

首先,打开应用模块 build.gradle 文件,然后添加 androidx Telecom 模块的依赖项:

dependencies {
    implementation ("androidx.core:core-telecom:1.0.0-alpha02")
}

在应用清单中,声明您的应用使用 MANAGE_OWN_CALLS 权限:

<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />

注册应用

如需让 Android 知道您的应用,您必须注册该应用及其 capability。这
会告知 Android 您的应用支持哪些功能,例如视频通话、通话流式传输和保持通话。
这些信息非常重要,以便 Android 可以自行配置以使用应用的功能。

 private val callsManager = CallsManager(context)

var capabilities: @CallsManager.Companion.Capability Int =
    CallsManager.CAPABILITY_BASELINE or
          CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING or
          CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING

callsManager.registerAppWithTelecom(capabilities)

平台集成

任何通话应用的两种最常见的通话场景是来电和去电。如需正确注册
调用的方向并适当地向用户发送通知,请使用以下 API。

注册通话

以下示例演示了如何注册来电:

companion object {
  const val APP_SCHEME = "MyCustomScheme"
  const val ALL_CALL_CAPABILITIES = (CallAttributes.SUPPORTS_SET_INACTIVE
    or CallAttributes.SUPPORTS_STREAM or CallAttributes.SUPPORTS_TRANSFER)

  const val INCOMING_NAME = "Luke"
  val INCOMING_URI: Uri = Uri.fromParts(APP_SCHEME, "", "")
  // Define all possible properties for CallAttributes
  val INCOMING_CALL_ATTRIBUTES =
    CallAttributes(
      INCOMING_NAME,
      INCOMING_URI,
      DIRECTION_INCOMING,
      CALL_TYPE_VIDEO_CALL,
      ALL_CALL_CAPABILITIES)
}

callAttributes 对象可以具有以下属性:

    displayName:调用方、会议或会话的名称。
    address:通话地址。请注意,这可扩展到会议链接。
    direction:通话方向,例如来电或去电。
    callType:与要传输的数据相关的信息,例如视频和音频。
    callCapabilities:用于指定调用功能的对象。

callCapabilities 对象可以具有以下属性:

    streaming:指示通话是否支持将音频流式传输到其他 Android 设备。
    transfer:指示是否可以转接来电。
    hold:指示通话是否可以置于保持状态。

添加通话

如果设备不支持电信,或者设置通话时出错,则 addCall() 方法会返回异常。

try {callsManager.addCall(INCOMING_CALL_ATTRIBUTES,onIsCallAnswered, // Watch needs to know if it can answer the callonIsCallDisconnected,onIsCallActive,onIsCallInactive) {callControlScope = this}
}

注意: 添加通话并且设置 callControlScope 后,这并不意味着您正在进行通话,而是表示平台知道您的通话。


接听来电

拨出电话后,您必须接听或拒绝来电。本示例演示了如何接听来电:

when (answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {is CallControlResult.Success -> {}is CallControlResult.Error -> {}
}

如果另一个通话正在进行中,answer() 将返回CallControlResult.Error,以
告知无法接听来电的原因。在这种情况下,用户需要将另一个通话置于保持状态。

拒接来电

要拒绝来电,请断开与 DisconnectCause.Rejected 的通话。

fun onRejectCall(){coroutineScope.launch {callControlScope?.let {it.disconnect(DisconnectCause(DisconnectCause.REJECTED))}}
}

去电

拨出电话时,当远程方接听后,您必须将通话设置为 active,让平台知道
通话正在进行中:

when (setActive()) {is CallControlResult.Success -> {onIsCallActive()}is CallControlResult.Error -> {updateCurrentCall {copy(errorCode = result.errorCode)}}
}

将通话置于保持状态

如果您的通话应用支持保持通话,请使用 setInActive 告知平台您的通话未处于活跃状态,且麦克风和摄像头可供其他应用随意使用:

when (setInActive()) {is CallControlResult.Success -> {}is CallControlResult.Error -> {updateCurrentCall {copy(errorCode = result.errorCode)}}
}

断开连接

如需断开通话连接,请提供正当原因以告知 Telecom 堆栈断开连接:

coroutineScope.launch {
    callControlScope?.disconnect(DisconnectCause(DisconnectCause.LOCAL))
}

转接音频

在通话期间,用户有时会在扬声器、手机听筒或蓝牙设备等设备之间切换。
使用 availableEndpoints 和 currentCallEndpoint API
获取用户可用的所有设备以及哪个设备处于活动状态的列表。

以下示例将两个流程组合起来,创建一个界面对象,以向用户显示设备列表
以及哪个设备处于有效状态:

availableEndpoint = combine(callControlScope.availableEndpoints,callControlScope.currentCallEndpoint) {availableDevices: List<CallEndpoint>, activeDevice : CallEndpoint ->availableDevices.map {EndPointUI(isActive = activeDevice.endpointName == it.endpointName, it)}
}

注意: 如果用户连接了助听器,平台会自动将此设备设为默认设备。某些 OEM 可能会有不同的行为。

如需更改活跃设备,请使用 requestEndpointChange 以及要更改的 CallEndpoint。

coroutineScope.launch {
     callControlScope?.requestEndpointChange(callEndpoint)
}

注意: 媒体流必须配置为使用 AudioManager.STREAM_VOICE_CALL


前台支持

Telecom 库支持前台。对于搭载 Android 13 及更低版本的设备,此库会
使用 ConnectionService。对于 Android 14 及更高版本,
它使用前台类型麦克风和摄像头来正确支持前台服务。详细了解前台服务。

作为前台要求的一部分,应用必须发布通知,让用户知道它正在前台运行。

为了确保您的应用获得前台执行优先级,请在向平台注册调用后创建通知。
当应用终止调用或通知失效时,前台优先级会被移除。

is TelecomCall.Registered -> {
    val notification = createNotification(call)
    notificationManager.notify(TELECOM_NOTIFICATION_ID, notification)
}

注意: 您必须在将调用添加到平台后的 5 秒内发布通知。


Surface 支持

手表具有通用端点接收器应用。此应用可为用户提供基本界面,例如接听、
拒接和挂断来电。应用通过实现 lambda 函数来支持这些操作,
以通知平台您已在设备上执行操作。

如果您的应用没有响应,则每个 lambda 函数都会在 5 秒后超时并抛出事务失败。

callsManager.addCall(attributes,onIsCallAnswered, // Watch/Auto need to know if they can answer the callonIsCallDisconnected,onIsCallActive,onIsCallInactive) {
//Call Scope
}
/***  Can the call be successfully answered??*  TIP: Check the connection/call state to see if you can answer a call*  Example you may need to wait for another call to hold.**/
val onIsCallAnswered: suspend(type: Int) -> Unit = {}/*** Can the call perform a disconnect*/
val onIsCallDisconnected: suspend (cause: DisconnectCause) -> Unit = {}/***  Check is see if you can make the call active.*  Other calls and state might stop us from activating the call*/
val onIsCallActive: suspend () -> Unit = {updateCurrentCall {}
}/*** Check to see if you can make the call inactivate*/
val onIsCallInactive: suspend () -> Unit = {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/17554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GO语言 linux部署

https://blog.csdn.net/wangye135/article/details/136177171 一、简述 1. 可以直接在服务器上运行编译好的二进制文件&#xff0c;不需要在服务器上下载语言环境。 2. 内置运行时环境&#xff1a;可执行文件中内置了运行时环境&#xff0c;包括垃圾回收、调度器等&#xff…

Java深拷贝浅拷贝

在Java中&#xff0c;深拷贝和浅拷贝是两种不同的对象复制方式。 浅拷贝&#xff1a;创建一个新对象&#xff0c;然后将原对象的非静态字段复制到新对象中。如果字段是值类型的&#xff0c;那么对该字段执行逐位复制。如果字段是引用类型的&#xff0c;则复制引用但不复制引用的…

SAP 根据报错消息号快速定位问题

通常用户在业务的操作过程中&#xff0c;经常会遇到报错信息&#xff0c;有些报错是系统控制抛出的信息&#xff0c;但是有些报错的信息是根据不同地点业务场景对填写的数据进行判断校验&#xff0c;然后给出的报错信息&#xff0c;正常情况报错信息一般是有文本&#xff0c;或…

【C语言】文件操作讲解

C语言文件操作讲解 文件文件名文件类型数据在内存中的存储 文件缓冲区文件指针文件的打开与关闭fopenfclosefopen与fclose的使用文件的打开方式 文件的顺序读写fputcfgetcfputsfgetsfprintffscanffwritefread输入流与输出流对比scanf\fscanf\sscanf与printf\fprintf\sprintfssc…

【区分vue2和vue3下的elementUI和elementUI Plus的button组件,介绍如何安装,属性,事件,方法等以及使用案例】

区分vue2下的Element UI和vue3下的Element Plus的Button组件 Element UI (vue2) Button组件&#xff1a;基于Vue 2的Element UI库中的Button组件提供了多种样式和类型&#xff0c;如默认、主要、成功、警告、危险等。 Element Plus (vue3) Button组件&#xff1a;作为Element …

汇编原理(二)寄存器——内存访问

一个字 两个字节 双字 字节为8位 字为16位&#xff08;看两格&#xff09; 双子dword32位&#xff08;看四格&#xff09; 内存中字的存储&#xff1a; 0地址单元中存放的字节型数据是多少&#xff1f; 0地址字单元中存放的字型数据是多少&#xff1f; 2地址字单元中存放…

Secure Operation

文章目录 Secure Summation OperationSecure Set Union Operation Secure Summation Operation 让我们通过一个具体的例子来说明这个算法。 假设有三个数据拥有者 S1, S2 和 S3&#xff0c;他们分别持有以下值&#xff1a; S1 持有 value1 10S2 持有 value2 20S3 持有 val…

基坑气膜:建筑工地环保新利器—轻空间

随着城市化进程的加快&#xff0c;建筑行业的飞速发展带来了严重的环境问题&#xff0c;如噪音和粉尘污染&#xff0c;给人们的生活带来诸多不便。为了解决这些问题&#xff0c;建筑行业一直在探索更为环保和高效的施工方式。近年来&#xff0c;基坑气膜技术逐渐崭露头角&#…

Audition 2024 for Mac/Win:音频录制与编辑的卓越之选

随着数字媒体的不断发展&#xff0c;音频内容创作已经成为各行各业中不可或缺的一部分。无论是音乐制作、广播节目、播客录制还是影视配音&#xff0c;都需要高品质的音频录制和编辑工具来实现专业水准的作品。在这个充满竞争的时代&#xff0c;要想在音频创作领域脱颖而出&…

解线性方程组——最速下降法及图形化表示 | 北太天元 or matlab

一、思路转变 A为对称正定矩阵&#xff0c; A x b Ax b Axb 求解向量 x x x这个问题可以转化为一个求 f ( x ) f(x) f(x)极小值点的问题&#xff0c;为什么可以这样&#xff1a; f ( x ) 1 2 x T A x − x T b c f(x) \frac{1}{2}x^TAx - x^Tb c f(x)21​xTAx−xTbc 可…

ZooKeeper安装

安装Zookeeper 1、下载Zookeeper安装包 打开链接选择一个版本进行下载 https://zookeeper.apache.org/releases.html2、上传Zookeeper安装包到集群 输入命令 scp apache-zookeeper-3.8.4-bin.tar.gz hadoop192.168.88.100:/tmp也可以使用xftp等上传&#xff0c;物理机用u盘…

Python 网格变换之平移、旋转、缩放、变换矩阵

网格变换 一、平移1.1、代码示例1.2、结果示例二、旋转2.1、代码示例2.2、结果示例三、缩放3.1、代码示例3.2、结果示例四、变换矩阵4.1、代码示例4.2、结果示例一、平移 网格平移:将网格沿着特定的方向移动一段距离。 1.1、代码示例

Android实现无线连接ADB调试

无线连接ADB(Android Debug Bridge)进行调试,是一种方便的远程调试方式,尤其适合在没有USB线或者设备物理接触不便的情况下使用。下面是如何设置无线ADB调试的步骤: 1. 准备工作 确保你的电脑和Android设备连接在同一局域网(Wi-Fi)下。 2. 在Android设备上操作 允许…

hadoop其中一个节点坏了,用其他节点克隆的教程+datanode正常显示,但master只有1个livenodes

如果一个slave出了非常棘手的问题&#xff0c;还是用其他slave克隆吧&#xff0c;很快的。 克隆教程&#xff1a; 1.克隆后只需要&#xff1a;sudo gedit /etc/network/interfaces&#xff0c;把ip地址改好。 2.ssh不需要重新设置&#xff0c;其他东西也都不需要重新进行设置…

linux日常运维2

下载linux离线安装包---- 利用 Downloadonly 插件下载 RPM 软件包及其所有依赖包 1. 先找个可以上网的linux操作系统&#xff0c;这里是以centos7操作系统为例&#xff0c;如果要使用centos6就先安装一个centos6的系统&#xff0c;然后让他可以上网&#xff0c;后面步骤如下 a.…

《精通Stable Diffusion AI绘画:基础技巧、实战案例与海量资源一站式学习》

随着人工智能技术的迅猛发展&#xff0c;AI绘画已经成为了一个炙手可热的话题。特别是在设计、艺术和创意领域&#xff0c;AI绘画工具的出现无疑为创作者们带来了更多的可能性和便利。《Stable Diffusion AI绘画从提示词到模型出图》这本书&#xff0c;就是一本深入解析Stable …

打包迁移Python env环境

打包迁移Python env环境 平常工作中可能遇到python虚拟环境迁移的场景&#xff0c;总结了如下几个方法。适用于同架构、相同类型系统之间的python虚拟环境迁移。 方法一&#xff1a;使用pip freeze和requirements.txt 这种方法将当前环境中的所有包记录到一个文件中&#xff0c…

恢复视频3个攻略:从不同情况下的恢复方法到实践!

随着科技的进步&#xff0c;我们的生活被各种各样的数字内容所包围&#xff0c;其中&#xff0c;视频因其独特的记录性质&#xff0c;承载着许多重要的资料。但不管是自媒体人还是普通人日常生活随手一拍&#xff0c;都会遇到误删视频的情况。为了帮助您找回手机视频&#xff0…

从零学爬虫:使用比如说说解析网页结构

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、网页结构概述 示例&#xff1a;查看网页结构 三、使用比如说说解析网页 1.…

windows10更改文件默认打开软件

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️感谢大家点赞&#x1f44d;&…