如何在Google Maps Android API v2中获取当前位置?

44

使用

mMap.setMyLocationEnabled(true)

可以设置我的位置图层启用。
但问题是当用户点击按钮时如何获取我的位置?我想要获取经度和纬度。


你需要什么?需要在用户触摸屏幕时获取位置,还是需要在用户点击“获取我的位置”按钮时获取用户位置? - Usman Kurd
检查这个最新的获取当前位置的方法: https://dev59.com/HI3da4cB1Zd3GeqPx0xi#56110319 - Venkatesh
这是最新的正确工作版本。 - Venkatesh
13个回答

59

Google 地图 API 位置现在可以使用,甚至可以添加监听器。您可以使用它来实现以下功能:

private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
    @Override
    public void onMyLocationChange(Location location) {
        LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
        mMarker = mMap.addMarker(new MarkerOptions().position(loc));
        if(mMap != null){
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
        }
    }
};

然后为地图设置监听器:

mMap.setOnMyLocationChangeListener(myLocationChangeListener);

当地图首次找到位置时,将调用此函数。

完全不需要使用LocationService或LocationManager。

OnMyLocationChangeListener接口已被弃用。请使用com.google.android.gms.location.FusedLocationProviderApi代替。FusedLocationProviderApi提供了更好的位置查找和功耗使用,并被“我的位置”蓝色点使用。请参阅示例应用程序文件夹中的MyLocationDemoActivity以获取示例代码或位置开发人员指南。


好的解决方案,但在添加新标记之前,您应该先删除位置标记。每次位置更改时,谷歌地图都会添加新标记。 - Winston
现在它可以工作了,但问题是有一些延迟。 - jjLin
11
该界面已弃用。 请改用com.google.android.gms.location.FusedLocationProviderApi。 来源链接:https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationChangeListener - Eduardo

31

目前,无论在任何情况下,GoogleMap.getMyLocation()都始终返回null。

目前我知道有两个关于Google的错误报告,一个是Issue 40932,另一个是Issue 4644

实现LocationListener就像之前提到的那样是不正确的,因为在您尝试使用的新API中,LocationListener将与LocationOverlay不同步。

按照Pramod J George早些时候提供的链接到Vogella网站上的教程将为您提供有关旧版Google Maps API的说明。

因此,我很抱歉没有给您通过这种方式检索位置的方法。目前来说,locationListener可能是唯一的方法,但我相信Google正在努力修复新API中的问题。

对于没有发布更多链接,StackOverlow认为我是垃圾信息,我也很抱歉。

---- 2013年2月4日更新 ----

谷歌表示,通过Issue 4644,此问题将在下一次更新Google Maps API中得到解决。我不确定更新将何时发生,但一旦发生我将再次编辑此帖子。

---- 2013年4月10日更新 ----

谷歌表示,此问题已通过Issue 4644得到解决。现在应该可以工作了。


链接的线程有一篇帖子说这个问题已经被解决了。你可能想要更新你的回答。+1 - Lzh
我似乎仍然得到了“null”。我在“onCreate”中调用“setMyLocationEnabled(true)”,然后尝试在“onPostCreate”中获取“getMyLocation()”。 - theblang
我甚至在onPostCreate方法中得到了null。 - Pavel
@mattblang,我尝试了你说的方法,但是在onPostCreate方法中仍然得到了null - Pavel
@PavelRyzhov 是的,我想我是说当我尝试在onPostCreate中调用时仍然得到了null。问题可能是位置尚未被获取,因为这是异步发生的,并且可能需要一些时间,特别是使用GPS。 - theblang

19

试一试

LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = service.getBestProvider(criteria, false);
Location location = service.getLastKnownLocation(provider);
LatLng userLocation = new LatLng(location.getLatitude(),location.getLongitude());

2
getLastKnownLocation 可能返回 null,因此它不够可靠。 - Andrei Drynov
4
这是获取上一次已知位置,而不是当前位置。 - Gilberto Ibarra

3

请确保已在设备上开启了位置服务,否则您将无法获取任何与位置相关的信息。

这对我有用,

    map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
    map.setMyLocationEnabled(true);
    GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
        @Override
        public void onMyLocationChange (Location location) {
           LatLng loc = new LatLng (location.getLatitude(), location.getLongitude());
           map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
        }
    };
    map.setOnMyLocationChangeListener(myLocationChangeListener);

}


2
当用户点击按钮时,调用此方法以获取位置信息-。
void getCurrentLocation() {
    Location myLocation  = mMap.getMyLocation();
    if(myLocation!=null)
    {
        double dLatitude = myLocation.getLatitude();
        double dLongitude = myLocation.getLongitude();
        Log.i("APPLICATION"," : "+dLatitude);
        Log.i("APPLICATION"," : "+dLongitude);
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(dLatitude, dLongitude)).title("My Location").icon(BitmapDescriptorFactory.fromBitmap(Utils.getBitmap("pointer_icon.png"))));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));

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

}

同时确保

setMyLocationEnabled

已设置为true

尝试并查看是否有效...


5
我的位置始终为空。 - Sami
2
mMap.getMyLocation()已被弃用 - sdelvalle57

1
我刚刚发现这段代码简单而实用, 尝试一下:
public class MainActivity extends ActionBarActivity implements
    ConnectionCallbacks, OnConnectionFailedListener {
...
@Override
public void onConnected(Bundle connectionHint) {
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (mLastLocation != null) {
        mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
        mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
    }
}}

这是教程链接: 获取上次已知位置


1
尝试这个。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
    mMap.setMyLocationEnabled(true);
} else {
    // Show rationale and request permission.
}

1

很不幸,这不会通知您更新。据报道,它也出现了故障。 - Steve Pomeroy
4
更新:此方法已被弃用,请改用 com.google.android.gms.location.LocationClient。请参阅 https://developers.google.com/maps/documentation/android/location 和 http://developer.android.com/google/play-services/location.html。 - samus

0

我宁愿使用FusedLocationApi,因为OnMyLocationChangeListener已经过时了。

首先声明这3个变量:

private LocationRequest  mLocationRequest;
private GoogleApiClient  mGoogleApiClient;
private LocationListener mLocationListener;

定义方法:

private void initGoogleApiClient(Context context)
{
    mGoogleApiClient = new GoogleApiClient.Builder(context).addApi(LocationServices.API).addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks()
    {
        @Override
        public void onConnected(Bundle bundle)
        {
            mLocationRequest = LocationRequest.create();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(1000);

            setLocationListener();
        }

        @Override
        public void onConnectionSuspended(int i)
        {
            Log.i("LOG_TAG", "onConnectionSuspended");
        }
    }).build();

    if (mGoogleApiClient != null)
        mGoogleApiClient.connect();

}

private void setLocationListener()
{
    mLocationListener = new LocationListener()
    {
        @Override
        public void onLocationChanged(Location location)
        {
            String lat = String.valueOf(location.getLatitude());
            String lon = String.valueOf(location.getLongitude());
            Log.i("LOG_TAG", "Latitude = " + lat + " Longitude = " + lon);
        }
    };

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

private void removeLocationListener()
{
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mLocationListener);
}
  • initGoogleApiClient() 用于初始化 GoogleApiClient 对象
  • setLocationListener() 用于设置位置变化监听器
  • removeLocationListener() 用于移除监听器

调用 initGoogleApiClient 方法来启动代码工作 :) 不要忘记在最后移除监听器 (mLocationListener),以避免内存泄漏问题。


0

试一下

public class MyLocationListener implements LocationListener
{

 @Override

public void onLocationChanged(Location loc)
{

loc.getLatitude();

loc.getLongitude();

String Text = “My current location is: ” +

“Latitud = ” + loc.getLatitude() +

“Longitud = ” + loc.getLongitude();

Toast.makeText( getApplicationContext(),Text,   Toast.LENGTH_SHORT).show();



tvlat.setText(“”+loc.getLatitude());

tvlong.setText(“”+loc.getLongitude());

this.gpsCurrentLocation();

}

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