Here is the code
public class MainActivity extends AppCompatActivity {
ToggleButton toggleButton;
TextView textSubHeader;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
textSubHeader = (TextView) findViewById(R.id.textSubHeader);
// File CallRecorder = new File("/sdcard/CallRecorder");
// CallRecorder.mkdirs();
}
@Override
protected void onResume() {
super.onResume();
// Runtime permission
try {
boolean permissionGranted_OutgoingCalls = ActivityCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_GRANTED;
boolean permissionGranted_phoneState = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
boolean permissionGranted_recordAudio = ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
boolean permissionGranted_WriteExternal = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
boolean permissionGranted_ReadExternal = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
if (permissionGranted_OutgoingCalls) {
if (permissionGranted_phoneState) {
if (permissionGranted_recordAudio) {
if (permissionGranted_WriteExternal) {
if (permissionGranted_ReadExternal) {
try {
toggleButton.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 200);
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 300);
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 400);
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 500);
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.PROCESS_OUTGOING_CALLS}, 600);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressLint("ResourceAsColor")
public void toggleButtonClick(View view) {
try {
boolean checked = ((ToggleButton) view).isChecked();
if (checked) {
Intent intent = new Intent(this, CallRecorder.class);
startService(intent);
Toast.makeText(getApplicationContext(), "Call Recording is set ON", Toast.LENGTH_SHORT).show();
textSubHeader.setText("Switch on Toggle to record your calls");
} else {
Intent intent = new Intent(this, CallRecorder.class);
stopService(intent);
Toast.makeText(getApplicationContext(), "Call Recording is set OFF", Toast.LENGTH_SHORT).show();
textSubHeader.setText("Switch Off Toggle to stop recording your calls");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 200 || requestCode == 300 || requestCode == 400 || requestCode == 500 || requestCode == 600) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
toggleButton.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class CallRecorder extends Service {
private MediaRecorder recorder;
private boolean recordStarted = false;
private String savedNumber;
public static final String ACTION_IN = "android.intent.action.PHONE_STATE";
public static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
private int lastState = TelephonyManager.CALL_STATE_IDLE;
private boolean isIncoming;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.registerReceiver(new CallReceiver(), filter);
return super.onStartCommand(intent, flags, startId);
}
private void stopRecording() {
if (recordStarted) {
recorder.stop();
recordStarted = false;
}
}
public abstract class PhoneCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_OUT)) {
savedNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER);
} else {
String stateStr = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
savedNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, savedNumber);
}
}
protected abstract void onIncomingCallReceived(Context ctx, String number);
protected abstract void onIncomingCallAnswered(Context ctx, String number);
protected abstract void onIncomingCallEnded(Context ctx, String number);
protected abstract void onOutgoingCallStarted(Context ctx, String number);
protected abstract void onOutgoingCallEnded(Context ctx, String number);
protected abstract void onMissedCall(Context ctx, String number);
public void onCallStateChanged(Context context, int state, String number) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
String time = dateFormat.format(new Date()) ;
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/indcallrecorder");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
if (lastState == state) {
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
savedNumber = number;
onIncomingCallReceived(context, number );
recorder = new MediaRecorder();
// recorder.setAudioSamplingRate(8000);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(sampleDir.getAbsolutePath() + "/" + "Incoming \n" + number + " \n" + time + " \n" + " Call.amr");
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordStarted = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
recorder = new MediaRecorder();
recorder.setAudioSamplingRate(8000);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(sampleDir.getAbsolutePath() + "/" + "Outgoing \n" + savedNumber + " \n" + time + " \n" + " Call.amr");
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordStarted = true;
onOutgoingCallStarted(context, savedNumber );
} else {
isIncoming = true;
onIncomingCallAnswered(context, savedNumber);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
onMissedCall(context, savedNumber);
} else if (isIncoming) {
stopRecording();
onIncomingCallEnded(context, savedNumber);
} else {
stopRecording();
onOutgoingCallEnded(context, savedNumber);
}
break;
}
lastState = state;
}
}
public class CallReceiver extends PhoneCallReceiver {
@Override
protected void onIncomingCallReceived(Context ctx, String number) {
}
@Override
protected void onIncomingCallAnswered(Context ctx, String number) {
}
@Override
protected void onIncomingCallEnded(Context ctx, String number) {
}
@Override
protected void onOutgoingCallStarted(Context ctx, String number) {
}
@Override
protected void onOutgoingCallEnded(Context ctx, String number) {
}
@Override
protected void onMissedCall(Context ctx, String number) {
}
}
}
I am implementing call recording option in my Android application and all the calls are recoding fine below Android version 10 but from Android version 10 to above versions calls are recorded and when I try to play the recorded calls its silent. I am not able to listen the recorded voice.
What can I try to resolve this?