/*------------------------------------------------------------------------------
** Ident: Sogeti Smart Mobile Solutions
** Author: rene
** Copyright: (c) Apr 24, 2011 Sogeti Nederland B.V. All Rights Reserved.
**------------------------------------------------------------------------------
** Sogeti Nederland B.V. | No part of this file may be reproduced
** Distributed Software Engineering | or transmitted in any form or by any
** Lange Dreef 17 | means, electronic or mechanical, for the
** 4131 NJ Vianen | purpose, without the express written
** The Netherlands | permission of the copyright holder.
*------------------------------------------------------------------------------
*
* This file is part of OpenGPSTracker.
*
* OpenGPSTracker 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.
*
* OpenGPSTracker 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 OpenGPSTracker. If not, see <http://www.gnu.org/licenses/>.
*
*/
package nl.sogeti.android.gpstracker.viewer;
import java.util.List;
import java.util.concurrent.Semaphore;
import nl.sogeti.android.gpstracker.R;
import nl.sogeti.android.gpstracker.actions.ControlTracking;
import nl.sogeti.android.gpstracker.actions.InsertNote;
import nl.sogeti.android.gpstracker.actions.ShareTrack;
import nl.sogeti.android.gpstracker.actions.Statistics;
import nl.sogeti.android.gpstracker.db.GPStracking.Media;
import nl.sogeti.android.gpstracker.db.GPStracking.Segments;
import nl.sogeti.android.gpstracker.db.GPStracking.Tracks;
import nl.sogeti.android.gpstracker.db.GPStracking.Waypoints;
import nl.sogeti.android.gpstracker.logger.GPSLoggerServiceManager;
import nl.sogeti.android.gpstracker.util.Constants;
import nl.sogeti.android.gpstracker.util.UnitsI18n;
import nl.sogeti.android.gpstracker.viewer.proxy.MapViewProxy;
import nl.sogeti.android.gpstracker.viewer.proxy.MyLocationOverlayProxy;
import org.osmdroid.tileprovider.util.CloudmadeUtil;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Gallery;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
/**
* Main activity showing a track and allowing logging control
*
* @version $Id: LoggerMap.java 1187 2011-12-30 21:34:41Z rcgroot $
* @author rene (c) Jan 18, 2009, Sogeti B.V.
*/
public class LoggerMap extends MapActivity
{
public static final String OSM_PROVIDER = "OSM";
public static final String GOOGLE_PROVIDER = "GOOGLE";
private static final String INSTANCE_E6LONG = "e6long";
private static final String INSTANCE_E6LAT = "e6lat";
private static final String INSTANCE_ZOOM = "zoom";
private static final String INSTANCE_SPEED = "averagespeed";
private static final String INSTANCE_TRACK = "track";
private static final int ZOOM_LEVEL = 16;
// MENU'S
private static final int MENU_SETTINGS = 1;
private static final int MENU_TRACKING = 2;
private static final int MENU_TRACKLIST = 3;
private static final int MENU_STATS = 4;
private static final int MENU_ABOUT = 5;
private static final int MENU_LAYERS = 6;
private static final int MENU_NOTE = 7;
private static final int MENU_SHARE = 13;
private static final int MENU_CONTRIB = 14;
private static final int DIALOG_NOTRACK = 24;
private static final int DIALOG_INSTALL_ABOUT = 29;
private static final int DIALOG_LAYERS = 31;
private static final int DIALOG_URIS = 34;
private static final int DIALOG_CONTRIB = 35;
private static final String TAG = "OGT.LoggerMap";
// UI's
private CheckBox mTraffic;
private CheckBox mSpeed;
private CheckBox mAltitude;
private CheckBox mDistance;
private CheckBox mCompass;
private CheckBox mLocation;
private TextView[] mSpeedtexts = new TextView[0];
private TextView mLastGPSSpeedView = null;
private TextView mLastGPSAltitudeView = null;
private TextView mDistanceView = null;
private Gallery mGallery;
private double mAverageSpeed = 33.33d / 3d;
private long mTrackId = -1;
private long mLastSegment = -1;
private UnitsI18n mUnits;
private WakeLock mWakeLock = null;
private SharedPreferences mSharedPreferences;
private GPSLoggerServiceManager mLoggerServiceManager;
private SegmentOverlay mLastSegmentOverlay;
private BaseAdapter mMediaAdapter;
private MapViewProxy mMapView = null;
private MyLocationOverlayProxy mMylocation;
private Handler mHandler;
private ContentObserver mTrackSegmentsObserver;
private ContentObserver mSegmentWaypointsObserver;
private ContentObserver mTrackMediasObserver;
private DialogInterface.OnClickListener mNoTrackDialogListener;
private DialogInterface.OnClickListener mOiAboutDialogListener;
private OnClickListener mNoteSelectDialogListener;
private OnCheckedChangeListener mCheckedChangeListener;
private android.widget.RadioGroup.OnCheckedChangeListener mGroupCheckedChangeListener;
private OnSharedPreferenceChangeListener mSharedPreferenceChangeListener;
private UnitsI18n.UnitsChangeListener mUnitsChangeListener;
/**
* Run after the ServiceManager completes the binding to the remote service
*/
private Runnable mServiceConnected;
private Runnable speedCalculator;
/**
* Called when the activity is first created.
*/
@Override
protected void onCreate(Bundle load)
{
super.onCreate(load);
setContentView(R.layout.map);
findViewById(R.id.mapScreen).setDrawingCacheEnabled(true);
mUnits = new UnitsI18n(this);
mLoggerServiceManager = new GPSLoggerServiceManager(this);
final Semaphore calulatorSemaphore = new Semaphore(0);
Thread calulator = new Thread("OverlayCalculator")
{
@Override
public void run()
{
Looper.prepare();
mHandler = new Handler();
calulatorSemaphore.release();
Looper.loop();
}
};
calulator.start();
try
{
calulatorSemaphore.acquire();
}
catch (InterruptedException e)
{
Log.e(TAG, "Failed waiting for a semaphore", e);
}
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mMapView = new MapViewProxy();
updateMapProvider();
mMylocation = new MyLocationOverlayProxy(this, mMapView);
mMapView.setBuiltInZoomControls(true);
mMapView.setClickable(true);
TextView[] speeds = { (TextView) findViewById(R.id.speedview05), (TextView) findViewById(R.id.speedview04), (TextView) findViewById(R.id.speedview03),
(TextView) findViewById(R.id.speedview02), (TextView) findViewById(R.id.speedview01), (TextView) findViewById(R.id.speedview00) };
mSpeedtexts = speeds;
mLastGPSSpeedView = (TextView) findViewById(R.id.currentSpeed);
mLastGPSAltitudeView = (TextView) findViewById(R.id.currentAltitude);
mDistanceView = (TextView) findViewById(R.id.currentDistance);
createListeners();
onRestoreInstanceState(load);
}
@Override
protected void onResume()
{
super.onResume();
mLoggerServiceManager.startup(this, mServiceConnected);
mSharedPreferences.registerOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
mUnits.setUnitsChangeListener(mUnitsChangeListener);
updateTitleBar();
updateBlankingBehavior();
updateMapProvider();
if (mTrackId >= 0)
{
ContentResolver resolver = this.getContentResolver();
Uri trackUri = Uri.withAppendedPath(Tracks.CONTENT_URI, mTrackId + "/segments");
Uri lastSegmentUri = Uri.withAppendedPath(Tracks.CONTENT_URI, mTrackId + "/segments/" + mLastSegment + "/waypoints");
Uri mediaUri = ContentUris.withAppendedId(Media.CONTENT_URI, mTrackId);
resolver.unregisterContentObserver(this.mTrackSegmentsObserver);
resolver.unregisterContentObserver(this.mSegmentWaypointsObserver);
resolver.unregisterContentObserver(this.mTrackMediasObserver);
resolver.registerContentObserver(trackUri, false, this.mTrackSegmentsObserver);
resolver.registerContentObserver(lastSegmentUri, true, this.mSegmentWaypointsObserver);
resolver.registerContentObserver(mediaUri, true, this.mTrackMediasObserver);
}
updateDataOverlays();
updateSpeedColoring();
updateSpeedDisplayVisibility();
updateAltitudeDisplayVisibility();
updateDistanceDisplayVisibility();
updateCompassDisplayVisibility();
updateLocationDisplayVisibility();
mMapView.executePostponedActions();
}
@Override
protected void onPause()
{
if (this.mWakeLock != null && this.mWakeLock.isHeld())
{
this.mWakeLock.release();
Log.w(TAG, "onPause(): Released lock to keep screen on!");
}
ContentResolver resolver = this.getContentResolver();
resolver.unregisterContentObserver(this.mTrackSegmentsObserver);
resolver.unregisterContentObserver(this.mSegmentWaypointsObserver);
resolver.unregisterContentObserver(this.mTrackMediasObserver);
mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this.mSharedPreferenceChangeListener);
mUnits.setUnitsChangeListener(null);
mMylocation.disableMyLocation();
mMylocation.disableCompass();
this.mLoggerServiceManager.shutdown(this);
super.onPause();
}
/*
* (non-Javadoc)
* @see com.google.android.maps.MapActivity#onPause()
*/
@Override
protected void onDestroy()
{
super.onDestroy();
mLastSegmentOverlay = null;
mMapView.clearOverlays();
mHandler.post(new Runnable()
{
public void run()
{
Looper.myLooper().quit();
}
});
if (mWakeLock != null && mWakeLock.isHeld())
{
mWakeLock.release();
Log.w(TAG, "onDestroy(): Released lock to keep screen on!");
}
if (mLoggerServiceManager.getLoggingState() == Constants.STOPPED)
{
stopService(new Intent(Constants.SERVICENAME));
}
mUnits = null;
}
/*
* (non-Javadoc)
* @see
* com.google.android.maps.MapActivity#onNewIntent(android.content.Intent)
*/
@Override
public void onNewIntent(Intent newIntent)
{
Uri data = newIntent.getData();
if (data != null)
{
moveToTrack(Long.parseLong(data.getLastPathSegment()), true);
}
}
@Override
protected void onRestoreInstanceState(Bundle load)
{
if (load != null)
{
super.onRestoreInstanceState(load);
}
Uri data = this.getIntent().getData();
if (load != null && load.containsKey(INSTANCE_TRACK)) // 1st method: track from a previous instance of this activity
{
long loadTrackId = load.getLong(INSTANCE_TRACK);
if (load.containsKey(INSTANCE_SPEED))
{
mAverageSpeed = load.getDouble(INSTANCE_SPEED);
}
moveToTrack(loadTrackId, false);
}
else if (data != null) // 2nd method: track ordered to make
{
long loadTrackId = Long.parseLong(data.getLastPathSegment());
mAverageSpeed = 0.0;
moveToTrack(loadTrackId, true);
}
else
// 3rd method: just try the last track
{
moveToLastTrack();
}
if (load != null && load.containsKey(INSTANCE_ZOOM))
{
mMapView.getController().setZoom(load.getInt(INSTANCE_ZOOM));
}
else
{
mMapView.getController().setZoom(LoggerMap.ZOOM_LEVEL);
}
if (load != null && load.containsKey(INSTANCE_E6LAT) && load.containsKey(INSTANCE_E6LONG))
{
GeoPoint storedPoint = new GeoPoint(load.getInt(INSTANCE_E6LAT), load.getInt(INSTANCE_E6LONG));
this.mMapView.getController().animateTo(storedPoint);
}
else
{
GeoPoint lastPoint = getLastTrackPoint();
this.mMapView.getController().animateTo(lastPoint);
}
}
@Override
protected void onSaveInstanceState(Bundle save)
{
super.onSaveInstanceState(save);
save.putLong(INSTANCE_TRACK, this.mTrackId);
save.putDouble(INSTANCE_SPEED, mAverageSpeed);
save.putInt(INSTANCE_ZOOM, this.mMapView.getZoomLevel());
GeoPoint point = this.mMapView.getMapCenter();
save.putInt(INSTANCE_E6LAT, point.getLatitudeE6());
save.putInt(INSTANCE_E6LONG, point.getLongitudeE6());
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
boolean propagate = true;
switch (keyCode)
{
case KeyEvent.KEYCODE_T:
propagate = this.mMapView.getController().zoomIn();
break;
case KeyEvent.KEYCODE_G:
propagate = this.mMapView.getController().zoomOut();
break;
case KeyEvent.KEYCODE_S:
setSatelliteOverlay(!this.mMapView.isSatellite());
propagate = false;
break;
case KeyEvent.KEYCODE_A:
setTrafficOverlay(!this.mMapView.isTraffic());
propagate = false;
break;
case KeyEvent.KEYCODE_F:
mAverageSpeed = 0.0;
moveToTrack(this.mTrackId - 1, true);
propagate = false;
break;
case KeyEvent.KEYCODE_H:
mAverageSpeed = 0.0;
moveToTrack(this.mTrackId + 1, true);
propagate = false;
break;
default:
propagate = super.onKeyDown(keyCode, event);
break;
}
return propagate;
}
private void setTrafficOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.TRAFFIC, b);
editor.commit();
}
private void setSatelliteOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.SATELLITE, b);
editor.commit();
}
private void setSpeedOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.SPEED, b);
editor.commit();
}
private void setAltitudeOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.ALTITUDE, b);
editor.commit();
}
private void setDistanceOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.DISTANCE, b);
editor.commit();
}
private void setCompassOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.COMPASS, b);
editor.commit();
}
private void setLocationOverlay(boolean b)
{
Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.LOCATION, b);
editor.commit();
}
private void setOsmBaseOverlay(int b)
{
Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.OSMBASEOVERLAY, b);
editor.commit();
}
private void createListeners()
{
/*******************************************************
* 8 Runnable listener actions
*/
speedCalculator = new Runnable()
{
public void run()
{
double avgspeed = 0.0;
ContentResolver resolver = LoggerMap.this.getContentResolver();
Cursor waypointsCursor = null;
try
{
waypointsCursor = resolver.query(Uri.withAppendedPath(Tracks.CONTENT_URI, LoggerMap.this.mTrackId + "/waypoints"), new String[] {
"avg(" + Waypoints.SPEED + ")", "max(" + Waypoints.SPEED + ")" }, null, null, null);
if (waypointsCursor != null && waypointsCursor.moveToLast())
{
double average = waypointsCursor.getDouble(0);
double maxBasedAverage = waypointsCursor.getDouble(1) / 2;
avgspeed = Math.min(average, maxBasedAverage);
}
if (avgspeed < 2)
{
avgspeed = 5.55d / 2;
}
}
finally
{
if (waypointsCursor != null)
{
waypointsCursor.close();
}
}
mAverageSpeed = avgspeed;
runOnUiThread(new Runnable()
{
public void run()
{
updateSpeedColoring();
}
});
}
};
mServiceConnected = new Runnable()
{
public void run()
{
updateBlankingBehavior();
}
};
/*******************************************************
* 8 Various dialog listeners
*/
mNoteSelectDialogListener = new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
Uri selected = (Uri) mGallery.getSelectedItem();
SegmentOverlay.handleMedia(LoggerMap.this, selected);
}
};
mGroupCheckedChangeListener = new android.widget.RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId)
{
switch (checkedId)
{
case R.id.layer_google_satellite:
setSatelliteOverlay(true);
break;
case R.id.layer_google_regular:
setSatelliteOverlay(false);
break;
case R.id.layer_osm_cloudmade:
setOsmBaseOverlay(Constants.OSM_CLOUDMADE);
break;
case R.id.layer_osm_maknik:
setOsmBaseOverlay(Constants.OSM_MAKNIK);
break;
case R.id.layer_osm_bicycle:
setOsmBaseOverlay(Constants.OSM_CYCLE);
break;
default:
break;
}
}
};
mCheckedChangeListener = new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
int checkedId;
checkedId = buttonView.getId();
switch (checkedId)
{
case R.id.layer_traffic:
setTrafficOverlay(isChecked);
break;
case R.id.layer_speed:
setSpeedOverlay(isChecked);
break;
case R.id.layer_altitude:
setAltitudeOverlay(isChecked);
break;
case R.id.layer_distance:
setDistanceOverlay(isChecked);
break;
case R.id.layer_compass:
setCompassOverlay(isChecked);
break;
case R.id.layer_location:
setLocationOverlay(isChecked);
break;
default:
break;
}
}
};
mNoTrackDialogListener = new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
// Log.d( TAG, "mNoTrackDialogListener" + which);
Intent tracklistIntent = new Intent(LoggerMap.this, TrackList.class);
tracklistIntent.putExtra(Tracks._ID, LoggerMap.this.mTrackId);
startActivityForResult(tracklistIntent, MENU_TRACKLIST);
}
};
mOiAboutDialogListener = new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
Uri oiDownload = Uri.parse("market://details?id=org.openintents.about");
Intent oiAboutIntent = new Intent(Intent.ACTION_VIEW, oiDownload);
try
{
startActivity(oiAboutIntent);
}
catch (ActivityNotFoundException e)
{
oiDownload = Uri.parse("http://openintents.googlecode.com/files/AboutApp-1.0.0.apk");
oiAboutIntent = new Intent(Intent.ACTION_VIEW, oiDownload);
startActivity(oiAboutIntent);
}
}
};
/**
* Listeners to events outside this mapview
*/
mSharedPreferenceChangeListener = new OnSharedPreferenceChangeListener()
{
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if (key.equals(Constants.TRACKCOLORING))
{
mAverageSpeed = 0.0;
updateSpeedColoring();
}
else if (key.equals(Constants.DISABLEBLANKING) || key.equals(Constants.DISABLEDIMMING))
{
updateBlankingBehavior();
}
else if (key.equals(Constants.SPEED))
{
updateSpeedDisplayVisibility();
}
else if (key.equals(Constants.ALTITUDE))
{
updateAltitudeDisplayVisibility();
}
else if (key.equals(Constants.DISTANCE))
{
updateDistanceDisplayVisibility();
}
else if (key.equals(Constants.COMPASS))
{
updateCompassDisplayVisibility();
}
else if (key.equals(Constants.TRAFFIC))
{
updateGoogleOverlays();
}
else if (key.equals(Constants.SATELLITE))
{
updateGoogleOverlays();
}
else if (key.equals(Constants.LOCATION))
{
updateLocationDisplayVisibility();
}
else if (key.equals(Constants.MAPPROVIDER))
{
updateMapProvider();
}
else if (key.equals(Constants.OSMBASEOVERLAY))
{
updateOsmBaseOverlay();
}
}
};
mTrackMediasObserver = new ContentObserver(new Handler())
{
@Override
public void onChange(boolean selfUpdate)
{
if (!selfUpdate)
{
if (mLastSegmentOverlay != null)
{
mLastSegmentOverlay.calculateMedia();
mMapView.postInvalidate();
}
}
else
{
Log.w(TAG, "mTrackMediasObserver skipping change on " + mLastSegment);
}
}
};
mTrackSegmentsObserver = new ContentObserver(new Handler())
{
@Override
public void onChange(boolean selfUpdate)
{
if (!selfUpdate)
{
LoggerMap.this.updateDataOverlays();
}
else
{
Log.w(TAG, "mTrackSegmentsObserver skipping change on " + mLastSegment);
}
}
};
mSegmentWaypointsObserver = new ContentObserver(new Handler())
{
@Override
public void onChange(boolean selfUpdate)
{
if (!selfUpdate)
{
LoggerMap.this.updateTrackNumbers();
if (mLastSegmentOverlay != null)
{
moveActiveViewWindow();
LoggerMap.this.updateMapProviderAdministration();
}
else
{
Log.e(TAG, "Error the last segment changed but it is not on screen! " + mLastSegment);
}
}
else
{
Log.w(TAG, "mSegmentWaypointsObserver skipping change on " + mLastSegment);
}
}
};
mUnitsChangeListener = new UnitsI18n.UnitsChangeListener()
{
public void onUnitsChange()
{
mAverageSpeed = 0.0;
updateTrackNumbers();
updateSpeedColoring();
}
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
boolean result = super.onCreateOptionsMenu(menu);
menu.add(ContextMenu.NONE, MENU_TRACKING, ContextMenu.NONE, R.string.menu_tracking).setIcon(R.drawable.ic_menu_movie).setAlphabeticShortcut('T');
menu.add(ContextMenu.NONE, MENU_LAYERS, ContextMenu.NONE, R.string.menu_showLayers).setIcon(R.drawable.ic_menu_mapmode).setAlphabeticShortcut('L');
menu.add(ContextMenu.NONE, MENU_NOTE, ContextMenu.NONE, R.string.menu_insertnote).setIcon(R.drawable.ic_menu_myplaces);
menu.add(ContextMenu.NONE, MENU_STATS, ContextMenu.NONE, R.string.menu_statistics).setIcon(R.drawable.ic_menu_picture).setAlphabeticShortcut('S');
menu.add(ContextMenu.NONE, MENU_SHARE, ContextMenu.NONE, R.string.menu_shareTrack).setIcon(R.drawable.ic_menu_share).setAlphabeticShortcut('I');
// More
menu.add(ContextMenu.NONE, MENU_TRACKLIST, ContextMenu.NONE, R.string.menu_tracklist).setIcon(R.drawable.ic_menu_show_list).setAlphabeticShortcut('P');
menu.add(ContextMenu.NONE, MENU_SETTINGS, ContextMenu.NONE, R.string.menu_settings).setIcon(R.drawable.ic_menu_preferences).setAlphabeticShortcut('C');
menu.add(ContextMenu.NONE, MENU_ABOUT, ContextMenu.NONE, R.string.menu_about).setIcon(R.drawable.ic_menu_info_details).setAlphabeticShortcut('A');
menu.add(ContextMenu.NONE, MENU_CONTRIB, ContextMenu.NONE, R.string.menu_contrib).setIcon(R.drawable.ic_menu_allfriends);
return result;
}
/*
* (non-Javadoc)
* @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem noteMenu = menu.findItem(MENU_NOTE);
noteMenu.setEnabled(mLoggerServiceManager.isMediaPrepared());
MenuItem shareMenu = menu.findItem(MENU_SHARE);
shareMenu.setEnabled(mTrackId >= 0);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
boolean handled = false;
Uri trackUri;
Intent intent;
switch (item.getItemId())
{
case MENU_TRACKING:
intent = new Intent(this, ControlTracking.class);
startActivityForResult(intent, MENU_TRACKING);
handled = true;
break;
case MENU_LAYERS:
showDialog(DIALOG_LAYERS);
handled = true;
break;
case MENU_NOTE:
intent = new Intent(this, InsertNote.class);
startActivityForResult(intent, MENU_NOTE);
handled = true;
break;
case MENU_SETTINGS:
intent = new Intent(this, ApplicationPreferenceActivity.class);
startActivity(intent);
handled = true;
break;
case MENU_TRACKLIST:
intent = new Intent(this, TrackList.class);
intent.putExtra(Tracks._ID, this.mTrackId);
startActivityForResult(intent, MENU_TRACKLIST);
break;
case MENU_STATS:
if (this.mTrackId >= 0)
{
intent = new Intent(this, Statistics.class);
trackUri = ContentUris.withAppendedId(Tracks.CONTENT_URI, mTrackId);
intent.setData(trackUri);
startActivity(intent);
handled = true;
break;
}
else
{
showDialog(DIALOG_NOTRACK);
}
handled = true;
break;
case MENU_ABOUT:
intent = new Intent("org.openintents.action.SHOW_ABOUT_DIALOG");
try
{
startActivityForResult(intent, MENU_ABOUT);
}
catch (ActivityNotFoundException e)
{
showDialog(DIALOG_INSTALL_ABOUT);
}
break;
case MENU_SHARE:
intent = new Intent(Intent.ACTION_RUN);
trackUri = ContentUris.withAppendedId(Tracks.CONTENT_URI, mTrackId);
intent.setDataAndType(trackUri, Tracks.CONTENT_ITEM_TYPE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Bitmap bm = findViewById(R.id.mapScreen).getDrawingCache();
Uri screenStreamUri = ShareTrack.storeScreenBitmap(bm);
intent.putExtra(Intent.EXTRA_STREAM, screenStreamUri);
startActivityForResult(Intent.createChooser( intent, getString( R.string.share_track ) ), MENU_SHARE);
handled = true;
break;
case MENU_CONTRIB:
showDialog(DIALOG_CONTRIB);
default:
handled = super.onOptionsItemSelected(item);
break;
}
return handled;
}
/*
* (non-Javadoc)
* @see android.app.Activity#onCreateDialog(int)
*/
@Override
protected Dialog onCreateDialog(int id)
{
Dialog dialog = null;
LayoutInflater factory = null;
View view = null;
Builder builder = null;
switch (id)
{
case DIALOG_LAYERS:
builder = new AlertDialog.Builder(this);
factory = LayoutInflater.from(this);
view = factory.inflate(R.layout.layerdialog, null);
mTraffic = (CheckBox) view.findViewById(R.id.layer_traffic);
mSpeed = (CheckBox) view.findViewById(R.id.layer_speed);
mAltitude = (CheckBox) view.findViewById(R.id.layer_altitude);
mDistance = (CheckBox) view.findViewById(R.id.layer_distance);
mCompass = (CheckBox) view.findViewById(R.id.layer_compass);
mLocation = (CheckBox) view.findViewById(R.id.layer_location);
((RadioGroup) view.findViewById(R.id.google_backgrounds)).setOnCheckedChangeListener(mGroupCheckedChangeListener);
((RadioGroup) view.findViewById(R.id.osm_backgrounds)).setOnCheckedChangeListener(mGroupCheckedChangeListener);
mTraffic.setOnCheckedChangeListener(mCheckedChangeListener);
mSpeed.setOnCheckedChangeListener(mCheckedChangeListener);
mAltitude.setOnCheckedChangeListener(mCheckedChangeListener);
mDistance.setOnCheckedChangeListener(mCheckedChangeListener);
mCompass.setOnCheckedChangeListener(mCheckedChangeListener);
mLocation.setOnCheckedChangeListener(mCheckedChangeListener);
builder.setTitle(R.string.dialog_layer_title).setIcon(android.R.drawable.ic_dialog_map).setPositiveButton(R.string.btn_okay, null).setView(view);
dialog = builder.create();
return dialog;
case DIALOG_NOTRACK:
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dialog_notrack_title).setMessage(R.string.dialog_notrack_message).setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(R.string.btn_selecttrack, mNoTrackDialogListener).setNegativeButton(R.string.btn_cancel, null);
dialog = builder.create();
return dialog;
case DIALOG_INSTALL_ABOUT:
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dialog_nooiabout).setMessage(R.string.dialog_nooiabout_message).setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(R.string.btn_install, mOiAboutDialogListener).setNegativeButton(R.string.btn_cancel, null);
dialog = builder.create();
return dialog;
case DIALOG_URIS:
builder = new AlertDialog.Builder(this);
factory = LayoutInflater.from(this);
view = factory.inflate(R.layout.mediachooser, null);
mGallery = (Gallery) view.findViewById(R.id.gallery);
builder.setTitle(R.string.dialog_select_media_title).setMessage(R.string.dialog_select_media_message).setIcon(android.R.drawable.ic_dialog_alert)
.setNegativeButton(R.string.btn_cancel, null).setPositiveButton(R.string.btn_okay, mNoteSelectDialogListener).setView(view);
dialog = builder.create();
return dialog;
case DIALOG_CONTRIB:
builder = new AlertDialog.Builder(this);
factory = LayoutInflater.from(this);
view = factory.inflate(R.layout.contrib, null);
TextView contribView = (TextView) view.findViewById(R.id.contrib_view);
contribView.setText(R.string.dialog_contrib_message);
builder.setTitle(R.string.dialog_contrib_title).setView(view).setIcon(android.R.drawable.ic_dialog_email)
.setPositiveButton(R.string.btn_okay, null);
dialog = builder.create();
return dialog;
default:
return super.onCreateDialog(id);
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onPrepareDialog(int, android.app.Dialog)
*/
@Override
protected void onPrepareDialog(int id, Dialog dialog)
{
RadioButton satellite;
RadioButton regular;
RadioButton cloudmade;
RadioButton mapnik;
RadioButton cycle;
switch (id)
{
case DIALOG_LAYERS:
satellite = (RadioButton) dialog.findViewById(R.id.layer_google_satellite);
regular = (RadioButton) dialog.findViewById(R.id.layer_google_regular);
satellite.setChecked(mSharedPreferences.getBoolean(Constants.SATELLITE, false));
regular.setChecked(!mSharedPreferences.getBoolean(Constants.SATELLITE, false));
int osmbase = mSharedPreferences.getInt(Constants.OSMBASEOVERLAY, 0);
cloudmade = (RadioButton) dialog.findViewById(R.id.layer_osm_cloudmade);
mapnik = (RadioButton) dialog.findViewById(R.id.layer_osm_maknik);
cycle = (RadioButton) dialog.findViewById(R.id.layer_osm_bicycle);
cloudmade.setChecked(osmbase == Constants.OSM_CLOUDMADE);
mapnik.setChecked(osmbase == Constants.OSM_MAKNIK);
cycle.setChecked(osmbase == Constants.OSM_CYCLE);
mTraffic.setChecked(mSharedPreferences.getBoolean(Constants.TRAFFIC, false));
mSpeed.setChecked(mSharedPreferences.getBoolean(Constants.SPEED, false));
mAltitude.setChecked(mSharedPreferences.getBoolean(Constants.ALTITUDE, false));
mDistance.setChecked(mSharedPreferences.getBoolean(Constants.DISTANCE, false));
mCompass.setChecked(mSharedPreferences.getBoolean(Constants.COMPASS, false));
mLocation.setChecked(mSharedPreferences.getBoolean(Constants.LOCATION, false));
int provider = new Integer(mSharedPreferences.getString(Constants.MAPPROVIDER, "" + Constants.GOOGLE)).intValue();
switch (provider)
{
case Constants.GOOGLE:
dialog.findViewById(R.id.google_backgrounds).setVisibility(View.VISIBLE);
dialog.findViewById(R.id.osm_backgrounds).setVisibility(View.GONE);
dialog.findViewById(R.id.shared_layers).setVisibility(View.VISIBLE);
dialog.findViewById(R.id.google_overlays).setVisibility(View.VISIBLE);
break;
case Constants.OSM:
dialog.findViewById(R.id.osm_backgrounds).setVisibility(View.VISIBLE);
dialog.findViewById(R.id.google_backgrounds).setVisibility(View.GONE);
dialog.findViewById(R.id.shared_layers).setVisibility(View.VISIBLE);
dialog.findViewById(R.id.google_overlays).setVisibility(View.GONE);
break;
default:
Log.e(TAG, "Fault in value " + provider + " as MapProvider.");
break;
}
break;
case DIALOG_URIS:
mGallery.setAdapter(mMediaAdapter);
default:
break;
}
super.onPrepareDialog(id, dialog);
}
/*
* (non-Javadoc)
* @see android.app.Activity#onActivityResult(int, int,
* android.content.Intent)
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
Uri trackUri;
long trackId;
switch (requestCode)
{
case MENU_TRACKLIST:
if (resultCode == RESULT_OK)
{
trackUri = intent.getData();
trackId = Long.parseLong(trackUri.getLastPathSegment());
mAverageSpeed = 0.0;
moveToTrack(trackId, true);
}
break;
case MENU_ABOUT:
break;
case MENU_TRACKING:
if (resultCode == RESULT_OK)
{
trackUri = intent.getData();
if (trackUri != null)
{
trackId = Long.parseLong(trackUri.getLastPathSegment());
mAverageSpeed = 0.0;
moveToTrack(trackId, true);
}
}
break;
case MENU_SHARE:
ShareTrack.clearScreenBitmap();
break;
default:
Log.e(TAG, "Returned form unknow activity: " + requestCode);
break;
}
}
/**
* (non-Javadoc)
*
* @see com.google.android.maps.MapActivity#isRouteDisplayed()
*/
@Override
protected boolean isRouteDisplayed()
{
return true;
}
/**
* (non-Javadoc)
*
* @see com.google.android.maps.MapActivity#isLocationDisplayed()
*/
@Override
protected boolean isLocationDisplayed()
{
return mSharedPreferences.getBoolean(Constants.LOCATION, false) || mLoggerServiceManager.getLoggingState() == Constants.LOGGING;
}
private void updateTitleBar()
{
ContentResolver resolver = this.getContentResolver();
Cursor trackCursor = null;
try
{
trackCursor = resolver.query(ContentUris.withAppendedId(Tracks.CONTENT_URI, this.mTrackId), new String[] { Tracks.NAME }, null, null, null);
if (trackCursor != null && trackCursor.moveToLast())
{
String trackName = trackCursor.getString(0);
this.setTitle(this.getString(R.string.app_name) + ": " + trackName);
}
}
finally
{
if (trackCursor != null)
{
trackCursor.close();
}
}
}
private void updateMapProvider()
{
int provider = new Integer(mSharedPreferences.getString(Constants.MAPPROVIDER, "" + Constants.GOOGLE)).intValue();
switch (provider)
{
case Constants.GOOGLE:
findViewById(R.id.myOsmMapView).setVisibility(View.GONE);
findViewById(R.id.myMapView).setVisibility(View.VISIBLE);
mMapView.setMap(findViewById(R.id.myMapView));
updateGoogleOverlays();
break;
case Constants.OSM:
CloudmadeUtil.retrieveCloudmadeKey(this);
findViewById(R.id.myMapView).setVisibility(View.GONE);
findViewById(R.id.myOsmMapView).setVisibility(View.VISIBLE);
mMapView.setMap(findViewById(R.id.myOsmMapView));
updateOsmBaseOverlay();
break;
default:
Log.e(TAG, "Fault in value " + provider + " as MapProvider.");
break;
}
}
private void updateGoogleOverlays()
{
LoggerMap.this.mMapView.setSatellite(mSharedPreferences.getBoolean(Constants.SATELLITE, false));
LoggerMap.this.mMapView.setTraffic(mSharedPreferences.getBoolean(Constants.TRAFFIC, false));
}
private void updateOsmBaseOverlay()
{
int baselayer = mSharedPreferences.getInt(Constants.OSMBASEOVERLAY, 0);
mMapView.setOSMType(baselayer);
}
protected void updateMapProviderAdministration()
{
if (findViewById(R.id.myMapView).getVisibility() == View.VISIBLE)
{
mLoggerServiceManager.storeDerivedDataSource(GOOGLE_PROVIDER);
}
if (findViewById(R.id.myOsmMapView).getVisibility() == View.VISIBLE)
{
mLoggerServiceManager.storeDerivedDataSource(OSM_PROVIDER);
}
}
private void updateBlankingBehavior()
{
boolean disableblanking = mSharedPreferences.getBoolean(Constants.DISABLEBLANKING, false);
boolean disabledimming = mSharedPreferences.getBoolean(Constants.DISABLEDIMMING, false);
if (disableblanking)
{
if (mWakeLock == null)
{
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
if( disabledimming )
{
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG);
}
else
{
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
}
}
if (mLoggerServiceManager.getLoggingState() == Constants.LOGGING && !mWakeLock.isHeld())
{
mWakeLock.acquire();
Log.w(TAG, "Acquired lock to keep screen on!");
}
}
}
private void updateSpeedColoring()
{
int trackColoringMethod = new Integer(mSharedPreferences.getString(Constants.TRACKCOLORING, "3")).intValue();
View speedbar = findViewById(R.id.speedbar);
if (trackColoringMethod == SegmentOverlay.DRAW_MEASURED || trackColoringMethod == SegmentOverlay.DRAW_CALCULATED)
{
// mAverageSpeed is set to 0 if unknown or to trigger an recalculation here
if (mAverageSpeed == 0.0)
{
mHandler.removeCallbacks(speedCalculator);
mHandler.post(speedCalculator);
}
else
{
drawSpeedTexts(mAverageSpeed);
speedbar.setVisibility(View.VISIBLE);
for (int i = 0; i < mSpeedtexts.length; i++)
{
mSpeedtexts[i].setVisibility(View.VISIBLE);
}
}
}
else
{
speedbar.setVisibility(View.INVISIBLE);
for (int i = 0; i < mSpeedtexts.length; i++)
{
mSpeedtexts[i].setVisibility(View.INVISIBLE);
}
}
List< ? > overlays = mMapView.getOverlays();
for (Object overlay : overlays)
{
if (overlay instanceof SegmentOverlay)
{
((SegmentOverlay) overlay).setTrackColoringMethod(trackColoringMethod, mAverageSpeed);
}
}
}
private void updateSpeedDisplayVisibility()
{
boolean showspeed = mSharedPreferences.getBoolean(Constants.SPEED, false);
if (showspeed)
{
mLastGPSSpeedView.setVisibility(View.VISIBLE);
}
else
{
mLastGPSSpeedView.setVisibility(View.GONE);
}
}
private void updateAltitudeDisplayVisibility()
{
boolean showaltitude = mSharedPreferences.getBoolean(Constants.ALTITUDE, false);
if (showaltitude)
{
mLastGPSAltitudeView.setVisibility(View.VISIBLE);
}
else
{
mLastGPSAltitudeView.setVisibility(View.GONE);
}
}
private void updateDistanceDisplayVisibility()
{
boolean showdistance = mSharedPreferences.getBoolean(Constants.DISTANCE, false);
if (showdistance)
{
mDistanceView.setVisibility(View.VISIBLE);
}
else
{
mDistanceView.setVisibility(View.GONE);
}
}
private void updateCompassDisplayVisibility()
{
boolean compass = mSharedPreferences.getBoolean(Constants.COMPASS, false);
if (compass)
{
mMylocation.enableCompass();
}
else
{
mMylocation.disableCompass();
}
}
private void updateLocationDisplayVisibility()
{
boolean location = mSharedPreferences.getBoolean(Constants.LOCATION, false);
if (location)
{
mMylocation.enableMyLocation();
}
else
{
mMylocation.disableMyLocation();
}
}
/**
* Retrieves the numbers of the measured speed and altitude from the most
* recent waypoint and updates UI components with this latest bit of
* information.
*/
private void updateTrackNumbers()
{
Location lastWaypoint = mLoggerServiceManager.getLastWaypoint();
UnitsI18n units = mUnits;
if (lastWaypoint != null && units != null)
{
// Speed number
double speed = lastWaypoint.getSpeed();
speed = units.conversionFromMetersPerSecond(speed);
String speedText = units.formatSpeed(speed, false);
mLastGPSSpeedView.setText(speedText);
// Speed color bar and refrence numbers
if (speed > 2 * mAverageSpeed)
{
mAverageSpeed = 0.0;
updateSpeedColoring();
mMapView.postInvalidate();
}
//Altitude number
double altitude = lastWaypoint.getAltitude();
altitude = units.conversionFromMeterToHeight(altitude);
String altitudeText = String.format("%.0f %s", altitude, units.getHeightUnit());
mLastGPSAltitudeView.setText(altitudeText);
//Distance number
double distance = units.conversionFromMeter( mLoggerServiceManager.getTrackedDistance() );
String distanceText = String.format("%.2f %s", distance, units.getDistanceUnit());
mDistanceView.setText(distanceText);
}
}
/**
* For the current track identifier the route of that track is drawn by
* adding a OverLay for each segments in the track
*
* @param trackId
* @see SegmentOverlay
*/
private void createDataOverlays()
{
mLastSegmentOverlay = null;
mMapView.clearOverlays();
mMapView.addOverlay(mMylocation);
ContentResolver resolver = this.getContentResolver();
Cursor segments = null;
int trackColoringMethod = new Integer(mSharedPreferences.getString(Constants.TRACKCOLORING, "2")).intValue();
try
{
Uri segmentsUri = Uri.withAppendedPath(Tracks.CONTENT_URI, this.mTrackId + "/segments");
segments = resolver.query(segmentsUri, new String[] { Segments._ID }, null, null, null);
if (segments != null && segments.moveToFirst())
{
do
{
long segmentsId = segments.getLong(0);
Uri segmentUri = ContentUris.withAppendedId(segmentsUri, segmentsId);
SegmentOverlay segmentOverlay = new SegmentOverlay(this, segmentUri, trackColoringMethod, mAverageSpeed, this.mMapView, mHandler);
mMapView.addOverlay(segmentOverlay);
mLastSegmentOverlay = segmentOverlay;
if (segments.isFirst())
{
segmentOverlay.addPlacement(SegmentOverlay.FIRST_SEGMENT);
}
if (segments.isLast())
{
segmentOverlay.addPlacement(SegmentOverlay.LAST_SEGMENT);
}
mLastSegment = segmentsId;
}
while (segments.moveToNext());
}
}
finally
{
if (segments != null)
{
segments.close();
}
}
Uri lastSegmentUri = Uri.withAppendedPath(Tracks.CONTENT_URI, mTrackId + "/segments/" + mLastSegment + "/waypoints");
resolver.unregisterContentObserver(this.mSegmentWaypointsObserver);
resolver.registerContentObserver(lastSegmentUri, false, this.mSegmentWaypointsObserver);
}
private void updateDataOverlays()
{
ContentResolver resolver = this.getContentResolver();
Uri segmentsUri = Uri.withAppendedPath(Tracks.CONTENT_URI, this.mTrackId + "/segments");
Cursor segmentsCursor = null;
List< ? > overlays = this.mMapView.getOverlays();
int segmentOverlaysCount = 0;
for (Object overlay : overlays)
{
if (overlay instanceof SegmentOverlay)
{
segmentOverlaysCount++;
}
}
try
{
segmentsCursor = resolver.query(segmentsUri, new String[] { Segments._ID }, null, null, null);
if (segmentsCursor != null && segmentsCursor.getCount() == segmentOverlaysCount)
{
// Log.d( TAG, "Alignment of segments" );
}
else
{
createDataOverlays();
}
}
finally
{
if (segmentsCursor != null)
{
segmentsCursor.close();
}
}
}
/**
* Call when an overlay has recalulated and has new information to be redrawn
*/
public void onDateOverlayChanged()
{
this.mMapView.postInvalidate();
}
private void moveActiveViewWindow()
{
GeoPoint lastPoint = getLastTrackPoint();
if (lastPoint != null && mLoggerServiceManager.getLoggingState() == Constants.LOGGING)
{
Point out = new Point();
this.mMapView.getProjection().toPixels(lastPoint, out);
int height = this.mMapView.getHeight();
int width = this.mMapView.getWidth();
if (out.x < 0 || out.y < 0 || out.y > height || out.x > width)
{
this.mMapView.clearAnimation();
this.mMapView.getController().setCenter(lastPoint);
// Log.d( TAG, "mMapView.setCenter()" );
}
else if (out.x < width / 4 || out.y < height / 4 || out.x > (width / 4) * 3 || out.y > (height / 4) * 3)
{
this.mMapView.clearAnimation();
this.mMapView.getController().animateTo(lastPoint);
// Log.d( TAG, "mMapView.animateTo()" );
}
}
}
/**
* @param avgSpeed avgSpeed in m/s
*/
private void drawSpeedTexts(double avgSpeed)
{
UnitsI18n units = mUnits;
if (units != null)
{
avgSpeed = units.conversionFromMetersPerSecond(avgSpeed);
for (int i = 0; i < mSpeedtexts.length; i++)
{
mSpeedtexts[i].setVisibility(View.VISIBLE);
double speed;
if( mUnits.isUnitFlipped() )
{
speed = ((avgSpeed * 2d) / 5d) * (mSpeedtexts.length - i - 1) ;
}
else
{
speed = ((avgSpeed * 2d) / 5d) * i;
}
String speedText = units.formatSpeed(speed, false);
mSpeedtexts[i].setText(speedText);
}
}
}
/**
* Alter this to set a new track as current.
*
* @param trackId
* @param center center on the end of the track
*/
private void moveToTrack(long trackId, boolean center)
{
Cursor track = null;
try
{
ContentResolver resolver = this.getContentResolver();
Uri trackUri = ContentUris.withAppendedId(Tracks.CONTENT_URI, trackId);
track = resolver.query(trackUri, new String[] { Tracks.NAME }, null, null, null);
if (track != null && track.moveToFirst())
{
this.mTrackId = trackId;
mLastSegment = -1;
resolver.unregisterContentObserver(this.mTrackSegmentsObserver);
resolver.unregisterContentObserver(this.mTrackMediasObserver);
Uri tracksegmentsUri = Uri.withAppendedPath(Tracks.CONTENT_URI, trackId + "/segments");
resolver.registerContentObserver(tracksegmentsUri, false, this.mTrackSegmentsObserver);
resolver.registerContentObserver(Media.CONTENT_URI, true, this.mTrackMediasObserver);
this.mMapView.clearOverlays();
updateTitleBar();
updateDataOverlays();
updateSpeedColoring();
if (center)
{
GeoPoint lastPoint = getLastTrackPoint();
this.mMapView.getController().animateTo(lastPoint);
}
}
}
finally
{
if (track != null)
{
track.close();
}
}
}
/**
* Get the last know position from the GPS provider and return that
* information wrapped in a GeoPoint to which the Map can navigate.
*
* @see GeoPoint
* @return
*/
private GeoPoint getLastKnowGeopointLocation()
{
int microLatitude = 0;
int microLongitude = 0;
LocationManager locationManager = (LocationManager) this.getApplication().getSystemService(Context.LOCATION_SERVICE);
Location locationFine = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (locationFine != null)
{
microLatitude = (int) (locationFine.getLatitude() * 1E6d);
microLongitude = (int) (locationFine.getLongitude() * 1E6d);
}
if (locationFine == null || microLatitude == 0 || microLongitude == 0)
{
Location locationCoarse = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (locationCoarse != null)
{
microLatitude = (int) (locationCoarse.getLatitude() * 1E6d);
microLongitude = (int) (locationCoarse.getLongitude() * 1E6d);
}
if (locationCoarse == null || microLatitude == 0 || microLongitude == 0)
{
microLatitude = 51985105;
microLongitude = 5106132;
}
}
GeoPoint geoPoint = new GeoPoint(microLatitude, microLongitude);
return geoPoint;
}
/**
* Retrieve the last point of the current track
*
* @param context
*/
private GeoPoint getLastTrackPoint()
{
Cursor waypoint = null;
GeoPoint lastPoint = null;
// First try the service which might have a cached version
Location lastLoc = mLoggerServiceManager.getLastWaypoint();
if (lastLoc != null)
{
int microLatitude = (int) (lastLoc.getLatitude() * 1E6d);
int microLongitude = (int) (lastLoc.getLongitude() * 1E6d);
lastPoint = new GeoPoint(microLatitude, microLongitude);
}
// If nothing yet, try the content resolver and query the track
if (lastPoint == null || lastPoint.getLatitudeE6() == 0 || lastPoint.getLongitudeE6() == 0)
{
try
{
ContentResolver resolver = this.getContentResolver();
waypoint = resolver.query(Uri.withAppendedPath(Tracks.CONTENT_URI, mTrackId + "/waypoints"), new String[] { Waypoints.LATITUDE,
Waypoints.LONGITUDE, "max(" + Waypoints.TABLE + "." + Waypoints._ID + ")" }, null, null, null);
if (waypoint != null && waypoint.moveToLast())
{
int microLatitude = (int) (waypoint.getDouble(0) * 1E6d);
int microLongitude = (int) (waypoint.getDouble(1) * 1E6d);
lastPoint = new GeoPoint(microLatitude, microLongitude);
}
}
finally
{
if (waypoint != null)
{
waypoint.close();
}
}
}
// If nothing yet, try the last generally known location
if (lastPoint == null || lastPoint.getLatitudeE6() == 0 || lastPoint.getLongitudeE6() == 0)
{
lastPoint = getLastKnowGeopointLocation();
}
return lastPoint;
}
private void moveToLastTrack()
{
int trackId = -1;
Cursor track = null;
try
{
ContentResolver resolver = this.getContentResolver();
track = resolver.query(Tracks.CONTENT_URI, new String[] { "max(" + Tracks._ID + ")", Tracks.NAME, }, null, null, null);
if (track != null && track.moveToLast())
{
trackId = track.getInt(0);
mAverageSpeed = 0.0;
moveToTrack(trackId, false);
}
}
finally
{
if (track != null)
{
track.close();
}
}
}
/**
* Enables a SegmentOverlay to call back to the MapActivity to show a dialog
* with choices of media
*
* @param mediaAdapter
*/
public void showDialog(BaseAdapter mediaAdapter)
{
mMediaAdapter = mediaAdapter;
showDialog(LoggerMap.DIALOG_URIS);
}
}