如何提高我的Android应用程序服务中的位置的准确性?

时间:2017-01-02 21:19:27

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

我正在创建一个设置用户当前位置(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;
        }
    }
}

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

1 个答案:

答案 0 :(得分:1)

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

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