ArViewer  Android Version
Arvos - Augmented reality viewer open source
 All Classes Namespaces Files Functions Variables
ArvosLocationListener.java
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013, Peter Graf
3 
4  This file is part of Arvos - AR Viewer Open Source for Android.
5  Arvos is free software.
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20  For more information on the AR Viewer Open Source or Peter Graf,
21  please see: http://www.mission-base.com/.
22  */
23 
24 package com.mission_base.arviewer_android;
25 
26 import android.location.Location;
27 import android.location.LocationListener;
28 import android.location.LocationManager;
29 import android.location.LocationProvider;
30 import android.os.Bundle;
31 import android.util.Log;
32 
39 public class ArvosLocationListener implements LocationListener
40 {
41  private IArvosLocationReceiver mReceiver;
42  private LocationManager mLocationManager;
43  private Arvos mInstance;
44 
53  public ArvosLocationListener(LocationManager locationManager, IArvosLocationReceiver receiver)
54  {
55  mLocationManager = locationManager; // (LocationManager)
56  // getSystemService(Context.LOCATION_SERVICE);
57  mReceiver = receiver;
58  mInstance = Arvos.getInstance();
59  }
60 
61  public void onResume()
62  {
63  requestLocation();
64  }
65 
66  public void onPause()
67  {
68  Log.d("removeUpdates", "this");
69  mLocationManager.removeUpdates(this);
70  }
71 
72  private Location mCurrentBestLocation = null;
73 
74  private void requestLocation()
75  {
76  Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
77  if (location != null)
78  {
79  onLocationChanged(false, location);
80  }
81 
82  location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
83  if (location != null)
84  {
85  onLocationChanged(false, location);
86  }
87 
88  Log.d("requestLocationUpdates", LocationManager.GPS_PROVIDER);
89  mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 3, this);
90  Log.d("requestLocationUpdates", LocationManager.NETWORK_PROVIDER);
91  mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 3, this);
92  }
93 
94  @Override
95  public void onLocationChanged(Location location)
96  {
97  onLocationChanged(true, location);
98  }
99 
100  private void onLocationChanged(boolean isNew, Location location)
101  {
102  // Log.d("onLocationChanged", "new " + isNew);
103  // Log.d("onLocationChanged", location.getProvider());
104 
105  mInstance.mLatitude = (float) location.getLatitude();
106  // Log.d("onLocationChanged", "lat " + mInstance.mLatitude);
107 
108  mInstance.mLongitude = (float) location.getLongitude();
109  // Log.d("onLocationChanged", "lon " + mInstance.mLongitude);
110  //
111  // Log.d("onLocationChanged", "alt " + location.getAltitude());
112  // Log.d("onLocationChanged", "acc " + location.getAccuracy());
113  // Log.d("onLocationChanged", "tim " + location.getTime());
114 
115  if (mReceiver != null)
116  {
117  if (isBetterLocation(location, mCurrentBestLocation))
118  {
119  mCurrentBestLocation = location;
120  mReceiver.onLocationChanged(true, location);
121  }
122  }
123  }
124 
125  @Override
126  public void onProviderDisabled(String provider)
127  {
128  Log.d("onProviderDisabled", provider);
129  }
130 
131  @Override
132  public void onProviderEnabled(String provider)
133  {
134  Log.d("onProviderEnabled", provider);
135  }
136 
137  @Override
138  public void onStatusChanged(String provider, int status, Bundle extras)
139  {
140  if (status == LocationProvider.OUT_OF_SERVICE)
141  {
142  Log.d("LocationProvider.OUT_OF_SERVICE", provider);
143  }
144  else if (status == LocationProvider.TEMPORARILY_UNAVAILABLE)
145  {
146  Log.d("LocationProvider.TEMPORARILY_UNAVAILABLE", provider);
147  }
148  else
149  {
150  Log.d("LocationProvider.AVAILABLE", provider);
151  }
152  }
153 
154  private static final int TWO_MINUTES = 1000 * 60 * 2;
155 
166  protected boolean isBetterLocation(Location location, Location currentBestLocation)
167  {
168  if (currentBestLocation == null)
169  {
170  // A new location is always better than no location
171  return true;
172  }
173 
174  // Check whether the new location fix is newer or older
175  long timeDelta = location.getTime() - currentBestLocation.getTime();
176  boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
177  boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
178  boolean isNewer = timeDelta > 0;
179 
180  // If it's been more than two minutes since the current location, use
181  // the new location
182  // because the user has likely moved
183  if (isSignificantlyNewer)
184  {
185  return true;
186  // If the new location is more than two minutes older, it must be
187  // worse
188  }
189  else if (isSignificantlyOlder)
190  {
191  return false;
192  }
193 
194  // Check whether the new location fix is more or less accurate
195  int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
196  boolean isLessAccurate = accuracyDelta > 0;
197  boolean isMoreAccurate = accuracyDelta < 0;
198  boolean isSignificantlyLessAccurate = accuracyDelta > 200;
199 
200  // Check if the old and new location are from the same provider
201  boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());
202 
203  // Determine location quality using a combination of timeliness and
204  // accuracy
205  if (isMoreAccurate)
206  {
207  return true;
208  }
209  else if (isNewer && !isLessAccurate)
210  {
211  return true;
212  }
213  else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)
214  {
215  return true;
216  }
217  return false;
218  }
219 
221  private boolean isSameProvider(String provider1, String provider2)
222  {
223  if (provider1 == null)
224  {
225  return provider2 == null;
226  }
227  return provider1.equals(provider2);
228  }
229 }