2016-10-01 124 views
1

我是Skobbler map中的新手。我使用Skobbler map來顯示我的當前位置。最初,位於地圖的某處。 enter image description here在android中啓用GPS後顯示當前位置

我已經在美利堅合衆國設置了默認位置。所以,當我打開應用程序它顯示這個。但是,這個標記仍然在地圖上的某個地方,在海面之上。要顯示的默認位置,我用這個:

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

enter image description here

之後,當我啓用了GPS,標記必須移動和顯示的時間內,我的當前位置。可以做些什麼來刷新地圖以顯示我的當前位置。可以做些什麼來解決這個問題?

回答

3

TL; DR:

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。

這不是一個生產就緒代碼,但只是讓你可以得到的圖片。

這是我怎麼樣來組織我的代碼,當涉及到的位置:

摘要位置活動從中你會延長所有使用位置的活動:

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活動:

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開發商的任何批評,以改善這是歡迎的。

+0

無法解析'centerOnCurrentPosition'方法。顯示位置時有「放大」圖標。我想要位置必須顯示如上圖所示。 –

+0

你使用什麼版本的Skobbler Sdk? –

+0

這是最新的一個。我已修復該問題。但是,「相機」運動速度如此之快。當我從當前位置移動一段距離時,「攝像頭」會更新得如此之快。它在5或6秒內從該距離返回到當前位置。我如何阻止?因爲,我有一個工作按鈕。由於該「攝像頭」的自動更新,我的按鈕意義不大。 –

1

設置FollowPositions爲True:

mapView.getMapSettings().setFollowPositions(true); 

這將使它以便地圖以每個位置更新重新居中。

+0

無法解析方法setFollowPositions ....此方法可能是這樣的:'mapView.getMapSettings()。setCurrentPositionShown(true); '!!!你的回答不是我正在尋找的。請發表評論,而不是像這樣。你的回答完全衝突了我的問題。 –

+0

@SananPandeya:我想你使用的是舊版本的SDK。 –