'I can't record my voice after make a phone call

I have developed an Android app for recording audio when the phone called. I know, I can't record the audio of the caller person but I want to record my voice when I answered the phone or start a call with another person. I can do this on some devices but on some devices when my phone starts to ringing, the voice is recorded but after I answered the phone, I can't record any voice. Or my voice is recorded when I start to call to person but after the person answered me, recording voice is stopped!

I use the below code:

 private void startRecord(){
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);*/

        mRecorder.setOutputFile(savePath);
   }

BroadCastReceiver:

 private final PhoneStateListener phoneListener = new PhoneStateListener() {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
        //Toast.makeText(context,"phoneListener Start",Toast.LENGTH_LONG).show();
        try {
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING: {
                    startedCall = true;
                    //Toast.makeText(context,"CALL_STATE_RINGING",Toast.LENGTH_LONG).show();
                    if (incomingNumber != null) {
                        //incoming call
                        //Toast.makeText(context,"Go to start forground service->ringing",Toast.LENGTH_LONG).show();
                        startForegroundService(incomingNumber);
                    }
                    break;
                }
                case TelephonyManager.CALL_STATE_OFFHOOK: {
                    //Toast.makeText(context,"CALL_STATE_OFFHOOK",Toast.LENGTH_LONG).show();
                    startedCall = true; // Newly added code
                    if (incomingNumber != null) {

                        //Toast.makeText(context,"Go to start forground service->OffHook",Toast.LENGTH_LONG).show();
                        //outgoing call
                        startForegroundService(incomingNumber);
                    }
                    break;
                }
                case TelephonyManager.CALL_STATE_IDLE: {
                    //Toast.makeText(context,"CALL_STATE_IDLE",Toast.LENGTH_LONG).show();
                    if (startedCall) {
                        stopForegroundService();
                    }
                    break;
                }
                default: {
                }
            }
        } catch (Exception ex) {

        }
    }
};


Solution 1:[1]

You have to use the AccessibilityService in Android 10 and above.

MainActivity code:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       
        if (Build.VERSION.SDK_INT >= 29) {
            if (!isAccessibilityServiceEnabled()) {
                startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
            }
        }

    }
    private boolean isAccessibilityServiceEnabled() {
        int accessibilityEnabled = 0;
        final String service = getPackageName() + "/" + RecordingAccessibilityService.class.getCanonicalName();

        try {
            accessibilityEnabled = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException e) {

        }
        TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');

        if (accessibilityEnabled == 1) {
            String settingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);

            if (settingValue != null) {
                mStringColonSplitter.setString(settingValue);
                while (mStringColonSplitter.hasNext()) {
                    String accessibilityService = mStringColonSplitter.next();

                    if (accessibilityService.equalsIgnoreCase(service)) {
                        return true;
                    }
                }
            }
        }

        return false;

    }

AccessibilityService code:

public class RecordingAccessibilityService extends AccessibilityService {


    @Override
    protected void onServiceConnected() {
        instance = this;
        super.onServiceConnected();

      TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        PhoneStateListener phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {

                if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                    Toast.makeText(getApplicationContext(), "onServiceConnected", Toast.LENGTH_SHORT).show();
                    updateNotification();
                    startRecord();
                }

                if (state == TelephonyManager.CALL_STATE_IDLE) {
                    stopRecord();
                }
                super.onCallStateChanged(state, incomingNumber);
            }
        };

        if (mgr != null) {
            mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }
    }
}

Manifest Code:

 <service
            android:name=".RecordingAccessibilityService"
            android:exported="false"
            android:label="@string/accessibility_description"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>

            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>

accessibility service config code:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowContentChanged|typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_description"
    android:label="@string/app_name"
    android:notificationTimeout="100" />

also must use BroadcastReceiver:

public class CallBroadcastReceiver extends BroadcastReceiver
{
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
            String numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            // Log.d("CallRecorder", "CallBroadcastReceiver intent has EXTRA_PHONE_NUMBER: " + numberToCall);
        }

        PhoneListener phoneListener = new PhoneListener(context);
        TelephonyManager telephony = (TelephonyManager)
                context.getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

    }

}

documentation:

https://developer.android.com/reference/android/accessibilityservice/AccessibilityService

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shahin Sadeghi