2013-05-11 66 views
2

我正在尝试为我的android应用程序使用GPS。特别是我使用从GPS(或从3g连接)接收到的坐标来显示用户在地图上的位置。但即使GPS关闭,用户也可以使用该应用程序。当应用程序已经运行时激活GPS

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

感谢

回答

1

如果您尚未调用LocationManager.requestLocationUpdates(),你可以监听PROVIDERS_CHANGED_ACTION Broadcast并开始请求位置更新/据此显示用户位置。

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

+0

感谢。我测试了第二个解决方案,并添加了“bestProvider()”以在“onProviderDisabled()/ onProviderEnabled()”中设置正确的提供程序,但不起作用。详细地说,当3g和gps被禁用并且用户在应用程序运行时激活它们时它不起作用。另外,当3g和GPS关闭时,bestProvider()总是返回“网络”。所以我想重写onStatusChanged()来验证提供者的状态,以便自动设置最佳提供者 – 2013-05-12 10:15:17

+0

你可以粘贴你的代码吗?什么确实(不)工作,例如,是否调用了onProviderEnabled()方法? – cygery 2013-05-12 12:18:32

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; 
    } 

} 

}

相关问题