/* * Protocoder * A prototyping platform for Android devices * * Victor Diaz Barrales victormdb@gmail.com * * Copyright (C) 2014 Victor Diaz * Copyright (C) 2013 Motorola Mobility LLC * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software * is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package org.protocoderrunner.sensors; import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.provider.Settings; import org.protocoderrunner.apprunner.logger.L; import org.protocoderrunner.utils.MLog; import java.io.IOException; import java.util.List; import java.util.Locale; import java.util.Vector; @TargetApi(Build.VERSION_CODES.GINGERBREAD) public class GPSManager { public interface GPSListener extends CustomSensorListener { public void onLocationChanged(double lat, double lon, double alt, float speed, float bearing); public void onSpeedChanged(float speed); public void onGPSSignalGood(); public void onGPSSignalBad(); public void onGPSStatus(boolean isGPSFix); } protected static final String TAG = "GPSManager"; private final Context c; LocationManager locationManager; String provider; Vector<GPSListener> listeners; private boolean isGPSFix; private Location mLastLocation; private long mLastLocationMillis; private LocationListener listener; private boolean running; // The minimum distance to change Updates in meters // private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 // meters // The minimum time between updates in milliseconds // private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 // minute public GPSManager(Context c) { this.c = c; listeners = new Vector<GPSListener>(); } // gps public void start() { MLog.d(TAG, "starting GPS"); // criteria.setSpeedRequired(true); locationManager = (LocationManager) c.getSystemService(Context.LOCATION_SERVICE); if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) == false) { MLog.d(TAG, "GPS not enabled"); showSettingsAlert(); } else { MLog.d(TAG, "GPS enabled"); } running = true; Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); // criteria.setBearingAccuracy(Criteria.ACCURACY_FINE); criteria.setCostAllowed(true); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setPowerRequirement(Criteria.POWER_HIGH); criteria.setSpeedRequired(false); provider = locationManager.getBestProvider(criteria, false); listener = new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { L.d(TAG, "the gps status is: " + status); // TODO add a listener to see when the GPS is on or not switch (status) { case GpsStatus.GPS_EVENT_SATELLITE_STATUS: if (mLastLocation != null) { isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000; } if (isGPSFix) { // A fix has been acquired. // Do something. } else { // The fix has been lost. // Do something. } for (CustomSensorListener l : listeners) { ((GPSListener) l).onGPSStatus(isGPSFix); } break; case GpsStatus.GPS_EVENT_FIRST_FIX: // Do something. isGPSFix = true; break; } } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); c.startActivity(intent); } @Override public void onLocationChanged(Location location) { MLog.d(TAG, "updated "); for (CustomSensorListener l : listeners) { ((GPSListener) l).onLocationChanged(location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getSpeed(), location.getAccuracy()); } if (location == null) { return; } mLastLocationMillis = SystemClock.elapsedRealtime(); mLastLocation = location; } }; locationManager.requestLocationUpdates(provider, 100, 0.1f, listener); } public Location getLastKnownLocation() { return locationManager.getLastKnownLocation(provider); } /** * Function to get location name * */ public String getLocationName(double lat, double lon) { String gpsLocation = ""; Geocoder gcd = new Geocoder(c, Locale.getDefault()); List<Address> addresses; try { addresses = gcd.getFromLocation(lat, lon, 1); gpsLocation = addresses.get(0).getLocality(); } catch (IOException e) { e.printStackTrace(); } return gpsLocation; } /** * Function to show settings alert dialog On pressing Settings button will * lauch Settings Options * */ public void showSettingsAlert() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(c); // Setting Dialog Title alertDialog.setTitle("GPS settings"); // Setting Dialog Message alertDialog.setMessage("GPS is not enabled. Do you want to go to the settings menu?"); // On pressing Settings button alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); c.startActivity(intent); } }); // on pressing cancel button alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); // Showing Alert Message alertDialog.show(); } public double getDistance(double startLatitude, double startLongitude, double endLatitude, double endLongitude) { float[] results = null; // Location.distanceBetween(startLatitude, startLongitude, endLatitude, // endLongitude, results); Location locationA = new Location("point A"); locationA.setLatitude(startLatitude); locationA.setLongitude(startLongitude); Location locationB = new Location("point B"); locationB.setLatitude(endLatitude); locationB.setLongitude(endLongitude); float distance = locationA.distanceTo(locationB); return distance; } public void stop() { running = false; for (GPSListener l : listeners) { listeners.remove(l); locationManager.removeUpdates(listener); } } public void addListener(GPSListener listener) { listeners.add(listener); } public void removeListener(GPSListener listener) { listeners.remove(listener); } }