使用不同的位置请求模式检索位置时出现问题
Getting issue while retrieve location with different location request mode
为了检索位置,我使用了 GoogleAPIClient
和 FusedLocationProvider
API。
这些函数在 onCreate()
方法中。
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
gpsChecker();
完整代码
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public void gpsChecker() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
AddVisitActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
为了 运行 的时间权限,我这样做了。
protected void startLocationUpdates() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(AddVisitActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
Snackbar.make(findViewById(android.R.id.content),
"Please Grant Permissions",
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(AddVisitActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddVisitActivity.this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, AddVisitActivity.this);
Log.d(TAG, "Location update started ...: ");
}
}
}).show();
} else {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ...: ");
}
}
}
使用 gpsChecker() 请求代码 1000 和 onActivityResult() 我已经做到了。
if (requestCode == 1000) {
switch (resultCode) {
case Activity.RESULT_OK:
Log.i(TAG, "User agreed to make required location settings changes.");
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Log.i(TAG, "User chose not to make required location settings changes.");
finish();
break;
}
}
当我在某些设备上执行此代码时,它可以正常工作,而在某些设备上,位置请求会自动设置为 Device Only 或 Battery Saving虽然我设置了 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
注意:小米Note 4、vivo V9 Pro、小米Note 5 Pro等部分设备出现问题
那么我需要在我的代码中更改什么才能使其在高精度下正常工作?
使用 GPS 提供商尝试此解决方案并确保您的 GPS 服务已开启。
静态最终整数LOCATION_INTERVAL = 1000;
静态最终浮点数 LOCATION_DISTANCE = 10f;
//放在onCreate()中;
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
mprovider = locationManager.getBestProvider(criteria, false);
if (mprovider != null && !mprovider.equals("")) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(mprovider);
locationManager.requestLocationUpdates(mprovider, LOCATION_INTERVAL, LOCATION_DISTANCE, this);
if (location != null)
onLocationChanged(location);
else
Toast.makeText(getBaseContext(), "No Location Provider Found Check Your Code", Toast.LENGTH_SHORT).show();
}
//put this LocationListener after onCreate();
public LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e(String.format("%f, %f", location.getLatitude(), location.getLongitude()), "");
Log.e("Location available", "Location available");
locationManager.removeUpdates(mLocationListener);
} else {
Log.e("Location is null", "Location is null");
}
current_latitude = location.getLatitude();
current_longitude = location.getLongitude();
/* LatLng latLng = new LatLng(current_latitude, current_longitude);
points.add(latLng);
redrawLine();*/
Log.e("current_latitude", String.valueOf(current_latitude));
Log.e("current_longitude", String.valueOf(current_longitude));
if (location.hasSpeed()) {
//progressBarCircularIndeterminate.setVisibility(View.GONE);
String speed = String.format(Locale.ENGLISH, "%.0f", location.getSpeed() * 3.6) + "km/h";
SpannableString s = new SpannableString(speed);
s.setSpan(new RelativeSizeSpan(0.25f), s.length() - 4, s.length(), 0);
txt_current_speed.setText(s);
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
终于通过改变解决了
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
至
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
并更改
private static final long INTERVAL = 1000 * 60 * 60;
private static final long FASTEST_INTERVAL = 1000 * 5;
间隔时间为 30 分钟,最快间隔时间为 5 秒,这意味着在 5 秒后获取一次位置,然后将在 30 分钟内获取新位置。
为了检索位置,我使用了 GoogleAPIClient
和 FusedLocationProvider
API。
这些函数在 onCreate()
方法中。
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
gpsChecker();
完整代码
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public void gpsChecker() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
AddVisitActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
为了 运行 的时间权限,我这样做了。
protected void startLocationUpdates() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(AddVisitActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
Snackbar.make(findViewById(android.R.id.content),
"Please Grant Permissions",
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(AddVisitActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddVisitActivity.this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, AddVisitActivity.this);
Log.d(TAG, "Location update started ...: ");
}
}
}).show();
} else {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ...: ");
}
}
}
使用 gpsChecker() 请求代码 1000 和 onActivityResult() 我已经做到了。
if (requestCode == 1000) {
switch (resultCode) {
case Activity.RESULT_OK:
Log.i(TAG, "User agreed to make required location settings changes.");
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Log.i(TAG, "User chose not to make required location settings changes.");
finish();
break;
}
}
当我在某些设备上执行此代码时,它可以正常工作,而在某些设备上,位置请求会自动设置为 Device Only 或 Battery Saving虽然我设置了 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
注意:小米Note 4、vivo V9 Pro、小米Note 5 Pro等部分设备出现问题
那么我需要在我的代码中更改什么才能使其在高精度下正常工作?
使用 GPS 提供商尝试此解决方案并确保您的 GPS 服务已开启。
静态最终整数LOCATION_INTERVAL = 1000; 静态最终浮点数 LOCATION_DISTANCE = 10f;
//放在onCreate()中; LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
mprovider = locationManager.getBestProvider(criteria, false);
if (mprovider != null && !mprovider.equals("")) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(mprovider);
locationManager.requestLocationUpdates(mprovider, LOCATION_INTERVAL, LOCATION_DISTANCE, this);
if (location != null)
onLocationChanged(location);
else
Toast.makeText(getBaseContext(), "No Location Provider Found Check Your Code", Toast.LENGTH_SHORT).show();
}
//put this LocationListener after onCreate();
public LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e(String.format("%f, %f", location.getLatitude(), location.getLongitude()), "");
Log.e("Location available", "Location available");
locationManager.removeUpdates(mLocationListener);
} else {
Log.e("Location is null", "Location is null");
}
current_latitude = location.getLatitude();
current_longitude = location.getLongitude();
/* LatLng latLng = new LatLng(current_latitude, current_longitude);
points.add(latLng);
redrawLine();*/
Log.e("current_latitude", String.valueOf(current_latitude));
Log.e("current_longitude", String.valueOf(current_longitude));
if (location.hasSpeed()) {
//progressBarCircularIndeterminate.setVisibility(View.GONE);
String speed = String.format(Locale.ENGLISH, "%.0f", location.getSpeed() * 3.6) + "km/h";
SpannableString s = new SpannableString(speed);
s.setSpan(new RelativeSizeSpan(0.25f), s.length() - 4, s.length(), 0);
txt_current_speed.setText(s);
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
终于通过改变解决了
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
至
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
并更改
private static final long INTERVAL = 1000 * 60 * 60;
private static final long FASTEST_INTERVAL = 1000 * 5;
间隔时间为 30 分钟,最快间隔时间为 5 秒,这意味着在 5 秒后获取一次位置,然后将在 30 分钟内获取新位置。