335 lines
12 KiB
Java
335 lines
12 KiB
Java
|
/**
|
||
|
* MainActivityFragment.java
|
||
|
* Implements the main fragment of the main activity
|
||
|
* This fragment displays a map using osmdroid
|
||
|
*
|
||
|
* This file is part of
|
||
|
* TRACKBOOK - Movement Recorder for Android
|
||
|
*
|
||
|
* Copyright (c) 2016 - Y20K.org
|
||
|
* Licensed under the MIT-License
|
||
|
* http://opensource.org/licenses/MIT
|
||
|
*
|
||
|
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
|
||
|
* https://github.com/osmdroid/osmdroid
|
||
|
*/
|
||
|
|
||
|
package org.y20k.trackbook;
|
||
|
|
||
|
import android.app.Activity;
|
||
|
import android.content.Context;
|
||
|
import android.content.SharedPreferences;
|
||
|
import android.location.Location;
|
||
|
import android.location.LocationListener;
|
||
|
import android.location.LocationManager;
|
||
|
import android.os.Bundle;
|
||
|
import android.preference.PreferenceManager;
|
||
|
import android.support.v4.app.Fragment;
|
||
|
import android.util.DisplayMetrics;
|
||
|
import android.view.LayoutInflater;
|
||
|
import android.view.MenuItem;
|
||
|
import android.view.View;
|
||
|
import android.view.ViewGroup;
|
||
|
import android.widget.Toast;
|
||
|
|
||
|
import org.osmdroid.api.IMapController;
|
||
|
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
||
|
import org.osmdroid.util.GeoPoint;
|
||
|
import org.osmdroid.views.MapView;
|
||
|
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
||
|
import org.osmdroid.views.overlay.compass.CompassOverlay;
|
||
|
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
||
|
import org.y20k.trackbook.helpers.LocationHelper;
|
||
|
import org.y20k.trackbook.helpers.LogHelper;
|
||
|
import org.y20k.trackbook.helpers.MapHelper;
|
||
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
||
|
|
||
|
import java.util.List;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* MainActivityFragment class
|
||
|
*/
|
||
|
public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||
|
|
||
|
/* Define log tag */
|
||
|
private static final String LOG_TAG = MainActivityFragment.class.getSimpleName();
|
||
|
|
||
|
|
||
|
/* Main class variables */
|
||
|
private Activity mActivity;
|
||
|
private MapView mMapView;
|
||
|
private IMapController mController;
|
||
|
private CompassOverlay mCompassOverlay = null;
|
||
|
private LocationManager mLocationManager;
|
||
|
private LocationListener mGPSListener;
|
||
|
private LocationListener mNetworkListener;
|
||
|
private Location mCurrentBestLocation;
|
||
|
private ItemizedIconOverlay mMyLocationOverlay;
|
||
|
|
||
|
|
||
|
/* Constructor (default) */
|
||
|
public MainActivityFragment() {
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public void onCreate(Bundle savedInstanceState) {
|
||
|
super.onCreate(savedInstanceState);
|
||
|
|
||
|
// get activity
|
||
|
mActivity = getActivity();
|
||
|
|
||
|
// action bar has options menu
|
||
|
setHasOptionsMenu(true);
|
||
|
|
||
|
// acquire reference to Location Manager
|
||
|
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
||
|
|
||
|
// get last know location
|
||
|
List locationProviders = mLocationManager.getProviders(true);
|
||
|
if (locationProviders.size() > 0) {
|
||
|
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||
|
} else {
|
||
|
promptUserForLocation();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||
|
// create basic map
|
||
|
mMapView = new MapView(inflater.getContext());
|
||
|
|
||
|
// get display metrics
|
||
|
final DisplayMetrics dm = mActivity.getResources().getDisplayMetrics();
|
||
|
|
||
|
// get map controller
|
||
|
mController = mMapView.getController();
|
||
|
|
||
|
// basic map setup
|
||
|
mMapView.setTileSource(TileSourceFactory.MAPNIK);
|
||
|
mMapView.setTilesScaledToDpi(true);
|
||
|
|
||
|
// add multi-touch capability
|
||
|
mMapView.setMultiTouchControls(true);
|
||
|
|
||
|
// initiate map state
|
||
|
if (savedInstanceState != null) {
|
||
|
// restore saved instance of map
|
||
|
GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE));
|
||
|
mController.setCenter(position);
|
||
|
mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL, 16));
|
||
|
// restore current location
|
||
|
mCurrentBestLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
||
|
} else if (mCurrentBestLocation != null) {
|
||
|
// fallback or first run: set map to current position
|
||
|
GeoPoint position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||
|
mController.setCenter(position);
|
||
|
mController.setZoom(16);
|
||
|
}
|
||
|
|
||
|
// add compass to map
|
||
|
mCompassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
||
|
mCompassOverlay.enableCompass();
|
||
|
mMapView.getOverlays().add(mCompassOverlay);
|
||
|
|
||
|
// mark user's location on map
|
||
|
if (mCurrentBestLocation != null) {
|
||
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
||
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||
|
}
|
||
|
|
||
|
return mMapView;
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public void onResume() {
|
||
|
super.onResume();
|
||
|
|
||
|
// start tracking position
|
||
|
startFindingLocation();
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public void onPause() {
|
||
|
super.onPause();
|
||
|
|
||
|
// disable location listener
|
||
|
stopFindingLocation();
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public void onDestroyView(){
|
||
|
super.onDestroyView();
|
||
|
|
||
|
// deactivate map
|
||
|
mMapView.onDetach();
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||
|
|
||
|
// handle action bar options menu selection
|
||
|
switch (item.getItemId()) {
|
||
|
|
||
|
// CASE MY LOCATION
|
||
|
case R.id.action_my_location:
|
||
|
|
||
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_my_location), Toast.LENGTH_LONG).show();
|
||
|
|
||
|
if (mLocationManager.getProviders(true).size() == 0) {
|
||
|
// location services are off - ask user to turn them on
|
||
|
promptUserForLocation();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// get current position
|
||
|
GeoPoint position;
|
||
|
if (mCurrentBestLocation != null) {
|
||
|
// app has a current best estimate location
|
||
|
position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||
|
} else {
|
||
|
// app does not have any location fix
|
||
|
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||
|
position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||
|
}
|
||
|
|
||
|
// center map on current position
|
||
|
mController.setCenter(position);
|
||
|
|
||
|
// mark user's new location on map and remove last marker
|
||
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
||
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||
|
|
||
|
return true;
|
||
|
|
||
|
// CASE DEFAULT
|
||
|
default:
|
||
|
return super.onOptionsItemSelected(item);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
public void onSaveInstanceState(Bundle outState) {
|
||
|
// save map position
|
||
|
outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude());
|
||
|
outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude());
|
||
|
outState.putInt(INSTANCE_ZOOM_LEVEL, mMapView.getZoomLevel());
|
||
|
outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation);
|
||
|
super.onSaveInstanceState(outState);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Start finding location for map */
|
||
|
private void startFindingLocation() {
|
||
|
|
||
|
// listener that responds to location updates
|
||
|
mGPSListener = createLocationsListener();
|
||
|
mNetworkListener = createLocationsListener();
|
||
|
|
||
|
// start listener
|
||
|
List locationProviders = mLocationManager.getProviders(true);
|
||
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||
|
try {
|
||
|
// enable location listener (gps)
|
||
|
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGPSListener);
|
||
|
} catch (SecurityException e) {
|
||
|
// catches permission problems
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||
|
try {
|
||
|
// enable location listener (network)
|
||
|
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mNetworkListener);
|
||
|
} catch (SecurityException e) {
|
||
|
// catches permission problems
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Stops finding location for map */
|
||
|
private void stopFindingLocation() {
|
||
|
// disable location listeners
|
||
|
List locationProviders = mLocationManager.getProviders(true);
|
||
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||
|
try {
|
||
|
mLocationManager.removeUpdates(mGPSListener);
|
||
|
} catch (SecurityException e) {
|
||
|
// catches permission problems
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||
|
try {
|
||
|
mLocationManager.removeUpdates(mNetworkListener);
|
||
|
} catch (SecurityException e) {
|
||
|
// catches permission problems
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Creates listener for changes in location status */
|
||
|
private LocationListener createLocationsListener() {
|
||
|
return new LocationListener() {
|
||
|
public void onLocationChanged(Location location) {
|
||
|
// check if the new location is better
|
||
|
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
||
|
// save location
|
||
|
mCurrentBestLocation = location;
|
||
|
|
||
|
// mark user's new location on map and remove last marker
|
||
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
||
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||
|
// TODO do something
|
||
|
}
|
||
|
|
||
|
public void onProviderEnabled(String provider) {
|
||
|
LogHelper.v(LOG_TAG, "Location provider enabled: " + provider);
|
||
|
}
|
||
|
|
||
|
public void onProviderDisabled(String provider) {
|
||
|
LogHelper.v(LOG_TAG, "Location provider disabled: " + provider);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Prompts user to turn on location */
|
||
|
private void promptUserForLocation() {
|
||
|
// TODO prompt user to turn on location
|
||
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_location_offline), Toast.LENGTH_LONG).show();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Saves state of map */
|
||
|
private void saveMaoState(Context context) {
|
||
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||
|
SharedPreferences.Editor editor = settings.edit();
|
||
|
editor.putInt(PREFS_ZOOM_LEVEL, mMapView.getZoomLevel());
|
||
|
editor.apply();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Loads app state from preferences */
|
||
|
private void loadMapState(Context context) {
|
||
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||
|
int zoom = settings.getInt(PREFS_ZOOM_LEVEL, 16);
|
||
|
}
|
||
|
|
||
|
}
|