在 android 启用 GPS 后显示当前位置

Display current location after GPS is enabled in android

我是 Skobbler map 的新人。我使用 Skobbler map 来显示我的当前位置。最初 marker 位于地图中的某处。

我已将默认位置设置在美利坚合众国。所以,当我打开应用程序时,它会显示这个。但是,标记仍在地图中的某处,在海的上方。为了显示默认位置,我使用了这个:

SKCoordinateRegion region = new SKCoordinateRegion();
region.setCenter(new SKCoordinate(-97.1867366, 38.4488163));
region.setZoomLevel(5);
mapView.changeMapVisibleRegion(region, true);

之后,当我启用GPS时,标记必须移动并在时间内显示我当前的位置。可以做什么来刷新地图以显示我当前的位置。可以做些什么来解决这个问题?

长话短说:

SKCoordinate coordinates = new SKCoordinate (-97.1867366, 38.4488163)
SKPosition lastSKPosition  = new SKPosition (coordinates);
SKPositionerManager.getInstance ().reportNewGPSPosition (lastSKPosition);
mapView.centerOnCurrentPosition (ZoomLevel, true, AnimationDuration);
mapView.setPositionAsCurrent (lastSKPosition.getCoordinate (), Accuracy, center);

不是 Skobbler 的专家,我不太喜欢 Skobbler SDK,因为它对我来说太复杂了,文档也很差,方法太多,类,所以我尝试利用Android SDK 和 Google API 尽我所能。

这不是生产就绪代码,只是为了让您了解情况。

当涉及到位置时,我喜欢这样组织我的代码:

抽象位置 activity 您将从中扩展所有使用位置的活动:

public abstract class LocationActivity extends AppCompatActivity {

    private GeoLocService locationService;

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);

        if (GeoLocService.checkLocationPerms (this)) {
            initLocService ();
        }
    }

    @Override
    protected void onStart () {
        super.onStart ();
        if (locationService != null) {
            locationService.onStart ();
        }
    }

    @Override
    public void onRequestPermissionsResult (int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult (requestCode, permissions, grantResults);
        if (requestCode == 1000) {
            if (GeoLocService.checkLocationPerms (this)) {
                initLocService ();
                locationService.onStart ();
            }
        }
    }

    @Override
    protected void onResume () {
        super.onResume ();
        if (locationService != null) {
            locationService.onResume ();
        }
    }

    @Override
    protected void onPause () {
        super.onPause ();
        if (locationService != null) {
            locationService.onPause ();
        }
    }

    @Override
    protected void onStop () {
        if (locationService != null) {
            locationService.disconnect ();
        }
        super.onStop ();
    }

    private void initLocService () {
        GeoLocService.LocationResponse response = new GeoLocService.LocationResponse () {

            @Override
            public void onLocation (Location location) {
                onLocationSuccess (location);
            }

            @Override
            public void onFailure (int errorCode) {
                onLocationFailure (errorCode);
            }
        };
        locationService = new GeoLocService (this, response);
    }

    protected void stopFetchingLocations () {
        if (locationService != null) {
            locationService.stopLocationUpdates ();
            locationService.disconnect ();
        }
    }

    protected GeoLocService getLocationService () {
        return locationService;
    }

    protected abstract void onLocationSuccess (Location location);
    protected abstract void onLocationFailure (int errorCode);
}

提供 geoloc 处理方法的 GeoLoc 服务:

public class GeoLocService implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {

    public final static long    UPDATE_INTERVAL_IN_MILLISECONDS = 10000;

    public final static long    FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;

    private GoogleApiClient     googleApiClient;
    private LocationRequest     locationRequest;
    private LocationResponse    locationResponse;
    private Location            currentLocation;

    private Date                lastUpdateTime;

    public GeoLocService (Activity context, LocationResponse locationResponse) {
        this.locationResponse   = locationResponse;

        googleApiClient         = new GoogleApiClient.Builder (context)
            .addConnectionCallbacks (this)
            .addOnConnectionFailedListener (this)
            .addApi (LocationServices.API)
            .build ();

        createLocationRequest ();
    }

    public void onStart () {
        if (googleApiClient != null) {
            googleApiClient.connect ();
        }
    }

    public void onResume () {
        if (googleApiClient != null && googleApiClient.isConnected ()) {
            startLocationUpdates ();
        }
    }

    public void onPause () {
        if (googleApiClient != null && googleApiClient.isConnected ()) {
            stopLocationUpdates ();
        }
    }

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

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

    public void startLocationUpdates () {
        LocationServices.FusedLocationApi.requestLocationUpdates (googleApiClient, locationRequest, this);
    }

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

    @Override
    public void onConnected(Bundle connectionHint) {
        if (currentLocation == null) {
            currentLocation = LocationServices.FusedLocationApi.getLastLocation (googleApiClient);
            lastUpdateTime  = Calendar.getInstance ().getTime ();
            sendUpdates ();
        }

        startLocationUpdates ();
    }

    private void sendUpdates () {
        if (locationResponse != null && currentLocation != null) {
            locationResponse.onLocation (currentLocation);
        }
    }

    @Override
    public void onLocationChanged (Location location) {
        currentLocation = location;
        lastUpdateTime  = Calendar.getInstance ().getTime ();
        sendUpdates ();
    }

    @Override
    public void onConnectionSuspended (int cause) {
        googleApiClient.connect ();
    }

    @Override
    public void onConnectionFailed (ConnectionResult result) {
        if (locationResponse != null) {
            locationResponse.onFailure (result.getErrorCode ());
        }
    }

    public static boolean checkLocationPerms (Activity context) {
        if (ActivityCompat.checkSelfPermission (context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission (context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions (
                    context,
                    new String [] {
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_NETWORK_STATE
                    },
                    1000
            );
            return false;
        }
        return true;
    }

    public GoogleApiClient getGoogleApiClient () {
        return googleApiClient;
    }

    public Date getLastUpdatedTime () {
        return lastUpdateTime;
    }

    public interface LocationResponse {
        void onLocation (Location location);
        void onFailure (int errorCode);
    }
}

最后是你的 Skobbler Activity :

public class SkobblerActivity extends LocationActivity implements SKMapSurfaceListener {

    private final static float  ZoomLevel           = 15;
    private final static int    AnimationDuration   = 750;
    private final static float  Accuracy            = 1;

    private int                 placedOnCurrentPosCount;

    private SKMapViewHolder     mapHolder;
    private SKMapSurfaceView    mapView;

    private SKPosition lastSKPosition  = new SKPosition (new SKCoordinate ());

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        .....
    }

    @Override
    protected void onLocationSuccess (Location location) {
        convertLocToSKLoc (location);
        SKPositionerManager.getInstance ().reportNewGPSPosition (lastSKPosition);
        if (mapView != null) {
            boolean center = false;
            if (placedOnCurrentPosCount < 2 && (location.getLatitude () != 0 || location.getLongitude () != 0)) {
                center = true;
                mapView.centerOnCurrentPosition (ZoomLevel, true, AnimationDuration);
            }

            mapView.setPositionAsCurrent (lastSKPosition.getCoordinate (), Accuracy, center);

            placedOnCurrentPosCount ++;
        }
    }

    @Override
    protected void onLocationFailure (int errorCode) {
    }

    private void convertLocToSKLoc (Location location) {
        lastSKPosition.getCoordinate ().setLatitude (location.getLatitude ());
        lastSKPosition.getCoordinate ().setLongitude (location.getLongitude ());
    }

    .......................
}

欢迎来自 skobbler 开发者的任何改进意见:)

将 FollowPositions 设置为 True:

mapView.getMapSettings().setFollowPositions(true);

这将使地图在每次位置更新时重新居中。