FusedLocationClient没有调用onLocationResult函数

9

我目前正在创建一个位置客户端,目前我有:

 public void startUpdatingLocationProcess(Context context) {

     parentContext = context;

    if (mFusedLocationClient == null){
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(parentContext);

        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        if (ContextCompat.checkSelfPermission(parentContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
        {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, new LocationCallback(){
                @Override
                public void onLocationResult(LocationResult locationResult) {

                    onLocationChanged(locationResult.getLastLocation());
                }

            } , Looper.myLooper());

         }


}

这是一个LocationApi类,我希望能在整个应用程序的生命周期内运行。由于这个应用程序有许多活动,所以我不想在每次销毁并创建新活动时“重新创建”请求。
FINE_LOCATION权限已允许并检查,logcat中没有错误,并且代码在创建mFusedLocationClient对象时运行requestLocationUpdates方法,但从未调用“onLocationResult”方法。
我是否遗漏了使用此API的某些内容?
3个回答

7
在请求位置更新之前,您的应用程序必须连接到位置服务并进行位置请求。 像这样的一些事情:
private static LocationRequest createLocationRequest() {
    LogHelper.trace("createLocationRequest");
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(200000);
    mLocationRequest.setFastestInterval(300000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    return mLocationRequest;
}

public static void checkLocationService(final Fragment fragment, final FusedLocationProviderClient client, final OnSuccessListener<LocationSettingsResponse> successListener, OnFailureListener failureListener) {

    LogHelper.trace("checkLocationService");
    final LocationRequest request = createLocationRequest();
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(request);

    SettingsClient settingsClient = LocationServices.getSettingsClient(fragment.getActivity());
    Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(builder.build());

    task.addOnSuccessListener(fragment.getActivity(), new OnSuccessListener<LocationSettingsResponse>() {
        @Override
        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
            LogHelper.trace("onSuccess");
            startLocationService(client, request, new LocationCallback());
            successListener.onSuccess(locationSettingsResponse);
        }
    });

    task.addOnFailureListener(fragment.getActivity(), failureListener);
}

你好!我已经添加了与位置服务的连接并发出请求,但是我从“OnFailureListener”中得到了一个响应,指出 -com.google.android.gms.common.api.ResolvableApiException: 6: RESOLUTION_REQUIRED我仍在研究这个错误,我在方法调用之前进行了FINE_LOCATION检查,并且在清单中也有INTERNET权限,您有任何想法为什么会得到这个响应吗? :) - Brandon
你好!抱歉回复晚了,我正在工作中。我找到了failureListener被调用的问题所在,是因为我没有检查我测试设备上的位置设置。现在我已经成功连接到客户端,并请求位置更新,代码如下:client.requestLocationUpdates(request, new LocationCallback(){ @Override public void onLocationResult(LocationResult locationResult) { onLocationChanged(locationResult.getLastLocation()); } } , Looper.myLooper()); - Brandon
但是 onLocationResult 从未被调用,我已经在 ACCESS FINE LOCATION 的权限检查中包装了它,虽然它通过了,但仍然没有响应。 - Brandon
在发出位置请求并调用requestLocationUpdates后,您必须使用client.getLastLocation()从Google Play服务获取最后一个位置。响应可能为空,如果为空,则必须再次调用它,因为更新需要几秒钟的时间。 - No Body
1
参数中的 client 是什么?还有 startLocationService 方法是什么,successListener 在哪里? - Mohamad Mousheimish
显示剩余5条评论

3
尝试从安卓设置中激活/关闭位置。

1

location == null

请参见位置不可用。如果您调用

fusedLocationClient.getLocationAvailability()
    .addOnSuccessListener(this, locationAvailability -> {
    })

你会看到LocationAvailability[isLocationAvailable: false]

可能是因为旧的模拟器或者其他原因导致的。

locationRequest = LocationRequest.create();
locationRequest
        .setNumUpdates(1)
        .setFastestInterval(0)
        .setSmallestDisplacement(0)

如果您设置了setNumUpdates(1),它只会返回一次坐标,很可能会出现null。我删除了这些行并使用了…
@SuppressLint("MissingPermission")
private fun startLocationUpdates() {
    fusedLocationProviderClient?.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}

开始搜索位置,然后
locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult?) {
        super.onLocationResult(locationResult)

        if (locationResult?.lastLocation == null) {
            Timber.d("Location missing in callback.")
        } else {
            Timber.d(
                "Location Callback ${locationResult.lastLocation}")
            latitude = locationResult.lastLocation.latitude
            longitude = locationResult.lastLocation.longitude
            stopLocationUpdates()
        }
    }
}

fusedLocationProviderClient?.lastLocation
    ?.addOnSuccessListener { location ->
        Timber.d("lastLocation success $location")
        if (location == null) {
            startLocationUpdates()
        } else {
            latitude = location.latitude
            longitude = location.longitude
        }
    }
    ?.addOnFailureListener { failure ->
        Timber.d("lastLocation failure ${failure.message}")
    }

接收坐标。


我也发现当我使用setNumUpdates时,有时候我的onLocationResult回调函数没有被触发。在移除对setNumUpdates的调用后,我的回调函数总是被触发。 - Adam Johns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接