setMicrophoneMute() 如何工作?

2024-01-11

我一直在尝试使用Android的AudioManager.setMicrophoneMute()没有取得多大成功。也就是说,无论我做什么,它都拒绝将麦克风静音。

我在网上搜索了一些线索,发现了一些报告类似经历的参考资料:

  • AudioManger.setMicrophoneMute 功能不起作用? http://groups.google.com/group/android-developers/browse_thread/thread/cf57da02446e424a
  • setMicrophoneMute(boolean) 在某些设备上不起作用 https://stackoverflow.com/questions/5217437/setmicrophonemuteboolean-doesnt-work-on-some-devices
  • 无法在 Android 中将麦克风静音 https://stackoverflow.com/questions/3043330/unable-to-mute-the-microphone-in-android

这就引出了一个问题:AudioManager.setMicrophoneMute()有工作吗?它只是一个存根方法,等待在 Android 的未来版本中实现吗?如果没有,它是如何工作的?我需要什么才能让它发挥作用?正如其名称所暗示的那样,其工作的条件是什么?

EDIT:我注意到这个方法的文档说:

此方法只能由以下应用程序使用replace这 音频设置或主要电话的全平台管理 应用。

这是什么意思?为什么我要更换平台范围的管理?我真的需要这样做吗?如果是这样,我该怎么做?

EDIT:下面的答案很好,但我还是不明白:

  1. 该标志(数据库中的 SET_MIC_MUTE)如何使用?
  2. 该标志何时真正断开麦克风信号 手机内部的前置放大电路?
  3. 如果它不这样做,那么谁会这样做?
  4. 如果没有任何作用,那么这种“静音”将如何发挥作用?

请解释。谢谢。


为了详细说明上面的 00b:s 答案和问题的编辑版本,我们必须更深入地挖掘源代码。 IAudioflinger 是 AudioFlinger 服务的接口以及对

virtual status_t setMicMute(bool state)
{
    Parcel data, reply;
    data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
    data.writeInt32(state);
    remote()->transact(SET_MIC_MUTE, data, &reply);
    return reply.readInt32();
}

其实就是让麦克风静音的Binder事务。 Binder 调用的接收端如下所示:

status_t BnAudioFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  { 
    switch(code) {
        ...
        case SET_MIC_MUTE: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            int state = data.readInt32();
            reply->writeInt32( setMicMute(state) );
            return NO_ERROR;
        } break;
    ...
    }
}

并调用 setMicMute 的实际实现音频调频器 http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=services/audioflinger/AudioFlinger.cpp;h=c68e20d6304072d88f7a79180ffe845b5ad0eac1;hb=a8313e71fe8b483448d14e22610101c5f3672744。下一步是查看这个函数:

status_t AudioFlinger::setMicMute(bool state) {
    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
    status_t ret = mAudioHardware->setMicMute(state);
    mHardwareStatus = AUDIO_HW_IDLE;
    return ret;
}

这里我们可以注意到两件事。首先是进行权限检查,以便能够将麦克风静音。在 settingsAllowed 中检查的权限是 android.permission.MODIFY_AUDIO_SETTINGS,因此如上面的评论之一所述,静音麦克风的第一个要求是您的应用程序已声明它需要此权限。接下来要注意的是,我们现在使用 mAudioHardware->setMicMute(state) 调用 setMicMute 的硬件特定版本。

有关硬件插入方式的更多信息,请研究文件 AudioHardwareInterface.cpp。基本上,它最终会出现在一个 libhardware 中,并通过 extern C 调用 createAudioHardware,该调用会为平台插入正确的 AudioHardWare。还有一些开关用于使用基于 A2DP 的硬件,这是一种用于仿真器和存根音频的通用硬件。假设您正在使用实际设备,那么实现很大程度上取决于硬件。为了感受一下它,我们可以使用 Crespo (Nexus S) 的可用音频硬件作为示例。

status_t AudioHardware::setMicMute(bool state) {
    LOGV("setMicMute(%d) mMicMute %d", state, mMicMute);
    sp<AudioStreamInALSA> spIn;
    {
        AutoMutex lock(mLock);
        if (mMicMute != state) {
            mMicMute = state;
            // in call mute is handled by RIL
            if (mMode != AudioSystem::MODE_IN_CALL) {
                spIn = getActiveInput_l();
            }
        }
    }

    if (spIn != 0) {
        spIn->standby();
    }

    return NO_ERROR;
}

基于这个例子,我们可以讨论智能手机中音频路由的实现。正如您在 Crespo 实现中所看到的,只有当您不在通话中时,麦克风静音呼叫才会被尊重。原因是音频是通过模拟基带路由的,模拟基带处理功率调节、放大和其他事情。通话时,语音音频通常由模拟基带和调制解调器 CPU 一起处理,而不是通过应用程序 CPU 路由。在这种情况下,您可能需要通过 RIL 通过调制解调器 CPU 才能将麦克风静音。但由于这种行为依赖于硬件,因此没有通用的解决方案。

针对您的 4 个附加问题提供简短版本:

  1. 该标志通过几层代码传递,直到它最终到达硬件特定的静音麦克风。

  2. 当硬件特定代码运行时,麦克风会断开连接,至少在某些设备上通话时除外。

  3. 当 setMicrophoneMute 不使麦克风静音时,即在通话时,可以使用电话 API 之一来做到这一点,我建议研究电话应用程序。

  4. 根据当前的实现,静音似乎在不通话时有效,但我们在此未研究的平台上可能存在特定于硬件的问题。

EDIT:

经过进一步挖掘,向调制解调器 CPU 发送静音命令的方法是通过内部电话接口,该接口是 com.android.internal.telephony 包的一部分,但 SDK 开发人员无法使用。根据您看到的评论,该函数只能由替换音频管理或原始电话应用程序的应用程序使用,我猜测 AudioManager.setMicrophoneMute() 应该始终使麦克风静音。但由于其他应用程序可能使用此功能,因此他们在硬件实现中添加了一个检查,以免弄乱电话应用程序的状态,该应用程序跟踪静音连接以及麦克风。由于硬件实现细节以及静音是一项比人们在考虑呼叫状态时最初想象的要复杂得多的操作这一事实,该功能现在可能无法按预期工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

setMicrophoneMute() 如何工作? 的相关文章

随机推荐

  • daemonset 不创建任何 pod

    我正在尝试使用 Kubernetes DaemonSets 但一点运气都没有 我已经寻找解决方案但无济于事 我希望这里有人可以提供帮助 首先 我见过这张票 https stackoverflow com questions 34818198
  • 从数组中获取大小为 n 的所有组合的算法(Java)? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 现在我正在尝试编写一个函数 它接受一个数组和一个整数 n 并给出每个大小 n 组合的列表 因此是 int 数组的列表 我
  • 获取报警信息

    我正在实现一个应用程序 其中必须显示警报信息 日期 时间 如果可用 有谁知道如何获取报警信息吗 非常感谢 结果 最后 我可以通过上面Curious的回答来检索警报信息 此外 当我在 packages apps 中探索 Deskclock 应
  • ipad 应用程序异常退出并显示信号 11:分段错误:11

    我的应用程序异常退出 信号为 11 我不知道这意味着什么 没有崩溃日志 调试器也没有显示错误 该应用程序刚刚消失 我得到以下日志 Apr 27 21 31 31 unknown Apollo 1408
  • 如何在编译时保存指向成员的指针?

    考虑下面的代码 template
  • 反应选择禁用选项

    我在禁用 React Select 元素内的大型列表中的某些选项时遇到问题 我有大约 6 500 个选项被加载到选择中 起初我遇到了搜索功能滞后的问题 但后来我开始使用react select fast filter options来解决这
  • 在 PHP 中写入文本文件时换行符不起作用

    我有以下测试脚本 但是 当运行并使用记事本打开时 数据以单行形式返回 没有中断 如下所示 Floppy Jalopy 疯狂盒子 Pointy Pinto 疯狂盒子 我找不到 疯狂盒子 的合适字符 但它确实是一个疯狂的盒子 是什么赋予了 最好
  • 仅在使用 cx_freeze 时出现 UnicodeDecodeError

    我收到错误 UnicodeDecodeError ascii codec can t decode byte 0xa0 in position 7338 ordinal not in range 128 一旦我尝试在使用 cx freeze
  • 在项目中声明全局变量并在xslt中使用它

    对于 XSLT 方面的疑问 我会寻求您的指导 在我当前的项目中 需要创建许多 XSLT 文件 在这些转换中 执行的共同步骤很少 例如更改输入 xml 中元素值的大写 我当前在 XSLT 中使用以下代码 因此如果创建了 50 个 XSLT 则
  • F# 正向管道从 int 转换为 bigint

    我对 F 相当陌生 遇到了这种情况 希望有人能解释为什么我的编译器不喜欢这些代码 如果在 F 中我执行以下操作 let FloatToInt 10 0 gt int let IntToFloat 10 gt float 一切都很好 数字被转
  • Python 中基于字符串的枚举

    封装我正在使用的状态列表enum模块 from enum import Enum class MyEnum Enum state1 state1 state2 state2 state MyEnum state1 MyEnum state1
  • __attribute__((__interrupt__, no_auto_psv)) 是做什么的?

    void attribute interrupt no auto psv T1Interrupt void 5 Hz attribute 指令或宏来自 GCC 但是 interrupt and no auto psv不是 它特定于硬件 那么
  • 检测何时触发position:sticky 的事件

    我正在使用新的position sticky info http updates html5rocks com 2012 08 Stick your landings position sticky lands in WebKit 创建类似
  • 如何创建 Java 自定义 Web 控件?

    这个问题最初出现在我的脑海中 我可以在 Servlet 中使用 AWT 控件吗 这将显示我对这个问题的无知 我是 JAVA 技术的新手 但经过一些阅读后 我似乎了解 AWT 控件直接连接操作系统 GUI 元素 因此无法在 Servlet 中
  • 对齐 CSS 网格中的列

    我应该设置哪些 CSS 属性 以便各列相互缠绕 忽略水平相邻列的高度 失败的尝试 我正在尝试这样做display grid 但它的行为不符合我的要求 一个例子 header height 2 0rem background PeachPuf
  • 通过 PowerShell/cmd 调用 Linux 应用程序的 Windows 子系统 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 随着最近推出的 Windows 内部版本 14316 我们拥有了适用于 Linux 的 Windows 子系统 测试版 它允许在 Wind
  • 设置超时时 JavaScript 闭环问题

    我在教程中找到了一些示例 说这是规范的示例 for var i 1 i lt 5 i setTimeout function console log i i i 1000 现在 我明白了 闭包将当前范围传递给函数 我假设它应该输出 1 2
  • AWS ELB - 多VPC负载均衡

    我正在开发一个项目 其中任务之一是为远程 VPC 中的实例提供 AWS ELB 服务 AWS ELB 位于 VPC A 中 实例位于 VPC B 中 我最初的回答是 否 因为 ELB 是负载均衡器 而不是路由器 文档和使用 AWS ELB
  • 如何在不打开网络浏览器的情况下在spotipy中进行身份验证?

    我尝试了标准方法 主页上有描述 但我需要在没有网络浏览器的情况下登录 我怎样才能做到这一点 您可以使用 Spotify 的 python 库之一 例如 https github com plamere spotipy https githu
  • setMicrophoneMute() 如何工作?

    我一直在尝试使用Android的AudioManager setMicrophoneMute 没有取得多大成功 也就是说 无论我做什么 它都拒绝将麦克风静音 我在网上搜索了一些线索 发现了一些报告类似经历的参考资料 AudioManger