融合位置问题 - 地理定位不起作用
Fused Location Issue - Geo localization not work
我必须使用所有可用传感器之一(例如 wifi、gps、数据 ecc)实现 return 用户当前地理位置的功能。
我查找了有关它的信息并找到了几个解决方案,目前我感兴趣的是 "fused location" 的使用,但我没有找到指南或完整的使用示例。
这是我目前使用的代码:
public class LocationService extends Service {
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private Boolean mRequestingLocationUpdates;
private WriteInLogFile wil = new WriteInLogFile();
@Override
public void onCreate() {
try {
DbGest db = DbGest.getInstance(getApplicationContext());
String deviceType = db.getSetting("deviceType");
long updateInterval;
if (deviceType.compareToIgnoreCase("smartphone") == 0) {
updateInterval = Long.parseLong(db.getSetting("pollGPSPhone"));
} else {
updateInterval = Long.parseLong(db.getSetting("pollGPSTablet"));
}
long updateInMillisecond = updateInterval / 2;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(updateInterval);
mLocationRequest.setFastestInterval(updateInMillisecond);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mRequestingLocationUpdates = false;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrentLocation = locationResult.getLastLocation();
updateLocation();
}
};
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setNeedBle(true);
mLocationSettingsRequest = builder.build();
startLocationUpdates();
} catch (Exception e) {
wil.WriteFile("1)LocationService - Exception: " + e.toString());
}
}
public void startLocationUpdates() {
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
mSettingsClient.checkLocationSettings(mLocationSettingsRequest).addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
wil.WriteFile("2)LocationService - Exception: " + e.toString());
}
});
}
}
private void stopLocationUpdates() {
if (!mRequestingLocationUpdates) {
return;
}
mFusedLocationClient.removeLocationUpdates(mLocationCallback).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
mRequestingLocationUpdates = false;
}
});
}
private void updateLocation() {
if (mCurrentLocation != null) {
DbGest.getInstance(getApplicationContext()).insertIntoLastPositionKnown(mCurrentLocation, getApplicationContext());
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
@Override
public IBinder onBind(Intent intent) {
return null;
} }
在这种情况下,如果我通过 Wi-Fi 连接到网络,代码可以正常工作,但是当我切换到 3g 时出现错误:
com.google.android.gms.common.api.ResolvableApiException: 6:
RESOLUTION_REQUIRED
在gradle中:
compile 'com.google.android.gms:play-services-gcm:11.6.2'
compile 'com.google.android.gms:play-services-vision:11.6.2'
compile 'com.google.android.gms:play-services-location:11.6.2'
compile 'com.google.android.gms:play-services-maps:11.6.2'
我不知道如何解决这个问题...
获取位置可能需要一些时间,我建议在后台处理它会使体验更流畅。检查您是否获得了权限,您的应用是否已启用该权限。如果您需要进一步的帮助,请 post 登录。我试过这段代码并且工作正常!
private void getUserLocation() {
FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
});
}
}
遇到同样错误的人:
它会在您调用
时出现
new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
或
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
我的解决方案 - 不调用 .addLocationRequest(...)
当我在添加请求的同一时刻调用 builder.addLocationRequest
和 task = client.checkLocationSettings(builder.build())
时发生此错误。
参见 https://developer.android.com/training/location/change-location-settings#get-settings
我必须使用所有可用传感器之一(例如 wifi、gps、数据 ecc)实现 return 用户当前地理位置的功能。
我查找了有关它的信息并找到了几个解决方案,目前我感兴趣的是 "fused location" 的使用,但我没有找到指南或完整的使用示例。
这是我目前使用的代码:
public class LocationService extends Service {
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private Boolean mRequestingLocationUpdates;
private WriteInLogFile wil = new WriteInLogFile();
@Override
public void onCreate() {
try {
DbGest db = DbGest.getInstance(getApplicationContext());
String deviceType = db.getSetting("deviceType");
long updateInterval;
if (deviceType.compareToIgnoreCase("smartphone") == 0) {
updateInterval = Long.parseLong(db.getSetting("pollGPSPhone"));
} else {
updateInterval = Long.parseLong(db.getSetting("pollGPSTablet"));
}
long updateInMillisecond = updateInterval / 2;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(updateInterval);
mLocationRequest.setFastestInterval(updateInMillisecond);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mRequestingLocationUpdates = false;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrentLocation = locationResult.getLastLocation();
updateLocation();
}
};
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setNeedBle(true);
mLocationSettingsRequest = builder.build();
startLocationUpdates();
} catch (Exception e) {
wil.WriteFile("1)LocationService - Exception: " + e.toString());
}
}
public void startLocationUpdates() {
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
mSettingsClient.checkLocationSettings(mLocationSettingsRequest).addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
wil.WriteFile("2)LocationService - Exception: " + e.toString());
}
});
}
}
private void stopLocationUpdates() {
if (!mRequestingLocationUpdates) {
return;
}
mFusedLocationClient.removeLocationUpdates(mLocationCallback).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
mRequestingLocationUpdates = false;
}
});
}
private void updateLocation() {
if (mCurrentLocation != null) {
DbGest.getInstance(getApplicationContext()).insertIntoLastPositionKnown(mCurrentLocation, getApplicationContext());
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
@Override
public IBinder onBind(Intent intent) {
return null;
} }
在这种情况下,如果我通过 Wi-Fi 连接到网络,代码可以正常工作,但是当我切换到 3g 时出现错误:
com.google.android.gms.common.api.ResolvableApiException: 6: RESOLUTION_REQUIRED
在gradle中:
compile 'com.google.android.gms:play-services-gcm:11.6.2'
compile 'com.google.android.gms:play-services-vision:11.6.2'
compile 'com.google.android.gms:play-services-location:11.6.2'
compile 'com.google.android.gms:play-services-maps:11.6.2'
我不知道如何解决这个问题...
获取位置可能需要一些时间,我建议在后台处理它会使体验更流畅。检查您是否获得了权限,您的应用是否已启用该权限。如果您需要进一步的帮助,请 post 登录。我试过这段代码并且工作正常!
private void getUserLocation() {
FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
});
}
}
遇到同样错误的人: 它会在您调用
时出现 new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
或
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
我的解决方案 - 不调用 .addLocationRequest(...)
当我在添加请求的同一时刻调用 builder.addLocationRequest
和 task = client.checkLocationSettings(builder.build())
时发生此错误。
参见 https://developer.android.com/training/location/change-location-settings#get-settings