如何在谷歌地图中平滑移动当前位置?

     2023-05-07     200

关键词:

【中文标题】如何在谷歌地图中平滑移动当前位置?【英文标题】:How to smoothly move the current position in Google Maps? 【发布时间】:2018-10-29 14:18:02 【问题描述】:

在我的Android项目中,我需要在车辆移动时,标记位置也应该平滑移动,但是当位置改变时,标记从一个位置跳到另一个位置,移动不顺畅。

我搜索了很多,但没有得到结果。 我不知道最好的方法是什么。请给我完整的指导。

非常感谢

更新

@AnkitMehta 谢谢你的回答

MapsActivity 中的所有代码:

import android.Manifest;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.location.Location;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
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.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
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.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener 

  private GoogleMap mMap;
  SupportMapFragment mapFragment;
  LocationRequest mLocationRequest;
  GoogleApiClient mGoogleApiClient;
  Location mLastLocation;
  Marker mCurrLocationMarker;

  @Override
  protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
  

  @Override
  protected void onPause() 
    super.onPause();

    //stop Location updates when Activity is no longer active
    if (mGoogleApiClient != null) 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    
  


  @Override
  public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;

    try 
      // Customise the styling of the base map using a JSON object defined
      // in a raw resource file.
      boolean success = googleMap.setMapStyle(
        MapStyleOptions.loadRawResourceStyle(
          this, R.raw.style_json));

      if (!success) 
        Log.e("LOG" , "Style parsing failed.");
      
     catch (Resources.NotFoundException e) 
      Log.e("LOG", "Can't find style. Error: ", e);
    

    //initialize Google play Services
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
        // Location Permission already granted
        buildGoogleApiClient();
        mMap.setMyLocationEnabled(true);

       else 
        // Request Location Permission
        checkLocationPermission();
      
     else 
      buildGoogleApiClient();
      mMap.setMyLocationEnabled(true);
    


  

  protected synchronized void buildGoogleApiClient() 
    mGoogleApiClient = new GoogleApiClient.Builder(this)
      .addConnectionCallbacks(this)
      .addOnConnectionFailedListener(this)
      .addApi(LocationServices.API)
      .build();
    mGoogleApiClient.connect();
  


  @Override
  public void onConnected(@Nullable Bundle bundle) 
    mLocationRequest = new LocationRequest();
    //mLocationRequest.setInterval(30000);
    //mLocationRequest.setFastestInterval(30000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    
  

  @Override
  public void onConnectionSuspended(int i) 

  

  @Override
  public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 

  

  @Override
  public void onLocationChanged(Location location) 
    mLastLocation = location;
    if (mCurrLocationMarker != null) 
      mCurrLocationMarker.remove();
    

    //Place current location marker
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    animateMarker(latLng, latLng, true);


    //move map camera
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11));
  

  public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
  private void checkLocationPermission() 
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
      != PackageManager.PERMISSION_GRANTED) 

      // Should we show an explanation?
      if (ActivityCompat.shouldShowRequestPermissionRationale(this,
        Manifest.permission.ACCESS_FINE_LOCATION)) 

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.
        new AlertDialog.Builder(this)
          .setTitle("Location Permission Needed")
          .setMessage("This app needs the Location permission, please accept to use location functionality")
          .setPositiveButton("OK", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialogInterface, int i) 
              //Prompt the user once explanation has been shown
              ActivityCompat.requestPermissions(MapsActivity.this,
                new String[]Manifest.permission.ACCESS_FINE_LOCATION,
                MY_PERMISSIONS_REQUEST_LOCATION );
            
          )
          .create()
          .show();


       else 
        // No explanation needed, we can request the permission.
        ActivityCompat.requestPermissions(this,
          new String[]Manifest.permission.ACCESS_FINE_LOCATION,
          MY_PERMISSIONS_REQUEST_LOCATION );
      
    
  

  @Override
  public void onRequestPermissionsResult(int requestCode,
                                         String permissions[], int[] grantResults) 
    switch (requestCode) 
      case MY_PERMISSIONS_REQUEST_LOCATION: 
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
          && grantResults[0] == PackageManager.PERMISSION_GRANTED) 

          // permission was granted, yay! Do the
          // location-related task you need to do.
          if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) 

            if (mGoogleApiClient == null) 
              buildGoogleApiClient();
            
            mMap.setMyLocationEnabled(true);
          

         else 

          // permission denied, boo! Disable the
          // functionality that depends on this permission.
          Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
        
        return;
      

      // other 'case' lines to check for other
      // permissions this app might request
    
  


  //This methos is used to move the marker of each car smoothly when there are any updates of their position
  public void animateMarker(final LatLng startPosition, final LatLng toPosition,
                            final boolean hideMarker) 


    final Marker marker = mMap.addMarker(new MarkerOptions()
      .position(startPosition)
      .icon(BitmapDescriptorFactory.fromResource(R.drawable.car)));


    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();

    final long duration = 1000;
    final Interpolator interpolator = new LinearInterpolator();

    handler.post(new Runnable() 
      @Override
      public void run() 
        long elapsed = SystemClock.uptimeMillis() - start;
        float t = interpolator.getInterpolation((float) elapsed
          / duration);
        double lng = t * toPosition.longitude + (1 - t)
          * startPosition.longitude;
        double lat = t * toPosition.latitude + (1 - t)
          * startPosition.latitude;

        marker.setPosition(new LatLng(lat, lng));

        if (t < 1.0) 
          // Post again 16ms later.
          handler.postDelayed(this, 16);
         else 
          if (hideMarker) 
            marker.setVisible(false);
           else 
            marker.setVisible(true);
          
        
      
    );
  

【问题讨论】:

你能分享一下你目前写的代码(用于在地图上移动相机)吗? 【参考方案1】:
CameraPosition cameraPosition = new CameraPosition.Builder()
                                .target(latLng)
                                .build();
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(cameraPosition);
map.animateCamera(cu);

这将移动到动画选择的纬度(相机位置 并使用相机更新)

【讨论】:

//移动地图相机而不是:mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11)); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11));只做:mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11));你只需要使用 animateCamera 而不是 moveCamera 非常感谢,您的代码改进了我的代码但是当我在我的车里时,我在地图上的位置显示不流畅,但几秒钟后它会跳转到另一个位置.. .是什么原因? 可能是你没有使用低延迟进行更新...它可以节省电池但需要更长的时间来提供更新的位置 好的,但是在谷歌地图应用中,这是一个顺利的举动 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_REFRESH_TIME, LOCATION_REFRESH_DISTANCE, mlocationListener); mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if(mLastLocation!=null) Toast.makeText(getApplicationContext(), "YES!mLastLocation!=null", Toast.LENGTH_SHORT).show();双纬度 = mLastLocation.getLatitude();双经度 = mLastLocation.getLongitude(); Toast.makeText(getApplicationContext(), "Latitude = " + latitude + "\nLongitude = " + longitude, Toast.LENGTH_SHORT).show();声明距离(m)n时间(ms)【参考方案2】:

重写此方法:

@Override
public void onLocationChange(Location location) 
     LatLng latLng = new LatLng(location.latitude, location.longitude);
     refreshMapPosition(latLng, 45)



private void refreshMapPosition(LatLng pos, float angle) 
    CameraPosition.Builder positionBuilder = new CameraPosition.Builder();
    positionBuilder.target(pos);
    positionBuilder.zoom(15f);
    positionBuilder.bearing(angle);
    positionBuilder.tilt(60);
    map.animateCamera(CameraUpdateFactory.newCameraPosition(positionBuilder.build()));

这个被覆盖的方法是在 GoogleMap 类上实现的,地图变量是我们定义的用于加载谷歌地图实例的变量。

请参考:https://developers.google.com/maps/documentation/android-sdk/views

【讨论】:

如何在谷歌地图上移动地图但将标记保留为android中的当前位置?

】如何在谷歌地图上移动地图但将标记保留为android中的当前位置?【英文标题】:howtomovesmapongooglemapbutkeepmarkerascurrentlocationinandroid?【发布时间】:2018-01-2204:59:37【问题描述】:我是android新手。我最近两天受苦了。我研究了很多... 查看详情

当我的当前位置在谷歌地图中移动时更新距离的任何代码

】当我的当前位置在谷歌地图中移动时更新距离的任何代码【英文标题】:Anycodeforupdatingthedistancewhenmycurrentlocationismovedingooglemap【发布时间】:2020-09-1102:09:58【问题描述】:我可以找到当前位置与附近地点之间的距离,但我无法... 查看详情

如何在谷歌地图应用程序中从另一个位置显示当前位置?

】如何在谷歌地图应用程序中从另一个位置显示当前位置?【英文标题】:HowtoshowthecurrentlocationfromanotherlocationingooglemapsApp?【发布时间】:2018-12-0706:19:24【问题描述】:我在我的应用程序中集成了谷歌地图。我必须显示从当前位... 查看详情

在谷歌地图中保留用户位置中心 - Swift

】在谷歌地图中保留用户位置中心-Swift【英文标题】:KeepuserlocationcenterinGoogleMaps-Swift【发布时间】:2015-06-1507:48:44【问题描述】:我已经在一个swift项目中实现了谷歌地图,并使用locationManager来跟踪并当前打印出用户的位置。当... 查看详情

如何使用谷歌 API 客户端在谷歌地图 Android 中显示我的当前位置

】如何使用谷歌API客户端在谷歌地图Android中显示我的当前位置【英文标题】:HowtoshowmycurrentlocationinGoogleMapAndroidusinggoogleAPIclient【发布时间】:2016-02-1719:44:20【问题描述】:我想在地图上显示我的位置并放大它。我想使用GoolgeAPIC... 查看详情

如何在谷歌地图上显示当前街道位置?

】如何在谷歌地图上显示当前街道位置?【英文标题】:HowcanigetcurrentstreetlocationshowingonGoogleMap?【发布时间】:2011-12-2707:34:11【问题描述】:我希望我的网站用户在Google地图上显示他们当前的街道位置。就像“Facebook签到”一样... 查看详情

如何拉取用户的当前位置并显示在谷歌地图 api 上? [复制]

】如何拉取用户的当前位置并显示在谷歌地图api上?[复制]【英文标题】:Howtopulluser\'scurrentlocationanddisplayongooglemapapi?[duplicate]【发布时间】:2018-01-2217:57:46【问题描述】:所以我要完成两件事1)拉取用户当前位置2)然后在谷歌地... 查看详情

在谷歌地图javascript api中 - 如何移动地图而不是标记

】在谷歌地图javascriptapi中-如何移动地图而不是标记【英文标题】:Ingooglemapsjavascriptapi-howtomovemapnotmarker【发布时间】:2022-01-2405:56:38【问题描述】:目前我有一个小项目需要使标记静态并将地图移动到地图上的标记显示-我希望... 查看详情

在谷歌地图中将当前位置映射到目的地位置

】在谷歌地图中将当前位置映射到目的地位置【英文标题】:mappingcurrentlocationtodestinationlocationingoogleMaps【发布时间】:2011-07-0918:18:29【问题描述】:我的注释上有一个按钮,如下所示调用谷歌地图。我正在尝试将一条路线从我... 查看详情

如何在谷歌地图 api v2 上获取设备的当前位置?

】如何在谷歌地图apiv2上获取设备的当前位置?【英文标题】:Howtogetcurrentlocationofdeviceongooglemapsapiv2?【发布时间】:2015-10-1221:59:47【问题描述】:我找到了一些方法可以做到这一点,但已被弃用或不起作用。我想从设备获取当前... 查看详情

允许用户在谷歌地图中向后移动标记位置并关闭窗口

】允许用户在谷歌地图中向后移动标记位置并关闭窗口【英文标题】:allowusertomovemarkerpositionback&closewindowingooglemaps【发布时间】:2015-05-3107:15:25【问题描述】:跟进最后一个问题...allowusertomovemarkerpositionback(z-index?)ingooglemapscust... 查看详情

如何在谷歌地图中找到当前的缩放级别?

】如何在谷歌地图中找到当前的缩放级别?【英文标题】:HowtofindcurrentzoomlevelinaGoogleMap?【发布时间】:2011-09-1703:51:33【问题描述】:如何在加载或点击Google地图时找到当前的缩放级别?【问题讨论】:嗯,Map.getZoom()?【参考方... 查看详情

在谷歌地图上显示我的位置?

...描述】:我从w3school获取他的代码。在这里,他们展示了如何将用户直接带到JavaScript代码中编写的地址。我不想将用户带到我在代码中设置的某个位置,而是将用户带到地图中的当前位置,但我可以找到一种方法来做到这一点。... 查看详情

java示例代码_在谷歌地图上显示当前位置附近的多个位置

java示例代码_在谷歌地图上显示当前位置附近的多个位置 查看详情

如何使用 swift 在谷歌地图中更改我的位置按钮的位置

】如何使用swift在谷歌地图中更改我的位置按钮的位置【英文标题】:Howtochangelocationofmylocationbuttoningooglemapsusingswift【发布时间】:2017-11-3008:27:13【问题描述】:我在我的项目中使用谷歌地图我想显示我的位置按钮有点上升我应... 查看详情

如何在谷歌地图中获取位置的 MID?

】如何在谷歌地图中获取位置的MID?【英文标题】:HowtogettheMIDofalocationingooglemaps?【发布时间】:2014-11-2409:57:31【问题描述】:我需要在我的wordpress网站中添加地图,但我只需要在‘mid=’之后添加字符示例:-https://www.google.com/map... 查看详情

在谷歌地图android中使用gps移动标记

】在谷歌地图android中使用gps移动标记【英文标题】:Movemarkerwithgpsingooglemapandroid【发布时间】:2017-07-2310:12:11【问题描述】:我想移动GOOGLEMAP中的标记,同时gps位置发生变化,就像在UBER应用程序中一样。我找到了一些解决方案... 查看详情

如何在谷歌地图中设置几个特定的​​位置?

】如何在谷歌地图中设置几个特定的​​位置?【英文标题】:HowtosetseveralspecificlocationsinGoogleMap?【发布时间】:2016-11-2710:26:48【问题描述】:我想为德黑兰的自行车站制作一个安卓应用程序。为此,我需要在地图上显示特定的... 查看详情