我正在尝试将 GPS 用于我的 android 应用程序。特别是,我使用从 GPS(或从 3g 连接)接收到的坐标在地图上显示用户的位置。但即使 GPS 关闭,用户也可以使用该应用程序。
我的问题是:当应用程序已经运行时,如何在激活 GPS(或 3g 连接)后自动显示用户的位置?
谢谢
我正在尝试将 GPS 用于我的 android 应用程序。特别是,我使用从 GPS(或从 3g 连接)接收到的坐标在地图上显示用户的位置。但即使 GPS 关闭,用户也可以使用该应用程序。
我的问题是:当应用程序已经运行时,如何在激活 GPS(或 3g 连接)后自动显示用户的位置?
谢谢
如果您还没有调用LocationManager.requestLocationUpdates()
,您可以收听PROVIDERS_CHANGED_ACTION 广播并开始请求位置更新/相应地显示用户位置。
如果您已经在请求位置更新,您可以覆盖 LocationListener 的onProviderDisabled()
/onProviderEnabled()
方法,以便在提供程序的可用性发生变化时得到通知。
是的当然。特别是,当应用程序正在运行但 WiFi 或 GPS 被禁用时,bestProvider() 返回“网络”。在这种情况下,当我激活 gps 或 wifi 时,应用程序无法识别它们。此外,当应用程序正在运行并且 WiFi 处于打开状态时,当我激活 GPS 时,应用程序无法识别它。
public class MainActivity extends FragmentActivity implements OnMapClickListener {
final int RQS_GooglePlayServices = 1;
private GoogleMap map;
private TextView tvLocInfo;
private FollowMeLocationSource followMeLocationSource;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocInfo = (TextView)findViewById(R.id.locinfo);
followMeLocationSource = new FollowMeLocationSource();
/* We query for the best Location Provider everytime this fragment is displayed
* just in case a better provider might have become available since we last displayed it */
followMeLocationSource.getBestAvailableProvider();
// Get a reference to the map/GoogleMap object
setUpMapIfNeeded();
map.setOnMapClickListener(this);
// TESTMARKER map.addMarker(new MarkerOptions()
// TESTMARKER map.addMarker(new MarkerOptions().position(new LatLng(41.934977, 12.488708))
// TESTMARKER .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
}
@Override
public void onResume() {
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
/* We query for the best Location Provider everytime this fragment is displayed
* just in case a better provider might have become available since we last displayed it */
followMeLocationSource.getBestAvailableProvider();
// Get a reference to the map/GoogleMap object
setUpMapIfNeeded();
//Enable the my-location layer (this causes our LocationSource to be automatically activated.)
map.setMyLocationEnabled(true);
}
@Override
public void onPause() {
super.onPause();
/* Disable the my-location layer (this causes our LocationSource to be automatically deactivated.) */
map.setMyLocationEnabled(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (map == null) {
FragmentManager myFragmentManager = getSupportFragmentManager();
SupportMapFragment mySupportMapFragment
= (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map);
map = mySupportMapFragment.getMap();
// Check if we were successful in obtaining the map.
if (map != null) {
Location location = followMeLocationSource.getLastKnownLocation();
LatLng latlng= new LatLng(location.getLatitude(), location.getLongitude());
map.moveCamera(CameraUpdateFactory.newLatLng(latlng));
// The Map is verified. It is now safe to manipulate the map.
// Replace the (default) location source of the my-location layer with our custom LocationSource
map.setLocationSource(followMeLocationSource);
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.zoomTo(15f));
}
}
}
@Override
public void onMapClick(LatLng point) {
tvLocInfo.setText(point.toString());
map.animateCamera(CameraUpdateFactory.newLatLng(point));
}
/* Our custom LocationSource.
* We register this class to receive location updates from the Location Manager
* and for that reason we need to also implement the LocationListener interface. */
private class FollowMeLocationSource implements LocationSource, LocationListener {
private final Criteria myCriteria = new Criteria();
private String bestAvailableProvider;
LocationManager myLocationManager = null;
OnLocationChangedListener myLocationListener = null;
/* Updates are restricted to one every 10 seconds, and only when
* movement of more than 10 meters has been detected.*/
private final int minTime = 10000; // minimum time interval between location updates, in milliseconds
private final int minDistance = 10; // minimum distance between location updates, in meters
private FollowMeLocationSource() {
// Get reference to Location Manager
myLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
// Specify Location Provider criteria
myCriteria.setAccuracy(Criteria.ACCURACY_FINE);
myCriteria.setPowerRequirement(Criteria.POWER_LOW);
myCriteria.setBearingRequired(true);
}
private void getBestAvailableProvider() {
/* The prefered way of specifying the location provider (e.g. GPS, NETWORK) to use
* is to ask the Location Manager for the one that best satisfies our criteria.
* By passing the 'true' boolean we ask for the best available (enabled) provider. */
bestAvailableProvider = myLocationManager.getBestProvider(myCriteria, true);
Log.i("Best Provider:", bestAvailableProvider);
}
private Location getLastKnownLocation() {
Location lastKnownLocation = myLocationManager.getLastKnownLocation(bestAvailableProvider);
Double lat = lastKnownLocation.getLatitude();
return lastKnownLocation;
}
@Override
public void onLocationChanged(Location location) {
/* Push location updates to the registered listener..
* (this ensures that my-location layer will set the blue dot at the new/received location) */
Log.i("EntradentroOnLocationChanged", "Entrato");
if (myLocationListener != null) {
myLocationListener.onLocationChanged(location);
double lat = location.getLatitude();
double lon = location.getLongitude();
tvLocInfo.setText(
"lat: " + lat + "\n" +
"lon: " + lon);
}
// ..and Animate camera to center on that location
//LatLng latlng= new LatLng(location.getLatitude(), location.getLongitude());
//map.animateCamera(CameraUpdateFactory.newLatLng(latlng));
}
@Override
public void onProviderDisabled(String provider) {
getBestAvailableProvider();
}
@Override
public void onProviderEnabled(String provider) {
getBestAvailableProvider();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
/* Activates this provider. This provider will notify the supplied listener
* periodically, until you call deactivate(). */
@Override
public void activate(OnLocationChangedListener listener) {
// We need to keep a reference to my-location layer's listener so we can push forward
// location updates to it when we receive them from Location Manager.
myLocationListener = listener;
// Request location updates from Location Manager
if (bestAvailableProvider != null) {
myLocationManager.requestLocationUpdates(bestAvailableProvider, minTime, minDistance, this);
} else {
// TODO (Display a message/dialog) No Location Providers currently available.
}
}
/* Deactivates this provider.
* This method is automatically invoked by disabling my-location layer. */
@Override
public void deactivate() {
// Remove location updates from Location Manager
myLocationManager.removeUpdates(this);
myLocationListener = null;
}
}
}