getLastKnownLocation null-如何获取数据?

时间:2019-03-22 12:48:25

标签: android

我正在尝试使用 getLastKnownLocation 获取位置信息,但是我经常会得到 null

这是我的工作:

  1. 在“设置”中关闭位置
  2. 运行我的应用- getLastKnownLocation 返回-这是预期的
  3. 在“设置”中打开位置
  4. 再次运行我的应用- getLastKnownLocation 返回!?
  5. 运行Google Maps
  6. 再次运行我的应用- getLastKnownLocation 返回有效的位置!?

我发现了这个问题,在已接受的答案中,该问题建议首先启动地图以获取位置: FusedLocationApi.getLastLocation always null

问题是:Google Maps如何获取位置?我该如何在代码中做同样的事情?

谢谢!

3 个答案:

答案 0 :(得分:2)

感谢大家的帮助!

我在清单中缺少 uses-features 声明-感谢@CommonsWare提供的链接:https://developer.android.com/guide/topics/location/strategies.html#java

<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature android:name="android.hardware.location.network" />

此外,还需要这样的更新:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

在我的情况下,GPS提供商需要花费几分钟才能连接并开始发送数据-网络提供商似乎更快,但并不总是能正常工作-因此,我将同时使用它们。

更新:一些关键点

  1. 这不是很直观,但是为了从 getLastKnownLocation 获取数据,该设备上的某些应用(无论是Google Maps还是我们自己的应用)都需要调用 requestLocationUpdates
  2. 某些提供商可能未在特定设备上启用-因此,最好同时使用 GPS_PROVIDER NETWORK_PROVIDER -或使用所有已启用的提供商: locationManager.getProviders(true)

这是我最终使用的代码:

for ( String provider : locationManager.getProviders(true) ) {
    setLocation( locationManager.getLastKnownLocation(provider) );
    locationManager.requestLocationUpdates(provider, Tools.MIN_5, 0, locationListener);
}
// call setLocation again in locationListener.onLocationChanged

答案 1 :(得分:1)

下面的代码块可能会对您有所帮助。

  if (!::mFusedLocationProviderClient.isInitialized) {
        mFusedLocationProviderClient = FusedLocationProviderClient(mContext)
        mLocationRequest = LocationRequest()
        mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
        mLocationRequest.interval = 10000
        mLocationRequest.fastestInterval = 5000
        mLocationRequest.smallestDisplacement = 1000 * 100f
    }
    if (ActivityCompat.checkSelfPermission(
            AppName.appContext,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
            AppName.appContext,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // not enough permission
        return
    }
    mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, object : LocationCallback() {
        override fun onLocationResult(p0: LocationResult?) {
            super.onLocationResult(p0)
            mFusedLocationProviderClient.removeLocationUpdates(this)
            if (p0 != null) {
             //here is your location
            } else {
              // location is null
            }
        }

        override fun onLocationAvailability(p0: LocationAvailability?) {
            if(p0?.isLocationAvailable!= true){
       //location not available.
            }
        }

    }, Looper.getMainLooper())

答案 2 :(得分:0)

请确保您授予所有权限,并且如果您在6.1设备以上运行应用程序,那么请处理权限。

之后使用了此代码。

将以下依赖项添加到应用程序级别的gradle文件中。

//Place API
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'

将此定义为全局减速度。

private lateinit var fusedLocationClient: FusedLocationProviderClient
private var context: Context? = null
private var locationCallback: LocationCallback? = null
private var locationRequest: LocationRequest? = null
private var googleApiClient: GoogleApiClient? = null

之后是onCreate方法。

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

获取位置的make方法。

fun getCurrentLocation() {
    // Get Current location and do reverse geocoding
    ProgressUtils.showOldProgressDialog(this)


    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            ProgressUtils.closeOldProgressDialog()
            for (location in locationResult.locations) {
                // here you get current lat ,long,etc value.. 
                        stopLocationUpdates()
                    }
                } catch (e: Exception) {
                    e.message.loggerError()
                    stopLocationUpdates()
                }
            }
        }
    }

    locationRequest = LocationRequest().apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }


    startLocationUpdates()


}

进行位置更新。.

 fun startLocationUpdates() {

    googleApiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .build()

    googleApiClient!!.connect()


    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest!!)
    builder.setAlwaysShow(true)

    val result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
    result.setResultCallback { result ->
        val status = result.status
        when (status.statusCode) {
            LocationSettingsStatusCodes.SUCCESS -> {
                Log.i(TAG, "All location settings are satisfied.")
                fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
            }
            LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ")

                try {
                    // Show the dialog by calling startResolutionForResult(), and check the result
                    // in onActivityResult().
                    status.startResolutionForResult(this, LOCATION_SETTING_REQUEST_CODE)
                } catch (e: IntentSender.SendIntentException) {
                    Log.i(TAG, "PendingIntent unable to execute request.")
                }

            }
            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.")
        }
    }

}

停止位置的制作方法。

private fun stopLocationUpdates() {

    if (locationCallback != null) {
        fusedLocationClient?.removeLocationUpdates(locationCallback)
    }
}

override fun onStop() {
    super.onStop()
    stopLocationUpdates()
}

override fun onPause() {
    super.onPause()
    stopLocationUpdates()
}

如果授予处理权限,而不是授予权限,则回叫获取onActivity Result方法,该方法放在下面的代码中。

     fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)