手机重启后Android获取位置为空
Posted
技术标签:
【中文标题】手机重启后Android获取位置为空【英文标题】:Android get location is null after phone reboot 【发布时间】:2015-03-26 05:39:10 【问题描述】:在我的应用程序中,我通过此功能获取手机的位置,但是当我重新启动手机并启动应用程序时,我从该方法中得到 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");
;
【问题讨论】:
你在说locationManager.getLastKnownLocation
吗?
@tyczj yap 其返回 null
好吧,你重启了手机,没有缓存的最后一个位置了
可能还没准备好?您是否尝试在重新启动后等待几分钟?就像 appWidget 在重启后一段时间后更新一样,你知道我的意思吗?
【参考方案1】:
当手机重新启动时,缓存的最后一个位置会丢失,所以如果你没有打开一个使用 GPS 的应用程序,如谷歌地图或其他东西,那么将没有最后一个位置。
永远不必将位置返回给您,您应该始终假设它可能为空
【讨论】:
我怎样才能在代码中实现这一点,你能和我分享一些sn-p吗? 获取位置,这是否意味着我应该使用getLastKnownLocation
而不是locationManager.requestLocationUpdates(...);
?
是的,如果没有位置,您需要请求位置更新并等待【参考方案2】:
如果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
如果是假的,那么你需要请求许可
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"
)
【讨论】:
以上是关于手机重启后Android获取位置为空的主要内容,如果未能解决你的问题,请参考以下文章
在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置
在 android 中获取更新位置和禁用 GPS 后如何获取?