如何在Google Maps Android API v2中将相机直接移动到当前位置?

56

如何在不点击任何按钮的情况下直接获取当前位置并将相机移动到该位置。
此外,我发现地图右上方有一个按钮。 当单击它时,它会转到当前位置。 如何获取单击该按钮时它返回的位置?

5个回答

94

请确保您拥有这些权限:

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

然后进行一些活动并注册LocationListener

package com.example.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;

public class LocationActivity extends SherlockFragmentActivity implements LocationListener     {
private GoogleMap map;
private LocationManager locationManager;
private static final long MIN_TIME = 400;
private static final float MIN_DISTANCE = 1000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map);
    map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, this); //You can also use LocationManager.GPS_PROVIDER and LocationManager.PASSIVE_PROVIDER        
}

@Override
public void onLocationChanged(Location location) {
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 10);
    map.animateCamera(cameraUpdate);
    locationManager.removeUpdates(this);
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) { }

@Override
public void onProviderEnabled(String provider) { }

@Override
public void onProviderDisabled(String provider) { }
}

映射文件.xml

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>

7
移除更新,点赞👍。 - Naskov
1
这个SherlockFragmentActivity是什么?你的回答中没有提到它。 - Samitha Chathuranga
1
这是一个旧的支持库,用于向后兼容ActionBar...你可以使用FragmentActivity替换它。http://actionbarsherlock.com/ - tmho
1
您不需要权限 android.permission.ACCESS_COARSE_LOCATION。 - Wédney Yuri
1
removeupdate() 真棒,现在地图更新每 x 秒后不再跳转到当前位置了,谢谢。 - Sunil Chaudhary
显示剩余4条评论

32

上面的回答并不符合Google api v2中有关位置跟踪的说明。我只是按照官方教程操作,最终得到了这个类,该类获取当前位置并将地图居中显示在该位置。

您可以扩展此类以添加LocationReciever以进行定期位置更新。我在api级别7上执行了此代码。

http://developer.android.com/training/location/retrieve-current.html

就是这样。

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;


public class MainActivity extends FragmentActivity implements 
    GooglePlayServicesClient.ConnectionCallbacks, 
    GooglePlayServicesClient.OnConnectionFailedListener{

private SupportMapFragment mapFragment;
private GoogleMap map;
private LocationClient mLocationClient;
/*
 * Define a request code to send to Google Play services
 * This code is returned in Activity.onActivityResult
 */
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {

    // Global field to contain the error dialog
    private Dialog mDialog;

    // Default constructor. Sets the dialog field to null
    public ErrorDialogFragment() {
        super();
        mDialog = null;
    }

    // Set the dialog to display
    public void setDialog(Dialog dialog) {
        mDialog = dialog;
    }

    // Return a Dialog to the DialogFragment.
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return mDialog;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    mLocationClient = new LocationClient(this, this, this);

    mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
    map = mapFragment.getMap();

    map.setMyLocationEnabled(true);

}

/*
 * Called when the Activity becomes visible.
 */
@Override
protected void onStart() {
    super.onStart();
    // Connect the client.
    if(isGooglePlayServicesAvailable()){
        mLocationClient.connect();
    }

}

/*
 * Called when the Activity is no longer visible.
 */
@Override
protected void onStop() {
    // Disconnecting the client invalidates it.
    mLocationClient.disconnect();
    super.onStop();
}

/*
 * Handle results returned to the FragmentActivity
 * by Google Play services
 */
@Override
protected void onActivityResult(
                int requestCode, int resultCode, Intent data) {
    // Decide what to do based on the original request code
    switch (requestCode) {

        case CONNECTION_FAILURE_RESOLUTION_REQUEST:
            /*
             * If the result code is Activity.RESULT_OK, try
             * to connect again
             */
            switch (resultCode) {
                case Activity.RESULT_OK:
                    mLocationClient.connect();
                    break;
            }

    }
}

private boolean isGooglePlayServicesAvailable() {
    // Check that Google Play services is available
    int resultCode =  GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    // If Google Play services is available
    if (ConnectionResult.SUCCESS == resultCode) {
        // In debug mode, log the status
        Log.d("Location Updates", "Google Play services is available.");
        return true;
    } else {
        // Get the error dialog from Google Play services
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog( resultCode,
                                                                                                              this,
                                                                                                              CONNECTION_FAILURE_RESOLUTION_REQUEST);

        // If Google Play services can provide an error dialog
        if (errorDialog != null) {
            // Create a new DialogFragment for the error dialog
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();
            errorFragment.setDialog(errorDialog);
            errorFragment.show(getSupportFragmentManager(), "Location Updates");
        }

        return false;
    }
}

/*
 * Called by Location Services when the request to connect the
 * client finishes successfully. At this point, you can
 * request the current location or start periodic updates
 */
@Override
public void onConnected(Bundle dataBundle) {
    // Display the connection status
    Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
    Location location = mLocationClient.getLastLocation();
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17);
    map.animateCamera(cameraUpdate);
}

/*
 * Called by Location Services if the connection to the
 * location client drops because of an error.
 */
@Override
public void onDisconnected() {
    // Display the connection status
    Toast.makeText(this, "Disconnected. Please re-connect.",
            Toast.LENGTH_SHORT).show();
}

/*
 * Called by Location Services if the attempt to
 * Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    /*
     * Google Play services can resolve some errors it detects.
     * If the error has a resolution, try sending an Intent to
     * start a Google Play services activity that can resolve
     * error.
     */
    if (connectionResult.hasResolution()) {
        try {
            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(
                    this,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
            /*
            * Thrown if Google Play services canceled the original
            * PendingIntent
            */
        } catch (IntentSender.SendIntentException e) {
            // Log the error
            e.printStackTrace();
        }
    } else {
       Toast.makeText(getApplicationContext(), "Sorry. Location services not available to you", Toast.LENGTH_LONG).show();
    }
}

}

1
在更新Google Play服务后,com.google.android.gms.location.LocationClient无法解决。 - Joseph Mekwan
1
答案现在已经两年了。如果您能发布新的答案,那将会很有帮助。 - Rohit Sharma
我已经用最新的文档回答了这个问题。请检查一下。 - Kishan Vaghela

11

我正在解释,如何在假设您已经实现了map-v2的情况下,获取当前位置并直接移动到摄像机的当前位置。有关详细信息,请参阅官方文档

将位置服务添加到gradle中。

implementation "com.google.android.gms:play-services-location:11.0.1"
在清单文件中添加位置权限。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

确保你请求RunTimePermission(运行时权限)。我正在使用Ask-Permission来实现。它很容易使用。

现在参考下面的代码获取当前位置并在地图上显示。

private FusedLocationProviderClient mFusedLocationProviderClient;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFusedLocationProviderClient = LocationServices
                .getFusedLocationProviderClient(getActivity());

}

private void getDeviceLocation() {
        try {
            if (mLocationPermissionGranted) {
                Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
                locationResult.addOnCompleteListener(new OnCompleteListener<Location>() {
                    @Override
                    public void onComplete(@NonNull Task<Location> task) {
                        if (task.isSuccessful()) {
                            // Set the map's camera position to the current location of the device.
                            Location location = task.getResult();
                            LatLng currentLatLng = new LatLng(location.getLatitude(),
                                    location.getLongitude());
                            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(currentLatLng,
                                    DEFAULT_ZOOM);
                            googleMap.moveCamera(update);
                        }
                    }
                });
            }
        } catch (SecurityException e) {
            Log.e("Exception: %s", e.getMessage());
        }
}
当用户授予位置权限时,请调用上述getDeviceLocation()方法。
private void updateLocationUI() {
        if (googleMap == null) {
            return;
        }
        try {
            if (mLocationPermissionGranted) {
                googleMap.setMyLocationEnabled(true);
                googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                getDeviceLocation();
            } else {
                googleMap.setMyLocationEnabled(false);
                googleMap.getUiSettings().setMyLocationButtonEnabled(false);
            }
        } catch (SecurityException e) {
            Log.e("Exception: %s", e.getMessage());
        }
    }

2

只需将moveCamera更改为animateCamera,如下所示

Googlemap.animateCamera(CameraUpdateFactory.newLatLngZoom(locate, 16F))

0

我的回答是给那些正在寻找应用程序启动时当前位置缩放动画和获取当前位置的人。

如果有任何遗漏,请在评论中告诉我。

注意:假设您已经授予了所有位置的运行时权限

@Override
public void onMapReady(GoogleMap googleMap) {
    MapsInitializer.initialize(this);
    mMap = googleMap;
    
    getData(mMap);
    animateCamera();


}

getData方法返回地图上理想位置的经纬度。因此,在摄像机缩放动画结束时,其会在当前位置变得理想,因此它提供了当前位置的经纬度。

  private void getData(GoogleMap mMap) {

    mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
        @Override
        public void onCameraIdle() {

            LatLng center = mMap.getCameraPosition().target;
            String sLatitude = String.format("%.6f", center.latitude);
            String sLongitude = String.format("%.6f", center.longitude);
            StringBuilder mLatLng = new StringBuilder();
            mLatLng.append(sLatitude);
            mLatLng.append("°");
            mLatLng.append(" ");
            mLatLng.append(sLongitude);
            mLatLng.append("°");
            binding.latLng.setText(mLatLng);

        }
    });

private void animateCamera() {
    Location location = getLastKnownLocation();
    if (location != null) {

        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setMyLocationButtonEnabled(true);
        mMap.getUiSettings().setAllGesturesEnabled(true);
        //delay is for after map loaded animation starts
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15));

            }
        }, 2000);
    }
}

这将返回最佳位置提供程序

private Location getLastKnownLocation() {
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    List<String> providers = locationManager.getProviders(true);
    Location bestLocation = null;
    for (String provider : providers) {
        @SuppressLint("MissingPermission") Location l = locationManager.getLastKnownLocation(provider);
        if (l == null) {
            continue;
        }
        if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
            // Found best last known location: %s", l);
            bestLocation = l;
        }
    }
    return bestLocation;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接