我和另一个开发者合作过,我们似乎找到了一个可以花一大笔钱来做这件事的人.他们给我们发送了一个测试apk,它似乎起了作用.我们将继续购买来源.我希望我们不会上当受骗.我一发现就会更新
Update 2:还在努力.在经历了更多痛苦的日子后,我现在认为没有什么特别的事情发生,但他们只是在原生一侧使用AudioFinger(See the link)拨打AudioFlinger::setParameters
我现在正在寻找如何编写一个简单的JNI来调用AudioFlinger::setParameters
我知道keyValuePairs会是什么,但对audio_io_handle_t一无所知
Update:我现在相信,其他应用程序可能会在CAF中使用QCOM音频.请参阅link for same时的音频校准
而voice_get_incall_rec_snd_device在link for same
我没有C/++知识.如何才能确定是否可以从本机端调用这些方法? 既然其他应用可以,那么一定有办法.
我每天至少有5-6个小时都在为此奋斗40多天.我不确定这是否得到了SO的允许,但我也很乐意为正确答案捐款.
我有一个通话录音应用程序,使用语音通话音频源.尽管ASOP没有实施/强制实施,但大多数制造商已经实施了VOICE_CALL,并且使用VOICE_CALL音频源的应用在许多设备上运行良好.直到安卓6.
谷歌用安卓6改变了这种行为.打开语音呼叫音频源现在需要android.准许捕获仅授予系统应用程序的音频输出.
这基本上停止了通话记录,或者应该停止.好吧,它适用于我和200多个其他通话记录应用程序,除了3个已经找到了绕过这一限制的方法.
我一直在用安卓6在许多不同的手机上试用这些应用程序,并发现了它们记录的某些特点.
都是使用Android AudioRecord类,打开MIC音频源.我也是;但在我的应用程序上,我只能从麦克风那里获得音频,而不能从对方那里获得音频.我发现的是,他们在开始录制之后或之前发出了某种类型的系统调用.
请看下面的日志(log),这些日志(log)来自成功录制VOICE_CALL的应用程序之一,即使它使用MIC进行录制.看起来APP是如何将VOICE_CALL音频源混合/路由/流式/合并到MIC中的.
- D/audio_hw_primary: in_set_parameters: enter: kvpairs=input_source=1;routing=-2147483644
- D/PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=10286 => granted (432 us)
- D/audio_hw_primary: in_set_parameters: enter: kvpairs=input_source=4;routing=-2147483584;format=1
- D/audio_hw_primary: select_devices: out_snd_device(0: ) in_snd_device(283: voice-dmic-ef)
- D/hardware_info: hw_info_append_hw_type : device_name = voice-dmic-ef
- D/voice: voice_get_incall_rec_snd_device: in_snd_device(283: voice-dmic-ef) incall_record_device(283: voice-dmic-ef)
正如您在第一行中看到的,它以麦克音频源INPUT_SOURCE=1;ROUTING=-2147483644开始.
然后,在第二行,它做了一些事情,并被授予了安卓系统.准许修改音频设置,这是正常权限,我的应用程序也有.这似乎是最重要的部分,看起来所有3家公司都在使用JNI来触发语音呼叫音频源到麦克风的流式传输/合并,并使用standart AudioRecorder API进行录制
在下一行中,你会看到音频硬件开始混合语音通话(输入源=4),尽管它们已经打开了麦克风(1)音频源.
我以为他们用了
AudioManager.setParameters("key=value")
并try 了许多变体,例如
AudioManager.setParameters("input_source=4;routing=-2147483584;format=1")
没有任何运气.
然后,我找到了Android, NDK, Audio routing, forcing audio through the headset个,并认为它们可能是一些如何混合/路由/流/合并语音呼叫到当前的录音会话,并且(因为没有C知识)try 使用回流来实现同样的事情与下面的代码(再次)没有运气.
private static void setForceUseOn() {
/*
setForceUse(int usage, int config);
----usage for setForceUse, must match AudioSystem::force_use
public static final int FOR_COMMUNICATION = 0;
public static final int FOR_MEDIA = 1;
public static final int FOR_RECORD = 2;
public static final int FOR_DOCK = 3;
public static final int FOR_SYSTEM = 4;
public static final int FOR_HDMI_SYSTEM_AUDIO = 5;
----device categories config for setForceUse, must match AudioSystem::forced_config
public static final int FORCE_NONE = 0;
public static final int FORCE_SPEAKER = 1;
public static final int FORCE_HEADPHONES = 2;
public static final int FORCE_BT_SCO = 3;
public static final int FORCE_BT_A2DP = 4;
public static final int FORCE_WIRED_ACCESSORY = 5;
public static final int FORCE_BT_CAR_DOCK = 6;
public static final int FORCE_BT_DESK_DOCK = 7;
public static final int FORCE_ANALOG_DOCK = 8;
public static final int FORCE_DIGITAL_DOCK = 9;
public static final int FORCE_NO_BT_A2DP = 10;
public static final int FORCE_SYSTEM_ENFORCED = 11;
public static final int FORCE_HDMI_SYSTEM_AUDIO_ENFORCED = 12;
public static final int FORCE_DEFAULT = FORCE_NONE;
*/
try {
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, 0, 0); // setForceUse(FOR_RECORD, FORCE_NONE)
} catch (Exception e) {
e.printStackTrace();
}
}
显然,我遗漏了一些东西,这使得录制成为可能.
我甚至提出付钱来获取这些信息,但都被拒绝了.我说得很公平.我会出版一次/如果我找到的话!
你知道他们可能在做什么吗?