Use LocationClient to obtain last known location.

This commit is contained in:
Jimmy Shih
2013-05-15 14:30:44 -07:00
parent 6b7ddc8522
commit 81ed568ed7
7 changed files with 144 additions and 76 deletions
-5
View File
@@ -1163,11 +1163,6 @@ limitations under the License.
</string> </string>
<!-- My Location --> <!-- My Location -->
<string name="my_location_approximate_location"
translation_description="When displaying the user's current location, a status message
indicating that GPS is not available and an approximate location is used instead.">
GPS is not available. An approximate location based on cell towers and WiFi networks is shown.
</string>
<string name="my_location_no_gps" <string name="my_location_no_gps"
translation_description="When displaying the user's current location, a status message translation_description="When displaying the user's current location, a status message
indicating that the current location cannot be determined. indicating that the current location cannot be determined.
@@ -38,6 +38,7 @@ import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.TrackIconUtils; import com.google.android.apps.mytracks.util.TrackIconUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils; import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.SearchManager; import android.app.SearchManager;
@@ -46,8 +47,8 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location; import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Looper;
import android.provider.SearchRecentSuggestions; import android.provider.SearchRecentSuggestions;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
@@ -186,7 +187,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null); trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
searchEngine = new SearchEngine(myTracksProviderUtils); searchEngine = new SearchEngine(myTracksProviderUtils);
searchRecentSuggestions = SearchEngineProvider.newHelper(this); searchRecentSuggestions = SearchEngineProvider.newHelper(this);
myTracksLocationManager = new MyTracksLocationManager(this); myTracksLocationManager = new MyTracksLocationManager(this, Looper.myLooper());
listView = (ListView) findViewById(R.id.search_list); listView = (ListView) findViewById(R.id.search_list);
listView.setEmptyView(findViewById(R.id.search_list_empty)); listView.setEmptyView(findViewById(R.id.search_list_empty));
@@ -391,19 +392,23 @@ public class SearchListActivity extends AbstractSendToGoogleActivity
return; return;
} }
String textQuery = intent.getStringExtra(SearchManager.QUERY); final String textQuery = intent.getStringExtra(SearchManager.QUERY);
setTitle(textQuery); setTitle(textQuery);
Location currentLocation = myTracksLocationManager.getLastKnownLocation( LocationListener locationListener = new LocationListener() {
LocationManager.GPS_PROVIDER);
final SearchQuery query = new SearchQuery(
textQuery, currentLocation, -1L, System.currentTimeMillis());
new Thread() {
@Override @Override
public void run() { public void onLocationChanged(final Location location) {
doSearch(query); new Thread() {
@Override
public void run() {
SearchQuery query = new SearchQuery(
textQuery, location, -1L, System.currentTimeMillis());
doSearch(query);
}
}.start();
} }
}.start(); };
myTracksLocationManager.requestLastLocation(locationListener);
} }
/** /**
@@ -16,24 +16,19 @@
package com.google.android.apps.mytracks.content; package com.google.android.apps.mytracks.content;
import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.services.MyTracksLocationManager; import com.google.android.apps.mytracks.services.MyTracksLocationManager;
import com.google.android.apps.mytracks.util.GoogleLocationUtils; import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.net.Uri; import android.net.Uri;
import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
/** /**
* Data source on the phone. * Data source on the phone.
@@ -45,15 +40,13 @@ public class DataSource {
private static final int NETWORK_PROVIDER_MIN_TIME = 5 * 60 * 1000; // 5 minutes private static final int NETWORK_PROVIDER_MIN_TIME = 5 * 60 * 1000; // 5 minutes
private static final String TAG = DataSource.class.getSimpleName(); private static final String TAG = DataSource.class.getSimpleName();
private final Context context;
private final ContentResolver contentResolver; private final ContentResolver contentResolver;
private final MyTracksLocationManager myTracksLocationManager; private final MyTracksLocationManager myTracksLocationManager;
private final SharedPreferences sharedPreferences; private final SharedPreferences sharedPreferences;
public DataSource(Context context) { public DataSource(Context context) {
this.context = context;
contentResolver = context.getContentResolver(); contentResolver = context.getContentResolver();
myTracksLocationManager = new MyTracksLocationManager(context); myTracksLocationManager = new MyTracksLocationManager(context, Looper.myLooper());
sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
} }
@@ -93,7 +86,7 @@ public class DataSource {
* *
* @param listener the listener * @param listener the listener
*/ */
public void registerLocationListener(LocationListener listener) { public void registerLocationListener(android.location.LocationListener listener) {
// Listen for GPS location // Listen for GPS location
myTracksLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); myTracksLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
@@ -113,42 +106,15 @@ public class DataSource {
* *
* @param listener the listener * @param listener the listener
*/ */
public void unregisterLocationListener(LocationListener listener) { public void unregisterLocationListener(android.location.LocationListener listener) {
myTracksLocationManager.removeUpdates(listener); myTracksLocationManager.removeUpdates(listener);
} }
/** /**
* Gets the last known location. * Request last location.
*/ */
public Location getLastKnownLocation() { public void requestLastLocation(LocationListener locationListener) {
Location location = myTracksLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); myTracksLocationManager.requestLastLocation(locationListener);
if (!isLocationRecent(location)) {
// Try network location
location = myTracksLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
String toast;
if (isLocationRecent(location)) {
toast = context.getString(R.string.my_location_approximate_location);
} else {
String setting = context.getString(
GoogleLocationUtils.isAvailable(context) ? R.string.gps_google_location_settings
: R.string.gps_location_access);
toast = context.getString(R.string.my_location_no_gps, setting);
}
Toast.makeText(context, toast, Toast.LENGTH_LONG).show();
}
return location;
}
/**
* Returns true if the location is recent.
*
* @param location the location
*/
private boolean isLocationRecent(Location location) {
if (location == null) {
return false;
}
return location.getTime() > System.currentTimeMillis() - MAX_LOCATION_AGE_MS;
} }
/** /**
@@ -24,8 +24,10 @@ import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.content.TrackDataListener.LocationState; import com.google.android.apps.mytracks.content.TrackDataListener.LocationState;
import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@@ -37,6 +39,7 @@ import android.location.LocationManager;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
@@ -223,14 +226,28 @@ public class TrackDataHub implements DataSourceListener {
* Forces update location and reports to all listeners. * Forces update location and reports to all listeners.
*/ */
public void forceUpdateLocation() { public void forceUpdateLocation() {
final Location location = dataSource.getLastKnownLocation(); if (!dataSource.isAllowed()) {
runInHanderThread(new Runnable() { String setting = context.getString(
@Override GoogleLocationUtils.isAvailable(context) ? R.string.gps_google_location_settings
public void run() { : R.string.gps_location_access);
notifyLocationChanged( Toast.makeText(
location, false, trackDataManager.getListeners(TrackDataType.LOCATION)); context, context.getString(R.string.my_location_no_gps, setting), Toast.LENGTH_LONG)
} .show();
}); } else {
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(final Location location) {
runInHanderThread(new Runnable() {
@Override
public void run() {
notifyLocationChanged(
location, false, trackDataManager.getListeners(TrackDataType.LOCATION));
}
});
}
};
dataSource.requestLastLocation(locationListener);
}
} }
public boolean isGpsProviderEnabled() { public boolean isGpsProviderEnabled() {
@@ -17,17 +17,22 @@
package com.google.android.apps.mytracks.services; package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.util.GoogleLocationUtils; import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.database.Cursor; import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.util.Log; import android.util.Log;
/** /**
@@ -50,13 +55,45 @@ public class MyTracksLocationManager {
private static final String NAME = "name"; private static final String NAME = "name";
private static final String VALUE = "value"; private static final String VALUE = "value";
private final ConnectionCallbacks connectionCallbacks = new ConnectionCallbacks() {
@Override
public void onDisconnected() {}
@Override
public void onConnected(Bundle bunlde) {
handler.post(new Runnable() {
@Override
public void run() {
if (requestLastLocation != null && locationClient.isConnected()) {
requestLastLocation.onLocationChanged(locationClient.getLastLocation());
requestLastLocation = null;
}
}
});
}
};
private final OnConnectionFailedListener
onConnectionFailedListener = new OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {}
};
private final Handler handler;
private final LocationClient locationClient;
private final LocationManager locationManager; private final LocationManager locationManager;
private final ContentResolver contentResolver; private final ContentResolver contentResolver;
private final GoogleSettingsObserver observer; private final GoogleSettingsObserver observer;
private boolean isAvailable; private boolean isAvailable;
private boolean isAllowed; private boolean isAllowed;
private LocationListener requestLastLocation;
public MyTracksLocationManager(Context context, Looper looper) {
handler = new Handler(looper);
locationClient = new LocationClient(context, connectionCallbacks, onConnectionFailedListener);
locationClient.connect();
public MyTracksLocationManager(Context context) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
contentResolver = context.getContentResolver(); contentResolver = context.getContentResolver();
observer = new GoogleSettingsObserver(); observer = new GoogleSettingsObserver();
@@ -71,6 +108,7 @@ public class MyTracksLocationManager {
* Closes the {@link MyTracksLocationManager}. * Closes the {@link MyTracksLocationManager}.
*/ */
public void close() { public void close() {
locationClient.disconnect();
contentResolver.unregisterContentObserver(observer); contentResolver.unregisterContentObserver(observer);
} }
@@ -115,10 +153,23 @@ public class MyTracksLocationManager {
} }
/** /**
* @see android.location.LocationManager#getLastKnownLocation(java.lang.String) * Request last location.
*
* @param locationListener location listener
*/ */
public Location getLastKnownLocation(String provider) { public void requestLastLocation(final LocationListener locationListener) {
return isAllowed ? locationManager.getLastKnownLocation(provider) : null; handler.post(new Runnable() {
@Override
public void run() {
if (!isAllowed) {
requestLastLocation = null;
locationListener.onLocationChanged(null);
} else {
requestLastLocation = locationListener;
connectionCallbacks.onConnected(null);
}
}
});
} }
/** /**
@@ -126,7 +177,7 @@ public class MyTracksLocationManager {
* long, float, android.location.LocationListener) * long, float, android.location.LocationListener)
*/ */
public void requestLocationUpdates( public void requestLocationUpdates(
String provider, long minTime, float minDistance, LocationListener listener) { String provider, long minTime, float minDistance, android.location.LocationListener listener) {
locationManager.requestLocationUpdates(provider, minTime, minDistance, listener); locationManager.requestLocationUpdates(provider, minTime, minDistance, listener);
} }
@@ -134,7 +185,7 @@ public class MyTracksLocationManager {
* @param listener * @param listener
* @see android.location.LocationManager#removeUpdates(android.location.LocationListener) * @see android.location.LocationManager#removeUpdates(android.location.LocationListener)
*/ */
public void removeUpdates(LocationListener listener) { public void removeUpdates(android.location.LocationListener listener) {
locationManager.removeUpdates(listener); locationManager.removeUpdates(listener);
} }
@@ -61,6 +61,7 @@ import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.PowerManager.WakeLock; import android.os.PowerManager.WakeLock;
import android.os.Process; import android.os.Process;
@@ -267,7 +268,7 @@ public class TrackRecordingService extends Service {
super.onCreate(); super.onCreate();
context = this; context = this;
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
myTracksLocationManager = new MyTracksLocationManager(this); myTracksLocationManager = new MyTracksLocationManager(this, Looper.myLooper());
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory()); voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
splitExecutor = new PeriodicTaskExecutor(this, new SplitPeriodicTaskFactory()); splitExecutor = new PeriodicTaskExecutor(this, new SplitPeriodicTaskFactory());
executorService = Executors.newSingleThreadExecutor(); executorService = Executors.newSingleThreadExecutor();
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>google-play-services_lib</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>