更新3:私は別の開発者と提携しましたが、多額のお金でこれを実行できる人を見つけたようです。彼らは私たちにテストapkを送ってくれました、そしてそれはうまくいくようです。先に進んでソースを購入します。詐欺に遭わないことを願っています。わかったら更新します
アップデート2:まだ作業中です。もっと辛い日々を過ごした後、私は今、何も派手なことは起こっていないと思いますが、彼らは単にネイティブ側でAudioFlinger(リンクを参照)を使用してAudioFlinger :: setParametersを呼び出しています
私は今、audio_io_handle_t ioHandle、const String8&keyValuePairsを使用してAudioFlinger :: setParametersを呼び出す簡単なJNIを作成する方法を探しています。
keyValuePairsが何であるかは知っていますが、audio_io_handle_tについての手がかりはありません
更新:他のアプリがCAFでQCOMオーディオを使用している可能性があると思います。同じものについては、リンクのaudio_extn_utils_send_audio_calibrationを参照してください
と同じリンクのvoice_get_incall_rec_snd_device
私はC / ++の知識がありません。これらのメソッドをネイティブ側から呼び出すことができるかどうかを確認するにはどうすればよいですか?他のアプリでもできるので、方法が必要です。
私はこれに40日以上、少なくとも1日5〜6時間苦労してきました。SOで許可されているかどうかはわかりませんが、正解も喜んで寄付させていただきます。
VOICE_CALLオーディオソースを使用する通話録音アプリがあります。ASOPはそれを実装/義務付けていませんが、ほとんどのメーカーはVOICE_CALLを実装しており、VOICE_CALLオーディオソースを使用するアプリは多くのデバイスで正常に機能しました。それはAndroid6までです。
GoogleはAndroid6でこの動作を変更しました。VOICE_CALLオーディオソースを開くには、システムアプリケーションにのみ付与されるandroid.permission.CAPTURE_AUDIO_OUTPUTが必要になりました。
これは基本的に通話の録音を停止します。まあ、それはこの制限を回避する方法を見つけた3人を除いて私のものと200以上の他の通話録音アプリのためにあります。
私はAndroid6を搭載したさまざまな携帯電話でこれらのアプリを試してきましたが、記録方法に特定の特徴があることがわかりました。
それらはすべてAndroidAudioRecordクラスを使用し、MICオーディオソースを開きます。私も; しかし、私のアプリでは、MICからのみ音声を取得し、相手からは取得しません。私が見つけたのは、彼らが録音を開始した直後または開始する前に、ある種のシステムコールを発行しているということです。
MICを使用して録音しているにもかかわらず、VOICE_CALLを正常に録音したアプリの1つから、次のログを確認してください。アプリは、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)
最初の行でわかるように、MICオーディオソースinput_source = 1; routing = -2147483644で始まります。
次に、2行目で何かを実行し、android.permission.MODIFY_AUDIO_SETTINGSが付与されます。これは通常の権限であり、私のアプリにもそれがあります。これは最も重要な部分のようで、3つすべてがJNIを使用して、VOICE_CALLオーディオソースのMICへのストリーミング/マージをトリガーし、標準のAudioRecorderAPIで録音するために行っていることを実行しているようです。
次の行では、MIC(1)オーディオソースを開いているにもかかわらず、オーディオハードウェアがVOICE_CALL(input_source = 4)のミキシングを開始していることがわかります。
私は彼らが使用したと思います
AudioManager.setParameters("key=value")
次のような多くのバリエーションを試しました
AudioManager.setParameters("input_source=4;routing=-2147483584;format=1")
運がない。
次に、Android、NDK、オーディオルーティングを見つけ、ヘッドセットを介してオーディオを強制し、 VOICE_CALLを現在のAudioRecordセッションにミックス/ルーティング/ストリーム/マージする方法である可能性があると考え、(Cの知識がないため)リフレクションを使用しようとしました運がなくても、以下のコードで同じことを(再び)達成することができます。
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();
}
}
明らかに、録音を可能にする何かが欠けています。
私はこの情報を得るためにお金を払うことさえ申し出ました、すべて拒否しました。私が言ったのは十分に公平だ。一度公開します/見つけたら公開します!
彼らが何をしているのかについて何か考えがありますか?