在我的应用程序中通过此功能获取手机的位置,但是当我重新启动手机并启动应用程序时,我从此方法中获取null。有什么东西可以丢失或做错吗?我该怎么做才能解决这个问题?
以下是使用的函数:
public void getAddress() {
Log.v("--", "get address 1");
boolean isGPSProviderEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network_enabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Log.v("--", "get address 31 " + isGPSProviderEnabled + " gps - "
+ isConnectedToNetwork());
if (isGPSProviderEnabled || network_enabled) {
Log.v("--", "get address 2");
Criteria c = new Criteria();
Log.v("--", "provider " + locationManager.getBestProvider(c, true));
locationManager.requestSingleUpdate(
locationManager.getBestProvider(c, true),
mLocationListener, Looper.myLooper());
location = locationManager.getLastKnownLocation(locationManager
.getBestProvider(c, true));
if (location == null) {
Log.v("--", "get address 6");
// TODO check if this is working
locationManager.requestSingleUpdate(
locationManager.getBestProvider(c, true),
mLocationListener, Looper.myLooper());
locationManager.requestLocationUpdates(
locationManager.getBestProvider(c, true), 0, 0,
mLocationListener);
Location oldLocation = new Location("");
oldLocation.setLatitude(new Double(prefs.getString(
Constants.LATITUDE, "48.51")));
oldLocation.setLongitude(new Double(prefs.getString(
Constants.LONGITUDE, "2.20")));
populateList(oldLocation);
// locationManager.requestLocationUpdates(
// locationManager.getBestProvider(c, true), 1000, 100,
// mLocationListener);
} else {
Log.v("--", "get address 3");
if (isConnectedToNetwork()) {
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
try {
com.quanticapps.athan.utils.Geocoder geocoder = new com.quanticapps.athan.utils.Geocoder(
Main.this);
GeocoderModel geocoderModel = geocoder
.getFromLocation(
location.getLatitude(),
location.getLongitude(), 5);
city = geocoderModel.getCity();
country = geocoderModel.getCountry();
prefs.edit().putString(Constants.CITY, city)
.apply();
Log.v("--", "get address 4");
} catch (IOException e) {
Log.v("--", "get address 11");
e.printStackTrace();
} catch (LimitExceededException e) {
Log.v("--", "get address 12");
e.printStackTrace();
}
return null;
};
protected void onPostExecute(Void result) {
prefs.edit().putString(Constants.COUNTRY, country)
.apply();
prefs.edit().putString(Constants.CITY, city)
.apply();
populateList(location);
};
}.execute();
} else {
city = null;
Log.v("--", "get address 33 " + location.getLatitude());
populateList(location);
}
}
} else {
Log.v("--", "get address 5");
startGpsEnableDialog();
}
}
和我的位置监听器:
private final LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(final Location location) {
// TODO
Log.v("--", "get address 121");
if (location != null) {
Main.this.location = location;
getAddress();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
Log.v("--", "provider enabled");
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
Log.v("--", "provider disabled");
}
};
答案 0 :(得分:2)
当手机重新启动时,缓存的最后一个位置会丢失,所以如果您没有打开使用GPS等谷歌地图的应用程序,那么将没有最后位置。
永远不会有一个位置返回给你,你应该总是假设它可以为null
答案 1 :(得分:0)
如果 fusedLocationClient
返回空位置,那么您应该使用 requestLocationUpdates
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
if (location == null) {
checkLocationSettingsAndStartLocationUpdates(
resolutionForResult
)
} else {
showUserCurrentLocation(location)
}
}
首先让我们定义 resolutionForResult
private val resolutionForResult =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { activityResult ->
if (activityResult.resultCode == RESULT_OK)
locationManger.startLocationUpdates(requestPermissionLauncher)
else {
showMessage("we can't determine your location")
}
}
那么这个方法
private fun checkLocationSettingsAndStartLocationUpdates(
resolutionForResult: ActivityResultLauncher<IntentSenderRequest>
) {
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
val client: SettingsClient = LocationServices.getSettingsClient(requireContext)
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
task.addOnSuccessListener { _ ->
startLocationUpdates()
}
task.addOnFailureListener { exception ->
if (exception is ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
val intentSenderRequest =
IntentSenderRequest.Builder(exception.resolution).build()
resolutionForResult.launch(intentSenderRequest)
} catch (sendEx: IntentSender.SendIntentException) {
}
}
}
}
然后startLocationUpdates
发生实际位置更新
fun startLocationUpdates(
) {
if (ActivityCompat.checkSelfPermission(
requireContext,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
requireContext,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissionLauncher.launch(
Manifest.permission.ACCESS_FINE_LOCATION
)
return
}
fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
这里也是locationRequest
和locationCallback
的声明
private val locationRequest: LocationRequest by lazy {
LocationRequest.create().apply {
interval = 10000
fastestInterval = 5000
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
}
和
private var locationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for (location in locationResult.locations) {
if (location != null) {
//showUserCurrentLocation(location)
stopLocationUpdates(this)//if you only need the location once then stop the updates
break
}
}
}
}
这里是stopLocationUpdates
方法
fun stopLocationUpdates(locationCallback: LocationCallback) {
fusedLocationClient.removeLocationUpdates(locationCallback)
}
fusedLocationClient
也是在用户授予权限或检查权限后定义的,
这里是如何检查权限是否得到保证
fun locationPermissionGranted(): Boolean {
return when (PackageManager.PERMISSION_GRANTED) {
ContextCompat.checkSelfPermission(
requireContext,
Manifest.permission.ACCESS_FINE_LOCATION
) -> {
fusedLocationClient =
LocationServices.getFusedLocationProviderClient(requireContext)
true
}
else -> {
false
}
}
}
如果是 false 那么你需要请求permissionfun
requestPermission(requestPermissionLauncher: ActivityResultLauncher<String>) {
requestPermissionLauncher.launch(
Manifest.permission.ACCESS_FINE_LOCATION
)
}
这里是 requestPermissionLauncher
的定义
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
fusedLocationClient =
LocationServices.getFusedLocationProviderClient(requireContext())
} else {
showMessage(
"the application can't show your " +
"current location on the map, because you denied the location permission"
)
}
}