I'm really interested in call recording in android. But as you already know android officially shuts off voice call recording in android 9. But just after the release of Android 10(sept 3 2019), while going through their new release notes, I came across the following page which looked promising, in terms of call recording. https://developer.android.com/guide/topics/media/sharing-audio-input. Here regarding voice call recording following things can be seen.
Voice call + ordinary app
A voice call is active if the audio mode returned by AudioManager.getMode() is MODE_IN_CALL or MODE_IN_COMMUNICATION.
Android shares the input audio according to these rules:
The call always receives audio. The app can capture audio if it is an accessibility service. The app can capture the voice call if it is a privileged (pre-installed) app with permission CAPTURE_AUDIO_OUTPUT.
To capture the voice call's uplink (TX), downlink (RX), or both, the app must specify the audio sources MediaRecorder.AudioSource.VOICE_UPLINK or MediaRecorder.AudioSource.VOICE_DOWNLINK, and/or the device AudioDeviceInfo.TYPE_TELEPHONY.
So after reading this I tried to capture audio inside an accessibility service. Here's my code. Accessibility service
public class MyAccessibilityService extends AccessibilityService {
FrameLayout mLayout;
public MyAccessibilityService() {
}
@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
}
@Override
public void onInterrupt() {
}
@Override
protected void onServiceConnected() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
mLayout = new FrameLayout(this);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
lp.format = PixelFormat.TRANSLUCENT;
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.TOP;
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.action_bar, mLayout);
wm.addView(mLayout, lp);
configureStartRecording();
configureStopRecording();
}
private void configureStartRecording() {
Button startRecordingButton = mLayout.findViewById(R.id.btnStartRecording);
startRecordingButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomMediaRecorder recorder = CustomMediaRecorder.getInstance();
File audiofile = null;
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(getExternalFilesDir(null), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
recorder.getRecorder().setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.getRecorder().setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.getRecorder().setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.getRecorder().setOutputFile(audiofile.getAbsolutePath());
try {
recorder.getRecorder().prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start(getApplicationContext());
Log.i(MainActivity.LOG_PREFIX, String.format("Recording started. Saving to path: '%s'", audiofile.getAbsolutePath()));
}
});
}
private void configureStopRecording() {
Button button = mLayout.findViewById(R.id.btnStopRecording);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomMediaRecorder recorder = CustomMediaRecorder.getInstance();
recorder.stop();
}
});
}
And The accessibility service config has the following configs
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"
So here are my observations.
1. Still we cannot set MediaRecorder.AudioSource.VOICE_DOWNLINK and VOICE_UPLINK audio sources. It fires an exception.
2. When MediaRecorder.AudioSource.VOICE_COMMUNICATION and MediaRecorder.AudioSource.MIC is given mic input prior to starting the call and after disconnecting the call is recorded.
So it looks like we are not getting any stream from the call even from an accessibility service. I tried this on a pixel 3A xl device which is newly updated to android 10.
So after reading this, and after my failed trial I have following questions...
In a nutshell I just want to know whether voice call recording is back with android 10...
First of all thanks for your code. I tried with the same code and I have used MediaRecorder.AudioSource.VOICE_RECOGNITION
and I am getting both side call recording in Samsung S10, Oneplus 7 and Real Me.