如何使用AudioSource.VOICE_CALL录制语音通话

5

尝试录音时,我使用MediaRecorder类。当使用AudioSource.MICAudioSource.VOICE_COMMUNICATION 时,只录制了我的声音而不是接收者的声音。当我使用AudioSource.VOICE_CALL时,在接听电话时会出现异常。以下是代码:

if(intent.getAction().equals("android.intent.action.PHONE_STATE")){
            if((bundle = intent.getExtras()) != null){
                state = bundle.getString(TelephonyManager.EXTRA_STATE);
                if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
                    inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                    wasRinging = true;
                    Toast.makeText(context, inCall + " is calling", Toast.LENGTH_SHORT).show();
                }
                else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                    if(wasRinging){
                        Toast.makeText(context, "Call Answered", Toast.LENGTH_SHORT).show();
                        Date date = new Date();
                        SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss");

                        String filename = "rec_" + format.format(date) + ".mp3";
                        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
                        String fileUri = path + "/" + filename;
                        Log.v("testing uri", fileUri);
                        File file = new File(fileUri);

                        recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
                        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
                        recorder.setOutputFile(file.getAbsolutePath());

                        try {
                            recorder.prepare();
                            recorder.start();
                            recording = true;

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                    wasRinging = false;
                    Toast.makeText(context, "Cancelled", Toast.LENGTH_SHORT).show();
                    if(recording && recorder != null){
                        recorder.stop();
                        recorder = null;
                        recording = false;
                    }
                }
            }
        }

这是一个错误信息...


java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } in com.asadullah.callrecorder.MyBroadCastReceiver@41d6c7a8
   at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:778)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:136)
   at android.app.ActivityThread.main(ActivityThread.java:5102)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
   at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: start failed.
   at android.media.MediaRecorder.start(Native Method)
   at com.asadullah.callrecorder.MyBroadCastReceiver.onReceive(MyBroadCastReceiver.java:62)
   at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768)

清单权限包括:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.STORAGE" />
5个回答

4

VOICE_CALL 已经被弃用了。因此发生了这个错误。

请使用 VOICE_COMMUNICATION 作为 AudioSource,因为它是针对语音通信(如 VoIP)进行调整的麦克风音频源。

我也正在开发一款通话录音应用,但在 Android 7.1.1 上失败了。

如果您没有在 Android 7.1.1 上尝试通话记录,则以下代码将起作用。

recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

1
你建议的代码会记录麦克风和扬声器的声音吗?也就是说,包括双向语音吗? - Asad
是的,我的建议对我有效,除了7.1.1版本外,你也可以尝试这个方法,它也会对你有用。如果你在使用VOICE_COMMUNICATION时无法听到接收者的声音,请尝试使用MediaRecorder.AudioSource.DEFAULT。 - Sudarshana Dayananda
谢谢。你救了我的命。 - pratham kesarkar
@SudarshanaDayananda 你好,我尝试了各种方法,但仍无法录制结果。你能帮助我解决这个问题吗? - Aditya Vyas-Lakhan
我尝试使用VOICE_COMMUNICATION录制通话,但它只记录来自麦克风的声音,而不是扬声器发出的声音。有什么建议吗? - Siddharth Mehra

2

为了使用VOICE_CALL,您需要获取特殊权限。

 <uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
   tools:ignore="ProtectedPermissions" />

你如何获取这个特殊权限?这真的可能吗? - android developer

1

我认为你忘记了获取这个权限。

    <uses-permission android:name="android.permission.CALL_PHONE" />

你怎么能确切地获得这个权限? - android developer

1
我认为在新版的安卓 (Api 23) 中录音之前需要一些权限。 查看这个 Stack Overflow 的问题 - 在安卓中录制电话为什么不起作用 权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

如果您需要更多帮助,甚至可以查看官方文档以获取有关此错误的更多信息。


0

您需要为语音通话获取CAPTURE_AUDIO_OUTPUT权限,此处有相关文档

但是由于此处所述的原因,您将无法获得该权限。

请注意这一行:“不适用于第三方应用程序。


那么如果你无法获得授权,添加它有什么帮助呢? - android developer
如果您的应用程序不是第三方应用程序。 - Recycled Steel
使用root权限,是否可以拥有这个权限? - android developer
我相信,但是我不确定如何做。 - Recycled Steel
我已经尝试过了,但似乎它并没有真正授予它。甚至没有返回它已被授予的信息。 - android developer
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接