0

次のコードを使用して、現在の場所を取得し、Google マップでルートをパスしました。私が直面した問題は、現在のデバイスの位置が常に安定していないことです。時々正しい位置を示しますが、実際の位置から 1km 離れた場所など、異なる位置を示します。

package com.colors.organisatiom.activity.colors;


import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.colors.organisatiom.activity.colors.classes.ConnectionManager;
import com.colors.organisatiom.activity.colors.interfaces.PolyLineCallback;
import com.colors.organisatiom.activity.colors.json.GetDistanceFromServer;
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;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import java.util.ArrayList;
import java.util.List;

public class LocationMap extends AppCompatActivity implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    private GoogleMap map;
    private String serviceCentreLongitude, serviceCentreLatitude, serviceCenhterLocation;
    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
    private RelativeLayout connectingParent;
    private PolylineOptions polylineOptions;
    private Polyline polyline;
    private List<Polyline> polylines = new ArrayList<>();
    private GoogleApiClient googleApiClient;
    private LocationRequest locationRequest;
    private static final long INTERVAL = 1 * 5;
    private static final long FASTEST_INTERVAL = 10;
    protected BroadcastReceiver mNotificationReceiver;
    private Marker currentLocationMarker;


    protected void createLocationRequest() {
        locationRequest = new LocationRequest();
        locationRequest.setInterval(INTERVAL);
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        serviceCentreLatitude = getIntent().getStringExtra("latitude");
        serviceCentreLongitude = getIntent().getStringExtra("longitude");
        serviceCenhterLocation = getIntent().getStringExtra("service_center_location");
        setContentView(R.layout.content_google_map);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Window window = this.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
        }
        mNotificationReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!LocationMap.this.isFinishing()) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(LocationMap.this);
                    builder.setTitle(intent.getStringExtra("title"));
                    builder.setMessage(intent.getStringExtra("message"));
                    builder.setPositiveButton("Dismiss", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //alertDialog.dismiss();
                        }
                    });
                    final AlertDialog alertDialog = builder.create();
                    alertDialog.show();
                }
            }
        };
        if (!isGooglePlayServicesAvailable()) {
            Toast.makeText(this, "Google play service not supported", Toast.LENGTH_LONG).show();
        }
        createLocationRequest();
        googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        connectingParent = (RelativeLayout) findViewById(R.id.connecting_parent);
        if (!new ConnectionManager(this).isConnectionToInternet()) {
            connectingParent.setVisibility(View.GONE);
            Toast.makeText(LocationMap.this, "No internet connection to route path", Toast.LENGTH_LONG).show();
        }
        ImageView search = (ImageView) findViewById(R.id.search);
        search.setVisibility(View.INVISIBLE);
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int hasAccessCoarseLocationPermission = checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION);
            int hasAccessFineLocationPermission = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION);
            if (hasAccessCoarseLocationPermission != PackageManager.PERMISSION_GRANTED && hasAccessFineLocationPermission != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                        REQUEST_CODE_ASK_PERMISSIONS);
            } else {
                showMapWithLocation();
                if (googleApiClient.isConnected()) {
                    startLocationUpdates();
                }
            }

        } else {
            showMapWithLocation();
            if (googleApiClient.isConnected()) {
                startLocationUpdates();
            }
        }

    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d("Started:", "onStart fired ..............");
        googleApiClient.connect();
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("Stopped", "onStop fired ..............");
        googleApiClient.disconnect();
        Log.d("Is connected status", "isConnected ...............: " + googleApiClient.isConnected());
    }

    private void showMapWithLocation() {
        map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        LatLng latLng = new LatLng(Double.parseDouble(serviceCentreLatitude), Double.parseDouble(serviceCentreLongitude));
        map.addMarker(new MarkerOptions()
                .position(latLng)
                .title(serviceCenhterLocation)).showInfoWindow();
        map.getUiSettings().setMapToolbarEnabled(false);
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
        map.animateCamera(cameraUpdate);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_PERMISSIONS:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    startLocationUpdates();
                    if (googleApiClient.isConnected()) {
                        startLocationUpdates();
                    }
                } else {
                    Toast.makeText(LocationMap.this, "Cannot show map", Toast.LENGTH_SHORT)
                            .show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private List<LatLng> decodePoly(String encoded) {
        List<LatLng> poly = new ArrayList<>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;
        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;
            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
        return poly;
    }


    @Override
    public void onConnected(Bundle bundle) {
        Log.e("Connection status:", "onConnected - isConnected ...............: " + googleApiClient.isConnected());
        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
        Log.e("Update started:", "Location update started ..............: ");
    }

    @Override
    public void onLocationChanged(Location location) {

            final double myLocationlatitude = location.getLatitude();
            final double myLocationlongitude = location.getLongitude();
            Log.e("Latitude", String.valueOf(myLocationlatitude));
            Log.e("Longitude", String.valueOf(myLocationlongitude));
            LatLng latLng = new LatLng(myLocationlatitude, myLocationlongitude);
            //drawing the path in google map
            //zoom the camera for the first time
            if (currentLocationMarker != null) {
                currentLocationMarker.remove();
            }
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title("My current location");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
            currentLocationMarker = map.addMarker(markerOptions);
            if (polylines == null) {
                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
                map.animateCamera(cameraUpdate);
            }
            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... params) {
                    new GetDistanceFromServer(String.valueOf(myLocationlatitude), String.valueOf(myLocationlongitude), serviceCentreLatitude, serviceCentreLongitude).drawPath(new PolyLineCallback() {
                        @Override
                        public void polyLinePointsHolder(String points) {
                            //remove the path and draw the path in google map while updating
                            if (polylines != null) {
                                for (Polyline line : polylines) {
                                    line.remove();
                                }
                            }
                            List<LatLng> list = decodePoly(points);
                            polylineOptions = new PolylineOptions()
                                    .addAll(list)
                                    .width(12)
                                    .color(Color.parseColor("#05b1fb"))
                                    .geodesic(true);
                            polyline = map.addPolyline(polylineOptions);
                            polylines.add(polyline);

                        }
                    });
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    connectingParent.setVisibility(View.GONE);

                    super.onPostExecute(aVoid);
                }
            }.execute();



    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e("Connection Failed", connectionResult.getErrorMessage());
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopLocationUpdates();
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                googleApiClient, this);
        Log.d("TAG", "Location update stopped .......................");
    }

    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(this).registerReceiver(mNotificationReceiver, new IntentFilter("1000"));
        if (googleApiClient.isConnected()) {
            startLocationUpdates();
            Log.d("TAG", "Location update resumed .....................");
        }
    }
}
4

1 に答える 1

1

位置情報の精度は、GPS のカバレッジ、デバイスの品質、周辺の Wi-Fi の可用性など、多くの要因によって影響を受ける可能性があります。できることは、取得した位置の精度を確認して、続行するかどうかを決定することです。これには、Location オブジェクトのhasAccuracy()およびメソッドを使用できます。getAccuracy()

これは getAccuracy メソッドに関するドキュメントからの引用です

この位置の推定精度をメートル単位で取得します。

精度は 68% 信頼の半径として定義されます。つまり、この場所の緯度と経度を中心とし、精度に等しい半径で円を描くと、実際の場所が円の内側にある確率は 68% になります。

統計用語では、位置誤差は正規分布でランダムであると想定されるため、68% の信頼円は 1 つの標準偏差を表します。実際には、位置誤差は常にこのような単純な分布に従うとは限らないことに注意してください。

この精度の推定は、水平方向の精度のみに関係し、方位、速度、または高度がこの場所に含まれている場合、これらの精度を示すものではありません。

この位置に精度がない場合は、0.0 が返されます。LocationManager によって生成されるすべての場所には精度が含まれます。

onLocationChanged メソッドでは、次のことができます

@Override
public void onLocationChanged(Location location) {
     if(location.hasAccuracy() && location.getAccuracy() < 100F) {
        // the location has accuracy and has an accuracy span within 100m radius
        // do whatever you want with this location and stop location listener
        stopLocationUpdates();
     }

     // if the above code did not get executed, the location listener will work 
     // until a location with acceptable accuracy is obtained
}
于 2016-02-09T08:58:31.447 に答える