【问题标题】:How to check if the device has already passed a position with GoogleMaps?如何检查设备是否已经通过谷歌地图的位置?
【发布时间】:2017-12-20 13:49:49
【问题描述】:

我正在使用 GoogleMaps API 的LocationListener 来处理地图。在我的应用程序中,它绘制了一条用户经过的路线。我想在用户处于他们已经去过的位置时设置警报。但我不知道是否存在为我执行此操作的服务,或者我是否有一个实现全部。我不明白地理定位的概念。

所以,我想提醒用户,当它经过跟踪的路线时。

private class FollowMeLocationSource implements LocationSource, LocationListener {

    private OnLocationChangedListener onLocationChangedListener;
    private LocationManager locationManager;
    private LocationListener locationListener;

    private final Criteria criteria = new Criteria();
    private String bestAvailableProvider;

     /* Updates are restricted to one every 10 seconds, and only when
     * movement of more than 10 meters has been detected.*/
     private final long minTime = 2000;
     private final float minDistance = 5;

     private FollowMeLocationSource() {

         locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
         getBestAvailableProvider();
         // Specify Location Provider criteria
         criteria.setAccuracy(Criteria.ACCURACY_FINE);
         criteria.setPowerRequirement(Criteria.POWER_LOW);
         criteria.setAltitudeRequired(true);
         criteria.setBearingRequired(true);
         criteria.setSpeedRequired(true);
         criteria.setCostAllowed(true);

         locationManager.requestLocationUpdates(bestAvailableProvider,minTime,minDistance,this);
     }

    private void getBestAvailableProvider() {
        /* The preferred 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 = locationManager.getBestProvider(criteria, true);
        Log.i(TAG,"bestAvailableProvider: " + bestAvailableProvider);
    }

    /* Activates this provider. This provider will notify the supplied listener
     * periodically, until you call deactivate().
     * This method is automatically invoked by enabling my-location layer. */
    @Override
    public void activate(OnLocationChangedListener listener) {
        Log.i(TAG,"activate");
        // 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.
        onLocationChangedListener = listener;

        // Request location updates from Location Manager
        if (bestAvailableProvider != null) {
            //locationManager.requestLocationUpdates(bestAvailableProvider, minTime, minDistance, this);
            Log.i(TAG,"activate, bestProvider != null");
            locationManager.requestLocationUpdates(bestAvailableProvider,minTime,minDistance,this);
        } else {
            Log.i(TAG,"activate, bestProvider == null");
            // (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() {
        Log.i(TAG,"deactivate");
        // Remove location updates from Location Manager
        locationManager.removeUpdates(this);

        onLocationChangedListener = null;
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.i(TAG,"onLocationChanged. Latitude: " + location.getLatitude() + " - Longitude: " + location.getLongitude());
        /* Push location updates to the registered listener..
         * (this ensures that my-location layer will set the blue dot at the new/received location) */
        if (onLocationChangedListener != null) {
            onLocationChangedListener.onLocationChanged(location);
        }

        /* ..and Animate camera to center on that location !
         * (the reason for we created this custom Location Source !) */
        listaRota.add(location);

        if ( listaRota.size() == 1 ) {
            mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(),location.getLongitude())).title("Inicio"));
        }

        if ( listaRota.size() >= 2 ) {
            drawPolyLineOnMap();
        }

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()),15));
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
        Log.i(TAG,"onStatusChanged: " + s + ", Estado: " + i);
    }

    @Override
    public void onProviderEnabled(String s) {
        Log.i(TAG,"onProviderEnabled: " + s);
    }

    @Override
    public void onProviderDisabled(String s) {
        Log.i(TAG,"onProviderDisabled: " + s);
    }
}

public void drawPolyLineOnMap() {

    List<LatLng> list = new ArrayList<>();

    for( Location l : listaRota ) {
        list.add(new LatLng(l.getLatitude(),l.getLongitude()));
    }

    PolylineOptions polylineOptions = new PolylineOptions();
    polylineOptions.color(Color.BLUE);
    polylineOptions.width(15);
    polylineOptions.addAll(list);

    mMap.clear();
    mMap.addPolyline(polylineOptions);
}

【问题讨论】:

    标签: android google-maps geolocation geofencing android-geofence


    【解决方案1】:

    该服务是Geofence Monitoring,有很多使用它的示例和教程(例如this one)。

    【讨论】:

    • 此服务仅支持 100 个区域。此服务不适用于我的应用程序。而且,这些区域是圆形的,我需要直线限制。
    • @Augusto 1) 100 个活动“区域”每个设备; 2)为什么它不起作用? 3)无论如何,您都可以在目标区域周围创建圆圈,然后,当针对此圆形地理围栏发出警报时,评估它是否也在您的目标区域内。但这不是一种可能的解决方案:如您所述,您始终可以创建自定义服务。
    • 我的问题是提醒司机他已经通过了一段路,所以圆圈不能解决我的问题。因此,我正在跟踪一条折线,并使用 PolyUtil 方法进行检查,并检查所讨论的点是否在使用先前点创建的折线内。当然,米有一定的公差。这是我发现最可行并且我能够实施的方法。我是这个领域的新手,我无法实施您的解决方案。
    猜你喜欢
    • 2010-10-24
    • 1970-01-01
    • 2021-07-29
    • 2014-07-26
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多