我正在尝试使用用户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();
}
}
答案 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();
}
}
圈内的结果:
圈外的结果:
答案 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();
}
}
答案 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();
}
}