diff --git a/app/app.iml b/app/app.iml
index ea171ad..2db12ae 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -88,6 +88,10 @@
+
+
+
+
@@ -111,7 +115,10 @@
+
+
+
@@ -126,6 +133,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index 392afb7..0dcef11 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -24,6 +24,7 @@
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
+ compile 'com.google.android.gms:play-services-location:8.4.0'
compile 'com.survivingwithandroid:weatherlib:1.6.0'
compile 'com.survivingwithandroid:weatherlib_okhttpclient:1.6.0'
compile 'com.squareup.okhttp:okhttp:2.0.+'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b8fd3d9..b42201a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,9 +17,12 @@
android:allowBackup="true"
android:icon="@mipmap/ic_icon"
android:label="@string/app_title"
- android:hardwareAccelerated="false"
+ android:hardwareAccelerated="true"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
+
+
diff --git a/app/src/main/java/de/apps4ics/mountainnavigation/LocationService.java b/app/src/main/java/de/apps4ics/mountainnavigation/LocationService.java
new file mode 100644
index 0000000..0fc5c1d
--- /dev/null
+++ b/app/src/main/java/de/apps4ics/mountainnavigation/LocationService.java
@@ -0,0 +1,143 @@
+/**
+ * This file is part of MountainNavigation.
+ *
+ * MountainNavigation is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MountainNavigation is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MountainNavigation. If not, see .
+ *
+ * @copyright Copyright (c) 2016 Vinzenz Rosenkanz
+ *
+ * @author Vinzenz Rosenkranz
+ */
+
+package de.apps4ics.mountainnavigation;
+
+import android.Manifest;
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.ActivityCompat;
+import android.util.Log;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+
+public class LocationService extends Service implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
+ private static final int GPS_MIN_TIME = 5000;
+ private static final int GPS_MIN_DIST = 10;
+ private GoogleApiClient mGoogleApiClient;
+ private LocationRequest mLocationRequest;
+ private LocationUpdateCallback locationCallback;
+ private int instances;
+
+ private Timer timer;
+
+ private final IBinder binder = new MyBinder();
+
+ public void setLocationCallback(LocationUpdateCallback locationCallback) {
+ this.locationCallback = locationCallback;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.d(MainActivity.TAG, "Creating...");
+ instances = 0;
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(LocationServices.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ mGoogleApiClient.connect();
+ timer = new Timer();
+ }
+
+ @Override
+ public int onStartCommand(final Intent intent, int flags, int startId) {
+ Log.d(MainActivity.TAG, "StartCommand...");
+ instances++;
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ Log.d(MainActivity.TAG, "Starting timer..." + instances);
+ }
+ }, 0, GPS_MIN_TIME);
+ return Service.START_STICKY;
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(MainActivity.TAG, "onBind...");
+ return binder;
+ }
+
+ @Override
+ public void onConnected(@Nullable Bundle bundle) {
+ mLocationRequest = LocationRequest.create();
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ mLocationRequest.setInterval(GPS_MIN_TIME);
+ mLocationRequest.setSmallestDisplacement(GPS_MIN_DIST);
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ return;
+ }
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ mGoogleApiClient, mLocationRequest, this);
+ }
+
+ @Override
+ public void onConnectionSuspended(int i) {
+ Log.d(MainActivity.TAG, "LOCATION suspended");
+ }
+
+ @Override
+ public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
+ Log.d(MainActivity.TAG, "LOCATION connection failed");
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ Log.d(MainActivity.TAG, "LOCATION found: " + location.toString());
+ locationCallback.onLocationUpdate(location);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mGoogleApiClient.disconnect();
+ }
+
+ public class MyBinder extends Binder {
+ LocationService getService() {
+ return LocationService.this;
+ }
+ }
+}
diff --git a/app/src/main/java/de/apps4ics/mountainnavigation/LocationUpdateCallback.java b/app/src/main/java/de/apps4ics/mountainnavigation/LocationUpdateCallback.java
new file mode 100644
index 0000000..731d971
--- /dev/null
+++ b/app/src/main/java/de/apps4ics/mountainnavigation/LocationUpdateCallback.java
@@ -0,0 +1,28 @@
+/**
+ * This file is part of MountainNavigation.
+ *
+ * MountainNavigation is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MountainNavigation is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MountainNavigation. If not, see .
+ *
+ * @copyright Copyright (c) 2016 Vinzenz Rosenkanz
+ *
+ * @author Vinzenz Rosenkranz
+ */
+
+package de.apps4ics.mountainnavigation;
+
+import android.location.Location;
+
+public interface LocationUpdateCallback {
+ void onLocationUpdate(Location location);
+}
diff --git a/app/src/main/java/de/apps4ics/mountainnavigation/MainActivity.java b/app/src/main/java/de/apps4ics/mountainnavigation/MainActivity.java
index 72c6c28..23e685e 100644
--- a/app/src/main/java/de/apps4ics/mountainnavigation/MainActivity.java
+++ b/app/src/main/java/de/apps4ics/mountainnavigation/MainActivity.java
@@ -22,22 +22,24 @@
package de.apps4ics.mountainnavigation;
import android.app.AlertDialog;
+import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.location.Criteria;
import android.location.Location;
-import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
+import android.os.IBinder;
+import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.design.widget.FloatingActionButton;
@@ -101,7 +103,7 @@
import de.apps4ics.mountainnavigation.pois.Poi;
import de.apps4ics.mountainnavigation.pois.Types;
-public class MainActivity extends AppCompatActivity implements LocationListener, OnSingleWeatherRetrieved {
+public class MainActivity extends AppCompatActivity implements OnSingleWeatherRetrieved, LocationUpdateCallback {
public static final String TAG = "MountainNavigation";
/**
@@ -116,11 +118,14 @@
private static final int MIN_WEATHER_RELOAD_DIST = 5000; //5km, in m
private static final int MIN_POI_RELOAD_TIME = 300000; //5min, in ms
private static final int MIN_POI_RELOAD_DIST = 500; //0.5km, in m
+ private long lastWeatherInformation;
+ private long lastPoiInformation;
private static int MAX_POIS_AROUND = 50;
public static final int MAX_WIFI_LEVELS = 5;
private static ConnectivityManager cm;
private static TelephonyManager tm;
private static WifiManager wm;
+ private static PowerManager pm;
private static NetworkInfo activeNetwork;
private static int networkStrength;
@@ -137,9 +142,6 @@
private static WeatherHandler weatherHandler;
private static HikeHandler hikeHandler;
- private long lastWeatherInformation;
- private long lastPoiInformation;
-
private static MapView mapView;
private IMapController mapController;
public static int ZOOM_LEVEL;
@@ -165,6 +167,23 @@
private static List foundLocations;
+ private LocationService locationService;
+ private ServiceConnection serviceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.d(TAG, "onServiceConnected");
+ LocationService.MyBinder binder = (LocationService.MyBinder) service;
+ locationService = binder.getService();
+ locationService.setLocationCallback(MainActivity.this);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "onServiceDisconnected");
+ locationService = null;
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -179,6 +198,7 @@
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
wm = (WifiManager) getSystemService(WIFI_SERVICE);
+ pm = (PowerManager) getSystemService(POWER_SERVICE);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
@@ -754,9 +774,6 @@
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
- Criteria criteria = new Criteria();
- provider = locationManager.getBestProvider(criteria, false);
- mLocation = locationManager.getLastKnownLocation(provider);
}
private void Toaster(String text){
@@ -825,59 +842,6 @@
}
@Override
- public void onLocationChanged(Location location) {
- if(mLocation != null) {
- Location oldLocation = new Location(mLocation);
- long currentTime = System.currentTimeMillis();
- float distance = mLocation.distanceTo(oldLocation);
-
- if(currentTime - lastWeatherInformation >= MIN_WEATHER_RELOAD_TIME || distance >= MIN_WEATHER_RELOAD_DIST) {
- lastWeatherInformation = currentTime;
- weatherHandler.getCurrentWeather(location, this);
- }
- if(currentTime - lastPoiInformation >= MIN_POI_RELOAD_TIME || distance >= MIN_POI_RELOAD_DIST) { //5 minutes
- lastPoiInformation = currentTime;
- ArrayList pois = new ArrayList<>(poiHandler.getPoisAround(location.getLatitude(), location.getLongitude(), MAX_POIS_AROUND));
- Log.d(TAG, "found " + pois.size() + " pois.");
- for(Poi p : pois) {
- p.display();
- }
- }
- }
- mLocation = location;
- if(mLocation == null) return;
- foundLocations.add(location);
-
- if(hikeHandler.isRecording()) hikeHandler.addLocation(mLocation);
-
- double lat = location.getLatitude();
- double lon = location.getLongitude();
- GeoPoint gp = new GeoPoint(lat, lon);
-
- mapView.getOverlays().remove(currentPosition);
- currentPosition.setPosition(gp);
- currentPosition.setSnippet(String.format(getString(R.string.osm_marker_snippet), gp.getLatitude(), gp.getLongitude(), gp.getAltitude(), 0));
- mapView.getOverlays().add(currentPosition);
- mapView.invalidate();
- mapController.setCenter(gp);
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- Log.d(TAG, "onStatusChanged: " + provider + ", " + status);
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- Log.d(TAG, "onProviderEnabled: " + provider);
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- Log.d(TAG, "onProviderDisabled: " + provider);
- }
-
- @Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
@@ -923,6 +887,45 @@
}
@Override
+ public void onLocationUpdate(Location location) {
+ Log.d(TAG, "isInteractive? " + pm.isInteractive());
+ if(mLocation != null && pm.isInteractive()) {
+ Location oldLocation = new Location(mLocation);
+ long currentTime = System.currentTimeMillis();
+ float distance = mLocation.distanceTo(oldLocation);
+
+ if(currentTime - lastWeatherInformation >= MIN_WEATHER_RELOAD_TIME || distance >= MIN_WEATHER_RELOAD_DIST) {
+ lastWeatherInformation = currentTime;
+ weatherHandler.getCurrentWeather(location, this);
+ }
+ if(currentTime - lastPoiInformation >= MIN_POI_RELOAD_TIME || distance >= MIN_POI_RELOAD_DIST) { //5 minutes
+ lastPoiInformation = currentTime;
+ ArrayList pois = new ArrayList<>(poiHandler.getPoisAround(location.getLatitude(), location.getLongitude(), MAX_POIS_AROUND));
+ Log.d(MainActivity.TAG, "found " + pois.size() + " pois.");
+ for(Poi p : pois) {
+ p.display();
+ }
+ }
+ }
+ mLocation = location;
+ if(mLocation == null) return;
+ foundLocations.add(location);
+
+ if(hikeHandler.isRecording()) hikeHandler.addLocation(mLocation);
+
+ double lat = location.getLatitude();
+ double lon = location.getLongitude();
+ GeoPoint gp = new GeoPoint(lat, lon);
+
+ mapView.getOverlays().remove(currentPosition);
+ currentPosition.setPosition(gp);
+ currentPosition.setSnippet(String.format(getString(R.string.osm_marker_snippet), gp.getLatitude(), gp.getLongitude(), gp.getAltitude(), 0));
+ mapView.getOverlays().add(currentPosition);
+ mapView.invalidate();
+ mapController.setCenter(gp);
+ }
+
+ @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
@@ -950,18 +953,25 @@
protected void onResume() {
super.onResume();
weatherHandler = new WeatherHandler(this);
- locationManager.requestLocationUpdates(provider, GPS_MIN_TIME, GPS_MIN_DIST, this);
+ Intent service = new Intent(this, LocationService.class);
+ bindService(service, serviceConnection, Context.BIND_AUTO_CREATE);
+ startService(service);
}
@Override
protected void onPause() {
super.onPause();
- locationManager.removeUpdates(this);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
+ unbindService(serviceConnection);
}
@Override