Permission failure: android.permission.CAPTURE_AUDIO_OUTPUT 解决办法

在 android M 以上,MediaRecorder 录音时音源设置为 VOICE_CALL,开始录音时会抛出权限异常

12-04 10:34:41.808   545  2254 D AudioRecord: set(): 0xe90ba000, inputSource 4, sampleRate 44100, format 0x1, channelMask 0x10, frameCount 2048, notificationFrames 1024, sessionId 0, transferType 0, flags 0, opPackageName cn.wangy.contacts uid 10059, pid 1917
12-04 10:34:41.814   409  2559 W ServiceManager: Permission failure: android.permission.CAPTURE_AUDIO_OUTPUT from uid=10059 pid=1917
12-04 10:34:41.815   409  2559 D PermissionCache: checking android.permission.CAPTURE_AUDIO_OUTPUT for uid=10059 => denied (548 us)
12-04 10:34:41.815   409  2559 E         : Request requires android.permission.CAPTURE_AUDIO_OUTPUT
12-04 10:34:41.815   409  2559 E AudioFlinger: createRecord() checkRecordThread_l failed
12-04 10:34:41.815   545  2254 E IAudioFlinger: createRecord returned error -22
12-04 10:34:41.815   545  2254 E AudioRecord: AudioFlinger could not create record track, status: -22
12-04 10:34:41.816   545  2254 E StagefrightRecorder: audio source is not initialized
12-04 10:34:41.816   545  2254 D MPEG4Writer: reset+ 1081
12-04 10:34:41.816  1917  1917 E MediaRecorder: start failed: -2147483648
12-04 10:34:41.816  1917  1917 W System.err: java.lang.RuntimeException: start failed.
12-04 10:34:41.825  1917  1917 W System.err: 	at android.media.MediaRecorder.start(Native Method)

方法一,给 app 增加 sharedUserId="android.uid.system",并使用系统签名

方法二,屏蔽系统源码,跳过权限检查

通过全局搜索,发现权限判断竟然在 c 中,通过 pid 和 vid 来检查

frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp

frameworks\av\services\audioflinger\ServiceUtilities.cpp

android 8.1

注释 AudioPolicyInterfaceImpl.cpp 中 switch 语句块 status = PERMISSION_DENIED;

或者修改 ServiceUtilities.cpp 中 captureAudioOutputAllowed() 返回 true

if (status == NO_ERROR) {
            // enforce permission (if any) required for each type of input
            switch (inputType) {
            case AudioPolicyInterface::API_INPUT_LEGACY:
                break;
            case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                // FIXME: use the same permission as for remote submix for now.
            case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
                if (!captureAudioOutputAllowed(pid, uid)) {
                    ALOGE("getInputForAttr() permission allowed: capture allowed");
                    //cczheng annotation for don‘t check android.Manifest.permission.CAPTURE_AUDIO_OUTPUT
                    /*ALOGE("getInputForAttr() permission denied: capture not allowed");
                    status = PERMISSION_DENIED;*/
                }
                break;
            case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
                if (!modifyAudioRoutingAllowed()) {
                    ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
                    status = PERMISSION_DENIED;
                }
                break;
            case AudioPolicyInterface::API_INPUT_INVALID:
            default:
                LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",
                        (int)inputType);
            }
        }

android 9.0

9.0 中 AudioPolicyInterfaceImpl.cpp 在 switch 语句块前新增加了包名判断,上面的报错权限就是从这里打印的,注释如下

// check calling permissions
    //cczheng annotation for don‘t check android.Manifest.permission.CAPTURE_AUDIO_OUTPUT
    /*if (!recordingAllowed(opPackageName, pid, uid)) {
        ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
                __func__, uid, pid);
        return PERMISSION_DENIED;
    }

    if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
        attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
        attr->source == AUDIO_SOURCE_VOICE_CALL) &&
        !captureAudioOutputAllowed(pid, uid)) {
        return PERMISSION_DENIED;
    }*/

    if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed(pid, uid)) {
        return BAD_VALUE;
    }

    sp<AudioPolicyEffects>audioPolicyEffects;
    {
        status_t status;
        AudioPolicyInterface::input_type_t inputType;

        Mutex::Autolock _l(mLock);
        {
            AutoCallerClear acc;
            // the audio_in_acoustics_t parameter is ignored by get_input()
            status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
                                                         config,
                                                         flags, selectedDeviceId,
                                                         &inputType, portId);
        }
        audioPolicyEffects = mAudioPolicyEffects;

        if (status == NO_ERROR) {
            // enforce permission (if any) required for each type of input
            switch (inputType) {
            case AudioPolicyInterface::API_INPUT_LEGACY:
                break;
            case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                // FIXME: use the same permission as for remote submix for now.
            case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
                if (!captureAudioOutputAllowed(pid, uid)) {
                    ALOGE("getInputForAttr() permission allowed: capture allowed");
                    //cczheng annotation for don‘t check android.Manifest.permission.CAPTURE_AUDIO_OUTPUT
                    /*ALOGE("getInputForAttr() permission denied: capture not allowed");
                    status = PERMISSION_DENIED;*/
                }
                break;
            case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
                if (!modifyAudioRoutingAllowed()) {
                    ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
                    status = PERMISSION_DENIED;
                }
                break;
            case AudioPolicyInterface::API_INPUT_INVALID:
            default:
                LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",
                        (int)inputType);
            }
        }

原文地址:https://www.cnblogs.com/cczheng-666/p/12607001.html

时间: 2024-10-11 12:20:07

Permission failure: android.permission.CAPTURE_AUDIO_OUTPUT 解决办法的相关文章

Android:调用其他程序中的activity和Permission Denial: starting Intent 错误解决办法

今天想调试多个task中栈的情况,在测试程序中调用另一个程序的activity, 代码片段如下: [java] view plaincopy btnStartX=(Button)findViewById(R.id.btnStartX); btnStartX.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stu

ServiceManager: Permmission failure: android.permission.RECORD_AUDIO

今天在Android6.0系统的手机上测试一款APP,出现如题错误: ServiceManager: Permmission failure: android.permission.RECORD_AUDIO 在AndroidManifest.xml中增加: <uses-permission android:name = "android.permission.RECORD_AUDIO"/> 仍然无解. 查询资料后发现,在Android6.0的系统上,部分permission

android.os.NetworkOnMainThreadException 解决办法:

产生的原因: 在4.0之后在主线程里面执行Http请求都会报这个错,也许是怕Http请求时间太长造成程序假死的情况 解决办法: 1.在发起Http请求的Activity里面的onCreate函数里面添加如下代码 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());    

Assertion failure in UITableViewCell layoutSublayersOfLayer解决办法

iOS6 设备在更新UITableViewCell的时候遇到了 Assertion failure in -[UITableViewCell layoutSublayersOfLayer:], /SourceCache/UIKit/UIKit-2380.17/UIView.m:5776 的问题, 解决方法是,把UITableViewCell里面的控件的添加方式由 [self addSubview:self.titleLabel]; 改成 [self.contentView addSubview:

Android Studio下载,无法打开developer.android.com的解决办法

developer.android.com目前也被block, 原先的dns解析已经无法使用. 这里提供几个可用IP 在Mac系统下,进入terminals 输入 sudo vim /etc/hosts 回车 在最后一行按a键,进入insert模式,输入如下内容 216.58.219.46  developer.android.com 然后esc,退出insert模式,输入一个:号,进入命令模式 :w 或者 :qw 存盘,并退出. 重新打开developer.android.com即可,下载an

无法启动Android模拟器的解决办法

网上收集到的解决方法有如下几种: 1.在创建avd的时候,它的name就像是java中创建class一样,首字母一定要大写,要不然系统就不能识别出来,就会出现无法写入的情况.. 2.创建sdcard的时候,size 可以不进行设置,如果你没创建sdcard的话,那里设置也没用,主要是file那里要指向你所创建的sdcard的路径,也就是sdcard.mimg,这时候sdcard已经存在了,就不要在size里面输入sdcard大小,要不然就会出现错误. 3.升级显卡驱动程序到最新版本. 4.启用显

虚拟机 安装X86 Android 联网的解决办法

我用的是最新的4.4.2 的X86 镜像,安装之后,我们需要找到: 终端模拟器(在Android系统的桌面就有,仔细找!) 输入su 让虚拟机获取 超级用户权限,弹出提示框我们选"永久记住选择"(这里我想说一下,由于我在开发界面,所以此处不需要考虑在 普通用户下是否能使用的问题,但是如果开发到具体功能了,我建议关闭root权限,否则有些Bug 你是测不到的,将用户当成小白这是必要的.) 然后,我们输入"dhcpcd eth0"(好了,这个就是传说中的eth0 补丁.

Ubuntu 14.04.4 下 scp 远程拷贝提示:Permission denied, please try again. 的解决办法

我在 s0 主机上远程拷贝 /etc/hosts 文件到 s1 主机上,出现下面的错误提示: [email protected]:~$ scp /etc/hosts [email protected]:/etc/[email protected]'s password: Permission denied, please try again. 解决办法如下: 1.    sudo gedit /etc/ssh/sshd_config    注释掉 PermitRootLogin without-

应用商城 下载apk 安装包解析错误 没有权限 Permission denied Android - failed to open zip archive

1.错误提示: 03-31 16:48:43.740: INFO/ActivityManager(59): Start proc com.android.packageinstaller for activity com.android.packageinstaller/.PackageInstallerActivity: pid=620 uid=10026 gids={} 03-31 16:48:44.749: WARN/zipro(620): Unable to open zip '/dat