eC Droid
eC Droid

Reputation: 681

Android how to detect if outgoing call is answered

I'm developing an app that will only be used in house for testing purpose. I have searched a lot and tried different suggestions as suggested in different post but none seems to be working for me.

I'm open to any suggestions like Reflections, Accessibility Service, root or any other hack. Please help.

Regards

Upvotes: 1

Views: 3591

Answers (3)

kaustav07
kaustav07

Reputation: 314

You can use accessibility events to detect the call duration and from that you can detect if the outgoing call is answered or not..

I have answered it in detail in Here` you can check that.

Upvotes: 1

Dheeraj Kumar
Dheeraj Kumar

Reputation: 103

TRY THIS

Set all required permission in manifest.xml file.

Call this class in Service

public class PhoneListener extends PhoneStateListener {

private static PhoneListener instance = null;

/**
 * Must be called once on app startup
 *
 * @param context - application context
 * @return
 */
public static PhoneListener getInstance(Context context) {
    if (instance == null) {
        instance = new PhoneListener(context);
    }
    return instance;
}

public static boolean hasInstance() {
    return null != instance;
}

private final Context context;
private CallLog phoneCall;

private PhoneListener(Context context) {
    this.context = context;
}

AtomicBoolean isRecording = new AtomicBoolean();
AtomicBoolean isWhitelisted = new AtomicBoolean();


/**
 * Set the outgoing phone number
 * <p/>
 * Called by {@link MyCallReceiver}  since that is where the phone number is available in a outgoing call
 *
 * @param phoneNumber
 */
public void setOutgoing(String phoneNumber) {
    if (null == phoneCall)
        phoneCall = new CallLog();
    phoneCall.setPhoneNumber(phoneNumber);
    phoneCall.setOutgoing();
    // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
    isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
}

@Override
public void onCallStateChanged(int state, String incomingNumber) {
    super.onCallStateChanged(state, incomingNumber);

    switch (state) {
        case TelephonyManager.CALL_STATE_IDLE: // Idle... no call
            if (isRecording.get()) {
                RecordCallService.stopRecording(context);
                phoneCall = null;
                isRecording.set(false);
            }
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK: // Call answered
            if (isWhitelisted.get()) {
                isWhitelisted.set(false);
                return;
            }
            if (!isRecording.get()) {
                isRecording.set(true);
                // start: Probably not ever usefull
                if (null == phoneCall)
                    phoneCall = new CallLog();
                if (!incomingNumber.isEmpty()) {
                    phoneCall.setPhoneNumber(incomingNumber);
                }
                // end: Probably not ever usefull
                RecordCallService.sartRecording(context, phoneCall);
            }
            break;
        case TelephonyManager.CALL_STATE_RINGING: // Phone ringing
            // DO NOT try RECORDING here! Leads to VERY poor quality recordings
            // I think something is not fully settled with the Incoming phone call when we get CALL_STATE_RINGING
            // a "SystemClock.sleep(1000);" in the code will allow the incoming call to stabilize and produce a good recording...(as proof of above)
            if (null == phoneCall)
                phoneCall = new CallLog();
            if (!incomingNumber.isEmpty()) {
                phoneCall.setPhoneNumber(incomingNumber);
                // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
                isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
            }
            break;
    }

}

}

And use Broadcast Receiver

public class MyCallReceiver extends BroadcastReceiver {

public MyCallReceiver() {
}

static TelephonyManager manager;

@Override
public void onReceive(Context context, Intent intent) {
    Log.i("JLCreativeCallRecorder", "MyCallReceiver.onReceive ");

    if (!AppPreferences.getInstance(context).isRecordingEnabled()) {
        removeListener();
        return;
    }

    if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
        if (!AppPreferences.getInstance(context).isRecordingOutgoingEnabled()) {
            removeListener();
            return;
        }
        PhoneListener.getInstance(context).setOutgoing(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
    } else {
        if (!AppPreferences.getInstance(context).isRecordingIncomingEnabled()) {
            removeListener();
            return;
        }
    }

    // Start Listening to the call....
    if (null == manager) {
        manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    }
    if (null != manager)
        manager.listen(PhoneListener.getInstance(context), PhoneStateListener.LISTEN_CALL_STATE);
}

private void removeListener() {
    if (null != manager) {
        if (PhoneListener.hasInstance())
            manager.listen(PhoneListener.getInstance(null), PhoneStateListener.LISTEN_NONE);
    }
}

}

I hope you get some help from this code.

Thanks

Upvotes: 0

Sadiq Md Asif
Sadiq Md Asif

Reputation: 902

You need this permission in manifest

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

TelephonyManager has a listener to get phone state. implement this tho know if the phone is ringing or in a call.

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        PhoneStateListener callStateListener = new PhoneStateListener() {

            public void onCallStateChanged(int state, String incomingNumber) {
                // TODO React to a incoming call.

                try {
                    if (state == TelephonyManager.CALL_STATE_RINGING) {
                        Toast.makeText(getApplicationContext(), "Phone Is Ringing" + incomingNumber, Toast.LENGTH_LONG).show();
                        number = incomingNumber;
                        //g.setPhoneNo(incomingNumber);
                        AndroidNetCommunicationClientActivity.mMsgSendRequest("CommandMsgCallIncoming" + number);
                    } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                        Toast.makeText(getApplicationContext(), "Phone is Currently in A call" + incomingNumber, Toast.LENGTH_LONG).show();
                        //number = mIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                        number = incomingNumber;


                    } else if (state == TelephonyManager.DATA_DISCONNECTED) {
                        number = "";
                        CallID = "";
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    //conn.MessageBox(MainActivity.this, e.getMessage());
                    e.printStackTrace();
                }
                super.onCallStateChanged(state, incomingNumber);

            }
        };
        telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

Upvotes: -1

Related Questions