From 2abeff2fb614c9c6c6184de394a47912a6a681f3 Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 13:34:34 +0300 Subject: [PATCH 01/44] Refactor location tracking to be done in the service --- .../fi/hikemate/Services/LocationService.java | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/ville/fi/hikemate/Services/LocationService.java b/app/src/main/java/ville/fi/hikemate/Services/LocationService.java index e6477d4..4255e9b 100644 --- a/app/src/main/java/ville/fi/hikemate/Services/LocationService.java +++ b/app/src/main/java/ville/fi/hikemate/Services/LocationService.java @@ -1,11 +1,25 @@ package ville.fi.hikemate.Services; import android.app.Service; +import android.content.Context; import android.content.Intent; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; import android.os.IBinder; -import android.support.annotation.IntDef; +import android.support.v4.content.LocalBroadcastManager; + +import com.google.android.gms.maps.model.LatLng; + +import java.util.LinkedList; public class LocationService extends Service { + + private LocationManager locationManager; + private LocationListener locationListener; + private LinkedList locations; + public LocationService() { } @@ -17,6 +31,48 @@ public IBinder onBind(Intent intent) { @Override public int onStartCommand(Intent intent, int flags, int startId) { + locations = new LinkedList<>(); + locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + initLocationListener(); + + try { + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, locationListener); + } catch(SecurityException e) { + e.printStackTrace(); + } return START_STICKY; } + + private void sendGPSLocations(double latitude, double longitude) { + Intent i = new Intent("GPSLocations"); + locations.add(new LatLng(latitude, longitude)); + i.putExtra("Locations", locations); + LocalBroadcastManager.getInstance(this).sendBroadcast(i); + } + + private void initLocationListener() { + locationListener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + sendGPSLocations(location.getLatitude(), location.getLongitude()); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) {} + + @Override + public void onProviderEnabled(String provider) {} + + @Override + public void onProviderDisabled(String provider) {} + }; + } + + @Override + public boolean stopService(Intent name) { + System.out.println("Stopping LocationService"); + locationManager = null; + locationListener = null; + return super.stopService(name); + } } From 2bf6e332c759864756a79d0f65374a6147919a05 Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 13:35:47 +0300 Subject: [PATCH 02/44] Remove location tracking and add a receiver to receive locations from the location service --- .../fi/hikemate/Activities/MapActivity.java | 131 +++++++++--------- 1 file changed, 64 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/ville/fi/hikemate/Activities/MapActivity.java b/app/src/main/java/ville/fi/hikemate/Activities/MapActivity.java index 97888bc..2418f5c 100644 --- a/app/src/main/java/ville/fi/hikemate/Activities/MapActivity.java +++ b/app/src/main/java/ville/fi/hikemate/Activities/MapActivity.java @@ -1,16 +1,16 @@ package ville.fi.hikemate.Activities; import android.Manifest; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentActivity; import android.os.Bundle; import android.support.v4.content.ContextCompat; +import android.support.v4.content.LocalBroadcastManager; import android.view.View; import com.google.android.gms.maps.CameraUpdateFactory; @@ -21,13 +21,17 @@ import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.LinkedList; import ville.fi.hikemate.R; import ville.fi.hikemate.Resources.Hike; -import ville.fi.hikemate.Resources.HikeList; import ville.fi.hikemate.Resources.HikeLocation; +import ville.fi.hikemate.Services.LocationService; import ville.fi.hikemate.Utils.Debug; +import ville.fi.hikemate.Utils.HikeToLatLng; import ville.fi.hikemate.Utils.StorageHandler; public class MapActivity extends FragmentActivity implements OnMapReadyCallback{ @@ -36,9 +40,6 @@ public class MapActivity extends FragmentActivity implements OnMapReadyCallback{ private FragmentActivity thisActivity = this; private final int MY_PERMISSIONS_REQUEST_LOCATION = 0; private GoogleMap mMap; - private LocationManager locationManager; - private LocationListener locationListener; - private Location location; private LinkedList hikes; private Hike hike; private StorageHandler sh; @@ -47,24 +48,28 @@ public class MapActivity extends FragmentActivity implements OnMapReadyCallback{ private boolean isTrackingLocation; private Intent mainActivityIntent; private LinkedList hikeLatLng; + private Intent locationServiceIntent; + private DateFormat dateFormat; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map); + mainActivityIntent = new Intent(host, MainActivity.class); isTrackingLocation = true; sh = new StorageHandler(); hikes = sh.readStorage(host); - hike = new Hike("MyHike"); - hikeLatLng = getLatLng(hike); + dateFormat = new SimpleDateFormat("dd/MM/yyyy"); + hike = new Hike(dateFormat.format(new Date())); + hikeLatLng = HikeToLatLng.getLatLng(hike); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); - locationManager = (LocationManager) host.getSystemService(Context.LOCATION_SERVICE); - initLocationListener(); + LocalBroadcastManager.getInstance(host).registerReceiver(mMessageReceiver, new IntentFilter("GPSLocations")); + locationServiceIntent = new Intent(host, LocationService.class); // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(host, @@ -88,12 +93,7 @@ protected void onCreate(Bundle savedInstanceState) { MY_PERMISSIONS_REQUEST_LOCATION); } } else { - try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, locationListener); - Debug.print(host, "onRequestPermissionResult", "LocationGranted", "LocationManager requesting", 1); - } catch(SecurityException e) { - e.printStackTrace(); - } + startService(locationServiceIntent); } } @@ -104,6 +104,7 @@ protected void onCreate(Bundle savedInstanceState) { */ public void cancelTracking(View v) { isTrackingLocation = false; + stopService(locationServiceIntent); startActivity(mainActivityIntent); } @@ -116,6 +117,7 @@ public void cancelTracking(View v) { */ public void saveHike(View v) { isTrackingLocation = false; + stopService(locationServiceIntent); for (LatLng latLng : hikeLatLng) { hike.addLocation(latLng.latitude, latLng.longitude); @@ -131,6 +133,13 @@ public void onMapReady(GoogleMap googleMap) { mMap = googleMap; } + /** + * Checks whether the user has the required permissions or not. + * + * @param requestCode + * @param permissions + * @param grantResults + */ @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { @@ -139,69 +148,57 @@ public void onRequestPermissionsResult(int requestCode, case MY_PERMISSIONS_REQUEST_LOCATION: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, locationListener); - Debug.print(host, "onRequestPermissionResult", "LocationGranted", "LocationManager requesting", 1); - } catch(SecurityException e) { - e.printStackTrace(); - } - + startService(locationServiceIntent); } else { // permission denied, boo! Disable the // functionality that depends on this permission. - // TODO: Go back to MainActivity. + // TODO: Go back to MainActivity / Exit application. } return; } } } - private void initLocationListener() { - Debug.print(host, "initLocationListener", "Initializing location listener", "Location listener init", 1); - locationListener = new LocationListener() { - @Override - public void onLocationChanged(Location location) { - Debug.print(host, "onLocationChanged", "Changing location", "Location changed", 1); - - if (isTrackingLocation) { - hikeLatLng.add(new LatLng(location.getLatitude(), location.getLongitude())); - - hikePolyLine = mMap.addPolyline(new PolylineOptions() - .clickable(false)); - hikePolyLine.setPoints(hikeLatLng); - - if (firstLocationGot == false) { - mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15)); - firstLocationGot = true; - } else { - mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), mMap.getCameraPosition().zoom)); - } - } - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) {} - - @Override - public void onProviderEnabled(String provider) {} - - @Override - public void onProviderDisabled(String provider) {} - }; - } - + /** + * Returns the currently active hike. + * + * @return + */ public Hike getHike() { return hike; } - public LinkedList getLatLng(Hike hike) { - LinkedList locs = new LinkedList<>(); - - for (HikeLocation loc: hike.getLocations()) { - locs.add(new LatLng(loc.getLat(), loc.getLng())); + /** + * Receiver for the LocationService's locations. + */ + private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { + + /** + * Sets the given locations to a linked list and draws a line according to them. + * + * @param context + * @param intent + */ + @Override + public void onReceive(Context context, Intent intent) { + System.out.println("Receiving broadcast"); + LinkedList locations = (LinkedList) intent.getExtras().get("Locations"); + + if (isTrackingLocation) { + hikeLatLng.add(locations.getLast()); + + hikePolyLine = mMap.addPolyline(new PolylineOptions() + .clickable(false)); + hikePolyLine.setPoints(hikeLatLng); + + if (firstLocationGot == false) { + mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(locations.getLast().latitude, locations.getLast().longitude), 15)); + firstLocationGot = true; + } else { + mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(locations.getLast().latitude, locations.getLast().longitude), mMap.getCameraPosition().zoom)); + } + } } - - return locs; - } + }; } From b917da394573af8454b3259f8c4acd8aa94e94b8 Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 13:36:30 +0300 Subject: [PATCH 03/44] Remove unused object and imports --- .../java/ville/fi/hikemate/Fragments/HikeListFragment.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/ville/fi/hikemate/Fragments/HikeListFragment.java b/app/src/main/java/ville/fi/hikemate/Fragments/HikeListFragment.java index 6a1a3d2..b9948c4 100644 --- a/app/src/main/java/ville/fi/hikemate/Fragments/HikeListFragment.java +++ b/app/src/main/java/ville/fi/hikemate/Fragments/HikeListFragment.java @@ -16,12 +16,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.util.LinkedList; -import java.util.List; import ville.fi.hikemate.Activities.StoredMapActivity; import ville.fi.hikemate.R; import ville.fi.hikemate.Resources.Hike; -import ville.fi.hikemate.Resources.HikeList; import ville.fi.hikemate.Utils.HikeListAdapter; import ville.fi.hikemate.Utils.StorageHandler; @@ -47,7 +45,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, emptyList = (TextView) view.findViewById(R.id.list_emptyList); - ObjectMapper mapper = new ObjectMapper(); StorageHandler sh = new StorageHandler(); hikes = sh.readStorage(getActivity()); if (hikes.size() < 1) { From 62bdb026016f3847f155105afb0062f42916bb93 Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 13:37:22 +0300 Subject: [PATCH 04/44] Set the applications to require a permission to use the device's camera --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80b76cf..1b5654d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="ville.fi.hikemate"> + From 0b985cd4d44158b0bb9722c5049093dee0380a97 Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 15:08:02 +0300 Subject: [PATCH 05/44] Add permissions to write and read external storage --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1b5654d..2d6c058 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + From 2d1dd2f9ab868c67dff9775197950c173c92865b Mon Sep 17 00:00:00 2001 From: Ville Haapavaara Date: Sun, 7 May 2017 15:08:26 +0300 Subject: [PATCH 06/44] Add a button for taking pictures --- app/src/main/res/layout/activity_map.xml | 34 +++++++++++++++++------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml index 627c30b..55eb7cc 100644 --- a/app/src/main/res/layout/activity_map.xml +++ b/app/src/main/res/layout/activity_map.xml @@ -11,20 +11,36 @@ android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" /> -