How to detect an answered phone call?

I am trying to detect successfully an automatically answered phone call on my app. I can successfully detect the ringing call and answer it, but once answered the active state or offhook never shows up. I am answering this call using the telephony service from the shell as a root user. Right now I am using for this the PreciseCallState from android, but already tried with the TelephonyManager and TelecomManager

Class where I detect and answer the incoming call

@VoiceInTaskScope
public class VoiceInPhoneStateListenerSystem extends AbstractVoiceInPhoneStateListener {

    private static final String TAG = "VoicePhoneStateListenerSystem: ";

    private int mCallFinished = 0;
    private int mLastState = 0;

    private PhoneStateListenerManager mPhoneStateListenerManager;

    @Inject
    public VoiceInPhoneStateListenerSystem(@Named(TasksModule.TASKS_CONTEXT) Context context,
                                            TelephonyManager telephonyManager,
                                            PhoneStateListenerManager phoneStateListenerManager,
                                            @Named(VoiceInTaskModule.VOICE_IN_ACTION_CALL_INTENT) Intent actionCallIntent,
                                            TimerWrapper timerWrapper, Sound sound, Provider<CSFBThread> csfbThreadProvider) {
        super(context, telephonyManager, actionCallIntent, timerWrapper, sound, csfbThreadProvider);
        this.mPhoneStateListenerManager = phoneStateListenerManager;

    }

    @Override
    @CoverageIgnore
    public void startListener() {
        mPhoneStateListenerManager.listen(this, PhoneStateListener.LISTEN_PRECISE_CALL_STATE);
    }

    @Override
    @CoverageIgnore
    public void endListener() {
        mPhoneStateListenerManager.listen(this, PhoneStateListener.LISTEN_NONE);
    }

    /**
     * Obtains the precise state of the call
     * 
     * @param callState info of the state 
     */
    @Override
    public void onPreciseCallStateChanged(final PreciseCallState callState) {
        final int ringingCallState =callState.getRingingCallState();
        final int foregroundState = callState.getForegroundCallState();
        final int backgroundState = callState.getBackgroundCallState();
        final int disconnectCause = callState.getDisconnectCause() 

        if ( ringingCallState == PreciseCallState.PRECISE_CALL_STATE_INCOMING){
            Log.info(TAG +"answer");
            superSu();
        }

        if( foregroundState == PreciseCallState.PRECISE_CALL_STATE_ACTIVE){
            Log.info(TAG + "inside!!!");
            this.initTimer();
        }
}

Method to answer incoming call

public static void superSu() {
        try {

            Process proc = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(proc.getOutputStream());

            os.writeBytes("service call phone 5\n");
            Thread.currentThread().interrupt();
            os.flush();

            os.writeBytes("exit\n");
            os.flush();

            if (proc.waitFor() == 255) {
                // TODO handle being declined root access
                // 255 is the standard code for being declined root for SU
            }
        } catch (IOException e) {
            // TODO handle I/O going wrong
            // this probably means that the device isn't rooted
        } catch (InterruptedException e) {
            // don't swallow interruptions
            Thread.currentThread().interrupt();
        }
    }

Upvotes: 1

Views: 334

Answers (1)

Doneeee!!! All I had to do was close the current thread on my superSu() method , just like this

 public static void superSu() {
        try {

            Process proc = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(proc.getOutputStream());

            os.writeBytes("service call phone 5\n");
            os.flush();

            os.writeBytes("exit\n");
            os.flush();

            Thread.currentThread().interrupt();//close current thread 

            if (proc.waitFor() == 255) {
                // TODO handle being declined root access
                // 255 is the standard code for being declined root for SU
            }
        } catch (IOException e) {
            // TODO handle I/O going wrong
            // this probably means that the device isn't rooted
        } catch (InterruptedException e) {
            // don't swallow interruptions
            Thread.currentThread().interrupt();
        }
    }

Upvotes: 1

Related Questions