首页 > 解决方案 > 我无法停止服务开始获取最后一个位置

问题描述

我从活动 (TrackerActivity) 启动服务 (TrackerService),以获取我的应用程序当前用户的最后位置。然后我显示当前用户的实时位置和登录 Firebase 数据库的我的应用程序的所有用户的标记(在 LentiMapsActivity 中)。

最后,我尝试将服务停止到 LentiMapsActivity 并返回到 MainActivity:

@Override
protected void onStop() {
    Intent intent = new Intent(LentiMapsActivity.this,TrackerService.class);
    stopService (intent);
    Log.d(TAG,"Stop the service");
    super.onStop();
}

但服务仍在运行。

这是我的 TrackerService 代码

public class TrackerService extends Service {

private FirebaseAuth mAuth;

private static final String TAG = TrackerService.class.getSimpleName();

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}

@Override
public void onCreate() {
    super.onCreate();
    requestLocationUpdates();
}

@Override
public void onDestroy() {
    stopSelf(2);
    Log.d(TAG,"Start onDestroy");
}

private void requestLocationUpdates() {
    LocationRequest request = new LocationRequest();
    request.create();
    request.setInterval(10000);
    request.setFastestInterval(5000);
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
    int permission = ContextCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);
    if (permission == PackageManager.PERMISSION_GRANTED) {
        client.requestLocationUpdates(request, new LocationCallback() {

            @Override
            public void onLocationResult(LocationResult locationResult) {
                final String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
                DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
                DatabaseReference latlongRef = rootRef.child("Users").child(uid).child("latlong");
                Location location = locationResult.getLastLocation();
                if (location != null) {
                    Log.d(TAG, "location update " + location);
                    latlongRef.setValue(location);
                }
            }
        }, null);
    }
}
}

和 LentiMapsActivity

public class LentiMapsActivity extends FragmentActivity implements OnMapReadyCallback{

private GoogleMap mMap;
private static final String TAG = LentiMapsActivity.class.getSimpleName();
List<String> localList;
private static final int PERMISSIONS_REQUEST = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lenti_maps);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    localList = new ArrayList<String>();

    Intent intent = new Intent(LentiMapsActivity.this, TrackerActivity.class);
    startActivity(intent);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMaxZoomPreference(16);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
        == PackageManager.PERMISSION_GRANTED
            || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        == PackageManager.PERMISSION_GRANTED) {
    mMap.setMyLocationEnabled(true);
}
    loadUsers ();
}

private void loadUsers() {
    final String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    final DatabaseReference usersRef = rootRef.child("Users");

    rootRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                String key = dataSnapshot1.getKey();
                localList.add(key);

                Local localCurrent = dataSnapshot.child(uid).child("latlong").getValue(Local.class);
                LatLng latLngCurrent = new LatLng(localCurrent.getLatitude(),localCurrent.getLongitude());

                for (int i = 0; i<localList.size(); i++)
                {
                    Local local = dataSnapshot.child(key).child("latlong").getValue(Local.class);
                    Local nick = dataSnapshot.child(key).getValue(Local.class);
                    if (local != null){
                        LatLng latLng = new LatLng(local.getLatitude(),local.getLongitude());
                        if (mMap != null)
                        {
                            mMap.addMarker(new MarkerOptions().position(latLng).title(nick.getNickname()));
                            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCurrent,11));
                        }
                    }
                }
            }
        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

@Override
protected void onStop() {
    Intent intent = new Intent(LentiMapsActivity.this,TrackerService.class);
    stopService (intent);
    Log.d(TAG,"Stop the service");
    super.onStop();
}

}

从日志:

D/FA: Connected to remote service
V/FA: Processing queued up service tasks: 4
D/EGL_emulation: eglMakeCurrent: 0x99315f40: ver 2 0 (tinfo 0x99338c00)
D/LentiMapsActivity: Stop the service
D/TrackerService: Start onDestroy
D/TrackerService: location update Location[fused 45.460000,9.150000 acc=12 et=+5d21h19m25s455ms vel=0.0 bear=0.0]
V/FA: Inactivity, disconnecting from the service
D/TrackerService: location update Location[fused 45.460000,9.150000 acc=12 et=+5d21h19m30s458ms vel=0.0 bear=0.0]
D/TrackerService: location update Location[fused 45.460000,9.150000 acc=12 et=+5d21h19m35s460ms vel=0.0 bear=0.0]
D/TrackerService: location update Location[fused 45.460000,9.150000 acc=12 et=+5d21h19m41s463ms vel=0.0 bear=0.0]

标签: androidfirebase-realtime-databaseandroid-service

解决方案


Service的的确确正在被摧毁。但这并不一定意味着您的应用程序已终止;根据您使用的 Android 版本,它可能会持续存在几秒钟到几天不等。

如果您的应用未终止,您的代码将无法禁用位置更新。在这种情况下,解决方案是将调用添加removeLocationUpdates()到您的TrackerService.onDestroy()方法。

编辑

示例代码:

public class TrackerService extends Service {

    ...

    private LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            final String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
            DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
            DatabaseReference latlongRef = rootRef.child("Users").child(uid).child("latlong");
            Location location = locationResult.getLastLocation();
            if (location != null) {
                Log.d(TAG, "location update " + location);
                latlongRef.setValue(location);
            }
        }
    };

    ...

    @Override
    public void onDestroy() {
        //No need to call this; the Service is already stopping:
        //stopSelf(2);
        FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
        client.removeLocationUpdates(mLocationCallback);
        Log.d(TAG,"Start onDestroy");
    }

    private void requestLocationUpdates() {
        LocationRequest request = new LocationRequest();
        request.create();
        request.setInterval(10000);
        request.setFastestInterval(5000);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
        int permission = ContextCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);
        if (permission == PackageManager.PERMISSION_GRANTED) {
            client.requestLocationUpdates(request, mLocationCallback, null);
        }
    }
}

推荐阅读