How to record phone calls in Android

I am developing an application that can record calls in Android. I read a lot of topics where the problem of recording calls was discussed. And I know that not all Android phones can record calls. But I'm wondering how to record calls to the most popular apps on the Play Market, such as https://play.google.com/store/apps/details?id=com.appstar.callrecorder or https://play.google.com/ store / apps / details? id = polis.app.callrecorder . I think that you are not using the MediaRecorder class to do this work, but something else. Because I developed my own application, but I can only record my voice. But these two applications record my voice and the voice of the person I'm calling. How do they do it? I know that we cannot access the speaker of a device to record sound from it. Could you give me some ideas on how to record voice calls? Here is my code that I use in my application:

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); } } 
+5
source share
2 answers

I think they are using MediaRecorder. Perhaps the main problem is that it is difficult to write data from it to something other than a file in local storage. To work with it, you can create a channel. Then use its file descriptor as input fd for MediaRecorder. Then the pipe output can be controlled by some stream that will read audio packets (in one format, aac or .. wav even), and then do whatever you want with the data.

Here is the code. Note that this proto may not even compile, just to give you an idea.

  /* 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(); } 
+1
source

As answered here. In accordance with this decision, you can record sound like i.e. Yours and the person you are talking to. I tried this code and it works great and works great

How to record phone calls in Android?

0
source

All Articles