commit d8d1a7f114adebc74813e8ddab31396e2f7b4877
parent f63f9b08e23957b926cc136a8dacda900024c5ac
Author: William Lindholm <william_lindholm@outlook.com>
Date: Fri, 5 May 2023 01:11:59 +0200
Implemented sorting algorithm that sorts based on distance from users gps location.
Diffstat:
3 files changed, 107 insertions(+), 10 deletions(-)
diff --git a/app/src/main/java/com/example/project_assignment/MainActivity.java b/app/src/main/java/com/example/project_assignment/MainActivity.java
@@ -1,31 +1,44 @@
package com.example.project_assignment;
+import android.Manifest;
+
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import android.app.Activity;
-import android.content.Intent;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
-import android.view.MotionEvent;
+import android.widget.Toast;
-import com.example.project_assignment.comparators.SortByName;
+import com.example.project_assignment.comparators.SortByLocation;
import com.example.project_assignment.comparators.SortByWeight;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("FieldCanBeLocal")
-public class MainActivity extends AppCompatActivity implements JsonTask.JsonTaskListener {
+public class MainActivity extends AppCompatActivity implements JsonTask.JsonTaskListener, LocationListener {
private final String JSON_URL = "https://data.nasa.gov/resource/y77d-th95.json";
+ private LocationManager locationManager;
+ private SharedPreferences preference;
+ private SharedPreferences.Editor preferenceEditor;
+
+ private ArrayList<Meteorite> meteorites;
+
+ private RecyclerViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -33,6 +46,23 @@ public class MainActivity extends AppCompatActivity implements JsonTask.JsonTas
setContentView(R.layout.activity_main);
new JsonTask(this).execute(JSON_URL);
+
+ preference = getSharedPreferences("preferences", MODE_PRIVATE);
+ preferenceEditor = preference.edit();
+
+ locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+
+ //request permission to use location services: fine location and coarse location.
+ if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+
+ Toast.makeText(MainActivity.this, "The app needs access to location services.", Toast.LENGTH_LONG);
+ ActivityCompat.requestPermissions(MainActivity.this,
+ new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 1);
+ return;
+ }
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
@Override
@@ -40,9 +70,9 @@ public class MainActivity extends AppCompatActivity implements JsonTask.JsonTas
Gson gson = new Gson();
Type type = new TypeToken<List<Meteorite>>() {}.getType();
- ArrayList<Meteorite> meteorites = gson.fromJson(json, type);
+ meteorites = gson.fromJson(json, type);
+
- Collections.sort(meteorites, new SortByWeight());
for (Meteorite m : meteorites) {
Log.d("Meteorite: ", m.toString());
@@ -50,12 +80,24 @@ public class MainActivity extends AppCompatActivity implements JsonTask.JsonTas
RecyclerView recyclerView = findViewById(R.id.recyclerView);
- RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, meteorites);
+ adapter = new RecyclerViewAdapter(this, meteorites);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter.notifyDataSetChanged();
}
+
+ @Override
+ public void onLocationChanged(@NonNull Location location) {
+ System.out.println("LATITUDE = " + location.getLatitude());
+
+ preferenceEditor.putString("latitude", String.valueOf(location.getLatitude()));
+ preferenceEditor.putString("longitude", String.valueOf(location.getLongitude()));
+ preferenceEditor.apply();
+
+ Collections.sort(meteorites, new SortByLocation(MainActivity.this));
+ adapter.notifyDataSetChanged();
+ }
}
diff --git a/app/src/main/java/com/example/project_assignment/Meteorite.java b/app/src/main/java/com/example/project_assignment/Meteorite.java
@@ -94,6 +94,36 @@ public class Meteorite implements Parcelable {
return mass_double;
}
+ //return the distance of the meteorite from any position.
+ public double getDistanceFrom(double userLatitude, double userLongitude) {
+ if (latitude == null) {
+ latitude = "0";
+ }
+ if (longitude == null) {
+ longitude = "0";
+ }
+
+ //1 = user
+ //2 = meteorite
+
+ double meteoriteLatitude = Double.parseDouble(this.latitude);
+ double meteoriteLongitude = Double.parseDouble(this.longitude);
+
+ final int R = 6371; // Radius of the earth
+
+ double latDistance = Math.toRadians(meteoriteLatitude - userLatitude);
+ double lonDistance = Math.toRadians(meteoriteLongitude - userLongitude);
+ double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
+ + Math.cos(Math.toRadians(userLatitude)) * Math.cos(Math.toRadians(meteoriteLatitude))
+ * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
+ double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+
+ double distance = R * c * 1000; // convert to meters
+
+
+ return Math.sqrt(distance);
+ }
+
public void setMass(String mass) {
this.mass = mass;
}
diff --git a/app/src/main/java/com/example/project_assignment/comparators/SortByLocation.java b/app/src/main/java/com/example/project_assignment/comparators/SortByLocation.java
@@ -1,4 +1,29 @@
package com.example.project_assignment.comparators;
-public class SortByLocation {
+import static android.content.Context.MODE_PRIVATE;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.example.project_assignment.MainActivity;
+import com.example.project_assignment.Meteorite;
+
+import java.util.Comparator;
+
+public class SortByLocation implements Comparator<Meteorite> {
+
+ private static SharedPreferences preference;
+ private double latitude;
+ private double longitude;
+ public SortByLocation(Context context) {
+ //fetch users current location from shared preference
+ preference = context.getSharedPreferences("preferences", Context.MODE_PRIVATE);
+ latitude = Double.parseDouble(preference.getString("latitude", "0"));
+ longitude = Double.parseDouble(preference.getString("longitude", "0"));
+ }
+ @Override
+ public int compare(Meteorite m1, Meteorite m2) {
+ System.out.println(latitude + ":" + longitude);
+ return Double.compare(m1.getDistanceFrom(latitude, longitude), m2.getDistanceFrom(latitude, longitude));
+ }
}