Android:使用 GoogleApiClient 时为空位置

Android: Null location when using GoogleApiClient

您好,我目前正在尝试使用 GoogleApiClient 为我的 Android 设备获取纬度和海拔高度值。我一直在关注这里的指南:

GoogleApiClient: Last Known Location Guide

我也在尝试通过我的服务而不是 Activity 执行此操作,这里是我的代码片段以供参考:

public class AppService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private GoogleApiClient googleApiClient;

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    googleApiClient.connect();
    try {
        Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
        Log.d("location", String.valueOf(lastLocation.getLatitude()));
        Log.d("location", String.valueOf(lastLocation.getLongitude()));
    } catch (SecurityException e) {
        Log.e("Location error", "Location object is null.");
    }

    googleApiClient.disconnect();

    //Stop service once it finishes its task
    stopSelf();
    return Service.START_STICKY;
}

@Override
public void onConnected(@Nullable Bundle bundle) {

}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}

每次我尝试访问 Location 变量以获取纬度和高度时,我都会收到 NullPointerException,知道为什么吗?

还想包含我的 AndroidManifest 文件以防万一,据我所知,我拥有所需的权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="app"
      android:versionCode="1"
      android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="@string/app_name" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </activity>
    <receiver
            android:name=".AutoStart"
            android:enabled="true" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>
    <service android:name=".AppService"/>
</application>
</manifest>

根据文档,对 googleApiClient.connect() 的调用是异步的:

public abstract void connect ()

Connects the client to Google Play services. This method returns immediately, and connects to the service in the background. If the connection is successful, onConnected(Bundle) is called and enqueued items are executed. On a failure, onConnectionFailed(ConnectionResult) is called.

If the client is already connected or connecting, this method does nothing.

因此,您应该等待 onConnected 回调执行,并将您的位置检索代码放在那里。

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
  if (googleApiClient == null) {
     googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
  }
  googleApiClient.connect();
  return Service.START_STICKY;
}

@Override
public void onConnected(@Nullable Bundle bundle) {
  try {
    Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    Log.d("location", String.valueOf(lastLocation.getLatitude()));
    Log.d("location", String.valueOf(lastLocation.getLongitude()));
  } catch (SecurityException e) {
    Log.e("Location error", "Location object is null.");
  }

  googleApiClient.disconnect();
  stopSelf();
}