Android 如何顺利移动谷歌地图的当前位置?

Android 如何顺利移动谷歌地图的当前位置?,android,google-maps,move,marker,smoothing,Android,Google Maps,Move,Marker,Smoothing,在我的Android项目中,我需要当车辆移动时,标记位置也应平稳移动,但当位置改变时,标记从一个位置跳到另一个位置,它不会平稳移动 我搜索了很多,但没有得到结果。 我不知道最好的办法是什么。请给我充分的指导 多谢各位 更新 @谢谢你的回答 MapsActivity中的所有代码: import android.Manifest; import android.content.DialogInterface; import android.content.pm.PackageManager; imp

在我的Android项目中,我需要当车辆移动时,标记位置也应平稳移动,但当位置改变时,标记从一个位置跳到另一个位置,它不会平稳移动

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

多谢各位

更新

@谢谢你的回答

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);
          }
        }
      }
    });
  }
}
导入android.Manifest;
导入android.content.DialogInterface;
导入android.content.pm.PackageManager;
导入android.content.res.Resources;
导入android.location.location;
导入android.os.Build;
导入android.os.Handler;
导入android.os.SystemClock;
导入android.support.annotation.NonNull;
导入android.support.annotation.Nullable;
导入android.support.v4.app.ActivityCompat;
导入android.support.v4.app.FragmentActivity;
导入android.os.Bundle;
导入android.support.v4.content.ContextCompat;
导入android.support.v7.app.AlertDialog;
导入android.util.Log;
导入android.view.animation.Interpolator;
导入android.view.animation.LinearInterpolator;
导入android.widget.Toast;
导入com.google.android.gms.common.ConnectionResult;
导入com.google.android.gms.common.api.GoogleAppClient;
导入com.google.android.gms.location.LocationListener;
导入com.google.android.gms.location.LocationRequest;
导入com.google.android.gms.location.LocationServices;
导入com.google.android.gms.maps.CameraUpdateFactory;
导入com.google.android.gms.maps.GoogleMap;
导入com.google.android.gms.maps.OnMapReadyCallback;
导入com.google.android.gms.maps.SupportMapFragment;
导入com.google.android.gms.maps.model.BitmapDescriptorFactory;
导入com.google.android.gms.maps.model.LatLng;
导入com.google.android.gms.maps.model.MapStyleOptions;
导入com.google.android.gms.maps.model.Marker;
导入com.google.android.gms.maps.model.MarkerOptions;
公共类MapsActivity扩展了FragmentActivity在MapreadyCallback、GoogleAppClient.ConnectionCallbacks、GoogleAppClient.OnConnectionFailedListener、LocationListener上的实现{
私有谷歌地图;
SupportMapFragment-mapFragment;
位置请求mLocationRequest;
GoogleapClient MGoogleapClient;
位置mLastLocation;
标记器mCurrLocationMarker;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_映射);
//获取SupportMapFragment,并在地图准备好使用时收到通知。
mapFragment=(SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
getMapAsync(这个);
}
@凌驾
受保护的void onPause(){
super.onPause();
//当活动不再处于活动状态时停止位置更新
if(mGoogleApiClient!=null){
LocationServices.FusedLocationApi.RemovelocationUpdate(mgoogleapClient,this);
}
}
@凌驾
4月1日公开作废(谷歌地图谷歌地图){
mMap=谷歌地图;
试一试{
//使用定义的JSON对象自定义底图的样式
//在原始资源文件中。
布尔成功=googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
这个,R.raw.style_(json));
如果(!成功){
e(“Log”,“样式解析失败”);
}
}catch(Resources.notfounde异常){
Log.e(“Log”,“找不到样式。错误:”,e);
}
//初始化Google play服务
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.M){
if(ContextCompat.checkSelfPermission(此,Manifest.permission.ACCESS\u FINE\u位置)==PackageManager.permission\u已授予){
//已授予位置权限
buildGoogleAppClient();
mMap.setMyLocationEnabled(真);
}否则{
//请求位置权限
checkLocationPermission();
}
}否则{
buildGoogleAppClient();
mMap.setMyLocationEnabled(真);
}
}
受保护的同步无效BuildGoogleAppClient(){
mgoogleapclient=新的Googleapclient.Builder(此)
.addConnectionCallbacks(此)
.addOnConnectionFailedListener(此)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@凌驾
未连接的公共无效(@Nullable Bundle){
mlLocationRequest=新位置请求();
//mLocationRequest.setInterval(30000);
//mlLocationRequest.SetFastTestInterval(30000);
mLocationRequest.setPriority(位置请求、优先级、平衡、功率、精度);
if(ContextCompat.checkSelfPermission(此,Manifest.permission.ACCESS\u FINE\u位置)==PackageManager.permission\u已授予){
LocationServices.FusedLocationApi.RequestLocationUpdate(mgoogleapClient、mlLocationRequest、this);
}
}
@凌驾
公共空间连接暂停(int i){
}
@凌驾
public void onconnection失败(@NonNull ConnectionResult ConnectionResult){
}
@凌驾
已更改位置上的公共无效(位置){
mLastLocation=位置;
if(mCurrLocationMarker!=null){
mCurrLocationMarker.remove();
}
//放置当前位置标记
LatLng LatLng=新LatLng(location.getLatitude(),location.getLongitude());
动画标记器(latLng,latLng,true);
//移动地图照相机
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
}
公共静态final int MY_PERMISSIONS_REQUEST_LOCATION=99;
私有void checkLocationPermission(){
if(ContextCompat.checkSelfPermission(这个,Manifest.permission.ACCESS\u FINE\u位置)
!=PackageManager.权限(已授予){
//我们应该解释一下吗?
如果(活动公司)应显示请求许可理由(此,
清单.权限.访问(位置){
//向用户显示解释*asynchrono
CameraPosition cameraPosition = new CameraPosition.Builder()
                                .target(latLng)
                                .build();
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(cameraPosition);
map.animateCamera(cu);
@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()));
}