我正在为一个班级项目开发里程跟踪应用程序,但是在停止里程跟踪服务时遇到了问题。我的“家庭”活动通过以下方式启动服务:
private void startGPSTracking() {
startService(new Intent(this, GPSTracking.class));
}
并且当用户单击“停止行程”按钮时,将称为:
private void stopGPSTracking() {
//TODO this isn't stopping the service
stopService(new Intent(this, GPSTracking.class));
Toast.makeText(Home.this, "Trip Recorded", Toast.LENGTH_SHORT).show();
Log.d("Stop GPS Tracking", "Tracking Stopped");
}
我正在获取祝酒词和日志条目,但这就像服务仍在侦听中一样。我的应用程序崩溃是因为调用了requestLocationUpdates(),但是没有有效/开放的旅程。跟踪服务中的stopSelf()也会发生相同的情况。
public class GPSTracking extends Service {
private FusedLocationProviderClient fusedLocationProviderClient;
private LocationRequest locationRequest;
//get user ID from authentication
String user_uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
//gets current GPS DB record
DatabaseReference databaseGPS = FirebaseDatabase.getInstance().getReference("gps").child(user_uid);
//gets current profile DB record
DatabaseReference databaseProfile = FirebaseDatabase.getInstance().getReference("profiles").child(user_uid);
String key;
double curLat, curLong, startLat, startLong, endLat, endLong = 0;
long curTime, startTime, endTime = 0;
double cost, mileage_rate;
int pause_time, count;
long duration;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
databaseProfile.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mileage_rate = dataSnapshot.child("mileage_rate").getValue(double.class);
pause_time = dataSnapshot.child("pause_time").getValue(int.class);
pause_time = pause_time--;
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
callPermissions();
}
private void loginToFirebase() {
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
//TODO how do you authenticate Realtime database with FirebaseAuth user?
String password = "xxxxxxxx";
FirebaseAuth.getInstance().signInWithEmailAndPassword(
email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(Task<AuthResult>task) {
if (task.isSuccessful()) {
addNewTrip();
} else {
Log.d("GPS Service", "Firebase Authentication failed");
}
}
});
}
private void addNewTrip() {
double cost = 54.5;
Trip trip = new Trip(mileage_rate);
key = databaseGPS.push().getKey();
Log.e("addNewTrip", "key: " + key);
databaseGPS.child(key).setValue(trip).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
//key = databaseGPS.getKey();
Toast.makeText(GPSTracking.this, "Trip Started", Toast.LENGTH_SHORT).show();
requestLocationUpdates();
} else {
Toast.makeText(GPSTracking.this, "Problem Starting Trip", Toast.LENGTH_SHORT).show();
}
}
});
}
private void requestLocationUpdates() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PermissionChecker.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PermissionChecker.PERMISSION_GRANTED) {
fusedLocationProviderClient = new FusedLocationProviderClient(this);
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setFastestInterval(60000);
locationRequest.setInterval(60000);
fusedLocationProviderClient.requestLocationUpdates(locationRequest, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
curLat = locationResult.getLastLocation().getLatitude();
curLong = locationResult.getLastLocation().getLongitude();
curTime = locationResult.getLastLocation().getTime();
if (curLat != 0 && curLong != 0 && startLat == 0 && startLong == 0) {
//starting a trip - start & end values are null
Log.e("Location", "Just starting trip");
updateStartpoint();
updateEndpoint();
return;
} else if ((curLat == endLat || curLong == endLong) && count == pause_time) {
//pause time reached - close the trip and complete calculations
updatedEndTime();
duration = endTime - startTime;
databaseGPS.child(key).child("duration").setValue(duration);
Log.e("Location", "Ending a trip");
initializeTrip();
stopGPSTracking();
return;
} else if ((curLat == endLat || curLong == endLong) && count < pause_time) {
//driving paused but pause time not reached - update pause time & increment count
Log.e("Location", "trip paused");
updatedEndTime();
count++;
return;
} else if ((curLat != startLat || curLong != startLong || curLat != endLat || curLong != endLong) && endTime != 0) {
//trip started but driving not paused - update ends
Log.e("Location", "driving");
if (curLat == endLat) { Log.e("Driving", "curLat == endLat"); };
count = 0;
updateEndpoint();
return;
}
}
}, getMainLooper());
} else callPermissions();
}
public void callPermissions() {
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
String rationale = "GPS Tracking - Please provide location permission to allow AutoMile to track your mileage.";
Permissions.Options options = new Permissions.Options()
.setRationaleDialogTitle("Info")
.setSettingsDialogTitle("Warning");
Permissions.check(this/*context*/, permissions, rationale, options, new PermissionHandler() {
@Override
public void onGranted() {
loginToFirebase();
Log.e("gpstracking", "permission granted");
}
@Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
super.onDenied(context, deniedPermissions);
callPermissions();
}
});
}
public void updateStartpoint() {
startLat = curLat;
startLong = curLong ;
startTime = curTime;
databaseGPS.child(key).child("start_lat").setValue(startLat);
databaseGPS.child(key).child("start_long").setValue(startLong);
databaseGPS.child(key).child("start_time").setValue(startTime);
}
public void updateEndpoint() {
endLat = curLat;
endLong = curLong;
endTime = curTime;
Log.e("Location", " Update End Point called: " + count);
databaseGPS.child(key).child("end_lat").setValue(endLat);
databaseGPS.child(key).child("end_long").setValue(endLong);
databaseGPS.child(key).child("end_time").setValue(endTime);
}
private void updatedEndTime() {
endTime = curTime;
databaseGPS.child(key).child("end_time").setValue(endTime);
}
private void initializeTrip() {
key = null;
curLat = 0;
curLong = 0;
curTime = 0;
startLat = 0;
startLong = 0;
startTime = 0;
endLat = 0;
endLong = 0;
endTime = 0;
cost = 0;
mileage_rate = 0;
pause_time = 0;
count = 0;
duration = 0;
}
private void stopGPSTracking() {
//TODO this isn't stopping the service
//stopService(new Intent(this, GPSTracking.class));
stopSelf();
Toast.makeText(GPSTracking.this, "Trip Recorded", Toast.LENGTH_SHORT).show();
Log.e("Stop GPS Tracking", "Tracking Stopped");
}
}
我确定我的代码格式不正确,已经问了一百万遍了,但是我似乎无法弄清楚如何将其应用于我的场景。感谢您的温柔,友善和任何见解。
答案 0 :(得分:0)
您应该在服务中覆盖onDestroy()并注销位置回调。如果您不这样做,它将在您停止服务后继续监听。