我对Xamarin和移动开发很新,但有C#的经验。 以下是我尝试从网上获取一些代码并将其调整为Xamarin。 拨打电话时,代码在例外时失败。 实际上,我无法在CallReceiver / PhonecallReceiver类中访问断点。 我正在运行VS2017社区,API23,手机。 我缺少什么?
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>
Output window:
08-01 15:53:29.279 D/Mono ( 2601): [0x9f7fd930] worker starting 08-01 15:53:29.308 D/Mono ( 2601): DllImport searching in: '__Internal' ('(null)'). 08-01 15:53:29.308 D/Mono ( 2601): Searching for 'java_interop_jnienv_call_void_method_a'. 08-01 15:53:29.308 D/Mono ( 2601): Probing 'java_interop_jnienv_call_void_method_a'. 08-01 15:53:29.308 D/Mono ( 2601): Found as 'java_interop_jnienv_call_void_method_a'. 08-01 15:53:29.316 E/AndroidRuntime( 2601): FATAL EXCEPTION: main 08-01 15:53:29.316 E/AndroidRuntime( 2601): Process: CallManipulation.CallManipulation, PID: 2601 08-01 15:53:29.316 E/AndroidRuntime( 2601): java.lang.RuntimeException: Unable to instantiate receiver CallManipulation.CallManipulation.CallReceiver: java.lang.ClassNotFoundException: Didn't find class "CallManipulation.CallManipulation.CallReceiver" on path: DexPathList[[zip file "/data/app/CallManipulation.CallManipulation-1/base.apk"],nativeLibraryDirectories=[/data/app/CallManipulation.CallManipulation-1/lib/arm, /data/app/CallManipulation.CallManipulation-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]] 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2706) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.app.ActivityThread.-wrap14(ActivityThread.java) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.os.Handler.dispatchMessage(Handler.java:102) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.os.Looper.loop(Looper.java:148) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.app.ActivityThread.main(ActivityThread.java:5417) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.reflect.Method.invoke(Native Method) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 08-01 15:53:29.316 E/AndroidRuntime( 2601): Caused by: java.lang.ClassNotFoundException: Didn't find class "CallManipulation.CallManipulation.CallReceiver" on path: DexPathList[[zip file "/data/app/CallManipulation.CallManipulation-1/base.apk"],nativeLibraryDirectories=[/data/app/CallManipulation.CallManipulation-1/lib/arm, /data/app/CallManipulation.CallManipulation-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]] 08-01 15:53:29.316 E/AndroidRuntime( 2601): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2701) 08-01 15:53:29.316 E/AndroidRuntime( 2601): ... 8 more 08-01 15:53:29.316 E/AndroidRuntime( 2601): Suppressed: java.lang.ClassNotFoundException: CallManipulation.CallManipulation.CallReceiver 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.Class.classForName(Native Method) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 08-01 15:53:29.316 E/AndroidRuntime( 2601): at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 08-01 15:53:29.316 E/AndroidRuntime( 2601): ... 10 more 08-01 15:53:29.316 E/AndroidRuntime( 2601): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available