1

So I have gotten the GPS to track and log my position continously from when I "press play". And I want to display the distance traveled, the average speed, the ascent and descent during the time spent.

I am logging my position with my "LocationsService.java"-class using the startLocationService(), which is looping through the LocationCallback (i think). I used the code I got from @TDIScott to create a hashmap that I put into a list.

public List<Map<Long, Location>> locationHistory = new ArrayList<>();

private LocationCallback locationCallback = new LocationCallback(){
    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
        if(locationResult != null && locationResult.getLastLocation() != null){
            double latitude = locationResult.getLastLocation().getLatitude();
            double longitude = locationResult.getLastLocation().getLongitude();
            int altitude = (int) locationResult.getLastLocation().getAltitude();
            double speed = locationResult.getLastLocation().getSpeed();
            Log.d("LOCATION_UPDATE", latitude + ", " + longitude + ", " + altitude + ", " + speed + ", " + System.currentTimeMillis() + ", " + locationResult.getLastLocation());

            Map<Long, Location> temp = new HashMap<>();
            temp.put(System.currentTimeMillis(), locationResult.getLastLocation());
            locationHistory.add(temp);
        }
    }
};

private void startLocationService() {
    String channelId = "location_notification_channel";
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Intent resultIntent = new Intent();
    PendingIntent pendingIntent = PendingIntent.getActivity(
            getApplicationContext(),
            0,
            resultIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
    );
    NotificationCompat.Builder builder = new NotificationCompat.Builder(
            getApplicationContext(),
            channelId
    );
    builder.setSmallIcon(R.mipmap.ic_launcher);
    builder.setContentTitle("iAthletics is recording"); //Endre til iAthletics is recording
    builder.setDefaults(NotificationCompat.DEFAULT_ALL);
    builder.setContentText("Running");
    builder.setContentIntent(pendingIntent);
    builder.setAutoCancel(false);
    builder.setPriority(NotificationCompat.PRIORITY_MAX);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if (notificationManager != null && notificationManager.getNotificationChannel(channelId) == null) {
            NotificationChannel notificationChannel = new NotificationChannel(channelId, "Location Service", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setDescription("This channel is used by location service");
            notificationManager.createNotificationChannel(notificationChannel);
        }
    }

    LocationRequest locationRequest = new LocationRequest();
    locationRequest.setInterval(1000);
    locationRequest.setFastestInterval(500);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationServices.getFusedLocationProviderClient(this).requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); //TODO Husk eventuell permission check hvis det ikke funker
    startForeground(Constants.LOCATION_SERVICE_ID, builder.build());
}

Updated question: How can I access the location-objects in the list created in the "LocationSevice.java"-class, and calculate the average speed, distance, ascent and descent? From the activity-class.

PS: I have tried the second code provided by TDIScott and it does not work.

If it is needed, here is how the locationobject is stored in the log and probably in the list:

Location[fused 59,896346,10,621862 hAcc=31 et=+4d21h21m52s480ms alt=65.79999542236328 vel=0.10678082 bear=100.58679 vAcc=11 sAcc=??? bAcc=??? {Bundle[mParcelledData.dataSize=52]

  • Yes calculate distance between for all intervals. Just sum them up. – blackapps Jul 16 '20 at 10:07
  • Can you tell me how to do that? Or at least point me in some direction on how? Total rookie when it comes to programming as I have learned what I have done by wathing tutorials etc by myself the last couple of months. Thanks. – AndreasAngel Jul 16 '20 at 10:17
  • Why would not it be possible to calculate the distance there? Start with one calculation only. You should remember last location to do the calculation. – blackapps Jul 16 '20 at 10:25
  • The problem is that I dont now how to "hold on to" the previous location and use it in a calculation. It is no problem, I think, to calulate it if I knew how to "hold on" to my previous location... So the question then is: How can I create a variable on the previous location? – AndreasAngel Jul 16 '20 at 10:42
  • double lastlatitude = 0; Put that as class variable. (Not in onLocationResult). Then in onLocationResult at the end if (lastlatitude > 0.0){ double dist = distancebetween(latitude, lastlatitude); lastlatitude= latitude;} – blackapps Jul 16 '20 at 10:49

2 Answers2

0

You can either store the data in a list of LocationResult so you say the distance between two times in more detail or just add them up as you go along.

Storing:

    List<Map<Long,LocationResult> locationHistory = new ArrayList();
    private LocationCallback locationCallback = new LocationCallback(){
@Override
public void onLocationResult(LocationResult locationResult) {
    super.onLocationResult(locationResult);
    if(locationResult != null && locationResult.getLastLocation() != null){
        double latitude = locationResult.getLastLocation().getLatitude();
        double longitude = locationResult.getLastLocation().getLongitude();
        int altitude = (int) locationResult.getLastLocation().getAltitude();
        Log.d("LOCATION_UPDATE", latitude + ", " + longitude + ", " + altitude);

        Map<Long, LocationResult> temp = new HashMap<>();
        temp.put(System.currentTimeMillis(), locationResult);

        locationHistory.add(temp);
    }
}
};

With the above, you now have a key of time in milliseconds and a value of LocationResult.

You can iterate via

    Map<Long, LocationResult> locationHistory = new HashMap<>();
    LocationResult temp = null;
    float distance = 0;
    for (Map.Entry<Long, LocationResult> entry : locationHistory.entrySet()) {
        if(temp != null){
            distance += temp.distanceTo(entry.getValue());
            temp = entry.getValue();
        }
    }

    textView.setText(String.valueOf(distance));

Now you have the LocationResult, add them up and do what you need. Be that calculate the distance, rise and decrease in altitude etc.

Scott Johnson
  • 707
  • 5
  • 13
  • The iteration for loop. what does that actually do and where should I put it? Sorry if its a stupid question. What do you mean by "just add them up as I go aloing" and how do I do that? – AndreasAngel Jul 16 '20 at 13:00
  • @AndreasAngel it literally just iterates through the `List>` you would do that where/when you want to update the View you mentioned – Scott Johnson Jul 16 '20 at 13:27
  • Thanks. That clearifies! :) So my locationService is in a separate class than where my TextView is and I've declared the list as a class variable: List> locationHistory; And made a separate method that I called "updateDistance" where I put the for-loop, in the class where the TextView is. How and where do I set up the calculation to calculate the distance? In the for-loop? Thanks again. – AndreasAngel Jul 16 '20 at 14:05
  • So I have updated the main question and code as I seem to get the hashmap and list to work, but the iteration code does not work. I appriciate your help, so If you could take another look at the code in the main question and help me get access to the object in the list from my activityclass, I would be grateful. @TDIScott – AndreasAngel Jul 17 '20 at 15:44
-1

You can check for any package available for geolocation.