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

在谷歌地图android中使用gps移动标记,android,google-maps,google-maps-api-3,gps,Android,Google Maps,Google Maps Api 3,Gps,我想在googlemap中移动标记,同时gps位置更改,就像在UBER应用程序中一样。我找到了一些解决办法,但无法解决我的问题。解决方案是和 下面是我的onLocationChange()方法 public void onLocationChanged(Location location) { double lattitude = location.getLatitude(); double longitude = location.getLongitude(); m

我想在
googlemap
中移动标记,同时
gps
位置更改,就像在
UBER
应用程序中一样。我找到了一些解决办法,但无法解决我的问题。解决方案是和

下面是我的
onLocationChange()
方法

public void onLocationChanged(Location location) {

    double lattitude = location.getLatitude();
    double longitude = location.getLongitude();

    mLastLocation = location;
    if (mCurrLocationMarker != null) {
        mCurrLocationMarker.remove();
    }
    //Place current location marker
    LatLng latLng = new LatLng(lattitude, longitude);
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.title("I am here");
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));

    mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);

    tv_loc.append("Lattitude: " + lattitude + "  Longitude: " + longitude);

    //move map camera
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

    //stop location updates
    if (mGoogleApiClient != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }

}
更新1(重新编辑)

为了更好地理解,我添加了更多的代码,但首先我想告诉大家,我在我的应用程序中使用了标签。第一个
选项卡是我的地图。所以我用碎片来做

public class MyLocation extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener{

GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker=null;
TextView tv_loc;
private static View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    if(view != null)
    {
        ViewGroup viewGroupParent = (ViewGroup)view.getParent();
        if(viewGroupParent !=null)
        {
            viewGroupParent.removeView(viewGroupParent);
        }
    }
    try{
        view = inflater.inflate(R.layout.my_location,container, false);
    }catch (Exception e)
    {
         /* map is already there, just return view as it is */
        return  view;
    }

    // inflat and return the layout
    //View rootView = inflater.inflate(R.layout.my_location, container, false);

    tv_loc = (TextView)view.findViewById(R.id.textView);
    mapFrag = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    mapFrag.getMapAsync(this);

    return view;

}

@Override
public 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) {
    mGoogleMap=googleMap;
    mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    //Initialize Google Play Services
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            //Location Permission already granted
            buildGoogleApiClient();
            mGoogleMap.setMyLocationEnabled(true);
        } else {
            //Request Location Permission
            checkLocationPermission();
        }
    }
    else {
        buildGoogleApiClient();
        mGoogleMap.setMyLocationEnabled(true);
    }
}

protected synchronized void buildGoogleApiClient() {

    mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {

    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(1000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    if (ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

}

@Override
public void onConnectionSuspended(int i) {

}


@Override
public void onLocationChanged(Location location) {

    double lattitude = location.getLatitude();
    double longitude = location.getLongitude();

    //Place current location marker
    LatLng latLng = new LatLng(lattitude, longitude);


    if(mCurrLocationMarker!=null){
        mCurrLocationMarker.setPosition(latLng);
    }else{
        mCurrLocationMarker = mGoogleMap.addMarker(new MarkerOptions()
                .position(latLng)
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
                .title("I am here"));
    }

    tv_loc.append("Lattitude: " + lattitude + "  Longitude: " + longitude);
    mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));

    //stop location updates
    if (mGoogleApiClient != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }
    /*double lattitude = location.getLatitude();
    double longitude = location.getLongitude();

    mLastLocation = location;
    if (mCurrLocationMarker != null) {
        //mGoogleMap.clear();
        mCurrLocationMarker.remove();
    }
    //Place current location marker
    LatLng latLng = new LatLng(lattitude, longitude);
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.title("I am here");
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)).draggable(true);

    mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
    mCurrLocationMarker.setPosition(new LatLng(lattitude,longitude));

    tv_loc.append("Lattitude: " + lattitude + "  Longitude: " + longitude);

    //move map camera
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

    //stop location updates
    if (mGoogleApiClient != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }*/
}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {

    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                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(getActivity())
                    .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(getActivity(),
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION );
                        }
                    })
                    .create()
                    .show();


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


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

    /*super.onRequestPermissionsResult(requestCode, permissions, 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(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED)
                {
                    if(mGoogleApiClient == null)
                    {
                        buildGoogleApiClient();
                    }
                    mGoogleMap.setMyLocationEnabled(true);
                }

            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                //finish();
                Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}


@Override
public void onResume()
{
    super.onResume();
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
}


@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}}

非常感谢您的帮助

您可以使用下面的代码更新标记的位置

public void onLocationChanged(Location location) {

    double lattitude = location.getLatitude();
    double longitude = location.getLongitude();

    //Place current location marker
    LatLng latLng = new LatLng(lattitude, longitude);


    if(mCurrLocationMarker!=null){
        mCurrLocationMarker.setPosition(latLng);
    }else{
        mCurrLocationMarker = mGoogleMap.addMarker(new MarkerOptions()
                                .position(latLng)
                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
                                .title("I am here");
    }

    tv_loc.append("Lattitude: " + lattitude + "  Longitude: " + longitude);
    gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));

    //stop location updates
    if (mGoogleApiClient != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }

}
您不需要每次都清除地图。您可以通过将标记添加到地图时返回的标记对象来完成此操作。
希望对您有所帮助。

这可以通过使用CameraPosition、googleMap.animateCamera和使用线性插值器的标记移动动画来完成

您可以查看本教程和相应的github


本教程使用谷歌地图v2。希望这有帮助。

首先在活动中实施LocationListener,然后

如果只需要显示一个标记(更新标记的位置),请使用以下命令:

private Marker currentPositionMarker = null;

 @Override
    public void onLocationChanged(Location location) {

      LatLng  latLng = new LatLng(location.getLatitude(), location.getLongitude());
        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(latLng).zoom(14).build();

        // mMap.clear(); // Call if You need To Clear Map
        if (currentPositionMarker == null)
            currentPositionMarker = mMap.addMarker(new MarkerOptions()
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW))
                    .position(latLng)
                    .zIndex(20));
        else 
            currentPositionMarker.setPosition(latLng);


        mMap.animateCamera(CameraUpdateFactory
                .newCameraPosition(cameraPosition));
    }
或者,如果每次都要添加新标记:

 @Override
    public void onLocationChanged(Location location) {

        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(latLng).zoom(14).build();

        mMap.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW))
                .position(latLng)
                .zIndex(20));

        mMap.animateCamera(CameraUpdateFactory
                .newCameraPosition(cameraPosition));
    } 
如果位置快速更改,您的应用程序需要几秒钟才能更新其位置标记使用以下方法:

在地图活动中实现
LocationListener、GoogleMap.OnMyLocationChangeListener
,然后使用位置更改侦听器

       @Override
    public void onMyLocationChange(Location location) { 
        //mMap.clear //if you want refresh map remove comment
        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude =location.getLongitude();

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude); //your_text_view.settext(latitude+","+longtitudde)

        // Showing the current location in Google Map
      mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.destination_marker)).position(latLng).title(maping_status));

        // Zoom in the Google Map
      mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
    }

为了制作动画,只需调用此方法(animateMarker),使用以前的位置和新位置以及标记对象

private Marker mCurrentMarker;
private float ZOOMLEVEL=18.0f;
private LatLng previousLatLon;
private Handler mLocalHandler;
private GoogleMap mGoogleMap;

public void animateMarker(final Marker marker, final LatLng toPosition,final LatLng fromPosition) {


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

        mLocalHandler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - mStartTime;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
                marker.setPosition(toPosition);
                marker.setAnchor(Constants.MAPANCHOR, Constants.MAPANCHOR);
                mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(toPosition, ZOOMLEVEL));
                if (t < 1.0) {
                    // Post again 16ms later.
                    mLocalHandler.postDelayed(this, 16);
                } else {
                    marker.setVisible(true);
                }
                }
            }
        });
        previousLatLon=toPosition;// reassign the previous location to current location
    }
专用标记mCurrentMarker;
私人浮动ZOOMLEVEL=18.0f;
私人车床;
私人处理程序Mlocahandler;
私有谷歌地图mGoogleMap;
公共空白动画标记器(最终标记器、最终板条位置、最终板条起始位置){
最终长持续时间=500;
最终插值器插值器=新的线性插值器();
mLocalHandler.post(新的Runnable(){
@凌驾
公开募捐{
长时间运行=SystemClock.uptimeMillis()-mStartTime;
float t=interpolator.getInterpolation((float)经过
/持续时间);
标记器。设置位置(位置);
marker.setAnchor(Constants.MAPANCHOR,Constants.MAPANCHOR);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(地形、缩放级别));
如果(t<1.0){
//16毫秒后再次发布。
mLocalHandler.postDelayed(这个,16);
}否则{
marker.setVisible(true);
}
}
}
});
previousLatLon=位置;//将以前的位置重新指定给当前位置
}

希望这个答案能对你有所帮助。使用Google Fused Api代替gps并阅读这个答案


请尝试此教程链接,以便更好地理解清单中的添加这些行

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

如果您仍在寻找解决方案,希望这将对您有所帮助。我曾在我的一个应用程序中使用过它,它有助于将标记从一个位置移动到另一个位置。 源代码可以在这里抓取

您可能需要向标记添加旋转以显示标记的确切方向。下面是我用来查找方向的代码块

    private float bearingBetweenLatLngs(LatLng begin, LatLng end) {
        Location beginL = convertLatLngToLocation(begin);
        Location endL = convertLatLngToLocation(end);

        return beginL.bearingTo(endL);
    }

尝试
mGoogleMap.clear()
而不是
mCurrLocationMarker.remove()
尝试了它,但没有用。快速问题,此方法在哪里?在活动、服务、应用程序中?如果是在一项活动中,它会一直工作到你回到活动中,还是根本不工作?我们需要看到更多的代码来真正帮助您。主要在该方法所在的位置。使用该方法尝试了您的代码,但当蓝点移动时,标记仍位于同一位置。pin移动时应设置在蓝点上扫描您是否检查您的onLocationChanged事件被调用?此外,蓝色引脚是默认地图,它们可能使用不同的逻辑进行位置更改。您可以通过硬编码值来检查设置位置方法,并检查位置是否更改。我尝试了同样的方法,但它正在改变。
停止位置更新
这会停止要更新的位置,因此我认为这就是为什么标记没有移动的原因。我的想法可能是我错了,而且每次都会调用
onLocationChange
方法。您也可以看到我的更新代码。请尝试删除“停止位置更新”下的代码。而不是。如果仍然没有,请尽可能上传整个活动代码。我将清楚地知道为什么不更新标记,标记会移动,并且每次移动前一个标记时仍会显示,此外,我使用的文本视图显示当前的
纬度
经度
。因此,文本视图在上一个仍然存在的情况下继续一个接一个地重复。您可以使用标记清除选项,如
mMap.clear()
。在从我的位置获取lat long之前添加上述代码。我希望这将有助于@faisal1208并添加内部方法,如
your_text\u view.settext(latitude+,“+longtitudde)
add在从上述方法中的当前位置获取lat long之后我编辑我的帖子以获得您喜欢的内容删除我提到的命令我希望您理解@faisal1208
    private float bearingBetweenLatLngs(LatLng begin, LatLng end) {
        Location beginL = convertLatLngToLocation(begin);
        Location endL = convertLatLngToLocation(end);

        return beginL.bearingTo(endL);
    }