Reputation: 73
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
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
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