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

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

目录

概述

依赖项和权限

注册应用

平台集成

注册通话

添加通话

接听来电

拒接来电

去电

将通话置于保持状态

断开连接

转接音频

前台支持

[Surface 支持](#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() 方法会返回异常。

Kotlin 复制代码
try {
    callsManager.addCall(
        INCOMING_CALL_ATTRIBUTES,
        onIsCallAnswered, // Watch needs to know if it can answer the call
        onIsCallDisconnected,
        onIsCallActive,
        onIsCallInactive
    ) {
        callControlScope = this
    }
}

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

接听来电

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

Kotlin 复制代码
when (answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
    is CallControlResult.Success -> {

    }

    is CallControlResult.Error -> {

    }
}

如果另一个通话正在进行中,answer() 将返回CallControlResult.Error,以

告知无法接听来电的原因。在这种情况下,用户需要将另一个通话置于保持状态。

拒接来电

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

Kotlin 复制代码
fun onRejectCall(){
    coroutineScope.launch {
        callControlScope?.let {
            it.disconnect(DisconnectCause(DisconnectCause.REJECTED))
        }
    }
}

去电

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

通话正在进行中:

Kotlin 复制代码
when (setActive()) {
    is CallControlResult.Success -> {
        onIsCallActive()
    }

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

将通话置于保持状态

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

Kotlin 复制代码
when (setInActive()) {
    is CallControlResult.Success -> {

    }

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

断开连接

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

coroutineScope.launch {

callControlScope?.disconnect(DisconnectCause(DisconnectCause.LOCAL))

}

转接音频

在通话期间,用户有时会在扬声器、手机听筒或蓝牙设备等设备之间切换。

使用 availableEndpoints 和 currentCallEndpoint API

获取用户可用的所有设备以及哪个设备处于活动状态的列表。

以下示例将两个流程组合起来,创建一个界面对象,以向用户显示设备列表

以及哪个设备处于有效状态:

Kotlin 复制代码
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 秒后超时并抛出事务失败。

Kotlin 复制代码
callsManager.addCall(
        attributes,
        onIsCallAnswered, // Watch/Auto need to know if they can answer the call
        onIsCallDisconnected,
        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 = {}
相关推荐
vxtkjzxt88814 分钟前
手机群控软件如何优化游戏运营的运营策略
游戏·智能手机
AORO20253 小时前
适合户外探险、物流、应急、工业,五款三防智能手机深度解析
网络·人工智能·5g·智能手机·制造·信息与通信
铉铉这波能秀3 小时前
如何在Android Studio中使用Gemini进行AI Coding
android·java·人工智能·ai·kotlin·app·android studio
川石课堂软件测试5 小时前
什么是BUG,你对BUG的了解有多少?
android·linux·服务器·python·功能测试·bug·安全性测试
vxtkjzxt8887 小时前
手机群控软件在游戏运营中的风险管控技术实现
游戏·智能手机
wanhengidc7 小时前
移动端云手机的优势都有哪些?
运维·服务器·游戏·智能手机·云计算
玩机达人887 小时前
三星S25Ultra/S24安卓16系统Oneui8成功获取完美root权限+LSP框架
android·linux·里氏替换原则
居安思危_Ho8 小时前
RK平台Uniapp自启动缓存问题解决
android·缓存·uni-app·rk平台·uniapp资源文件
molong9318 小时前
Activity/Service/Broadcast/ContentProvider 生命周期交互
android·学习·交互
molong93111 小时前
Android 权限模型(前台、后台、特殊权限)
android