/*
* Copyright 2011 Greg Milette and Adam Stroud
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package root.gast.playground.location;
import root.gast.playground.R;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
/**
* Activity that records a device's current location and plots both the current location
* and historical location on a Google map.
*
* @author Adam Stroud <<a href="mailto:adam.stroud@gmail.com">adam.stroud@gmail.com</a>>
*/
public class TrackLocationActivity extends MapActivity
{
private static final String TAG = "TrackLocationActivity";
private static final int REQUEST_CODE = 0;
private static final String TRACKING_PREFERENCE_KEY =
"TRACKING_PREFERENCE_KEY";
private static final String ADD_LOCATION_ACTION =
"root.gast.playground.location.ACTION_LOCATION_CHANGED";
private LocationManager locationManager;
private MapView mapView;
private TrackLocationOverlay trackLocationOverlay;
private PendingIntent pendingIntent;
private Button startTrackingButton;
private Button stopTrackingButton;
private boolean tracking;
private SharedPreferences preferences;
private PointDatabaseManager pointDatabaseManager;
private UpdateViewBroadcastReceiver broadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.track_location);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
mapView = (MapView) findViewById(R.id.mapView);
startTrackingButton =
(Button) findViewById(R.id.startTrackingLocationButton);
stopTrackingButton =
(Button) findViewById(R.id.stopTrackingLocationButton);
mapView.setBuiltInZoomControls(true);
Drawable starDrawable =
getResources().getDrawable(android.R.drawable.star_on);
trackLocationOverlay =
new TrackLocationOverlay(starDrawable, mapView);
mapView.getOverlays().add(trackLocationOverlay);
preferences = getPreferences(MODE_PRIVATE);
pointDatabaseManager =
PointDatabaseManager.getInstance(getApplicationContext());
broadcastReceiver =
new UpdateViewBroadcastReceiver(trackLocationOverlay, mapView);
}
@Override
protected void onResume()
{
super.onResume();
registerReceiver(broadcastReceiver,
new IntentFilter(ADD_LOCATION_ACTION));
tracking = preferences.getBoolean(TRACKING_PREFERENCE_KEY, false);
startTrackingButton.setEnabled(!tracking);
stopTrackingButton.setEnabled(tracking);
if (tracking)
{
String[] queryString =
new String[]
{
PointDatabaseManager.COLUMN_LATITUDE,
PointDatabaseManager.COLUMN_LONGITUDE,
PointDatabaseManager.COLUMN_ACCURACY
};
Cursor pointCursor =
pointDatabaseManager.getPointCursor(queryString,
null,
null,
"_id ASC");
if (pointCursor.getCount() > 0)
{
for (pointCursor.moveToFirst(); !pointCursor.isAfterLast(); pointCursor.moveToNext())
{
double latitude = pointCursor.getDouble(pointCursor.getColumnIndex(PointDatabaseManager.COLUMN_LATITUDE));
double longitude = pointCursor.getDouble(pointCursor.getColumnIndex(PointDatabaseManager.COLUMN_LONGITUDE));
float accuracy = pointCursor.getFloat(pointCursor.getColumnIndex(PointDatabaseManager.COLUMN_ACCURACY));
trackLocationOverlay.addPoint(latitude, longitude, accuracy);
}
}
pointCursor.close();
}
}
@Override
protected void onPause()
{
super.onPause();
unregisterReceiver(broadcastReceiver);
preferences.edit().putBoolean(TRACKING_PREFERENCE_KEY, tracking).commit();
}
@Override
protected boolean isRouteDisplayed()
{
return true;
}
@Override
protected boolean isLocationDisplayed()
{
return true;
}
public void onStartTrackingButtonClick(View view)
{
Log.d(TAG, "Tracking = " + tracking);
if (!tracking)
{
startTrackingButton.setEnabled(false);
stopTrackingButton.setEnabled(true);
pendingIntent = createPendingIntent();
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
for (String provider : locationManager.getProviders(criteria, true))
{
Log.d(TAG, "Enabling provider " + provider);
locationManager.requestLocationUpdates(provider,
0,
0,
pendingIntent);
}
tracking = true;
}
}
public void onStopTrackingButtonClick(View view)
{
if (tracking)
{
if (pendingIntent == null)
{
pendingIntent = createPendingIntent();
}
locationManager.removeUpdates(pendingIntent);
startTrackingButton.setEnabled(true);
stopTrackingButton.setEnabled(false);
tracking = false;
pointDatabaseManager.deletePoints();
pointDatabaseManager.close();
}
}
private PendingIntent createPendingIntent()
{
Intent intent = new Intent(ADD_LOCATION_ACTION);
return PendingIntent.getBroadcast(getApplicationContext(),
REQUEST_CODE,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
private static class UpdateViewBroadcastReceiver
extends FilteringLocationBroadcastReceiver
{
private TrackLocationOverlay trackLocationOverlay;
private MapView mapView;
private boolean initialZoomSet;
public UpdateViewBroadcastReceiver(TrackLocationOverlay overlay,
MapView mapView)
{
this.trackLocationOverlay = overlay;
this.mapView = mapView;
}
@Override
public void onFilteredLocationChanged(Context context,
Location location)
{
trackLocationOverlay.addPoint(location.getLatitude(),
location.getLongitude(),
location.getAccuracy());
int latE6 = (int) (location.getLatitude() * 1E6);
int longE6 = (int) (location.getLongitude() * 1E6);
mapView.getController().animateTo(new GeoPoint(latE6, longE6));
if (!initialZoomSet)
{
mapView.getController().setZoom(15);
initialZoomSet = true;
}
}
}
}