安卓位置管理器 - "location not changed"事件



我正在构建一个服务,它会让我知道位置在一段时间内是否在一定数量的米内没有变化。

然后我的监听器上有事件onLocationChanged ..但我不知道如何做相反的…即,几分钟后,如果该位置在我提供的距离内,则发送广播。

这是我到目前为止写的代码

LocationService

public class LocationService extends Service {
    public static final String LOC_INTENT = "com.xxx.intent.action.LOCATION";
    private Thread triggerService;
    protected LocationManager locationManager;
    protected MyLocationListener MyLocationListener;
    protected Criteria criteria;
    public static final int MIN_TIME = 300000; // 5 Minutes
    public static final long MIN_DISTANCE_MOTOR = 50; // 50 Metres
    private SharedPreferences settings;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        settings = getSharedPreferences(getString(R.string.settings_prefsName), 0);
        addLocationListener();
        return START_STICKY;
    }
    private void addLocationListener()
    {
        triggerService = new Thread(new Runnable(){
            public void run(){
                try{
                    Looper.prepare();//Initialise the current thread as a looper.
                    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
                    criteria = new Criteria();
                    criteria.setAccuracy(Criteria.ACCURACY_FINE);
                    final String PROVIDER = locationManager.getBestProvider(criteria, true);
                    updateLocation(getLastBestLocation(MIN_TIME, MIN_DISTANCE_MOTOR));
                    MyLocationListener = new MyLocationListener();
                    locationManager.requestLocationUpdates(PROVIDER, MIN_TIME, MIN_DISTANCE_MOTOR, MyLocationListener);
                    Log.d("LOC_SERVICE", "Service RUNNING! ("+PROVIDER+")");
                    Looper.loop();
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
        }, "LocationThread");
        triggerService.start();
    }

    public Location getLastBestLocation(int minDistance, long minTime) {
        Location bestResult = null;
        float bestAccuracy = Float.MAX_VALUE;
        long bestTime = Long.MIN_VALUE;
        List<String> matchingProviders = locationManager.getAllProviders();
        for (String provider: matchingProviders) {
            Location location = locationManager.getLastKnownLocation(provider);
            if (location != null) {
                float accuracy = location.getAccuracy();
                long time = location.getTime();
                if ((time > minTime && accuracy < bestAccuracy)) {
                    bestResult = location;
                    bestAccuracy = accuracy;
                    bestTime = time;
                }
                else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
                    bestResult = location;
                    bestTime = time;
                }
            }
        }
        return bestResult;
    }
    public static void updateLocation(Location location)
    {
        Context appCtx = MyApplication.getAppContext();
        double latitude, longitude;
        float speed;
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        speed = location.getSpeed();
        Intent filterRes = new Intent();
        filterRes.setAction(LOC_INTENT);
        filterRes.putExtra("latitude", latitude);
        filterRes.putExtra("longitude", longitude);
        filterRes.putExtra("speed", speed);
        appCtx.sendBroadcast(filterRes);
    }

    class MyLocationListener implements LocationListener
    {
        @Override
        public void onLocationChanged(Location location)
        {
            if(settings.getBoolean("active", false))
                updateLocation(location);
        }
        @Override
        public void onProviderDisabled(String provider) {
        }
        @Override
        public void onProviderEnabled(String provider) {
        }
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    }
}

设置一个计时器,无论您想测试多长时间。当它响起时,检查您在onLocationChanged中获得的最后一个位置是否比计时器长度更早。

编辑

我想象你的服务是这样的

服务开始

  • requestLocationUpdates以适当的最小时间和最小距离呼叫,您将在
  • 之后收到通知
  • 检查是否收到更新的重复任务集(检查Timer.scheduleAtFixedRate
  • )

运行服务
  • 当定时器关闭或onLocationChanged被调用时执行必要的操作
服务停止

  • 使用removeUpdates删除位置更新
  • 停止计时器

最新更新