FusedLocation GoogleApi - 侦听器不得为空 (Xamarin.Android)

Posted

技术标签:

【中文标题】FusedLocation GoogleApi - 侦听器不得为空 (Xamarin.Android)【英文标题】:FusedLocation GoogleApi - Listener must not be null (Xamarin.Android) 【发布时间】:2016-12-19 09:28:56 【问题描述】:

我得到以下信息:

Java.Lang.NullPointerException:监听器不能为空。

似乎无法摆脱它。我已经用尽了所有可能的解决方案。

using System;
using android.App;
using Android.Gms.Location;
using Android.Gms.Common.Apis;
using Android.OS;
using Android.Gms.Maps.Model;
using Android.Widget;
using Android.Locations;
using Android.Gms.Common;

namespace Maps.Droid.LocationService 
    public class FusedLocation : GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener 
        private Activity activity;
        private GoogleApiClient mGoogleApiClient;
        private LocationRequest mLocationRequest;
        private Location currentLocation;
        private bool locationAvailable = false;

        public FusedLocation(Activity activity) 
            this.activity = activity;

            setGoogleApiClient();
            setLocationRequest();

            //var requestBuilder = new LocationSettingsRequest.Builder().AddLocationRequest(mLocationRequest);
            //requestBuilder.SetAlwaysShow(true);

            // Next check whether the current location settings are satisfied:
            //var result = LocationServices.SettingsApi.CheckLocationSettings(mGoogleApiClient, requestBuilder.Build());
        

        private void setGoogleApiClient() 
            if (mGoogleApiClient == null) 
                mGoogleApiClient = new GoogleApiClient.Builder(activity)
                    .AddConnectionCallbacks(this)
                    .AddOnConnectionFailedListener(this)
                    .AddApi(LocationServices.API)
                    .Build();
            
        

        private void setLocationRequest() 
            if (mLocationRequest == null) 
                mLocationRequest = new LocationRequest();
                mLocationRequest.SetInterval(LocationTracker.MIN_TIME_BW_UPDATES);
                mLocationRequest.SetFastestInterval(LocationTracker.MIN_TIME_BW_UPDATES / 2);
                mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
            
        

        public LatLng getLatLng() 
            return new LatLng(currentLocation.Latitude, currentLocation.Longitude);
        

        public double getLatitude() 
            return currentLocation == null ? 0.0 : currentLocation.Latitude;
        

        public double getLongitude() 
            return currentLocation == null ? 0.0 : currentLocation.Longitude;
        

        public void startLocationServices() 
            if (!mGoogleApiClient.IsConnected) 
                mGoogleApiClient.Connect();
                LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            
        

        public void pauseLocationServices() 
            // Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
            if (mGoogleApiClient.IsConnected) 
                LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this);
            
        

        public void stopLocationServices() 
            // only stop if it's connected, otherwise we crash
            if (mGoogleApiClient != null) 
                mGoogleApiClient.Disconnect();
            
        

        public bool canGetLocation() 
            return locationAvailable;
        

        public void OnConnected(Bundle connectionHint) 
            // Get last known recent location. If the user launches the activity,
            // moves to a new location, and then changes the device orientation, the original location
            // is displayed as the activity is re-created.
            if (currentLocation == null) 
                currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient);
            

            locationAvailable = true;

            // Begin polling for new location updates.
            startLocationUpdates();
        

        // Trigger new location updates at interval
        protected void startLocationUpdates() 
            setGoogleApiClient(); // The method checks if it has been already initialized
            setLocationRequest(); // The method checks if it has been already initialized

            // Request location updates
            LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        

        public void OnConnectionSuspended(int cause) 
            // GoogleApiClient will automatically attempt to restore the connection.
            // Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them

            if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) 
                Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show();
             else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) 
                Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show();
            
        
        public void OnLocationChanged(Location location) 
            currentLocation = location;
        

        public void OnConnectionFailed(ConnectionResult result) 
            if (mGoogleApiClient != null) 
                mGoogleApiClient.Connect();
            
        

        public IntPtr Handle 
            get;
        

        public void Dispose() 
        
    

看来问题出在方法setGoogleApiClient();

检查这张图片:

发现错误后点击继续:

08-12 16:09:14.446 D/OpenGLRenderer(13084): Enabling debug mode 0
08-12 16:09:15.176 D/Mono    (13084): Assembly Ref addref Maps.Droid[0x64b8c7f8] -> Xamarin.GooglePlayServices.Maps[0x64bdfe50]: 2
08-12 16:09:15.176 D/Mono    (13084): Assembly Ref addref Maps.Droid[0x64b8c7f8] -> Xamarin.GooglePlayServices.Basement[0x64bde280]: 2
08-12 16:09:15.176 D/Mono    (13084): Assembly Ref addref Maps.Droid[0x64b8c7f8] -> Xamarin.GooglePlayServices.Location[0x64bdf070]: 2
08-12 16:09:15.206 D/Mono    (13084): Assembly Ref addref Xamarin.GooglePlayServices.Location[0x64bdf070] -> Xamarin.GooglePlayServices.Basement[0x64bde280]: 3
08-12 16:09:15.206 D/Mono    (13084): Assembly Ref addref Maps.Droid[0x64b8c7f8] -> Xamarin.GooglePlayServices.Base[0x64bdd490]: 2
08-12 16:09:15.206 D/Mono    (13084): Assembly Ref addref Xamarin.GooglePlayServices.Base[0x64bdd490] -> Xamarin.GooglePlayServices.Basement[0x64bde280]: 4
08-12 16:09:15.216 I/dalvikvm(13084): Could not find method android.content.pm.PackageManager.getPackageInstaller, referenced from method com.google.android.gms.common.zze.zzi
08-12 16:09:15.216 W/dalvikvm(13084): VFY: unable to resolve virtual method 404: Landroid/content/pm/PackageManager;.getPackageInstaller ()Landroid/content/pm/PackageInstaller;
08-12 16:09:15.216 D/dalvikvm(13084): VFY: replacing opcode 0x6e at 0x000b
08-12 16:09:15.216 D/Mono    (13084): DllImport searching in: '__Internal' ('(null)').
08-12 16:09:15.216 D/Mono    (13084): Searching for 'java_interop_jnienv_call_static_object_method'.
08-12 16:09:15.216 D/Mono    (13084): Probing 'java_interop_jnienv_call_static_object_method'.
08-12 16:09:15.216 D/Mono    (13084): Found as 'java_interop_jnienv_call_static_object_method'.
08-12 16:09:15.226 D/Mono    (13084): DllImport searching in: '__Internal' ('(null)').
08-12 16:09:15.226 D/Mono    (13084): Searching for 'java_interop_jnienv_call_int_method_a'.
08-12 16:09:15.226 D/Mono    (13084): Probing 'java_interop_jnienv_call_int_method_a'.
08-12 16:09:15.226 D/Mono    (13084): Found as 'java_interop_jnienv_call_int_method_a'.
08-12 16:09:15.336 D/Mono    (13084): DllImport attempting to load: '/system/lib/liblog.so'.
08-12 16:09:15.336 D/Mono    (13084): DllImport loaded library '/system/lib/liblog.so'.
08-12 16:09:15.336 D/Mono    (13084): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
08-12 16:09:15.336 D/Mono    (13084): Searching for '__android_log_print'.
08-12 16:09:15.336 D/Mono    (13084): Probing '__android_log_print'.
08-12 16:09:15.336 D/Mono    (13084): Found as '__android_log_print'.
08-12 16:09:15.336 I/mono-stdout(13084): 1
1
1
08-12 16:09:15.346 I/mono-stdout(13084): 1
2
2
08-12 16:09:15.346 I/mono-stdout(13084): 2
08-12 16:09:15.346 I/mono-stdout(13084): 2
08-12 16:09:15.346 D/Mono    (13084): DllImport searching in: '__Internal' ('(null)').
08-12 16:09:15.346 D/Mono    (13084): Searching for 'java_interop_jnienv_get_static_field_id'.
08-12 16:09:15.346 D/Mono    (13084): Probing 'java_interop_jnienv_get_static_field_id'.
08-12 16:09:15.346 D/Mono    (13084): Found as 'java_interop_jnienv_get_static_field_id'.
08-12 16:09:15.356 D/Mono    (13084): DllImport searching in: '__Internal' ('(null)').
08-12 16:09:15.356 D/Mono    (13084): Searching for 'java_interop_jnienv_get_static_object_field'.
08-12 16:09:15.356 D/Mono    (13084): Probing 'java_interop_jnienv_get_static_object_field'.
08-12 16:09:15.356 D/Mono    (13084): Found as 'java_interop_jnienv_get_static_object_field'.
Unhandled Exception:

Java.Lang.NullPointerException: Listener must not be null

08-12 16:09:17.826 D/Mono    (13084): DllImport attempting to load: '/system/lib/liblog.so'.
08-12 16:09:17.826 D/Mono    (13084): DllImport loaded library '/system/lib/liblog.so'.
08-12 16:09:17.826 D/Mono    (13084): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
08-12 16:09:17.826 D/Mono    (13084): Searching for '__android_log_print'.
08-12 16:09:17.826 D/Mono    (13084): Probing '__android_log_print'.
08-12 16:09:17.836 D/Mono    (13084): Found as '__android_log_print'.
08-12 16:09:17.856 I/MonoDroid(13084): UNHANDLED EXCEPTION:
08-12 16:09:17.866 I/MonoDroid(13084): Java.Lang.NullPointerException: Listener must not be null
08-12 16:09:17.866 I/MonoDroid(13084):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
08-12 16:09:17.876 I/MonoDroid(13084):   at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00085] in /Users/builder/data/lanes/3540/1cf254db/source/Java.Interop/src/Java.Interop/Java.Interop/JniEnvironment.g.cs:11283 
08-12 16:09:17.876 I/MonoDroid(13084):   at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue* parms) [0x00000] in /Users/builder/data/lanes/3540/1cf254db/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:102 
08-12 16:09:17.876 I/MonoDroid(13084):   at Android.Gms.Common.Apis.GoogleApiClient+Builder.AddConnectionCallbacks (IConnectionCallbacks listener) [0x0004a] in <filename unknown>:0 
08-12 16:09:17.876 I/MonoDroid(13084):   at Maps.Droid.LocationService.FusedLocation..ctor (Android.App.Activity activity) [0x000a0] in C:\Users\Gustavo.Costa\documents\visual studio 2015\Projects\Maps\Maps\Maps.Droid\LocationService\FusedLocation.cs:38 
08-12 16:09:17.876 I/MonoDroid(13084):   at Maps.Droid.LocationService.LocationTracker..ctor (Android.App.Activity activity) [0x00026] in C:\Users\Gustavo.Costa\documents\visual studio 2015\Projects\Maps\Maps\Maps.Droid\LocationService\LocationTracker.cs:22 
08-12 16:09:17.876 I/MonoDroid(13084):   at Maps.Droid.MapActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00015] in C:\Users\Gustavo.Costa\documents\visual studio 2015\Projects\Maps\Maps\Maps.Droid\MapActivity.cs:15 
08-12 16:09:17.876 I/MonoDroid(13084):   at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00011] in /Users/builder/data/lanes/3540/1cf254db/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Android.App.Activity.cs:2426 
08-12 16:09:17.876 I/MonoDroid(13084):   at (wrapper dynamic-method) System.Object:0a7eba53-2ed2-4ace-97be-6a8e8dacad4a (intptr,intptr,intptr)
08-12 16:09:17.876 I/MonoDroid(13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:17.876 I/MonoDroid(13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:17.876 I/MonoDroid(13084):  at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:17.876 I/MonoDroid(13084):  at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:17.876 I/MonoDroid(13084):  at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:17.876 I/MonoDroid(13084):  at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.os.Looper.loop(Looper.java:136)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:17.876 I/MonoDroid(13084):  at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:17.876 I/MonoDroid(13084):  at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:17.876 I/MonoDroid(13084):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:17.876 I/MonoDroid(13084):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:17.876 I/MonoDroid(13084):  at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:17.876 I/MonoDroid(13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:17.876 I/MonoDroid(13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:17.876 I/MonoDroid(13084):  at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:17.876 I/MonoDroid(13084):  at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:17.876 I/MonoDroid(13084):  at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:17.876 I/MonoDroid(13084):  at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.os.Looper.loop(Looper.java:136)
08-12 16:09:17.876 I/MonoDroid(13084):  at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:17.876 I/MonoDroid(13084):  at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:17.876 I/MonoDroid(13084):  at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:17.876 I/MonoDroid(13084):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:17.886 I/MonoDroid(13084):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:17.886 I/MonoDroid(13084):  at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:17.886 D/Mono    (13084): DllImport searching in: '__Internal' ('(null)').
08-12 16:09:17.886 D/Mono    (13084): Searching for 'java_interop_jnienv_throw'.
08-12 16:09:17.886 D/Mono    (13084): Probing 'java_interop_jnienv_throw'.
08-12 16:09:17.886 D/Mono    (13084): Found as 'java_interop_jnienv_throw'.
An unhandled exception occured.

08-12 16:09:19.416 E/mono    (13084): 
08-12 16:09:19.416 E/mono    (13084): Unhandled Exception:
08-12 16:09:19.416 E/mono    (13084): Java.Lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono    (13084):   at (wrapper dynamic-method) System.Object:0a7eba53-2ed2-4ace-97be-6a8e8dacad4a (intptr,intptr,intptr)
08-12 16:09:19.416 E/mono    (13084):   at (wrapper native-to-managed) System.Object:0a7eba53-2ed2-4ace-97be-6a8e8dacad4a (intptr,intptr,intptr)
08-12 16:09:19.416 E/mono    (13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:19.416 E/mono    (13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono    (13084):   at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:19.416 E/mono    (13084):   at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:19.416 E/mono    (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:19.416 E/mono    (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:19.416 E/mono    (13084):   at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:19.416 E/mono    (13084):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:19.416 E/mono    (13084):   at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:19.416 E/mono    (13084):   at android.os.Looper.loop(Looper.java:136)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:19.416 E/mono    (13084):   at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:19.416 E/mono    (13084):   at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:19.416 E/mono    (13084):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:19.416 E/mono    (13084):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:19.416 E/mono    (13084):   at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:19.416 E/mono    (13084): 
08-12 16:09:19.416 E/mono    (13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:19.416 E/mono    (13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono    (13084):   at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:19.416 E/mono    (13084):   at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:19.416 E/mono    (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:19.416 E/mono    (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:19.416 E/mono    (13084):   at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:19.416 E/mono    (13084):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:19.416 E/mono    (13084):   at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:19.416 E/mono    (13084):   at android.os.Looper.loop(Looper.java:136)
08-12 16:09:19.416 E/mono    (13084):   at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:19.416 E/mono    (13084):   at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:19.416 E/mono    (13084):   at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:19.416 E/mono    (13084):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:19.416 E/mono    (13084):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:19.416 E/mono    (13084):   at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:19.416 E/mono    (13084): 
08-12 16:09:19.416 E/mono-rt (13084): [ERROR] FATAL UNHANDLED EXCEPTION: Java.Lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono-rt (13084):   at (wrapper dynamic-method) System.Object:0a7eba53-2ed2-4ace-97be-6a8e8dacad4a (intptr,intptr,intptr)
08-12 16:09:19.416 E/mono-rt (13084):   at (wrapper native-to-managed) System.Object:0a7eba53-2ed2-4ace-97be-6a8e8dacad4a (intptr,intptr,intptr)
08-12 16:09:19.416 E/mono-rt (13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:19.416 E/mono-rt (13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono-rt (13084):   at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:19.416 E/mono-rt (13084):   at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:19.416 E/mono-rt (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:19.416 E/mono-rt (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:19.416 E/mono-rt (13084):   at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:19.416 E/mono-rt (13084):   at android.os.Looper.loop(Looper.java:136)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:19.416 E/mono-rt (13084):   at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:19.416 E/mono-rt (13084):   at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:19.416 E/mono-rt (13084):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:19.416 E/mono-rt (13084):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:19.416 E/mono-rt (13084):   at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:19.416 E/mono-rt (13084): 
08-12 16:09:19.416 E/mono-rt (13084):   --- End of managed Java.Lang.NullPointerException stack trace ---
08-12 16:09:19.416 E/mono-rt (13084): java.lang.NullPointerException: Listener must not be null
08-12 16:09:19.416 E/mono-rt (13084):   at com.google.android.gms.common.internal.zzx.zzb(Unknown Source)
08-12 16:09:19.416 E/mono-rt (13084):   at com.google.android.gms.common.api.GoogleApiClient$Builder.addConnectionCallbacks(Unknown Source)
08-12 16:09:19.416 E/mono-rt (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.n_onCreate(Native Method)
08-12 16:09:19.416 E/mono-rt (13084):   at md551afeb14f78091b7dcc7953e9e497c49.MapActivity.onCreate(MapActivity.java:33)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.Activity.performCreate(Activity.java:5411)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2233)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 16:09:19.416 E/mono-rt (13084):   at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 16:09:19.416 E/mono-rt (13084):   at android.os.Looper.loop(Looper.java:136)
08-12 16:09:19.416 E/mono-rt (13084):   at android.app.ActivityThread.main(ActivityThread.java:5230)
08-12 16:09:19.416 E/mono-rt (13084):   at java.lang.reflect.Method.invokeNative(Native Method)
08-12 16:09:19.416 E/mono-rt (13084):   at java.lang.reflect.Method.invoke(Method.java:515)
08-12 16:09:19.416 E/mono-rt (13084):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
08-12 16:09:19.416 E/mono-rt (13084):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
08-12 16:09:19.416 E/mono-rt (13084):   at dalvik.system.NativeStart.main(Native Method)
08-12 16:09:19.416 E/mono-rt (13084): 
In mgmain JNI_OnLoad

【问题讨论】:

请提供有关错误的更多详细信息,堆栈跟踪也会很有用 Xamarin 没有显示太多,不太确定该怎么做,我正在 Visual Studio 中处理它 它没有连接到google api客户端 Output 窗格内应该有整​​个堆栈跟踪。确保您完全点击Continue 以查看相应的跟踪。 @JonDouglas 做到了! 【参考方案1】:

找到问题。您只能在 Activity 上实现 GoogleApiClient。想要创建一个使用位置服务的界面。这种方式不可能!


更新:

我设法找到了解决方案。如果用户有 google play 服务,则使用 FusedLocation 服务,如果用户没有,则我们使用 Android 位置服务。然后我们只需要与一个LocationTracker类型的对象进行交互,一切都由这个接口完成:

namespace Maps.Droid.LocationService 
    public interface LocationInterface 
        void startLocationServices();
        void stopLocationServices();
        void pauseLocationServices();
        void resumeLocationServices();
        double getLatitude();
        double getLongitude();
        bool canGetLocation();
    


using System;
using Android.App;
using Android.Gms.Location;
using Android.Gms.Common.Apis;
using Android.OS;
using Android.Gms.Maps.Model;
using Android.Widget;
using Android.Locations;
using Android.Gms.Common;
using Android.Gms.Maps;

namespace Maps.Droid.LocationService 
    public class FusedLocation : Java.Lang.Object, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener 
        private Activity activity;
        private GoogleApiClient mGoogleApiClient;
        private LocationRequest mLocationRequest;
        private Location currentLocation;
        private bool locationAvailable = false;
        private GoogleMap map;

        public FusedLocation(Activity activity) 
            this.activity = activity;

            mLocationRequest = new LocationRequest();
            mLocationRequest.SetInterval(LocationTracker.MIN_TIME_BW_UPDATES);
            mLocationRequest.SetFastestInterval(LocationTracker.MIN_TIME_BW_UPDATES / 2);
            mLocationRequest.SetSmallestDisplacement(LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES);
            mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);

            mGoogleApiClient = new GoogleApiClient.Builder(Application.Context)
                .AddConnectionCallbacks(this)
                .AddOnConnectionFailedListener(this)
                .AddApi(LocationServices.API)
                .Build();
        

        public Location getCurrentLocation() 
            return currentLocation;
        

        public void setMap(GoogleMap map) 
            this.map = map;
        

        public double getLatitude() 
            return currentLocation.Latitude;
        

        public double getLongitude() 
            return currentLocation.Longitude;
        

        public void OnResume() 
            if (mGoogleApiClient.IsConnected) 
                LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            
        
        public void OnPause() 
            // Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
            if (mGoogleApiClient.IsConnected) 
                LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this);
            
        

        public void OnStart() 
            mGoogleApiClient?.Connect();
        

        public void OnStop() 
            // only stop if it's connected, otherwise we crash
            if (mGoogleApiClient.IsConnected) 
                mGoogleApiClient?.Disconnect();
            
        

        public LatLng getLatLng() 
            return new LatLng(currentLocation.Latitude, currentLocation.Longitude);

        
        public bool canGetLocation() 
            return locationAvailable && currentLocation != null;
        

        public void OnConnected(Bundle connectionHint) 
            // Get last known recent location. If the user launches the activity,
            // moves to a new location, and then changes the device orientation, the original location
            // is displayed as the activity is re-created.
            currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient);

            if (currentLocation != null) 
                locationAvailable = true;
                LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

                if (map != null) 
                    map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM));
                
            
        

        public void OnConnectionSuspended(int cause) 
            // GoogleApiClient will automatically attempt to restore the connection.
            // Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them
            if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) 
                Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show();
             else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) 
                Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show();
            
        

        public void OnLocationChanged(Location location) 
            currentLocation = location;
        

        public void OnConnectionFailed(ConnectionResult result) 
            Console.WriteLine("Connection failed: " + result.ToString());
        
    


using System;
using Android.OS;
using Android.Locations;
using Android.Runtime;
using Android.App;
using Android.Content;
using Android.Widget;
using Android.Gms.Maps.Model;
using Java.Util.Concurrent;

namespace Maps.Droid.LocationService 
    public class AndroidLocation : Java.Lang.Object, ILocationListener 
        // Properties
        private LocationManager locMgr;
        private Activity activity;
        private Location locationGPS, locationNetwork/*, locationPassive*/, currentLocation;
        private bool locationAvailable = false;
        private Android.Gms.Maps.GoogleMap map;

        // UNCOMMNET
        // private bool isPassiveEnabled = false; // Gets location from other apps that uses Location Services

        // Initializer method (Constructor). Call this method onCreate
        public AndroidLocation(Activity activity) 
            this.activity = activity;
            getLocation();
        

        public Location getCurrentLocation() 
            return currentLocation;
        

        public void setMap(Android.Gms.Maps.GoogleMap map) 
            this.map = map;
        

        private Location getLocation() 
            // Use Standard Android Location Service Provider
            try 
                locMgr = activity.GetSystemService(Context.LocationService) as LocationManager;

                bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);

                // Varying precision, Less power consuming. Combination of WiFi and Cellular data
                bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider);

                // UNCOMMENT
                // bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);

                // UNCOMMNET
                //if (isPassiveEnabled) 
                //    locMgr.RequestLocationUpdates(LocationManager.PassiveProvider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                //    locationPassive = locMgr.GetLastKnownLocation(LocationManager.PassiveProvider);
                //

                if (isGPSEnabled) 
                    locMgr.RequestLocationUpdates(LocationManager.GpsProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    locationGPS = locMgr?.GetLastKnownLocation(LocationManager.GpsProvider);
                

                if (isNetworkEnabled) 
                    locMgr.RequestLocationUpdates(LocationManager.NetworkProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    locationNetwork = locMgr?.GetLastKnownLocation(LocationManager.NetworkProvider);
                

                // UNCOMMENT - Method must be implement if PassiveLocation is to be used
                // currentLocation = getBestLocation(locationGPS, locationNetwork, locationPassive);

                currentLocation = getBestLocation(locationNetwork, locationGPS);

                if (currentLocation != null) 
                    locationAvailable = true;
                    if (map != null) 
                        map.AnimateCamera(Android.Gms.Maps.CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM));
                    
                
             catch (Exception e) 
                Console.WriteLine("ERROR: getLocation() " + e.ToString());
            

            return currentLocation;
        

        // Determines the most recent and/or most accurate location
        private Location getBestLocation(Location loc1, Location loc2) 
            if (loc1 == null || loc2 == null) 
                return loc1 ?? loc2; // If either location is null then return the not null location
            

            long time1 = TimeUnit.Milliseconds.ToSeconds(loc1.Time);
            long time2 = TimeUnit.Milliseconds.ToSeconds(loc2.Time);

            long twiceUpdate = (LocationTracker.MIN_TIME_BW_UPDATES / 1000) * 2;
            if (Math.Abs(time1 - time2) > twiceUpdate)  // If location times are more than twiceUpdate apart
                if (time1 > time2)  // More time value, most current time
                    return loc1;
                 else 
                    return loc2;
                
             else 
                float accuracy1 = loc1.Accuracy;
                float accuracy2 = loc2.Accuracy;

                // Smaller the value (meters), the greater the accuracy
                if (accuracy1 < accuracy2) 
                    return loc1;
                 else 
                    return loc2;
                
            
        

        public void OnStop() 
            locMgr = null;
        

        public void OnPause() 
            locMgr?.RemoveUpdates(this);
        

        public void OnStart() 
        

        public void OnResume() 
            if (locMgr == null || currentLocation == null) 
                getLocation();
            
        

        public bool canGetLocation() 
            return locationAvailable;
        

        public LatLng getLatLng() 
            return new LatLng(currentLocation.Latitude, currentLocation.Longitude);
        

        public double getLatitude() 
            return currentLocation.Latitude;
        

        public double getLongitude() 
            return currentLocation.Longitude;
        

        public void OnLocationChanged(Location location) 
            currentLocation = getBestLocation(currentLocation, location);
        

        // User disabled a provider
        public void OnProviderDisabled(string provider) 
            getLocation(); // Check if all providers are disabled and pop up alertDialog if they are so
        

        // User enabled a provider
        public void OnProviderEnabled(string provider) 
            getLocation(); // Update all available providers for getting the best provider available
        

        public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras) 
        
    


using Android.App;
using Android.Gms.Common;
using Android.Gms.Common.Apis;
using Android.Gms.Maps.Model;
using Android.Gms.Maps;
using Android.Locations;
using Android.Content;
using Android.Widget;

namespace Maps.Droid.LocationService 
    public class LocationTracker 
        public static long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 5 meters
        public static long MIN_TIME_BW_UPDATES = 1000 * 15; // 15 seconds ok, 5 seconds really fast, 30s slow
        public static float DEFAULT_ZOOM = 16f;

        private bool hasGooglePlayServices;
        public GoogleApiClient mGoogleApiClient;
        private FusedLocation fusedLocation;
        private AndroidLocation androidLocation;
        private bool locationIsDisabled;

        public LocationTracker(Activity activity) 
            if (locationIsDisabled = isLocationDisabled(activity)) 
                showSettingsAlert(activity);
             else 
                hasGooglePlayServices = checkPlayServices(activity);

                if (hasGooglePlayServices) 
                    fusedLocation = new FusedLocation(activity);
                 else 
                    androidLocation = new AndroidLocation(activity);
                
            
        

        private void showSettingsAlert(Activity activity) 
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.SetTitle("Location Services Not Active");
            builder.SetMessage("Please enable Location Services and GPS");
            builder.SetPositiveButton("OK", delegate 
                // Show location settings when the user acknowledges the alert dialog
                var intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings);
                activity.StartActivity(intent);
            );
            builder.SetNegativeButton("Cancel", delegate 
                Toast.MakeText(activity, "Location disabled by user", ToastLength.Short).Show();
            );
            AlertDialog alertDialog = builder.Create();
            alertDialog.SetCanceledOnTouchOutside(false);
            alertDialog.Show();
        

        private bool isLocationDisabled(Activity activity) 
            LocationManager locMgr = activity.GetSystemService(Context.LocationService) as LocationManager;

            // More precise, More power consuming
            bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider);

            // Varying precision, Less power consuming. Combination of WiFi and Cellular data
            bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider);

            // UNCOMMENT
            // bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.PassiveProvider);

            // UNCOMMENT
            // return !isGPSEnabled && !isNetworkEnabled && !isPassiveEnabled; // True only when the 3 location services are disabled

            return !isGPSEnabled && !isNetworkEnabled; // True only when both location services are disabled
        

        // Call this method at OnMapReady callback if initial zooming/animation on user's location is desired
        public void setMap(GoogleMap map) 
            if (locationIsDisabled) 
                return;
            

            if (hasGooglePlayServices) 
                fusedLocation.setMap(map);
             else 
                androidLocation.setMap(map);
            
        

        public void OnResume() 
            if (locationIsDisabled) 
                return;
            

            if (hasGooglePlayServices) 
                fusedLocation.OnResume();
             else 
                androidLocation.OnResume();
            
        

        public void OnPause() 
            if (locationIsDisabled) 
                return;
            

            if (hasGooglePlayServices) 
                fusedLocation.OnPause();
             else 
                androidLocation.OnPause();
            
        

        public void OnStart() 
            if (locationIsDisabled) 
                return;
            

            if (hasGooglePlayServices) 
                fusedLocation.OnStart();
             else 
                androidLocation.OnStart();
            
        

        public void OnStop() 
            if (locationIsDisabled) 
                return;
            

            if (hasGooglePlayServices) 
                fusedLocation.OnStop();
             else 
                androidLocation.OnStop();
            
        

        private bool checkPlayServices(Activity activity) 
            GoogleApiAvailability apiAvailability = GoogleApiAvailability.Instance;
            int resultCode = apiAvailability.IsGooglePlayServicesAvailable(activity);
            if (resultCode == ConnectionResult.Success) 
                return true;
            
            return false;
        

        public double getLatitude() 
            if (locationIsDisabled) 
                return 0;
            

            if (hasGooglePlayServices) 
                return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLatitude();
             else 
                return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLatitude();
            
        

        public double getLongitude() 
            if (locationIsDisabled) 
                return 0;
            

            if (hasGooglePlayServices) 
                return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLongitude();
             else 
                return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLongitude();
            
        

        public bool canGetLocation() 
            if (locationIsDisabled) 
                return false;
            

            if (hasGooglePlayServices) 
                return fusedLocation.canGetLocation();
             else 
                return androidLocation.canGetLocation();
            
        

        public LatLng getLatLng() 
            if (locationIsDisabled) 
                return null;
            

            LatLng latlng;
            if (hasGooglePlayServices) 
                latlng = fusedLocation.getLatLng();
             else 
                latlng = androidLocation.getLatLng();
            

            return latlng;
        

        public Location getCurrentLocation() 
            if (hasGooglePlayServices) 
                return fusedLocation.getCurrentLocation();
             else 
                return androidLocation.getCurrentLocation();
            
        
    

然后在您的片段或活动上使用它:

在 OnCreate 初始化它:

Location tracker = new LocationTracker(this.Activity);

为生命周期做一个参照:

public override void OnResume() 
            base.OnResume();
            tracker.OnResume();
        

        public override void OnPause() 
            base.OnPause();
            tracker.OnPause();
        

        public override void OnStart() 
            base.OnStart();
            tracker.OnStart();
        

        public override void OnStop() 
            base.OnStop();
            tracker.OnStop();
        

如果您希望动画在开始时在用户位置进行缩放,那么您必须在拥有 googlemap 时添加这行代码:

tracker.setMap(googleMap); // Invoke this method if zooming/animating to the user's location is desired

在这个解决方案上花了很多天。希望它可以帮助别人!

【讨论】:

以上是关于FusedLocation GoogleApi - 侦听器不得为空 (Xamarin.Android)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 fusedLocation 获得良好的准确性?

我的所有 FusedLocation 请求的列表

FusedLocation 不会触发 android api <= 21 的 locationcallback

FusedLocation Pending Intent 有时在没有位置的情况下调用

当我在谷歌设置android中关闭和打开位置时,FusedLocation 不起作用

fusedLocation API 间隔与关闭 GPS 无线电有何关系