I want to find out if an outgoing call has been answered. Unfortunately, in the case of an outgoing call I see
Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } extras:Bundle{ state => OFFHOOK; }Bundle
Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } extras:Bundle{ state => IDLE; }Bundle
regardless of whether or not the call was answered.
How do I detect that an outgoing call is answered? (For both rooted and unrooted devices, please.)
In Android you can't distinguish between answered and unanswered outgoing calls using intent(but available on ios).
My workaround: Check phone app log (see CallLog.Calls
), if outgoing calls has time log is greater than 0, then it was answered.
public static final int TIME_TO_WAIT_PHONE_LOG_UPDATE_MILISECOND = 2000;
public static final int PHONE_CALL_SUCCESS = 0x00; // answered
public static final int PHONE_CALL_FAILED = 0x01; // unanswered
//
private class PhoneCallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// Calling not picked up
// Đang gọi chưa nhấc máy
Log.i(DEBUG_TAG, "OFFHOOK, num = " + incomingNumber);
isCalling = true;
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
if (isCalling) {
// close
// Kết Thúc
Log.v(DEBUG_TAG, "CALL_STATE_IDLE, num = " + incomingNumber);
isCalling = false;
// Read the log to see if the other party can hear the machine or not
// Đọc log xem thử bên kia có nghe máy hay không
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
int result = getCallDetails();
if (mOnCallFinishListener != null) {
mOnCallFinishListener.onCallFinish(supporter, result);
}
}
}, MikeMikeConfig.TIME_TO_WAIT_PHONE_LOG_UPDATE_MILISECOND);
}
}
}
}
private int getCallDetails() {
int ret = 0;
StringBuffer sb = new StringBuffer();
Cursor managedCursor = activity.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, /*null*/ CallLog.Calls.DEFAULT_SORT_ORDER);
// on some phones (e.g. LG) null does not mean DEFAULT_SORT_ORDER which is "date DESC"
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Log :");
//while (managedCursor.moveToNext()) {
managedCursor.moveToNext();
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = managedCursor.getString(duration);
String dir = null; int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration); sb.append("\n----------------------------------");
//} //managedCursor.close(); textView.setText(sb); }
//Log.v(DEBUG_TAG, sb + "");
int call_duration = Integer.parseInt(callDuration);
Log.v(DEBUG_TAG, "duration = " + call_duration);
if (call_duration > 0) ret = MikeMikeConfig.PHONE_CALL_SUCCESS;
if (call_duration == 0) ret = MikeMikeConfig.PHONE_CALL_FAILED;
return ret;
}