安卓手机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 = {}
相关推荐
Mr Lee_36 分钟前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野1 小时前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&1 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
Winston Wood3 小时前
Android Parcelable和Serializable的区别与联系
android·序列化
清风徐来辽3 小时前
Android 项目模型配置管理
android
帅得不敢出门4 小时前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
problc4 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
帅得不敢出门15 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了16 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任18 小时前
Mac和安卓手机互传文件(ADB)
android·macos