Android Google Map如何检查gps位置是否在圈内

时间:2015-05-11 14:25:03

标签: android google-maps gps geolocation android-maps-v2

我正在尝试使用用户gps位置检测用户是否在标记的半径内。我有标记的坐标,但我不知道如何计算用户是否在该区域。我试图使用以下内容,但即使当前位置在圈内,我仍然会收到“外部”消息。

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


}

4 个答案:

答案 0 :(得分:14)

我刚刚运行了更新的代码并找出了主要问题。

您应该使用传递到Location回调的onMyLocationChange(),以便它使用您当前的位置来判断设备是否在圈内:

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

                }
            });

以下是我运行的完整工作示例,它是原始代码的简化版本:

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


}

圈内的结果:

Inside

圈外的结果:

Outside

答案 1 :(得分:2)

@Daniel Nugent: imho getRadius()将返回半径,而不是直径,因此&#34; /2&#34;是错的

@WARpoluido: 我看不到位置发生变化时mMarker变量会更新。为什么不使用onMyLocationChange()给出的值?

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

答案 2 :(得分:2)

您好我已经使用此代码正常工作

//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

答案 3 :(得分:0)

Daniel Nugent 的公认解决方案已经不再那么好了,因为现在setOnMyLocationChangeListener 已被弃用

以下是如何在片段中执行此操作的最新方式 - 将getActivity()this更改为活动:

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