2015-05-11 11 views
12

Sto provando a rilevare se un utente si trova nel raggio di un indicatore, utilizzando la posizione GPS dell'utente. Ho le coordinate dell'indicatore, ma non so come calcolare se l'utente si trova nell'area. Ho provato a utilizzare quanto segue, ma anche quando la posizione corrente è all'interno del cerchio continuo a ricevere il messaggio "esterno".Android Google Map come verificare se la posizione GPS è all'interno del cerchio

public class MapaEscola extends FragmentActivity { 

    private GoogleMap googleMap; 
    private Serializable escolas; 
    private ProgressDialog dialog; 
    private Circle mCircle; 
    private Marker mMarker; 



    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     getActionBar().setDisplayHomeAsUpEnabled(true); 
     getActionBar().setHomeButtonEnabled(true); 

     setContentView(R.layout.maps); 

     // Loading map 
     initilizeMap(); 

     // Changing map type 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 

     // Showing/hiding your current location 
     googleMap.setMyLocationEnabled(true); 

     // Enable/Disable zooming controls 
     googleMap.getUiSettings().setZoomControlsEnabled(true); 

     // Enable/Disable my location button 
     googleMap.getUiSettings().setMyLocationButtonEnabled(true); 

     // Enable/Disable Compass icon 
     googleMap.getUiSettings().setCompassEnabled(true); 

     // Enable/Disable Rotate gesture 
     googleMap.getUiSettings().setRotateGesturesEnabled(true); 

     // Enable/Disable zooming functionality 
     googleMap.getUiSettings().setZoomGesturesEnabled(true); 

     Bundle extra = getIntent().getBundleExtra("extra"); 
     ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array"); 


     try { 

      for(int i = 0; i < objects.size(); i ++) { 
       System.out.println(" escolas " + objects.get(i).getLatitude() + " " + objects.get(i).getLongitude()); 

       float latitude = objects.get(i).getLatitude(); 
       float longitude = objects.get(i).getLongitude(); 

       googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.316281, -51.155528), 15)); 

       MarkerOptions options = new MarkerOptions(); 

       // Setting the position of the marker 

       options.position(new LatLng(latitude, longitude)); 

       googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 

       LatLng latLng = new LatLng(latitude, longitude); 
       drawMarkerWithCircle(latLng); 


       googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { 
        @Override 
        public void onMyLocationChange(Location location) { 
         float[] distance = new float[2]; 

         Location.distanceBetween(mMarker.getPosition().latitude, mMarker.getPosition().longitude, 
           mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance); 

         if(distance[0] > (mCircle.getRadius()/2) ){ 
          Toast.makeText(getBaseContext(), "Outside", Toast.LENGTH_LONG).show(); 
         } else { 
          Toast.makeText(getBaseContext(), "Inside", Toast.LENGTH_LONG).show(); 
         } 

        } 
       }); 




      } 



     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 


    private void drawMarkerWithCircle(LatLng position){ 
     double radiusInMeters = 500.0; 
     int strokeColor = 0xffff0000; //red outline 
     int shadeColor = 0x44ff0000; //opaque red fill 

     CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8); 
     mCircle = googleMap.addCircle(circleOptions); 

     MarkerOptions markerOptions = new MarkerOptions().position(position); 
     mMarker = googleMap.addMarker(markerOptions); 
    } 



    private void initilizeMap() { 

     if (googleMap == null) { 
      googleMap = ((MapFragment) getFragmentManager().findFragmentById(
        R.id.map)).getMap(); 

      // check if map is created successfully or not 
      if (googleMap == null) { 
       Toast.makeText(getApplicationContext(), 
         "Não foi possível carregar o mapa", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    @Override 
    public void onBackPressed() { 

     super.onBackPressed(); 
     finish(); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // TODO Auto-generated method stub 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.menu_main, menu); 

     return super.onCreateOptionsMenu(menu); 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    public boolean onOptionsItemSelected(MenuItem item) { 


     switch (item.getItemId()) { 

      case android.R.id.home: 
       super.onBackPressed(); 
       finish(); 

       return true; 


     } 

     return true; 

    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     initilizeMap(); 
    } 


} 

risposta

13

Ho appena eseguito il codice aggiornato e ho capito qual è il problema principale.

Si deve usare il Location passato nel onMyLocationChange() richiamata, in modo che utilizzi la posizione corrente per capire se il dispositivo si trova all'interno del cerchio o no:

googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { 
       @Override 
       public void onMyLocationChange(Location location) { 
        float[] distance = new float[2]; 

        /* 
        Location.distanceBetween(mMarker.getPosition().latitude, mMarker.getPosition().longitude, 
          mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance); 
          */ 

        Location.distanceBetween(location.getLatitude(), location.getLongitude(), 
          mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance); 

        if(distance[0] > mCircle.getRadius()){ 
         Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show(); 
        } else { 
         Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show(); 
        } 

       } 
      }); 

Ecco l'esempio di lavoro completo che ho Ran, si tratta di una versione ridotta verso il basso del codice originale:

public class MainActivity extends ActionBarActivity { 

    private GoogleMap googleMap; 
    private Serializable escolas; 
    private ProgressDialog dialog; 
    private Circle mCircle; 
    private Marker mMarker; 



    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setHomeButtonEnabled(true); 

     setContentView(R.layout.activity_main); 

     // Loading map 
     initilizeMap(); 

     // Changing map type 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 

     // Showing/hiding your current location 
     googleMap.setMyLocationEnabled(true); 

     // Enable/Disable zooming controls 
     googleMap.getUiSettings().setZoomControlsEnabled(true); 

     // Enable/Disable my location button 
     googleMap.getUiSettings().setMyLocationButtonEnabled(true); 

     // Enable/Disable Compass icon 
     googleMap.getUiSettings().setCompassEnabled(true); 

     // Enable/Disable Rotate gesture 
     googleMap.getUiSettings().setRotateGesturesEnabled(true); 

     // Enable/Disable zooming functionality 
     googleMap.getUiSettings().setZoomGesturesEnabled(true); 

     // Bundle extra = getIntent().getBundleExtra("extra"); 
     //ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array"); 


     try { 
       //test outside 
       double mLatitude = 37.77657; 
       double mLongitude = -122.417506; 


       //test inside 
       //double mLatitude = 37.7795516; 
       //double mLongitude = -122.39292; 


       googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 15)); 

       MarkerOptions options = new MarkerOptions(); 

       // Setting the position of the marker 

       options.position(new LatLng(mLatitude, mLongitude)); 

       //googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 

       LatLng latLng = new LatLng(mLatitude, mLongitude); 
       drawMarkerWithCircle(latLng); 


       googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { 
        @Override 
        public void onMyLocationChange(Location location) { 
         float[] distance = new float[2]; 

         /* 
         Location.distanceBetween(mMarker.getPosition().latitude, mMarker.getPosition().longitude, 
           mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance); 
           */ 

         Location.distanceBetween(location.getLatitude(), location.getLongitude(), 
           mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance); 

         if(distance[0] > mCircle.getRadius() ){ 
          Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show(); 
         } else { 
          Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show(); 
         } 

        } 
       }); 




     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 


    private void drawMarkerWithCircle(LatLng position){ 
     double radiusInMeters = 500.0; 
     int strokeColor = 0xffff0000; //red outline 
     int shadeColor = 0x44ff0000; //opaque red fill 

     CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8); 
     mCircle = googleMap.addCircle(circleOptions); 

     MarkerOptions markerOptions = new MarkerOptions().position(position); 
     mMarker = googleMap.addMarker(markerOptions); 
    } 



    private void initilizeMap() { 

     if (googleMap == null) { 
      googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(
        R.id.map)).getMap(); 

      // check if map is created successfully or not 
      if (googleMap == null) { 
       Toast.makeText(getApplicationContext(), 
         "Não foi possível carregar o mapa", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    @Override 
    public void onBackPressed() { 

     super.onBackPressed(); 
     finish(); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // TODO Auto-generated method stub 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.menu_main, menu); 

     return super.onCreateOptionsMenu(menu); 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    public boolean onOptionsItemSelected(MenuItem item) { 


     switch (item.getItemId()) { 

      case android.R.id.home: 
       super.onBackPressed(); 
       finish(); 

       return true; 


     } 

     return true; 

    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     initilizeMap(); 
    } 


} 

Risultati del all'interno del cerchio:

Inside

Risultati del di fuori del cerchio:

Outside

+0

Ciao, Daniel, grazie per il vostro aiuto, ma sto ancora ottenere gli stessi risultati – AND4011002849

+0

@WARpoluido Dai un'occhiata alla risposta aggiornata. Hai anche avuto una chiamata non necessaria a 'getMap()' lì, dai un'occhiata al codice completo. –

+0

Funziona ora, grazie mille! – AND4011002849

2

@ Daniel Nugent: IMHO getRadius() restituirà il raggio e non il diametro in modo che il "/2" è sbagliato

@WARpoluido: Non vedo che la variabile mMarker venga aggiornata quando la posizione cambia. Perché non usi il valore dato a onMyLocationChange()?

Location.distanceBetween(mCircle.getCenter().latitude, mCircle.getCenter().longitude, location.getLatitude(), location.getLongitude(), distance); 
if(distance[0] > mCircle.getRadius()){ 
... 
+1

Ah, hai ragione. Ero confuso diametro e raggio. Buona pesca! Inoltre, hai ragione riguardo la posizione! Buon occhio, ho dovuto eseguirlo per vederlo. –

+0

Ho appena alzato la tua risposta, perché ti meriti un po 'di credito per questo. Grazie per aver corretto l'errore raggio/diametro dalla mia risposta iniziale! –

1

Ciao ho ottenuto il mio lavoro correttamente con questo codice

//Getting current location 
private void getCurrentLocation() { 
    mMap.clear(); 
    //Creating a location object 
    Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); 
    if (location != null) { 
     //Getting longitude and latitude 
     longitude = location.getLongitude(); 
     latitude = location.getLatitude(); 
     //moving the map to location 
     moveMap(); 
    } 

    Circle circle = mMap.addCircle(new CircleOptions() 
        .center(new LatLng(54.773097, -6.557841)) 
        .radius(55) 
        .strokeColor(Color.RED) 
    ); 



    pLong = location.getLongitude(); 
    pLat = location.getLatitude(); 

    float[] distance = new float[2]; 


    Location.distanceBetween(pLat, pLong, 
      circle.getCenter().latitude, circle.getCenter().longitude, distance); 

    if(distance[0] > circle.getRadius() ){ 
     Toast.makeText(getBaseContext(), "You are not in a bunker", Toast.LENGTH_LONG).show(); 
    } else { 
     Toast.makeText(getBaseContext(), "You are inside a bunker", Toast.LENGTH_LONG).show(); 
    } 

} 

Inside the circle

Outside the circle

0

La soluzione accettata di Daniel Nugent non è così buono più perché setOnMyLocationChangeListener è deprecato adesso.

Ecco attuale modo come farlo nel frammento - cambiamento getActivity() con this per attività:

private boolean mLocationPermissionGranted; 

// The geographical location where the device is currently located. That is, the last-known 
// location retrieved by the Fused Location Provider. 
private Location mLastKnownLocation; 
private long UPDATE_INTERVAL = 10 * 1000; /* 10 secs */ 
private long FASTEST_INTERVAL = 2000; /* 2 sec */ 
private FusedLocationProviderClient mFusedLocationProviderClient; 

private void addLocationChangeListener(){ 
     // Construct a FusedLocationProviderClient. 
     mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); 

     // Create the location request to start receiving updates 
     LocationRequest mLocationRequest = new LocationRequest(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(UPDATE_INTERVAL); 
     mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
     //mLocationRequest.setMaxWaitTime(0); 
     //mLocationRequest.setSmallestDisplacement(0); 

     // Create LocationSettingsRequest object using location request 
     LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); 
     builder.addLocationRequest(mLocationRequest); 
     LocationSettingsRequest locationSettingsRequest = builder.build(); 

     // Check whether location settings are satisfied 
     // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient 
     SettingsClient settingsClient = LocationServices.getSettingsClient(getActivity()); 
     settingsClient.checkLocationSettings(locationSettingsRequest); 


     // new Google API SDK v11 uses getFusedLocationProviderClient(this) 
     if (mLocationPermissionGranted) { 
      mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, 
        new LocationCallback() { 
         @Override 
         public void onLocationResult(LocationResult locationResult) { 
          // do work here 
          Location location = locationResult.getLastLocation(); 
         } 
        }, 
        Looper.myLooper()); 
     } else { 
      getLocationPermission(); 
     } 
    } 
Problemi correlati