当前位置: 首页 > 知识库问答 >
问题:

如何在Android中记录电话

欧阳山
2023-03-14

我正在开发一个可以在Android系统中记录通话的应用程序。我读过很多讨论通话记录问题的话题。我知道不是所有的Android手机都可以记录通话。但是我想知道如何记录通话,这是游戏市场上最受欢迎的应用程序,比如https://play.google.com/store/apps/details?id=com.appstar.callrecorder或https://play.google.com/store/apps/details?id=polis.app.callrecorder.。我认为你不是用MediaRecorder类来做这项工作的,而是用其他东西。因为我已经开发了自己的应用程序,但是我只能记录我的声音。但是这两个应用程序既记录了我的声音,也记录了我打电话的一个男人的声音。他们是怎么做到的?我知道我们无法访问设备扬声器来录制声音。你能给我一些关于如何录制语音通话的想法吗?这是我在应用程序中使用的代码:

public class CallRecorderService extends Service {

    private MediaRecorder mRecorder;
    private boolean isRecording = false;

    private PhoneStateListener phoneStateListener = new PhoneStateListener() {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    stopRecording();
                break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    startRecording(incomingNumber);
                break;
                case TelephonyManager.CALL_STATE_RINGING:
                break;
                default:

                break;
            }
        }
    };

    @Override
    public void onCreate() {
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void startRecording(String number) {
        try {
            String savePath = Environment.getExternalStorageDirectory().getAbsolutePath();
            savePath += "/Recorded";
            File file = new File(savePath);
            if (!file.exists()) {
                file.mkdir();
            }

            savePath += "/record_" + System.currentTimeMillis() + ".amr";
            mRecorder = new MediaRecorder();

            SharedPreferences sPrefs = getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE);
            int inputSource = sPrefs.getInt(Constants.SOURCE_INPUT, Constants.SOURCE_VOICE_CALL);
            int outputSource = sPrefs.getInt(Constants.SOURCE_OUTPUT, Constants.OUTPUT_MPEG4);

            switch (inputSource) {
                case Constants.SOURCE_MIC:
                    increaseSpeakerVolume();
                break;
            }

            mRecorder.setAudioSource(inputSource);
            mRecorder.setOutputFormat(outputSource);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setOutputFile(savePath);
            mRecorder.prepare();
            mRecorder.start();
            isRecording = true;

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void stopRecording(){
        if (isRecording) {
            isRecording = false;
            mRecorder.stop();
            mRecorder.release();
        }
    }

    private void increaseSpeakerVolume(){

        AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audio.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL,
                AudioManager.ADJUST_RAISE,
                AudioManager.FLAG_SHOW_UI);
    }

}

共有1个答案

葛哲彦
2023-03-14

我认为他们确实使用媒体记录。也许它的主要问题是,将它中的数据写入其他内容(本地存储中的文件)是很棘手的。为了解决这个问题,你可以创建一个管道。然后使用其文件描述符作为媒体记录器的输入 fd。然后,管道输出可以由某个线程控制,该线程将读取音频包(以格式,aac or..wav甚至),然后对数据执行任何操作。

这是一些代码。注意,这是一个原型,甚至可能不会编译,只是给你一个想法。

        /* 2M buffer should be enough. */
        private final static int SOCKET_BUF_SIZE = 2 * 1024 * 1000;

        private void openSockets() throws IOException {
            receiver = new LocalSocket();
            receiver.connect(new LocalSocketAddress("com.companyname.media-" + socketId));
            receiver.setReceiveBufferSize(SOCKET_BUF_SIZE);
            sender = lss.accept();
            sender.setSendBufferSize(SOCKET_BUF_SIZE);
        }

        private void closeSockets() {
            try {
                if (sender != null) {
                    sender.close();
                    sender = null;
                }
                if (receiver != null) {
                    receiver.close();
                    receiver = null;
                }
            } catch (Exception ignore) {
            }
        }


      public void prepare() throws IllegalStateException, IOException {
        int samplingRate;

        openSockets();

        if (mode == MODE_TESTING) {
            samplingRate = requestedSamplingRate;
        } else {
            samplingRate = actualSamplingRate;
        }
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        try {
            Field name = MediaRecorder.OutputFormat.class.getField("AAC_ADTS");
            if (BuildConfig.DEBUG)
                Log.d(StreamingApp.TAG, "AAC ADTS seems to be supported: AAC_ADTS=" + name.getInt(null));
            mediaRecorder.setOutputFormat(name.getInt(null));
        } catch (Exception e) {
            throw new IOException("AAC is not supported.");
        }

        try {
            mediaRecorder.setMaxDuration(-1);
            mediaRecorder.setMaxFileSize(Integer.MAX_VALUE);
        } catch (RuntimeException e) {
            Log.e(StreamingApp.TAG, "setMaxDuration or setMaxFileSize failed!");
        }

        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mediaRecorder.setAudioChannels(1);
        mediaRecorder.setAudioSamplingRate(samplingRate);
        mediaRecorder.setOutputFile(sender.getFileDescriptor());

        startListenThread(receiver.getInputStream());
        mediaRecorder.start();
    }
 类似资料:
  • 我想做一个应用程序,记录来电和去电,它会自动运行,当用户得到或作出任何呼叫。

  • 我需要在我的android应用程序中记录电话。我试过使用MediaRecorder,将AudioSource设置为MIC、VOICE_COMMUNICATION、VOICE_CALL和其他选项。但它们都没有记录通话。有人能建议在android中记录电话的任何解决方案吗? 以下是我试用过的代码。但它不记录通话。只记录通话前后的语音。请建议任何解决方案。 开始录制的代码 获取输出文件文件名的代码 停止

  • 我目前正在开发一个项目,我需要为应用程序录制VOIP通话,例如(Whatsapp和其他使用VOIP通话的应用程序) 我已经尝试了下面的代码来触发事件,当whatsapp调用时,所以我同时启动了录音机,但这是问题所在 当录音开始时,同时WhatsApp通话,然后接收器无法收听我的声音,但我可以听到他的声音,音频只录制了我的声音-基本上,录音开始时,它使用与WhatsApp相同的音频源,所以Whats

  • 将<code>MediaRecorder</code>音频源设置为上述任何一个都不起作用。可能是制造商禁用了通话记录。但像ACR记录器这样的应用程序是如何工作的呢? 他们在使用NDK吗?我正在尝试构建一个类似的应用程序,但最终得出的结论是我必须使用NDK。任何建议都将不胜感激。 呼叫记录器-ACR

  • 有下一个例子: 知道locale属性包含的是来自数据库的dictionary对象,我如何用JSDoc记录其内部属性? 目前,我正在考虑为我的区域设置对象键入typedef,那么我可以将locale属性设置为我定义的类型的数组吗?这样做对吗?

  • 问题内容: 我正在寻找最快和正确的方法来检查数据库中是否存在记录: 您有任何问题吗? 问题答案: 考虑那是你的课 我将您的参数保留为a,但我认为应该将其作为。 它比因为不需要在select子句中从表中检索所有值而更快。 您可以将字符串放入静态最终常量中,以使其更快。