0

创建以下服务以不断更新用户位置。即使应用程序在后台,设备空闲或屏幕关闭或应用程序从最近列表中删除/杀死,也必须跟踪用户的位置。

但不知何故,这段代码不起作用。位置更新在一段时间后自动停止,并且在某些设备上它不起作用;甚至无法正常工作我不明白为什么,我已将所有内容从蓝色变为紫色。

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();
    }
 }
4

1 回答 1

0

对于运行 Android Oreo 的设备,您无法实现这一点。但是对于其他人,您可以通过设置来实现这一点

 <service
            android:name=".YourLocationService"
            android:exported="false"
            android:process=":YourLocationService"
            android:stopWithTask="false" />

在您的清单文件中。是这里stopWithTask="false"的关键。

@Override
    public void onTaskRemoved(Intent rootIntent) {

        Intent restartService = new Intent(getApplicationContext(), this.getClass());
        PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME, 5000, pendingIntent);


    }
于 2017-11-27T11:06:23.573 回答