17

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...

  1. What does this new behavior for android 10 really mean. What is the relevance here for an accessibility service? Which I tried and already failed?
  2. Have I done anything wrong during configuring the accessibility service?
  3. If this approach does not solve call recording issue is android 10 also missing with the call recording feature? Or is there any other way of doing it in android 10. Because I'm only interested in call recording in android 10.

In a nutshell I just want to know whether voice call recording is back with android 10...

asasamar
  • 263
  • 1
  • 2
  • 9
  • 2
    For apps in Play Store Google restricts usage of accessibility service. Only those apps are allowed that are designed to help disabled people. Call recording is most likely out of scope. Therefore such an app would had be installed via side-loading. – Robert Sep 06 '19 at 12:34
  • I have android 9 PKQ1 (Xiaomi Mi 9T) and there is Call recording option in Call settings. Records everything/custom/unknown numbers. – okkko Sep 06 '19 at 12:40
  • @Robert, Yes, then what does this statement really means. "The call always receives audio. The app can capture audio if it is an accessibility service." As you know, android completely blocked call recording from Android 9. So just wanted to clarify this new behaviour. – asasamar Sep 09 '19 at 07:21
  • @okkko, yes it might be possible using system apps. But wanted to know how it can be achieved using a non system app. – asasamar Sep 09 '19 at 07:22
  • 1
    Its possible to record calls in android 10 with accessibility service. Cube call recorder is doing it. Have you tried enabling your service in Accessibility service? That step is missing in your post. – Srihari Karanth Oct 23 '19 at 07:53
  • @asasamar did you find any solution to this? – Abhinav Suthar Nov 26 '19 at 22:23
  • @okkko how is this possible using a system app? You can't record calls using a system app on Pixel Android 10. – Jay Dec 27 '19 at 21:40
  • @ApexFred I guess it depends on the system flavor/brand. – okkko Dec 29 '19 at 09:36
  • I've resorted to using CUBE ACR and it seems to be working right now, the team is keeping up to date with Android changes. – Jay Dec 29 '19 at 19:55
  • I attempted something similar, with no luck. https://stackoverflow.com/questions/59761791/can-a-third-party-accessibility-service-capture-audio-on-android-10 – Miguel Rochefort Jan 16 '20 at 02:36

1 Answers1

4

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.

Neha Sharma
  • 449
  • 5
  • 13