统一的通话记录

VoIP 应用可以将通话记录集成到系统通话记录中。这样一来,用户就可以在系统拨号器应用中集中查看 VoIP 通话记录,并直接从拨号器应用中回拨电话。本指南介绍了对 VoIP 通话应用、系统拨号器应用和管理统一通话记录设置所需的更改。

通话应用的变更

如需将 VoIP 应用与系统通话记录集成,请按以下步骤操作。

注册回调 intent 过滤器

注册受系统保护的 intent TelecomManager.ACTION_CALL_BACK。

正确注册此 intent 过滤器后,您的应用使用 CallsManager.addCall 或其他相关 Telecom API 添加的任何调用都会被系统自动记录。当用户在拨号器中选择 VoIP 通话记录条目以回拨电话时,系统会使用此注册的 intent 向您的应用发送回调。

<!-- Activity to handle the callback intent from the system dialer -->
<activity
    android:name=".VoipCallActivity"
    android:exported="true">

    <!-- Register callback intent -->
    <intent-filter>
        <action android:name="android.telecom.action.CALL_BACK" />
    </intent-filter>
</activity>

排除通话记录

注册回调后,所有通话都会记录到系统拨号器中。如需按每次通话排除通话,请在 CallAttributesCompat 内将 isLogExcluded 布尔值设置为 true。

CallAttributesCompat(
    displayName = displayName,
    address = address,
    isLogExcluded = excludeCallLogging, // to exclude call from logging
    direction = if (isIncoming) {
        CallAttributesCompat.DIRECTION_INCOMING
    } else {
        CallAttributesCompat.DIRECTION_OUTGOING
    },
    callType = CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
    callCapabilities = (
        CallAttributesCompat.SUPPORTS_SET_INACTIVE
            or CallAttributesCompat.SUPPORTS_STREAM
            or CallAttributesCompat.SUPPORTS_TRANSFER
        ),
)

处理回调

通过 CallsManager.addCall 添加的调用会通过 CallControlScope.getCallId 获取唯一的 UUID。

// check the intent action for CALL_BACK
if (intent.action == TelecomManager.ACTION_CALL_BACK) {
    launchCall(
        // fetching stored call details for the UUID to initiate callback
        callDetails = getCallDetails(
            uuid = intent.getStringExtra(TelecomManager.EXTRA_UUID)
        )
    )
}

验证通话记录条目

系统调用日志会保留有限数量的条目,并最终清除旧的调用记录。由于应用存储了 UUID 与用于回调处理的调用详情之间的映射,因此应定期检查系统调用日志中仍存在哪些 UUID。如果 UUID 不再位于系统日志中,用户就无法针对相应通话发起回调,应用可以安全地从本地存储中移除相应映射。这种做法有助于优化存储空间。

如需获取系统日志中归因于应用的 UUID 的当前列表,请使用 CallLog.Calls.CONTENT_VOIP_URI。

拨号器应用的变更

请按以下步骤操作,以使拨号器应用能够显示 VoIP 通话记录并向 VoIP 应用发起回拨。

在拨号器应用中显示 VoIP 通话记录

默认情况下,VoIP 应用通话记录不会显示在拨号器应用中。如需在拨号器应用中显示集成式通话记录,请执行以下操作:

从拨号器应用发起回调

如需从拨号器发起回调,请使用 TelecomManager.placeCall。平台使用通话记录条目的唯一 CallLog.Calls._ID 来启动正确的 VoIP 应用。此启动包含 TelecomManager.ACTION_CALL_BACK intent,这是一个用于发起回拨的系统定义的操作。此 intent 在 intent extra TelecomManager.EXTRA_UUID 中包含通话的 UUID,从而使 VoIP 应用能够识别正在回拨的具体通话。

// Uri generated with unique ID of the call log entry to launch the respective VoIP app for callback
val address = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI, callId)

// extra information required to initiate callback
val extras = Bundle()

telecomManager.placeCall(address, extras)

管理统一通话记录设置

从 Android 17(API 级别 37)开始,用户可以在系统设置中按应用查看和切换统一的通话记录(通常位于设置 > 通话账号 > 集成通话记录下,或直接在默认拨号器应用中查看)。第三方通话应用和拨号器应用都可以与这些设置互动。

如需打开统一通话记录设置,请使用 TelecomManager.ACTION_CONFIGURE_CALL_LOG_INTEGRATION intent 操作启动 activity:

val intent = Intent(TelecomManager.ACTION_CONFIGURE_CALL_LOG_INTEGRATION)
startActivity(intent)

当用户在系统设置中针对某个应用关闭统一通话记录时,系统会立即永久清除原生通话记录提供程序 (CallLog.Calls) 中该软件包的所有现有通话记录条目。该应用将来发起或接收的通话不会记录在系统拨号器中。

监听偏好设置更改

当用户在系统设置或拨号器中为您的通话应用启用或停用统一通话记录时,为了保持同步,请为 TelecomManager.ACTION_VOIP_CALL_LOG_PREFERENCE (android.telecom.action.VOIP_CALL_LOG_PREFERENCE) 广播 intent 注册广播接收器:

val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == TelecomManager.ACTION_VOIP_CALL_LOG_PREFERENCE) {
            // Status of the Unified Call History of the app
            val isEnabled = intent.getBooleanExtra(
                TelecomManager.EXTRA_VOIP_CALL_LOG_PREFERENCE_STATUS,
                true
            )
        }
    }
}

当用户切换开关时,平台会向您的应用广播此 intent,其中包含 TelecomManager.EXTRA_VOIP_CALL_LOG_PREFERENCE_STATUS extra 中的更新后的布尔值状态。您的应用可以监听此广播,而无需等待针对 CallLog.Calls 的定期验证。当统一通话记录被停用(即设置为 false)时,您的应用可以更新其内部状态或执行清理操作,例如清除用于回调处理的本地缓存通话映射。