@Override
public void onCreate() {
super.onCreate();
mContext = this;
sessionManager = new SessionManager(this);
jsonArrayPickUp = new JSONArray();
jsonArrayArrived = new JSONArray();
if (sessionManager.getBeginJourney()) {
distancespd = sessionManager.getDistanceInDouble();
} else {
distancespd = 0.0;
}
if (!sessionManager.getRouteArray().isEmpty() && (sessionManager.getAppointmentStatus() == 8)) {
try {
jsonArray = new JSONArray(sessionManager.getRouteArray());
JSONObject jsonObject = jsonArray.getJSONObject(0);
if (jsonObject.has("bid")) {
if (!jsonObject.get("bid").equals(sessionManager.getBid())) {
sessionManager.setRouteArray("");
jsonArray = new JSONArray();
}
}
} catch (JSONException e) {
Timber.e(CommonUtils.getExceptionString(e));
}
} else {
jsonArray = new JSONArray();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timber.d("AAA ForegroundService onStartCommand called");
try {
if (intent.getAction().equals(VariableConstants.ACTION.STARTFOREGROUND_ACTION)) {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(VariableConstants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(getResources().getString(R.string.foreground_channel), this.getString(R.string.app_name),
NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
notification = new NotificationCompat.Builder(this, getResources().getString(R.string.foreground_channel))
.setContentTitle(getResources().getString(R.string.app_name))
.setTicker("")
.setContentText("Driver online")
.setSmallIcon(R.drawable.notification_logo)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setAutoCancel(false)
.setChannelId(getResources().getString(R.string.foreground_channel))
.setOngoing(true).build();
}
mSubscribePubNubChannel();
startForeground(VariableConstants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
if (!isforegroundServiceStarted) {
isforegroundServiceStarted = true;
createLocationRequest();
startPublishingWithTimer();
}
} else if (intent.getAction().equals(
VariableConstants.ACTION.STOPFOREGROUND_ACTION)) {
stopForeground(true);
stopSelf();
}
} catch (NullPointerException e) {
Timber.e("Crash in foreground service");
Timber.e(CommonUtils.getExceptionString(e));
}
return START_STICKY;
}
public void mSendNotification() {
Intent intent = new Intent(ForegroundService.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
/***************************************************************/
private void createLocationRequest() {
if (mLocationRequest == null && locationCallback == null) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setSmallestDisplacement(5);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
initLocation();
}
}
private void initLocation() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Utility.showToast(ForegroundService.this,"Please give location permissions");
}
});
task.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
startLocationUpdates();
}
});
}
@SuppressLint("MissingPermission")
private void startLocationUpdates() {
if (locationCallback != null)
getFusedLocationProviderClient(this).removeLocationUpdates(locationCallback);
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
double currentLat = location.getLatitude();
double currentLng = location.getLongitude();
Utility.printLog("location Updates: current lat long " + currentLat + " " + currentLng);
Utility.printLog("location Updates: previous lat long " + sessionManager.getDriverPrevLat() + " " + sessionManager.getDriverPrevLng());
sessionManager.setDriverCurrentLat("" + currentLat);
sessionManager.setDriverCurrentLng("" + currentLng);
if (sessionManager.getAppointmentStatus() != 4) {
Timber.d("status...." + sessionManager.getAppointmentStatus());
calculateRouteArray(
currentLat,
currentLng,
sessionManager.getDriverPrevLat(),
sessionManager.getDriverPrevLng());
} else {
if (jsonArrayPickUp.length() > 0) {
jsonArrayPickUp = new JSONArray();
}
}
// Timber.d("ForegroundService Pk lat:" + sessionManager.getDriverCurrentLat() + " long: " + sessionManager.getDriverCurrentLng());
if (sessionManager.getIsPassengerDropped()) {
sessionManager.setIsPassengerDropped(false);
distancespd = 0.0;
sessionManager.setDistanceInDouble("" + 0.0);
sessionManager.setDriverPrevLat("");
sessionManager.setDriverPrevLng("");
jsonArray = new JSONArray();
Timber.d("Journey jsonArray " + jsonArray.toString());
}
}
}
};
getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest,
locationCallback, null);
}
public void calculateRouteArray(final double curLat, final double curLong, final double previousLat, final double previousLong) {
double dis;
double distanceInMtr = 0.0;
if (previousLat == 0.0 || previousLong == 0.0) {
sessionManager.setDriverPrevLat("" + curLat);
sessionManager.setDriverPrevLng("" + curLong);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("lat", curLat);
jsonObject.put("long", curLong);
jsonObject.put("dist", sessionManager.getDistance());
jsonObject.put("bid", sessionManager.getBid());
jsonObject.put("timestamp", new Date().getTime());
} catch (JSONException e) {
Timber.e(CommonUtils.getExceptionString(e));
}
if (sessionManager.getAppointmentStatus() == 8) {
jsonArray.put(jsonObject);
sessionManager.setRouteArray(jsonArray.toString());
Timber.d("Array: RouteArray " + sessionManager.getRouteArray());
} else if (sessionManager.getAppointmentStatus() == 6) {
jsonArrayPickUp.put(jsonObject);
sessionManager.setPickUpRouteArray(jsonArrayPickUp.toString());
Timber.d("Array: PickUpRouteArray " + sessionManager.getPickUpRouteArray());
} else if (sessionManager.getAppointmentStatus() == 7) {
jsonArrayArrived.put(jsonObject);
sessionManager.setArrivedRouteArray(jsonArrayArrived.toString());
Timber.d("Array: ArrivedRouteArray " + sessionManager.getArrivedRouteArray());
}
}
if (previousLat == curLat || previousLong == curLong || previousLat == 0.0 || previousLong == 0.0)
return;
dis = distance(previousLat, previousLong, curLat, curLong, METER);
if (dis >= sessionManager.getMinDistForRouteArray()) {
// Add checking if distance has been reset. If reset, set total distance to 0
if (sessionManager.getDistanceInDouble() <= 0.0) distancespd = 0.0;
sessionManager.setDriverPrevLat("" + curLat);
sessionManager.setDriverPrevLng("" + curLong);
distanceInMtr = dis;
distancespd += distanceInMtr;
sessionManager.setDistanceInDouble("" + distancespd);
distanceKm = distancespd / sessionManager.getDistanceDivider();
strDouble = String.format(Locale.US, "%.2f", distanceKm);
sessionManager.setDistance(strDouble);
Timber.d("Calculated distance from last point in meter " + distanceInMtr);
Timber.d("Total calculated distance" + distancespd);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("lat", curLat);
jsonObject.put("long", curLong);
jsonObject.put("timestamp", new Date().getTime());
jsonObject.put("bid", sessionManager.getBid());
jsonObject.put("dist", sessionManager.getDistanceInDouble());
} catch (JSONException e) {
Timber.e(CommonUtils.getExceptionString(e));
}
if (sessionManager.getAppointmentStatus() == 8) {
if (jsonArrayArrived.length() > 0) {
jsonArrayArrived = new JSONArray();
}
jsonArray.put(jsonObject);
sessionManager.setRouteArray(jsonArray.toString());
Timber.d("Array:Session route array" + sessionManager.getRouteArray());
} else if (sessionManager.getAppointmentStatus() == 6) {
jsonArrayPickUp.put(jsonObject);
sessionManager.setPickUpRouteArray(jsonArrayPickUp.toString());
Timber.d("Array:Pickup route array" + sessionManager.getPickUpRouteArray());
} else if (sessionManager.getAppointmentStatus() == 7) {
if (jsonArrayPickUp.length() > 0) {
jsonArrayPickUp = new JSONArray();
}
jsonArrayArrived.put(jsonObject);
sessionManager.setArrivedRouteArray(jsonArrayArrived.toString());
Timber.d("Array:Arrived route array" + sessionManager.getArrivedRouteArray());
}
}
}
public static double distance(double lat1, double lng1, double lat2, double lng2, String unit) {
double earthRadius = 3958.75; // miles (or 6371.0 kilometers)
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double sindLat = Math.sin(dLat / 2);
double sindLng = Math.sin(dLng / 2);
double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2) * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = earthRadius * c;
if (KILOMETER.equals(unit)) // Kilometer
{
dist = dist * 1.609344;
} else if (NAUTICAL_MILES.equals(unit)) // Nautical Miles
{
dist = dist * 0.8684;
} else if (METER.equals(unit)) // meter
{
dist = dist * 1609.344;
}
return dist;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean isApplicationSentToBackground(final Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
return false;
}
@Override
public void onDestroy() {
super.onDestroy();
if (locationCallback != null)
getFusedLocationProviderClient(this).removeLocationUpdates(locationCallback);
if (timerHandler != null) {
timerHandler.removeCallbacksAndMessages(null);
}
isforegroundServiceStarted = false;
Timber.d("AAA ForegroundService destroy called");
mUnsubscribePubNub();
if (!sessionManager.getAppRunning() && sessionManager.isUserLogdIn()) {
Utility.printLog("in stop service and restart");
Intent broadcastIntent = new Intent(ForegroundService.this, ServiceRestartBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
}
}
我正在我们的应用程序中使用此服务来计算驾驶员在旅途中移动时的距离。驱动程序的OnLocationUpdate我正在使用calculateRouteArray()计算距离。在大多数时候,一切都按预期进行。 但是有时它恰好是计算出的行进距离的两倍。
此问题可能与监听器运行两次或服务在后台运行两次有关。但是我到处都有国旗。我无法查明计算双倍距离的原因。
先谢谢您