Search code examples
androidxamarinlistenertelephonymanager

Getting phone state in Xamarin


I have following code:

public class StateListener : PhoneStateListener
    {
        StateListener phoneStateListener = new StateListener();
        TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
        telephonyManager.Listen(phoneStateListender, PhoneStateListenerFlags.CallState);

        public void onCallStateChanged(CallState state, String incomingNumber)
        {
            base.OnCallStateChanged(state, incomingNumber);
            switch (state)
            {
                case CallState.Ringing:
                    break;
                case CallState.Offhook:
                    break;
                case CallState.Idle:
                    break;
            }
        }
    }

This is an inner class because my base class is "MainActivity : Activity". The above code was from Java, so I tried to convert it to C#. However, I get erros in this case:

 (TelephonyManager)GetSystemService(Context.TelephonyService); 

throws an error that field initializers must be static and

 telephonyManager.Listen(phoneStateListender, PhoneStateListenerFlags.CallState);

is not available in this context. I don't even know if the code above would even work. How to achieve in Xamarin that I can get the state of an outgoing call?


Solution

  • You have to move the creation code into the OnCreate method of your Activity.

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
    
        StateListener phoneStateListener = new StateListener();
        TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
        telephonyManager.Listen(phoneStateListener, PhoneStateListenerFlags.CallState);
    }
    

    And then you can create the class:

    public class StateListener : PhoneStateListener
    {
        public override void OnCallStateChanged(CallState state, string incomingNumber)
        {
            base.OnCallStateChanged(state, incomingNumber);
            switch (state)
            {
                case CallState.Ringing:
                    break;
                case CallState.Offhook:
                    break;
                case CallState.Idle:
                    break;
            }
        }
    }
    

    If you want to do something on you activity after OnCallStateChanged you have to pass the activity (e.g. in the constructor):

    public class StateListener : PhoneStateListener
    {
        private readonly MainActivity _activity;
    
        public StateListener(MainActivity activity)
        {
            _activity = activity;
        }
    
        public override void OnCallStateChanged(CallState state, string incomingNumber)
        {
            base.OnCallStateChanged(state, incomingNumber);
            _activity.UpdateCallState(state, incomingNumber);
        }
    }
    
    public class MainActivity : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
    
            StateListener phoneStateListener = new StateListener(this);
            TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
            telephonyManager.Listen(phoneStateListener, PhoneStateListenerFlags.CallState);
        }
    
        public void UpdateCallState(CallState state, string incomingNumber)
        {
            // numberLabel.Text = ...
        }
    }