Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is voice call recording back with android 10 (2019)?

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

like image 990
asasamar Avatar asked Sep 06 '19 12:09

asasamar


1 Answers

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.

like image 198
Neha Sharma Avatar answered Sep 20 '22 07:09

Neha Sharma