Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
144 views
in Technique[技术] by (71.8m points)

android - Do something when I'm inside radius of circle

I'm using Google Maps API.

What I want is when I move into some specific location and there is a circle I already have draw on the map, it will then go to another Activity.

So it was like :

  1. my position is a = (X,Y)

  2. Circle position is b = (X,Y) radius = 10

  3. When I'm inside b radius it will go to another Activity or do something.

Any ideas ?

I'm already using distanceTo(), but still haven't succeeded.

Edit: Here is updated code that still is not working for me:

public void onLocationChanged(Location location)
{
float [] distance = new float[];
Location.distanceBetween(location.getLatitude(),location.getLongitude(),-6.xxxxxxx,106.xxxxxxx,distance);

if (distance[0] < 50)
   {
   Intent i = new Intent(student_activity.this,indoor.class);
   student_activity.this,startActivity(i);
   }
}

This method setUpMapIfNeeded() is called in onCreate method :

public void circle()
{
Circle circle = mMap.addCircle (new CircleOptions()
.center(new LatLng(-6.xxxxxxx,106.xxxxxxx))
.radius(50)
.strokeColor(Color.RED)
.strokeWidth(1)
.fillColor(Color.RED)
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use geofencing, but if you are simply trying to determine if your current location is within a circle drawn on a map, you could use this technique.

Simply compare the distance from the current location to the center of the circle, and check if the distance is less than the radius.

I answered a similar question here, where you can see more info, and screenshot examples.

Note that the code below uses the depricated onMyLocationChangeListener, but you could use any type of location callback to do this, including FusedLocationProviderApi.

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

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

                if( distance[0] < mCircle.getRadius() ){
                    //current location is within circle
                    //start new activity
                    Intent i = new Intent(ThisActivity.this, OtherActivity.class);
                    ThisActivity.this.startActivity(i);
                }

            }
        });

Edit: Here is a fully working and tested class that uses the FusedLocationApi to get the current location:

import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends ActionBarActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleMap mMap;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Circle mCircle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        setUpMapIfNeeded();

        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

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

    @Override
    protected void onPause(){
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }


    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected", Toast.LENGTH_SHORT).show();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setSmallestDisplacement(0.1F);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }


    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        mMap.getUiSettings().setMapToolbarEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setMyLocationEnabled(true);

        circle();

    }

    public void circle()
    {
        double radiusInMeters = 50.0;
        int strokeColor = 0xffff0000; //red outline
        int shadeColor = 0x44ff0000; //opaque red fill

        mCircle = mMap.addCircle (new CircleOptions()
                .center(new LatLng(37.9614, -122.105))
                .radius(radiusInMeters)
                .fillColor(shadeColor)
                .strokeColor(strokeColor)
                .strokeWidth(1));
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

        Log.d("locationtesting",  "lat: " + location.getLatitude() + " lon: " + location.getLongitude());

        Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();

        float[] distance = new float[2];

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

        if( distance[0] < mCircle.getRadius() ){
            //current location is within circle
            //start new activity
            Intent i = new Intent(this, OtherActivity.class);
            startActivity(i);
        }
    }
}

Layout xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:id="@+id/map" tools:context=".MapsActivity"
    android:name="com.google.android.gms.maps.SupportMapFragment" />

Dependencies in build.gradle:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.google.android.gms:play-services:7.0.0'
}

First I did a test without the call to startActivity() just to make sure that my current location was within the circle. As you can see in the screenshot, it was:

Map Test

Then, I added the call to startActivity() in the onLocationChanged() callback, and it launched OtherActivity immediately after launching the app.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...