如何在Google Maps API V2上获取设备的当前位置?

4

我发现一些方法可以做到这一点,但已经过时或者不起作用。我想从设备中获取当前的纬度和经度。

以下是我获取当前位置的方法,但GoogleMap的getMyLocation()方法已被弃用

void getCurrentLocation()
{
    Location myLocation  = map.getMyLocation();
    if(myLocation!=null)
    {
        double dLatitude = myLocation.getLatitude();
        double dLongitude = myLocation.getLongitude();
        map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
                .title("My Location").icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));

    }
    else
    {
        Toast.makeText(this, "Unable to fetch the current location", Toast.LENGTH_SHORT).show();
    }
}

在向他人请求编写代码之前,请先展示一些自己的代码或工作。 - andrewdleach
希望这个链接能对你有所帮助。 - Nagabhushana G M
不建议使用GPSTracker类,参见这里:http://gabesechansoftware.com/location-tracking/ - Daniel Nugent
3个回答

9

针对api-23及以上版本:

请参考这里的答案。

针对api-22及以下版本:

使用FusedLocationProviderAPI比使用较旧的开源位置API更为推荐,尤其是因为您已经在使用Google地图,所以已经在使用Google Play服务。只需设置一个位置监听器,在每个onLocationChanged()回调中更新当前位置标记即可。如果您只想要一个位置更新,请在第一个回调返回后取消回调的注册。

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

    private GoogleMap map;
    private LocationRequest mLocationRequest;
    private GoogleApiClient mGoogleApiClient;
    private Location mLastLocation;
    private Marker marker;

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

    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mGoogleApiClient == null || !mGoogleApiClient.isConnected()){

            buildGoogleApiClient();
            mGoogleApiClient.connect();

        }

        if (map == null) {
            MapFragment mapFragment = (MapFragment) getFragmentManager()
                    .findFragmentById(R.id.map);

            mapFragment.getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap retMap) {

        map = retMap;

        setUpMap();

    }

    public void setUpMap(){

        map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        map.setMyLocationEnabled(true);
    }

    @Override
    protected void onPause(){
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected", Toast.LENGTH_SHORT).show();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        //mLocationRequest.setSmallestDisplacement(0.1F);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        mLastLocation = location;

        //remove previous current location Marker
        if (marker != null){
            marker.remove();
        }

        double dLatitude = mLastLocation.getLatitude();
        double dLongitude = mLastLocation.getLongitude();
        marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
                .title("My Location").icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));

    }

}

抱歉直到现在才回复。我尝试了这段代码,但我不知道 onLocationChanged 监听器在哪里被调用,因为它不起作用。它应该是自动调用的,不是吗? - Rene Limon
我正在尝试在我的设备上。 - Rene Limon
@ReneLimon 很抱歉,代码中出现了错误,导致GoogleApiClient无法构建。我已经更新了答案,并提供了完全测试和可用的代码! - Daniel Nugent
@DanielNugent java.lang.RuntimeException: 无法恢复活动 {akashdubey.com.googlemapsdemo/akashdubey.com.googlemapsdemo.MapsActivity}: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' - Akash Dubey
@akash 确保你的布局xml中有地图,查看此处的答案以获取更新的代码:https://dev59.com/5VsW5IYBdhLWcg3wyZsw#34582595 - Daniel Nugent

2

这个是正常工作的,其他的都已经过时了。

最初的回答
   private FusedLocationProviderClient fusedLocationClient;
 fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    Activity#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for Activity#requestPermissions for more details.
            return;
        }
    }
    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location != null) {
                        mylatitude = location.getLatitude();
                        mylongitude = location.getLongitude();
                        Log.d("chk", "onSuccess: "+mylongitude);
                        // Logic to handle location object
                    }
                }
            });

This link will be helpful


1
 public class MainActivity extends FragmentActivity implements OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    GoogleMap.OnMarkerDragListener,
    GoogleMap.OnMapLongClickListener,
    GoogleMap.OnMarkerClickListener, LocationListener,
    View.OnClickListener {


private static final String TAG = "MapsActivity";
Location mCurrentLocation;
String mLastUpdateTime;
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private Marker mCurrLocationMarker;
private LocationRequest mLocationRequest;
private ArrayList<LatLng> routePoints;
private Polyline line;

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

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(map);


    mapFragment.getMapAsync(this);

    //Initializing googleApiClient
    googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    routePoints = new ArrayList<LatLng>();


}

@Override
public void onClick(View v) {

}

@Override
public void onConnected(Bundle bundle) {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(1000);
    mLocationRequest.setSmallestDisplacement(0.1F); //added
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); //changed
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

@Override
public void onMapLongClick(LatLng latLng) {
    // mMap.clear();
    mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
}

@Override
public boolean onMarkerClick(Marker marker) {
    Toast.makeText(MainActivity.this, "onMarkerClick", Toast.LENGTH_SHORT).show();
    return true;
}

@Override
public void onMarkerDragStart(Marker marker) {
    Toast.makeText(MainActivity.this, "onMarkerDragStart", Toast.LENGTH_SHORT).show();
}

@Override
public void onMarkerDrag(Marker marker) {
    Toast.makeText(MainActivity.this, "onMarkerDrag", Toast.LENGTH_SHORT).show();
}

@Override
public void onMarkerDragEnd(Marker marker) {
    // getting the Co-ordinates
   /* latitude = marker.getPosition().latitude;
    longitude = marker.getPosition().longitude;*/

    //move to current position
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
    // googleMapOptions.mapType(googleMap.MAP_TYPE_HYBRID)
    //    .compassEnabled(true);

   /* LatLng india = new LatLng(20.5937, 78.9629);
    mMap.addMarker(new MarkerOptions().position(india).title("Marker in India"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(india));
    mMap.setOnMarkerDragListener(this);
    mMap.setOnMapLongClickListener(this);*/
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    mMap.setMyLocationEnabled(true);
}


@Override
protected void onStart() {
    googleApiClient.connect();
    super.onStart();
}

@Override
protected void onStop() {
    googleApiClient.disconnect();
    super.onStop();
}

@Override
public void onLocationChanged(Location location) {

    if (mCurrLocationMarker != null) {
        mCurrLocationMarker.remove();
    }
    mCurrentLocation = location;
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    addMarker();
   /* //Place current location marker
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.title("Current Position");
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    mCurrLocationMarker = mMap.addMarker(markerOptions);

    //move map camera
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(18));

    PolylineOptions pOptions = new PolylineOptions()
            .width(5)
            .color(Color.GREEN)
            .geodesic(true);
    for (int z = 0; z < routePoints.size(); z++) {
        LatLng point = routePoints.get(z);
        pOptions.add(point);
    }
    line = mMap.addPolyline(pOptions);
    routePoints.add(latLng);*/
}

private void addMarker() {
    MarkerOptions options = new MarkerOptions();
    IconGenerator iconFactory = new IconGenerator(this);
    iconFactory.setStyle(IconGenerator.STYLE_GREEN);
    options.icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(mLastUpdateTime)));
    options.anchor(iconFactory.getAnchorU(), iconFactory.getAnchorV());
    LatLng currentLatLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
    options.position(currentLatLng);
    mCurrLocationMarker = mMap.addMarker(options);
    long atTime = mCurrentLocation.getTime();
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date(atTime));
    mCurrLocationMarker.setTitle(mLastUpdateTime);
    Log.d(TAG, "Marker added.............................");
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng,
            18));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
    PolylineOptions pOptions = new PolylineOptions()
            .width(5)
            .color(Color.BLACK)
            .geodesic(true);
    for (int z = 0; z < routePoints.size(); z++) {
        LatLng point = routePoints.get(z);
        pOptions.add(point);
    }
    line = mMap.addPolyline(pOptions);
    routePoints.add(currentLatLng);
    Log.d(TAG, "Zoom done.............................");
}
}

1
谢谢您的帮助。您已经发布了一堵代码墙。您觉得加上一些描述会更好吗? - goto

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