2

我正在尝试将 GPS 用于我的 android 应用程序。特别是,我使用从 GPS(或从 3g 连接)接收到的坐标在地图上显示用户的位置。但即使 GPS 关闭,用户也可以使用该应用程序。

我的问题是:当应用程序已经运行时,如何在激活 GPS(或 3g 连接)后自动显示用户的位置?

谢谢

4

2 回答 2

1

如果您还没有调用LocationManager.requestLocationUpdates(),您可以收听PROVIDERS_CHANGED_ACTION 广播并开始请求位置更新/相应地显示用户位置。

如果您已经在请求位置更新,您可以覆盖 LocationListener 的onProviderDisabled()/onProviderEnabled()方法,以便在提供程序的可用性发生变化时得到通知。

于 2013-05-11T15:41:35.130 回答
0

是的当然。特别是,当应用程序正在运行但 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;
    }

}

}

于 2013-05-12T14:27:38.920 回答