创建以下服务以不断更新用户位置。即使应用程序在后台,设备空闲或屏幕关闭或应用程序从最近列表中删除/杀死,也必须跟踪用户的位置。
但不知何故,这段代码不起作用。位置更新在一段时间后自动停止,并且在某些设备上它不起作用;甚至无法正常工作我不明白为什么,我已将所有内容从蓝色变为紫色。
gradle:2.3.3 播放服务和地图版本:11.0.4 编译 sdk 版本:25
## 但我在 Android 6.0.1 Marshmallow 上运行此应用请帮我解决这个问题。提前致谢。
public class ServiceLocationNew extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final long INTERVAL = 10000;
private static final long FASTEST_INTERVAL = 10000;
private static final long FUSED_DISTANCE = 5;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
Location mLastLocation;
@Override
public void onCreate() {
super.onCreate();
buildApiClient();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (mGoogleApiClient == null) {
buildApiClient();
}
if (!isGooglePlayServicesAvailable()) {
stopSelf();
}
createLocationRequest();
return START_STICKY;
}
public void buildApiClient() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
return false;
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
startLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
@Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
updateUI();
}
if (mGoogleApiClient.isConnected()) {
if (mLocationRequest != null) {
startLocationUpdates();
} else {
createLocationRequest();
}
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
updateUI();
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
public static float distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
float dist = (float) (earthRadius * c);
return dist;
}
private void updateUI() {
if (mCurrentLocation != null) {
//calculate distance between current and last location
double dLon = (Double.parseDouble(mLastLocation.getLongitude) - mCurrentLocation.getLongitude());
double y = Math.sin(dLon) * Math.cos(Double.parseDouble(mLastLocation.getLatitude));
double x = Math.cos(mCurrentLocation.getLatitude()) * Math.sin(Double.parseDouble(mLastLocation.getLatitude)) - Math.sin(mCurrentLocation.getLatitude()) * Math.cos(Double.parseDouble(mLastLocation.getLatitude)) * Math.cos(dLon);
double brng = Math.toDegrees((Math.atan2(y, x)));
brng = (360 - ((brng + 360) % 360));
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(mCurrentLocation.getLatitude() - mLastLocation.getLatitude());
double dLng = Math.toRadians(mCurrentLocation.getLongitude() - mLastLocation.getLongitude());
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
float distance = (float) (earthRadius * c);
if (distance >= CV.LOCATION_DISTANCE) {
Tblname.Insert(mCurrentLocation);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
}
}