0

I'm very new to mobile development and to Xamarin.

I created a new Xamarin.Forms solution "AndroidApp1" which by default consists of two projects, "AndroidApp1.Android" and "AndroidApp1".

If I understood correctly what I read, the first one contains the code specific to Android and the second one contains the code that can be used in Android, iOS or Windows Phone.

My solution runs in an Android emulation in debug mode, now I'd like to be notified when there's an incoming call, I'd like to get the telephone number that is calling me.

Google told me, that I need to create a class that inherits from BroadcastReceiver and override the OnReceive function.

I assume that this class needs to reside in the Android specific project (AndroidApp1.Android), so I created the class here, but now what? I can't find any information about what to do with this class? Where do I instantiate it? How do I get the notification and the phone number to react on in my "AndroidApp1" project?

Here's the source code of my BroadcastReceiver (copied from the internet):

[BroadcastReceiver(Enabled = true, Exported = false)]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE" })]
public class IncomingCallReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // ensure there is information
        if (intent.Extras != null)
        {
            // get the incoming call state
            string state = intent.GetStringExtra(TelephonyManager.ExtraState);

            // check the current state
            if (state == TelephonyManager.ExtraStateRinging)
            {
                // read the incoming call telephone number...
                string telephone = intent.GetStringExtra(TelephonyManager.ExtraIncomingNumber);
                // check the reade telephone
                if (string.IsNullOrEmpty(telephone))
                    telephone = string.Empty;
            }
            else if (state == TelephonyManager.ExtraStateOffhook)
            {
                // incoming call answer
            }
            else if (state == TelephonyManager.ExtraStateIdle)
            {
                // incoming call end
            }
        }
    }
}
Nostromo
  • 1,177
  • 10
  • 28

3 Answers3

0

You need to register brodcast receiver for the call state.

  <action android:name="android.intent.action.PHONE_STATE" />
  <action android:name="android.intent.action.NEW_OUTGOING_CALL" />

and create a notification once your get broadcast events.

Make sure you have defined permission.

 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Ramesh Yankati
  • 1,197
  • 9
  • 13
  • Can you please explain a little bit in more detail? Where (in which file, in which project) do I do register tie broadcastreveiver? Where (in which file, in which project) do I ask for the permissions? What do I do with my `IncomingCallReceiver` class once it is registered? Where do I instantiate it? How do I get the information out of the `IncomingCallReceiver` class, that there is an incoming call? Do I implement events in it? – Nostromo Oct 12 '18 at 04:55
  • You need to register the receiver in Android Manifest file. Something like this – Ramesh Yankati Oct 12 '18 at 07:36
0

You need to have a Broadcast Receiver something like this.

        /**
         * Listener to detect incoming calls. 
         */
        private class CallStateListener extends PhoneStateListener {
           @Override
           public void onCallStateChanged(int state, String incomingNumber) {
             switch (state) {
               case TelephonyManager.CALL_STATE_RINGING:
               // called when someone is ringing to this phone

             Toast.makeText(ctx, "Incoming: "+incomingNumber, 
               Toast.LENGTH_LONG).show();
               break;

           }
         }


      You can register the lister for incoming call events.
      tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
      tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

     Here is the more info 
     https://stackoverflow.com/questions/9684866/how-to-detect-when-phone-is-answered-or-rejected
Ramesh Yankati
  • 1,197
  • 9
  • 13
0

Finally I am one step forward. I created a class StateListener that inherits from PhoneStateListener in the Android specific project like this:

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;
        }
    }
}

Then I instantiated this class in the OnCreate function of the MainActivity class of the Android specific project with these three lines of code:

StateListener phoneStateListener = new StateListener();
TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(Context.TelephonyService);
telephonyManager.Listen(phoneStateListener, PhoneStateListenerFlags.CallState);

Now when I set break points in the case parts of the switch (state) in OnCallStateChanged they break, but the incomingNumber is always empty, although I've set the corresponding rights in the manifest.

So, that will be my next step, to get the calling number.

Nostromo
  • 1,177
  • 10
  • 28