823
823

Reputation: 73

How to Record phone call in Android

I need to record a phone call in my android application. I have tried with MediaRecorder with the AudioSource set to MIC, VOICE_COMMUNICATION, VOICE_CALL and other options. But none of them record the call. Can anyone please suggest any solution for record a phone call in android.

following is the code that I have tried. But it does not record the call. only record the voice before and after the call. Please suggest Any Solution.

Code to start recording

public void startRecording(){
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, RECORD_AUDIO);

            } else {
                setReorder();
            }
        }

 public void setReorder(){
        audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.MODE_IN_CALL);
        audioManager.setSpeakerphoneOn(true);
        recorder = new MediaRecorder();
//        recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(output_formats[currentFormat]);
//        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(getFilename());
        recorder.setOnErrorListener(errorListener);
        recorder.setOnInfoListener(infoListener);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            // Do the file write
            prepareAndStart();
        } else {
            // Request permission from the user
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE);
        }
    }

public void prepareAndStart() {
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);

            } else {
                startRec();
            }


    }

    public void startRec(){
        try{
            recorder.prepare();
            recorder.start();

        } catch (IllegalStateException e) {
            Log.e("REDORDING :: ",e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            Log.e("REDORDING :: ",e.getMessage());
            e.printStackTrace();
        }
    }


//    @SuppressLint("MissingSuperCall")
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 0:
                // Re-attempt file write
                setReorder();
            case 1:
                prepareAndStart();
            case 2:
                startRec();
        }
    }

Code to get file name for output file

    private String getFilename() {
//        String filepath = Environment.getExternalStorageDirectory().getPath();
        String filepath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
        File file = new File(filepath, AUDIO_RECORDER_FOLDER);
        Log.d("FILEPATH", filepath);

        if (!file.exists()) {
            file.mkdirs();
            Log.d( "!file.exists","created file");

        }
        Log.d("BEFORE RETURN", "created file EXISTS");
        Log.d("BEFORE RETURN", file.getAbsolutePath());
        return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
//        return (file.getAbsolutePath());

    }

Code to stop recording

    public void stopRecording(){
        audioManager.setSpeakerphoneOn(false);

        try{
            if (null != recorder) {
                recorder.stop();
                Log.d("REDORDING STOP :: ", "recorder.stop();");
                recorder.reset();
                Log.d("REDORDING STOP :: ", "recorder.reset();");
                recorder.release();
                Log.d("REDORDING STOP :: ", "recorder.release();");

                recorder = null;
            }
        }catch(RuntimeException stopException){
            Log.e("REDORDING STOP :: ", "RuntimeException stopException");
            Log.e("REDORDING STOP :: ",stopException.getMessage());
            stopException.printStackTrace();
        }
    }

Upvotes: 2

Views: 6552

Answers (2)

Farrukh Tulkunov
Farrukh Tulkunov

Reputation: 972

When the phone call starts Mic access is moved to the priority app which is the voice call itself and its handling app. Your app will no longer have access to the mic if it's an ordinary app. However if your app has an Accessibility service you can share the microphone

https://developer.android.com/guide/topics/media/sharing-audio-input

As far as I know, VOICE_COMMUNICATION is also just a mic with some filter on top, so the same mic sharing should work in this case

Lastly VOICE_CALL Now things get interesting here. This source requires Manifest.permission.CAPTURE_AUDIO_OUTPUT permission. If your app doesn't have it will crash. The problem is this permission is not provided to third-party app in any way. The accessibility trick will not help you here.

Now if you just want a recording accessiblity+mic works most of the time and depending on the situation your recording will turn out either fine or unlistenable. If you don't want rooted phone or custom ROM etc. this is the only way you can record a call.

If you can root or custom ROM your device then you can look into installing your app as system application in order to get the permissions you need.

Upvotes: 4

Lev M.
Lev M.

Reputation: 6269

Unfortunately, it is not possible on most unrooted Android phones to record phone calls using a regular app.

You would need to either:

A) Sign your app with the OEM certificate to get escalated privileges

B) Root the phone

C) Find a security exploit

I think there are some rare models that have a different configuration of audio pathing that can allow this, but there are very few of them.

Upvotes: 2

Related Questions