Android,NDK,音频路由,通过耳机强制音频

时间:2015-02-26 08:59:37

标签: android c++ android-ndk android-source android-audiorecord

用例

  • 录制Android耳机音频

环境

  • 三星Galaxy 5
  • Android 5.0
  • 带有USB音频捕获设备的Windows桌面操作系统

实施

  • 将Android设备耳机输出挂钩到Windows操作系统输入输入
  • 记录从Android设备发送的内容

问题陈述

  • 如果在Android设备上播放音频时插入音频插孔,设备音频输出将通过耳机插孔进行路由并且录制正常工作
  • 一旦音乐播放(例如一首歌曲)在Android设备上停止,下次启动音频播放时将使用设备扬声器而不是耳机插孔(用于录制)

尝试解决问题

  • 在shell帐户下运行的本机C ++命令行工具(不能使用Java)
  • 动态加载'libmedia.so'并调用eg。 android::AudioSystem::setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA,AUDIO_POLICY_FORCE_HEADPHONES)
  • logcat报告:
    • 02-26 10:39:50.418 289 1707 ServiceManager权限失败:来自uid的android.permission.MODIFY_AUDIO_SETTINGS = 2000 pid = 19577
    • 02-26 10:39:50.418 289 1707请求需要android.permission.MODIFY_AUDIO_SETTINGS

问题

  • 请记住,解决方案应该在非root设备上运行
    • 有没有办法将'android.permission.MODIFY_AUDIO_SETTINGS'权限授予'shell'帐户?
    • 有没有其他方法可以通过耳机强制系统范围(而不是应用专用)音频?

代码捕捉

            HRESULT forceAudioThroughHeadPhones() {
                typedef int(*SET_FORCE_USE)(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
                struct sigaction sa, osa;
                sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
                sa.sa_sigaction = [](int signo, siginfo_t* psi, void *data)->void { ucontext_t *uc = (ucontext_t *)data; };
                sigaction(SIGILL, &sa, &osa);
                void* hMod = dlopen("libmedia.so", RTLD_LAZY);
                sigaction(SIGILL, &osa, 0);
                if (0 == hMod)
                    return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
                SET_FORCE_USE setForceUse = (SET_FORCE_USE)dlsym(hMod, "_ZN7android11AudioSystem11setForceUseE24audio_policy_force_use_t25audio_policy_forced_cfg_t");
                if (0 == setForceUse)
                    return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
                android::status_t err;
                if (ERROR_SUCCESS != (err = setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_HEADPHONES)))
                    return E_FAIL;
                if (ERROR_SUCCESS != (err = setForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM, AUDIO_POLICY_FORCE_HEADPHONES)))
                    return E_FAIL;
                return S_OK;
            }
  • 'setForceUse'返回-1,errno等于'Zero'。

UPDATE:

使用 adb shell服务调用时,我得到了相同的权限logcat错误...

10|shell@klte:/ $ service call media.audio_policy 1 i32 2 
Result: Parcel(ffffffff    '....')

0 个答案:

没有答案