安卓手机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 = {}
相关推荐
黄林晴2 小时前
如何判断手机是否是纯血鸿蒙系统
android
火柴就是我2 小时前
flutter 之真手势冲突处理
android·flutter
法的空间3 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
循环不息优化不止3 小时前
深入解析安卓 Handle 机制
android
恋猫de小郭3 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
jctech3 小时前
这才是2025年的插件化!ComboLite 2.0:为Compose开发者带来极致“爽”感
android·开源
用户2018792831673 小时前
为何Handler的postDelayed不适合精准定时任务?
android
叽哥3 小时前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin
Cui晨3 小时前
Android RecyclerView展示List<View> Adapter的数据源使用View
android
氦客3 小时前
Android Doze低电耗休眠模式 与 WorkManager
android·suspend·休眠模式·workmanager·doze·低功耗模式·state_doze