【问题标题】:LocationManager minTime won't work properlyLocationManager minTime 无法正常工作
【发布时间】:2014-10-04 03:48:26
【问题描述】:

我想每 5 分钟获取一次用户的位置,所以我使用以下代码创建了一个 Service

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class Tracker extends Service {

    private SharedPreferences prefs;
    private LocationManager locationManager;
    private long minTime = 300000; // miliseconds
    private float minDistance = 10; // meters
    private boolean gpsStatus;
    private boolean networkStatus;

    @Override
    public void onCreate() {
        Log.i("Location2", "Location: Created");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Location2", "Location: Started");

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        gpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        networkStatus = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);

        return Service.START_STICKY;
    }

    private void resetLocationProvider() {
        Log.e("Location2", "Provider Reset");
        deleteLocationListener();
        locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);
    }

    private void deleteLocationListener() {
        locationManager.removeUpdates(locationListener);
    }

    private LocationListener locationListener = new LocationListener() {

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }

        @Override
        public void onProviderEnabled(String provider) {
            resetLocationProvider();
            Log.e("Location2", "Provider Enabled: " + provider);
        }

        @Override
        public void onProviderDisabled(String provider) {
            resetLocationProvider();
            Log.e("Location2", "Provider Disabled: " + provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.i("Location2", "Location Time: " + TimeToDate.getDate(location.getTime(), "yyyy-MM-dd HH:mm:ss"));
            Log.i("Location2", "Location Provider: " + location.getProvider());
            Log.i("Location2", "Location Accuracy: " + location.getAccuracy());
            Log.i("Location2", "Location Latitude: " + location.getLatitude());
            Log.i("Location2", "Location Longitude: " + location.getLongitude());

            if (gpsStatus != locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                gpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                resetLocationProvider();
                return;
            }

            if (networkStatus != locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                networkStatus = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                resetLocationProvider();
            }
        }
    };

    private String getProviderName() {
        LocationManager locationManager = (LocationManager) this
                .getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        criteria.setPowerRequirement(Criteria.POWER_MEDIUM); // Chose your desired power consumption level.
        criteria.setAccuracy(Criteria.ACCURACY_FINE); // Choose your accuracy requirement.
        criteria.setSpeedRequired(false); // Chose if speed for first location fix is required.
        criteria.setAltitudeRequired(false); // Choose if you use altitude.
        criteria.setBearingRequired(false); // Choose if you use bearing.
        criteria.setCostAllowed(false); // Choose if this provider can waste money :-)

        // Provide your criteria and flag enabledOnly that tells
        // LocationManager only to return active providers.
        return locationManager.getBestProvider(criteria, true);
    }

    @Override
    public void onDestroy() {
        deleteLocationListener();
        super.onDestroy();
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

}

正如所见,我使用了300,000 ms 中的minTime,但我每20 秒而不是5 分钟得到一个位置。正如documentation 所说:

位置更新之间的间隔时间永远不会少于 minTime,虽然它可能更多取决于位置提供程序 其他应用程序请求的实现和更新间隔

我也知道,active provider 不是 background process 的好选择。但是,我的代码有什么问题?

【问题讨论】:

  • 检查前一个 lat lng 到当前 lnt lng 之间的 gps 时间差

标签: android gps locationmanager


【解决方案1】:

基于this answer,我将代码更改为:

        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                if (location.getProvider().equals(LocationManager.GPS_PROVIDER) && android.os.Build.VERSION.SDK_INT < 16) {
                    Log.i("TEST", "DATE: " + TimeToDate.getDate(location.getTime(), "yyyy-MM-dd HH:mm:ss"));
                    Log.i("TEST", "LAT: " + location.getLatitude());
                    Log.i("TEST", "LONG: " + location.getLongitude());
                    locationManager.removeUpdates(locationListener);
                    new Handler().postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            locationManager.requestLocationUpdates(getProviderName(), minTime, minDistance, locationListener);
                        }
                    }, minTime);
                }
                ...

现在它可以工作了。

【讨论】:

    猜你喜欢
    • 2018-04-13
    • 1970-01-01
    • 2016-12-01
    • 2011-04-02
    • 1970-01-01
    • 2016-09-01
    • 2012-07-11
    • 2018-04-08
    • 2017-04-20
    相关资源
    最近更新 更多