【问题标题】:LocationClient by Google Services not using GPS dataGoogle 服务的 LocationClient 不使用 GPS 数据
【发布时间】:2014-05-18 17:22:07
【问题描述】:

我目前正在尝试 Google 服务提供的 LocationClient。当我在建筑物旁边时,我会收到频繁的位置更新,但在道路中间,它们的频率较低且准确性较低。在乡下,根本没有更新。我想知道谷歌位置服务是否使用 GPS,所以我禁用了所有位置提供程序,但手机设置中的 GPS 除外,我立即停止接收任何更新。显然,我的 LocationClient 没有收到任何使用 GPS 数据的更新。

我错过了什么吗?我必须为 LocationClient 设置什么,还是必须使用标准的 LocationManager.GPS_PROVIDER?

我正在尝试构建一个运行应用程序,我需要准确的位置数据。任何建议将不胜感激;-)!

这是我使用的实现:

public class CustomLocationProvider implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener, android.location.LocationListener {

    private static final float DATA_UPDATE_DISTANCE = 100.0f;
    private static final long ONE_MIN = 1000 * 60;
    private static final long FIVE_MIN = ONE_MIN * 5;
    private static final int UPDATE_TIME = 5000;
    private static final int FASTEST_INTERVAL = 16;
    private static final int ACCURACY_THRESHOLD = 30;

    private Context mContext;
    private LocationClient mLocationClient;
    private Location mPreviousLocation;
    private float mTotalDistance;
    private float mDistanceSinceLastUpdate = 0.0f;

    private WeakReference<Activity> mDelegate;

    public interface LocationProviderDelegate {
        void locationUpdated(Location location);
    }

    // These settings are the same as the settings for the map. They will in fact give you updates
    // at the maximal rates currently possible.
    private static final LocationRequest REQUEST = LocationRequest.create()
            .setInterval(UPDATE_TIME)         // 5 seconds
            .setFastestInterval(FASTEST_INTERVAL)    // 16ms = 60fps
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    public CustomLocationProvider (Context context, Activity delegate) {
        if(context != null) {
            mContext = context;
            mDelegate = new WeakReference<Activity>(delegate);
        }
    }

    public void enableTracking(boolean enable) {
        if(enable) {

            setUpLocationClientIfNeeded();
            mLocationClient.connect();
        } else {
            if(mLocationClient != null) {
                mLocationClient.disconnect();
            }
        }
    }

    private void setUpLocationClientIfNeeded() {
        if (mLocationClient == null) {
            mLocationClient = new LocationClient(
                    mContext,
                    this,  // ConnectionCallbacks
                    this); // OnConnectionFailedListener
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        if(mPreviousLocation != null
                && location.getTime() > mPreviousLocation.getTime()
                && location.getAccuracy() < ACCURACY_THRESHOLD)
        {
            float distanceIncrement =  mPreviousLocation.distanceTo(location);
            mDistanceSinceLastUpdate += distanceIncrement;
            mTotalDistance += distanceIncrement;

            if(mDistanceSinceLastUpdate >= DATA_UPDATE_DISTANCE)
            {
                mDistanceSinceLastUpdate = 0.0f;
                requestDataUpdate(location);
            }

            updateLocation(location);
        } else if( mPreviousLocation == null){
            requestDataUpdate(location);
            updateLocation(location);
        }
    }

    private void updateLocation(Location location) {
        try {
            ((LocationProviderDelegate) mDelegate.get()).locationUpdated(location);
        } catch (Exception e) {
            Logger.logError("Cannot cast as a LocationProviderDelegate");
        }
        mPreviousLocation = location;
    }

    /**
     * Callback called when connected to GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        mLocationClient.requestLocationUpdates(
                REQUEST,
                this);  // LocationListener
        Location location = mLocationClient.getLastLocation();
        if (location != null) {
            if (age(location) < FIVE_MIN) {
                mPreviousLocation = location;
                requestDataUpdate(location);
            }
        }
    }

    /**
     * Callback called when disconnected from GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onDisconnected() {
        // Do nothing
    }

    /**
     * Implementation of {@link OnConnectionFailedListener}.
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Logger.postMessageToTheUser("Connection failed", mDelegate.get());
    }

    public void Reset(){
        mTotalDistance = 0;
    }

    public float TotalDistance() {
        return mTotalDistance;
    }

    public void requestDataUpdate(Location location)
    {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        double offset = 0.002;

        LatLngBounds bounds = LatLngBounds.builder()
                .include(new LatLng(latitude - offset, longitude - offset))
                .include(new LatLng(latitude + offset, longitude + offset))
                .build();

        updateData();
    }


    private long age(Location location) {
        return System.currentTimeMillis() - location.getTime();
    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        String newStatus = "";
        switch (status) {
        case LocationProvider.OUT_OF_SERVICE:
            newStatus = "OUT_OF_SERVICE";
            break;
        case LocationProvider.TEMPORARILY_UNAVAILABLE:
            newStatus = "TEMPORARILY_UNAVAILABLE";
            break;
        case LocationProvider.AVAILABLE:
            newStatus = "AVAILABLE";
            break;
        }
        String msg = provider + ": " + newStatus;
        Logger.postMessageToTheUser(msg, mDelegate.get());
    }
}

【问题讨论】:

    标签: android gps location google-api-client


    【解决方案1】:

    Google Play Services 提供的LocationClient 使用了融合的位置提供程序。这意味着它将使用可用的最佳提供商以及手机的传感器为您提供最准确的位置。

    从您的代码看来,如果位置精度小于 30m,您将忽略更新。请记住,即使 GPS 是获取位置的最准确方式,您也无法控制该位置的准确度。

    另外,调用LocationRequest.create() 将使用默认参数创建请求。我想你想最后打电话给create()(在setInterval()等之后)而不是第一个。

    【讨论】:

    • 感谢您的回答,这有助于理解它是如何工作的,但它并没有告诉我为什么只启用 GPS(甚至在精度过滤之前)我根本没有收到任何更新。地图会收到更新。
    • 在你设置好间隔和其他参数后,尝试最后调用create(),暂时取消准确性检查。
    • 现在看起来好多了!明天我将进行更多测试,如果它解决了我的问题,则将问题设置为已解决。谢谢!
    • 没问题。很高兴能提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2015-02-06
    相关资源
    最近更新 更多