Hi,
I'm very new to Xamarin and mobile development, but have an experience with C#.
Following is my attempt to take some code from the web and adjusting it to Xamarin.
The code fails on exception, while placing a call.
I, actually, can't reach breakpoints in my CallReceiver / PhonecallReceiver classes.
I'm running VS2017 community, API23, arm phone.
What I'm missing?
What I have tried:
MainActivity:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Telephony;
using Java.Lang;
using String = System.String;
using System.Collections.Generic;
using Java.Util;
using Javax.Security.Auth;
namespace CallManipulation
{
public abstract class PhonecallReceiver : BroadcastReceiver
{
private static CallState lastState = CallState.Idle;
private static DateTime callStartTime;
private static bool isIncoming;
private static String savedNumber;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals("android.intent.action.NEW_OUTGOING_CALL"))
{
savedNumber = intent.Extras.GetString("android.intent.extra.PHONE_NUMBER");
}
else
{
String stateStr = intent.Extras.GetString(TelephonyManager.ExtraState);
String number = intent.Extras.GetString(TelephonyManager.ExtraIncomingNumber);
CallState state = CallState.Idle;
if (stateStr.Equals(TelephonyManager.ExtraStateIdle))
{
state = CallState.Idle;
}
else if (stateStr.Equals(TelephonyManager.ExtraStateOffhook))
{
state = CallState.Offhook;
}
else if (stateStr.Equals(TelephonyManager.ExtraStateRinging))
{
state = CallState.Ringing;
}
OnCallStateChanged(context, state, number);
}
}
protected virtual void onIncomingCallStarted(Context ctx, String number, DateTime start) { }
protected virtual void onOutgoingCallStarted(Context ctx, String number, DateTime start) { }
protected virtual void onIncomingCallEnded(Context ctx, String number, DateTime start, DateTime end) { }
protected virtual void onOutgoingCallEnded(Context ctx, String number, DateTime start, DateTime end) { }
protected virtual void onMissedCall(Context ctx, String number, DateTime start) { }
public void OnCallStateChanged(Context context, CallState state, string number)
{
if (lastState == state)
return;
switch (state)
{
case CallState.Ringing:
isIncoming = true;
callStartTime = new DateTime().Date;
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case CallState.Offhook:
if (lastState != CallState.Ringing)
{
isIncoming = false;
callStartTime = new DateTime().Date;
onOutgoingCallStarted(context, savedNumber, callStartTime);
}
break;
case CallState.Idle:
if (lastState == CallState.Ringing)
onMissedCall(context, savedNumber, callStartTime);
else if (isIncoming)
onIncomingCallEnded(context, savedNumber, callStartTime, new DateTime().Date);
else
onOutgoingCallEnded(context, savedNumber, callStartTime, new DateTime().Date);
break;
}
lastState = state;
}
}
public class CallReceiver : PhonecallReceiver
{
protected override void onIncomingCallStarted(Context ctx, string number, DateTime start)
{
}
protected override void onOutgoingCallStarted(Context ctx, string number, DateTime start)
{
}
protected override void onIncomingCallEnded(Context ctx, string number, DateTime start, DateTime end)
{
}
protected override void onOutgoingCallEnded(Context ctx, string number, DateTime start, DateTime end)
{
}
protected override void onMissedCall(Context ctx, string number, DateTime start)
{
}
}
[Activity(Label = "CallManipulation", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="CallManipulation.CallManipulation" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application android:label="CallManipulation">
<!--This part is inside the application-->
<receiver android:name=".CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
</manifest>