i know this question is asked many times here , but still I want to confirm that is there any way to get event when outgoing call get picked by user ? As i have to restrict my custom dialer to pass another number to native dialer until the previous call is not answered. Same as in TrueCaller App .
I have found some links and tried them but they are not working in a way i expect.In some devices my code is working fine as i think it's device specific issue.
Here are some links :-
What is the PhoneStateListener state when outgoing call is answered?
How to detect that the call which is done from our android device is answered or rejceted?
Please let me know your suggestion over this .
Here is my Service class code :-
import android.annotation.SuppressLint; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.PixelFormat; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.MediaRecorder; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.provider.CallLog; import android.telephony.TelephonyManager; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.Toast; import java.lang.reflect.Method; import java.util.Date; import static android.provider.ContactsContract.CommonDataKinds.Website.URL; public class PhoneStateService extends Service { private static WindowManager wm; public static View popupView; private static WindowManager.LayoutParams params1; private static int lastState = TelephonyManager.CALL_STATE_IDLE; private static Date callStartTime; public static boolean isIncoming, showPopup, callNotReceived; private static String savedNumber; public static Runnable runnable; public static Handler handler; BroadcastReceiver callExplicitReceiver; @Override public void onCreate() { final IntentFilter intentFilter = new IntentFilter(); intentFilter.setPriority(2147483647); intentFilter.addAction("android.intent.action.PHONE_STATE"); this.callExplicitReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER"); } else { String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); String number = intent.getExtras().getString(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, number); } } } }; registerReceiver(callExplicitReceiver, intentFilter); } public static void onIncomingCallReceived(Context ctx, String number, Date start) { } public static void onIncomingCallAnswered(Context ctx, String number, Date start) { } public static void onIncomingCallEnded(Context ctx, String number, Date start, Date end) { } public static void onOutgoingCallStarted(Context ctx, String number, Date start) { callNotReceived = true; } public static boolean checkDuration(Context context) { @SuppressLint("MissingPermission") Cursor mCallCursor = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, null, null, null, null); int duration = mCallCursor.getColumnIndex( CallLog.Calls.DURATION); while (mCallCursor.moveToFirst()) { Toast.makeText(context, mCallCursor.getString(duration), Toast.LENGTH_LONG).show(); } return false; } public static void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) { callNotReceived = false; } public static void onMissedCall(Context ctx, String number, Date start) { } public void onCallStateChanged(Context context, int state, String number) { if (lastState == state) { return; } switch (state) { case TelephonyManager.CALL_STATE_RINGING: isIncoming = true; callStartTime = new Date(); savedNumber = number; onIncomingCallReceived(context, number, callStartTime); showPopup(context); break; case TelephonyManager.CALL_STATE_OFFHOOK: showPopup(context); if (lastState != TelephonyManager.CALL_STATE_RINGING) { isIncoming = false; callStartTime = new Date(); onOutgoingCallStarted(context, savedNumber, callStartTime); } else { isIncoming = true; callStartTime = new Date(); onIncomingCallAnswered(context, savedNumber, callStartTime); } checkDuration(context); break; case TelephonyManager.CALL_STATE_IDLE: handler.removeCallbacks(runnable); if (lastState == TelephonyManager.CALL_STATE_RINGING) { onMissedCall(context, savedNumber, callStartTime); } else if (isIncoming) { onIncomingCallEnded(context, savedNumber, callStartTime, new Date()); } else { onOutgoingCallEnded(context, savedNumber, callStartTime, new Date()); } break; } lastState = state; } @Override public void onDestroy() { unregisterReceiver(callExplicitReceiver); } @Override public IBinder onBind(Intent intent) { return null; } private void showPopup(Context applicationContext) { wm = (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE); params1 = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); params1.height = WindowManager.LayoutParams.WRAP_CONTENT; params1.width = WindowManager.LayoutParams.MATCH_PARENT; params1.x = 0; params1.y = 0; params1.gravity = Gravity.TOP; params1.format = PixelFormat.TRANSLUCENT; LayoutInflater layoutInflater = (LayoutInflater) applicationContext .getSystemService(applicationContext.LAYOUT_INFLATER_SERVICE); popupView = layoutInflater.inflate(R.layout.activity_dialog, null); int[] attrs = new int[]{R.attr.selectableItemBackground}; TypedArray typedArray = applicationContext.obtainStyledAttributes(attrs); int backgroundResource = typedArray.getResourceId(0, 0); popupView.setBackgroundResource(backgroundResource); wm.addView(popupView, params1); if (showPopup) { popupView.setVisibility(View.VISIBLE); } else { popupView.setVisibility(View.GONE); } popupView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { popupView.setVisibility(View.GONE); Intent i = new Intent(applicationContext, DiallerViewActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); i.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); applicationContext.startActivity(i); } }); } }