Search code examples
androidbroadcastreceiver

Detect Phone State OnCreate


I'm making an app that need to detect phone call onCreate. If a phone call is received, my app has to hide in the background. I used PhoneStateListener. However, it only activates when there is a phone status change.

How can I detect phone status on onCreate function?


Solution

  • For incoming calls we need to use the TelephonyManager class and its method listen to register a listener that will receive call state, data connection, network, SIM, and other events related to telephony. We are interested only in the call state notifications. This requires android.permission.READ_PHONE_STATE permission.

    So, create our listener class derived from PhoneStateListener, and override the onCallStateChanged method, as follows:

    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.IBinder;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    
    public class PhoneState extends Service {
        private CallStateListener mCallStateListener = new CallStateListener();
        private TelephonyManager mTelephonyManager;
        private int mCallState;
    
        @Override
        public void onCreate() {
        super.onCreate();
        mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        mCallState = mTelephonyManager.getCallState();
        mTelephonyManager.listen(mCallStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }
    
        @Override
        public void onDestroy() {
            Log.d("onDestroy", "onDestroy");
        mTelephonyManager.listen(mCallStateListener, PhoneStateListener.LISTEN_NONE);
        super.onDestroy();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
        return null; //-- not a bound service--
        }
    
        private final class CallStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
    
            switch (mCallState) {
    
                case TelephonyManager.CALL_STATE_IDLE:
                    if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                        Log.d("state", "idle --> off hook = new outgoing call");
                        // idle --> off hook = new outgoing call
                        //triggerSenses(Sense.CallEvent.OUTGOING);
                    } else if (state == TelephonyManager.CALL_STATE_RINGING) {
                        Log.d("state", "idle --> ringing = new incoming call");
                        // idle --> ringing = new incoming call
                        //triggerSenses(Sense.CallEvent.INCOMING);
                    }
                    break;
    
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    if (state == TelephonyManager.CALL_STATE_IDLE) {
                        Log.d("state", "off hook --> idle  = disconnected");
                        // off hook --> idle  = disconnected
                        //triggerSenses(Sense.CallEvent.ENDED);
                    } else if (state == TelephonyManager.CALL_STATE_RINGING) {
                        Log.d("state", "off hook --> ringing = another call waiting");
                        // off hook --> ringing = another call waiting
                        //triggerSenses(Sense.CallEvent.WAITING);
                    }
                    Log.d("CALL_STATE_OFFHOOK", String.valueOf(state));
                    break;
    
                case TelephonyManager.CALL_STATE_RINGING:
                    if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                        Log.d("state", "ringing --> off hook = received");
                        // ringing --> off hook = received
                        //triggerSenses(Sense.CallEvent.RECEIVED);
                    } else if (state == TelephonyManager.CALL_STATE_IDLE) {
                        Log.d("state", "ringing --> idle = missed call");
                        // ringing --> idle = missed call
                        //triggerSenses(Sense.CallEvent.MISSED);
                    }
                    break;
            }
    
            mCallState = state;
        }
        }
    
        public static void init(Context c) {
            c.startService(new Intent(c, PhoneState.class));
        Log.d("Service enabled","Service enabled: " + true);
        }
    }
    

    In your main Activity you just start the Phonestate service as,

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    
    public class SpinnerSample extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        PhoneState.init(getBaseContext());
        }
    }
    

    When you uninstall the application it will automatically stopped your service. Other wise it will detect the phone call either the application is active nor inactive.