android 后台应用申请音频焦点失败

现象

app在前台可以申请音频焦点,但是在后台申请音频焦点失败。

原因

HardeningEnforcer.blockFocusMethod方法拒绝了后台app的申请,这个方法的第一个if会判断app是否符合拿到音频焦点的条件。第二if判断如果targetSdk是否小于35,如果小于35也不会拒绝。

java 复制代码
//frameworks/base/services/core/java/com/android/server/audio/HardeningEnforcer.java
/**
 * Checks whether the call in the current thread should be allowed or blocked
 * @return false if the method call is allowed, true if it should be a no-op
 */
@SuppressWarnings("AndroidFrameworkCompatChange")
protected boolean blockFocusMethod(int callingUid, int focusMethod, @NonNull String clientId,
                                   int focusReqType, @NonNull String packageName, String attributionTag, int targetSdk) {

    if (noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, callingUid, packageName, attributionTag)) {
        blocked = false;
    } else if (targetSdk < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
        // Build.VERSION_CODES.VANILLA_ICE_CREAM=35
        // 如果targetSdk<35,允许申请音频焦点
        blocked = false;
        unblockedBySdk = true;
    }
    metricsLogFocusReq(blocked, focusReqType, callingUid, unblockedBySdk);
    if (!blocked) {
        // 不允许申请音频焦点
        return false;
    }
    // 允许申请音频焦点
    return true;
}

解决方法

方法一

直接降级targetSdk,改到35以下

ini 复制代码
android {
    defaultConfig {
        targetSdk = 34
    }
}

方法二

创建前台Service来申请音频焦点,developer.android.com/develop/bac...

方法三

添加MODIFY_AUDIO_ROUTING或MODIFY_AUDIO_SETTINGS_PRIVILEGED权限。必须要有系统签名的应用才能获取这个权限。

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING"/>
  <!-- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED"/> -->

</manifest>

AudioService在申请音频焦点时,会先判断是否有这个权限。如果MODIFY_AUDIO_ROUTING或MODIFY_AUDIO_SETTINGS_PRIVILEGED,就不会调用HardeningEnforcer.blockFocusMethod,自然也不会拒绝音频焦点了。

java 复制代码
//frameworks/base/services/core/java/com/android/server/audio/AudioService.java
public int requestAudioFocus(AudioAttributes aa, int focusReqType, IBinder cb,
                             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
                             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {

    // 检查申请音频焦点的app是否有权限绕过HardeningEnforcer
    // does caller have system privileges to bypass HardeningEnforcer
    boolean permissionOverridesCheck = false;
    if ((mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
         == PackageManager.PERMISSION_GRANTED)
        || (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
            == PackageManager.PERMISSION_GRANTED)) {
        permissionOverridesCheck = true;
    } else if (uid < UserHandle.AID_APP_START) {
        permissionOverridesCheck = true;
    }

    try {
        if (permissionOverridesCheck) {
            mHardeningEnforcer.metricsLogFocusReq(/*blocked*/ false, focusReqType, uid,
                                                  /*unblockedBySdk*/ false);
        }
        if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid,
                                                                             HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS,
                                                                             clientId, focusReqType, callingPackageName, attributionTag, sdk)) {
            // 没有MODIFY_AUDIO_ROUTING权限,并且blockFocusMethod返回false,
            // 才会申请焦点失败
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
        }
    } finally {
        Binder.restoreCallingIdentity(token);
    }
}
相关推荐
zhuhai06138 小时前
Android Socket 深度剖析:从原理到实战
android
毕设源码-朱学姐8 小时前
【开题答辩全过程】以 基于Android的留守儿童贫困资助管理系统的设计与实现为例,包含答辩的问题和答案
android
愤怒的代码9 小时前
深入理解 IdleHandler:从启动优化到内存管理
android·架构·kotlin
恋猫de小郭9 小时前
OpenAI :你不需要跨平台框架,只需要在 Android 和 iOS 上使用 Codex
android·前端·openai
路在脚下,梦在心里9 小时前
net学习总结
android·学习
走在路上的菜鸟9 小时前
Android学Dart学习笔记第二十节 类-枚举
android·笔记·学习·flutter
星光一影9 小时前
合成植物大战僵尸 安卓原生APP Cocos游戏 支持Sigmob
android·游戏·php·html5·web app
2501_915918419 小时前
iOS 项目中证书管理常见的协作问题
android·ios·小程序·https·uni-app·iphone·webview
allk559 小时前
Android ANR 深度起底:从系统埋雷机制到全链路治理体系
android