使用FusedlocationProviderClientApi在Android中进行实时位置跟踪的问题

时间:2020-01-06 15:48:18

标签: java android google-maps location fusedlocationproviderclient

我已经在Android Studio中的Google地图活动片段上尝试了以下代码,甚至在手机上进行了编译和运行,但我的位置未显示。请帮助我在代码中找到错误。

    package com.example.ambulance;

    import ...

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

private GoogleMap googleMap;
private FusedLocationProviderClient fusedLocationProviderClient;
private int REQUEST_ACCESS = 5445;
private boolean firstTimeFlag = true;
private Marker currentLocationMarker;
private static Location currentLocation;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.google_map);
    supportMapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap)
{
    this.googleMap = googleMap;
}

@Override
protected void onResume()
{
    super.onResume();
    if(isGooglePlayServicesAvailable())
    {
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        startLocationUpdates();
    }
}

private boolean isGooglePlayServicesAvailable()
{
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();

    int status = googleApiAvailability.isGooglePlayServicesAvailable(this);

    if(ConnectionResult.SUCCESS == status)
        return true;
    else
    {
        if(googleApiAvailability.isUserResolvableError(status))
            Toast.makeText(this, "Please Install Google Play Services to Use this Application", Toast.LENGTH_LONG).show();
    }
    return false;
}

private void startLocationUpdates()
{
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(300);
    locationRequest.setSmallestDisplacement(1);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(MapsActivity.this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS);
        return;
    }
    fusedLocationProviderClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.myLooper());
}

//Here we are defining the mLocationCallback object, that is used in the previous function.

private final LocationCallback mLocationCallback = new LocationCallback(){

    @Override
    public void onLocationResult(LocationResult locationResult)
    {
        super.onLocationResult(locationResult);
        if(locationResult.getLastLocation() == null)
            return;

        currentLocation = locationResult.getLastLocation();

        if(firstTimeFlag && googleMap != null)
        {
            animateCamera(currentLocation);
            firstTimeFlag = true;
        }
        showMarker(currentLocation);
    }
};

private void animateCamera(@NonNull Location location)
{
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(getCameraPositionWithBearing(latLng)));
}

@NonNull
private CameraPosition getCameraPositionWithBearing(LatLng latLng) {

    return new CameraPosition.Builder().target(latLng).zoom(16).build();

}

private void showMarker(@NonNull Location currentLocation)
{
    LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());

    if(currentLocationMarker == null)
        currentLocationMarker = googleMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.defaultMarker()).position(latLng));
    else
        MarkerAnimation.animateMarkerToGB(currentLocationMarker, latLng, new LatLngInterpolator.Spherical());
}
}


    package com.example.ambulance;

    import ...

public interface LatLngInterpolator
{
LatLng interpolate(float fraction, LatLng a, LatLng b);

class Spherical implements  LatLngInterpolator
{
    /* From github.com/googlemaps/android-maps-utils */

    @Override
    public LatLng interpolate(float fraction, LatLng from, LatLng to)
    {
        //http://en.wikipedia.org/wiki/Slerp

        double fromLat = toRadians(from.latitude);
        double fromLng = toRadians(from.longitude);
        double toLat = toRadians(to.latitude);
        double toLng = toRadians(to.longitude);
        double cosFromLat = cos(fromLat);
        double cosToLat = cos(toLat);

        //Computes Spherical interpolation co-efficients.

        double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng);
        double sinAngle = sin(angle);

        if (sinAngle < 1E-6)
            return from;

        double a = sin((1 - fraction) * angle) / sinAngle;
        double b = sin(fraction * angle) / sinAngle;

        //Converts from polar to vector and interpolate.

        double x = a * cosFromLat * cos(fromLat) + b * cosToLat * cos(toLng);
        double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng);
        double z = a * sin(fromLat) + b * sin(toLat);

        //Converts interpolated vectors back to polar.

        double lat = atan2(z, sqrt(x*x + y*y));
        double lng = atan2(y, x);
        return new LatLng(toDegrees(lat), toDegrees(lng));
    }

    private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng)
    {
        //Haversine's Formula

        double dLat = fromLat - toLat;
        double dLng = fromLng - toLng;
        return 2 * asin(sqrt(pow(sin(dLat / 2), 2) + cos(fromLat) * cos(toLat * pow(sin(dLng / 2), 2))));
    }
}
}


    package com.example.ambulance;

    import ...

public class MarkerAnimation {
    public static void animateMarkerToGB(final Marker marker, final LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {
    final LatLng startPosition = marker.getPosition();
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final Interpolator interpolator = new AccelerateDecelerateInterpolator();
    final float durationInMs = 2000;

    handler.post(new Runnable() {
        long elapsed;
        float t;
        float v;

        @Override
        public void run() {
            //Calculator Progress Using Interpolator.
            elapsed = SystemClock.uptimeMillis() - start;
            t = elapsed / durationInMs;
            v = interpolator.getInterpolation(t);

            marker.setPosition(latLngInterpolator.interpolate(v, startPosition, finalPosition));

            //Repeat till progress is complete.

            if (t < 1) {
                //Post again 16ms later.
                handler.postDelayed(this, 16);
            }

        }
    });
}
}

这是我正在使用的代码。 另外,我已经在AndroidManifest.xml文件中授予了必要的权限。

1 个答案:

答案 0 :(得分:0)

您已在return方法中添加了startLocationUpdates,以防止应用程序到达此代码:

fusedLocationProviderClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.myLooper());

删除它可以解决此问题,我已经对此进行了验证。

private void startLocationUpdates() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(300);
    locationRequest.setSmallestDisplacement(1);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS);
    }
    fusedLocationProviderClient.requestLocationUpdates(locationRequest, mLocationCallback, Looper.myLooper());
}

希望这会有所帮助!

相关问题