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>
<!-- 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"
translation_description="When displaying the user's current location, a status message
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.TrackIconUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R;
import android.app.SearchManager;
@@ -46,8 +47,8 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.provider.SearchRecentSuggestions;
import android.util.Log;
import android.view.ContextMenu;
@@ -186,7 +187,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
searchEngine = new SearchEngine(myTracksProviderUtils);
searchRecentSuggestions = SearchEngineProvider.newHelper(this);
myTracksLocationManager = new MyTracksLocationManager(this);
myTracksLocationManager = new MyTracksLocationManager(this, Looper.myLooper());
listView = (ListView) findViewById(R.id.search_list);
listView.setEmptyView(findViewById(R.id.search_list_empty));
@@ -391,19 +392,23 @@ public class SearchListActivity extends AbstractSendToGoogleActivity
return;
}
String textQuery = intent.getStringExtra(SearchManager.QUERY);
final String textQuery = intent.getStringExtra(SearchManager.QUERY);
setTitle(textQuery);
Location currentLocation = myTracksLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
final SearchQuery query = new SearchQuery(
textQuery, currentLocation, -1L, System.currentTimeMillis());
new Thread() {
LocationListener locationListener = new LocationListener() {
@Override
public void run() {
doSearch(query);
public void onLocationChanged(final Location location) {
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;
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.services.MyTracksLocationManager;
import com.google.android.apps.mytracks.util.GoogleLocationUtils;
import com.google.android.maps.mytracks.R;
import com.google.android.gms.location.LocationListener;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
/**
* 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 String TAG = DataSource.class.getSimpleName();
private final Context context;
private final ContentResolver contentResolver;
private final MyTracksLocationManager myTracksLocationManager;
private final SharedPreferences sharedPreferences;
public DataSource(Context context) {
this.context = context;
contentResolver = context.getContentResolver();
myTracksLocationManager = new MyTracksLocationManager(context);
myTracksLocationManager = new MyTracksLocationManager(context, Looper.myLooper());
sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
}
@@ -93,7 +86,7 @@ public class DataSource {
*
* @param listener the listener
*/
public void registerLocationListener(LocationListener listener) {
public void registerLocationListener(android.location.LocationListener listener) {
// Listen for GPS location
myTracksLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
@@ -113,42 +106,15 @@ public class DataSource {
*
* @param listener the listener
*/
public void unregisterLocationListener(LocationListener listener) {
public void unregisterLocationListener(android.location.LocationListener listener) {
myTracksLocationManager.removeUpdates(listener);
}
/**
* Gets the last known location.
* Request last location.
*/
public Location getLastKnownLocation() {
Location location = myTracksLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
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;
public void requestLastLocation(LocationListener locationListener) {
myTracksLocationManager.requestLastLocation(locationListener);
}
/**
@@ -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.content.MyTracksProviderUtils.LocationIterator;
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.PreferencesUtils;
import com.google.android.gms.location.LocationListener;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -37,6 +39,7 @@ import android.location.LocationManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.widget.Toast;
import java.util.Collections;
import java.util.EnumSet;
@@ -223,14 +226,28 @@ public class TrackDataHub implements DataSourceListener {
* Forces update location and reports to all listeners.
*/
public void forceUpdateLocation() {
final Location location = dataSource.getLastKnownLocation();
runInHanderThread(new Runnable() {
@Override
public void run() {
notifyLocationChanged(
location, false, trackDataManager.getListeners(TrackDataType.LOCATION));
}
});
if (!dataSource.isAllowed()) {
String setting = context.getString(
GoogleLocationUtils.isAvailable(context) ? R.string.gps_google_location_settings
: R.string.gps_location_access);
Toast.makeText(
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() {
@@ -17,17 +17,22 @@
package com.google.android.apps.mytracks.services;
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 android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
/**
@@ -50,13 +55,45 @@ public class MyTracksLocationManager {
private static final String NAME = "name";
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 ContentResolver contentResolver;
private final GoogleSettingsObserver observer;
private boolean isAvailable;
private boolean isAllowed;
public MyTracksLocationManager(Context context) {
private LocationListener requestLastLocation;
public MyTracksLocationManager(Context context, Looper looper) {
handler = new Handler(looper);
locationClient = new LocationClient(context, connectionCallbacks, onConnectionFailedListener);
locationClient.connect();
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
contentResolver = context.getContentResolver();
observer = new GoogleSettingsObserver();
@@ -71,6 +108,7 @@ public class MyTracksLocationManager {
* Closes the {@link MyTracksLocationManager}.
*/
public void close() {
locationClient.disconnect();
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) {
return isAllowed ? locationManager.getLastKnownLocation(provider) : null;
public void requestLastLocation(final LocationListener locationListener) {
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)
*/
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);
}
@@ -134,7 +185,7 @@ public class MyTracksLocationManager {
* @param listener
* @see android.location.LocationManager#removeUpdates(android.location.LocationListener)
*/
public void removeUpdates(LocationListener listener) {
public void removeUpdates(android.location.LocationListener listener) {
locationManager.removeUpdates(listener);
}
@@ -61,6 +61,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
@@ -267,7 +268,7 @@ public class TrackRecordingService extends Service {
super.onCreate();
context = this;
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
myTracksLocationManager = new MyTracksLocationManager(this);
myTracksLocationManager = new MyTracksLocationManager(this, Looper.myLooper());
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
splitExecutor = new PeriodicTaskExecutor(this, new SplitPeriodicTaskFactory());
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>