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 我有什么遗漏吗?

4

3 回答 3

6

在请求位置更新之前,您的应用必须连接到位置服务并发出位置请求。像这样的一些事情:

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);
}
于 2018-10-01T09:26:58.783 回答
2

尝试从 android 设置中激活/停用位置。

于 2018-10-09T05:09:16.530 回答
1

location == null.

另请参阅LocationAvailability 无可用位置。如果你打电话

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}")
    }

接收坐标。

于 2021-01-20T10:08:48.183 回答