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);
    }
}
相关推荐
三少爷的鞋12 分钟前
Android 慢性病之拒绝"带病"上线:为什么 ANR 是必须根除的代码 HP?
android
草莓熊Lotso16 分钟前
Linux 线程深度剖析:线程 ID 本质、地址空间布局与 pthread 源码全解
android·linux·运维·服务器·数据库·c++
私人珍藏库22 分钟前
【Android】Shizuku升级版-Stellar-提高软件权限
android·app·工具·软件·多功能
白毛大侠26 分钟前
# MySQL InnoDB 隔离级别与 MVCC 完全解析
android·数据库·mysql
冬奇Lab11 小时前
MediaPlayer 播放器架构:NuPlayer 的 Source/Decoder/Renderer 三驾马车
android·音视频开发·源码阅读
炸炸鱼.13 小时前
Python 操作 MySQL 数据库
android·数据库·python·adb
用户416596736935514 小时前
nextlib 项目架构与深度技术指南 (Architecture & Technical Master Guide)
android
aq553560015 小时前
Laravel10.x重磅升级,新特性一览
android·java·开发语言
Trouvaille ~15 小时前
【MySQL篇】数据类型:存储数据的基础
android·数据库·mysql·adb·字符集·数据类型·基础入门
2401_8858850416 小时前
开发视频短信接口好开发吗?图文视频短信接口对接教程
android·音视频