【问题标题】:How to improve the accurancy of the location in my android app service?如何提高我的 android 应用服务中位置的准确性?
【发布时间】:2017-01-02 21:19:27
【问题描述】:

我正在制作一个应用程序来设置用户当前位置 (A),然后用户单击一个按钮来设置新的当前用户位置 (B),然后我绘制这两点之间的路径。 我得到了一项使用 Fused Locations 获取位置的服务。问题是大多数时候我得到的位置是 hasAccuracy = false,并且 getAccuracy > 20。

这是我的服务:

import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class GoogleMapService extends Service implements LocationListener {

    private static final String TAG = "GoogleMapServiceTAG_";
    private IBinder myBinder = new GoogleMapServiceBinder();

    // Google client to interact with Google API
    private GoogleApiClient mGoogleApiClient;

    private LocationRequest mLocationRequest;

    private double fusedLatitude = 0.0;
    private double fusedLongitude = 0.0;

    private static final long INTERVAL = 1000 * 5;
    private static final long FASTEST_INTERVAL = 1000 * 3;

    public void init() {
        if (checkPlayServices()) {
            startFusedLocation();
            startLocationUpdates(this);
        }
    }

    public void startLocationUpdates(final LocationListener listener) {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    LocationServices.FusedLocationApi.
                            requestLocationUpdates(mGoogleApiClient, mLocationRequest, listener);
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                    if (!isGoogleApiClientConnected()) {
                        mGoogleApiClient.connect();
                    }
                    startLocationUpdates(listener);
                }
            }
        }, 1000);
    }

    public boolean isGoogleApiClientConnected() {
        return mGoogleApiClient != null && mGoogleApiClient.isConnected();
    }

    public void startFusedLocation() {
        if (mGoogleApiClient == null) {
            createLocationRequest();
            mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnectionSuspended(int cause) {
                        }

                        @Override
                        public void onConnected(Bundle connectionHint) {

                        }
                    }).addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {

                        @Override
                        public void onConnectionFailed(ConnectionResult result) {

                        }
                    }).build();
            mGoogleApiClient.connect();
        } else {
            mGoogleApiClient.connect();
        }
    }

    public void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
    }

    public void stopFusedLocation() {
        if (mGoogleApiClient != null) {
            mGoogleApiClient.disconnect();
        }
    }

    public void setFusedLatitude(double lat) {
        fusedLatitude = lat;
    }

    public void setFusedLongitude(double lon) {
        fusedLongitude = lon;
    }

    public double getFusedLatitude() {
        return fusedLatitude;
    }

    public double getFusedLongitude() {
        return fusedLongitude;
    }

    public void createLocationRequest() {
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    }

    // check if google play services is installed on the device
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                Toast.makeText(getApplicationContext(),
                        "This device is supported. Please download google play services", Toast.LENGTH_LONG)
                        .show();
            } else {
                Toast.makeText(getApplicationContext(),
                        "This device is not supported.", Toast.LENGTH_LONG)
                        .show();
            }
            return false;
        }
        return true;
    }

    @Override
    public void onLocationChanged(Location location) {
        Toast.makeText(this, "!location.hasAccuracy(): " + (!location.hasAccuracy()) + ", location.getAccuracy(): " + (location.getAccuracy()), Toast.LENGTH_SHORT).show();

        /*if (!location.hasAccuracy()) {
            return;
        }*/
        if (location.getAccuracy() > 10) {
            return;
        }
        setFusedLatitude(location.getLatitude());
        setFusedLongitude(location.getLongitude());
        Toast.makeText(this, "getFusedLatitude(): " + getFusedLatitude() + ", getFusedLongitude(): " + getFusedLongitude(), Toast.LENGTH_SHORT).show();
        Log.d("parkCar2", "Lat:" + getFusedLatitude() + ", lon: " + getFusedLongitude());
    }

    @Override
    public boolean onUnbind(Intent intent) {
        stopLocationUpdates();
        return false;
    }

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

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

    public class GoogleMapServiceBinder extends Binder {
        public GoogleMapService getServiceGoogle() {
            return GoogleMapService.this;
        }
    }
}

我可以做些什么来提高我的应用中定位服务的准确性? 提前致谢

【问题讨论】:

    标签: android google-maps google-play-services


    【解决方案1】:

    您可以采取一些措施来提高定位准确性:

    • 使用LocationRequest.PRIORITY_HIGH_ACCURACY 请求位置更新
    • 指定/请求权限ACCESS_FINE_LOCATION,而不是ACCESS_COARSE_LOCATION
    • 在您设备的位置设置中,启用它并选择高精度模式
    • 启用 WiFi 和蜂窝数据
    • 位于附近有许多公共 WiFi 热点的位置
    • 在户外使用该应用
    • 使用最新的 play-services-location 库

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 2020-03-26
      • 2019-11-27
      • 1970-01-01
      相关资源
      最近更新 更多