You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13下InCallService拨号应用通话振铃时振动异常求助

Android 13中InCallService通话振铃阶段振动被抑制的解决方案

问题描述

我使用InCallService开发了一款带有自定义铃声和振动功能的简易拨号应用,该应用在Android 8上运行正常。但在Android 13系统中,非通话状态下振动功能正常,而在通话振铃阶段,振动被抑制(仅持续50-100ms,预期为1000ms),振动由前台Activity触发。推测可能遗漏了Android新版本的相关特性,现附上代码及配置:

振动触发代码

private final VibrationEffect vibrationEffect = createOneShot(1000, DEFAULT_AMPLITUDE);
    
if (SDK_INT >= 33) vibrator.vibrate(vibrationEffect, VibrationAttributes.createForUsage(VibrationAttributes.USAGE_RINGTONE));
else vibrator.vibrate(vibrationEffect, new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());

清单文件配置

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

<service  android:name=".Serv"
android:exported="true"
android:permission="android.permission.BIND_INCALL_SERVICE">

        <meta-data
         android:name="android.telecom.IN_CALL_SERVICE_RINGING"
            android:value="true" />

        <meta-data
            android:name="android.telecom.IN_CALL_SERVICE_UI"
            android:value="true" />

        <intent-filter>
            <action android:name="android.telecom.InCallService" />
        </intent-filter>
    </service>

问题分析与解决方案

Android 13(API 33)针对通话场景的振动行为新增了更严格的系统管控逻辑,当使用USAGE_RINGTONE这类通用振铃属性时,系统可能会优先接管振动行为,导致自定义振动被截断。以下是针对性的解决方法:

1. 更换振动属性为通信信号专用类型

将振动属性从USAGE_RINGTONE/USAGE_NOTIFICATION_RINGTONE替换为USAGE_COMMUNICATION_SIGNALLING,该属性专门用于通话振铃、来电提醒这类通信信号场景,系统对其的限制更少:

private final VibrationEffect vibrationEffect = VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE);
    
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    vibrator.vibrate(vibrationEffect, 
        VibrationAttributes.createForUsage(VibrationAttributes.USAGE_COMMUNICATION_SIGNALLING));
} else {
    vibrator.vibrate(vibrationEffect, 
        new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_COMMUNICATION_SIGNALLING).build());
}

2. 确保前台Activity的优先级

在触发振动前,强制将Activity移至前台,避免系统因优先级问题中断振动:

if (!isFinishing() && !isDestroyed()) {
    moveTaskToFront(getTaskId(), 0);
}
// 执行振动逻辑

3. 规避系统默认振铃振动冲突

Android 13中系统会自动触发通话振铃振动,可能与自定义振动冲突。可以通过TelecomManager监听通话状态,在确认振铃状态后,再触发自定义振动:

TelecomManager telecomManager = getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
    // 执行自定义振动逻辑
}

4. 再次确认权限有效性

虽然非通话状态振动正常,但仍可在振动逻辑前增加权限检查,确保权限未被系统回收:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) == PackageManager.PERMISSION_GRANTED) {
    // 执行振动逻辑
}

内容的提问来源于stack exchange,提问作者siapost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:02:03