如何在Google地图Android中获取当前位置

70

实际上我的问题是我无法获取当前位置的纬度和经度,我已经尝试了很多方法。我知道这个问题在SO上已经被问过了,我也尝试了那些答案,但仍然没有得到答案。请帮帮我。
代码:

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

        // check if map is created successfully or not
        if (googleMap == null) {
            Toast.makeText(getApplicationContext(),
                    "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                    .show();
        }
    }
    googleMap.setMyLocationEnabled(true);
    Location myLocation = googleMap.getMyLocation();  //Nullpointer exception.........
    LatLng myLatLng = new LatLng(myLocation.getLatitude(),
            myLocation.getLongitude());

    CameraPosition myPosition = new CameraPosition.Builder()
            .target(myLatLng).zoom(17).bearing(90).tilt(30).build();
    googleMap.animateCamera(
        CameraUpdateFactory.newCameraPosition(myPosition));

1
在这里使用 Kotlin 获取答案:https://dev59.com/QnA75IYBdhLWcg3wuLjD#53800632 - MHSaffari
18个回答

2
所有上述解决方案都使用了现已弃用的代码!这里是新的解决方案:
  1. 在您的gradle文件中添加 implementation 'com.google.android.gms:play-services-places:15.0.1' 依赖项

  2. 在您的清单文件中添加网络权限:

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

最初的回答
  1. Now use this code to get current location

      FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
      mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        // GPS location can be null if GPS is switched off
                            currentLat = location.getLatitude();
                            currentLong = location.getLongitude();
                            Toast.makeText(HomeNavigationBarActivtiy.this, "lat " + location.getLatitude() + "\nlong " + location.getLongitude(), Toast.LENGTH_SHORT).show();
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        e.printStackTrace();
                    }
                });
    

此解决方案还需要授予权限。 - CoolMind

2

来自Google示例(CurrentPlaceDetailsOnMap),使用FusedLocationProviderClientkotlin,以便setOnMyLocationChangeListener已被弃用。

首先,在dependencies中添加implementation 'com.google.android.libraries.places:places:2.4.0'

接下来,在您的fragment中添加这些变量

private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private var lastKnownLocation: Location? = null

onViewCreated 中添加以下内容:

next in

    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext())

onMapReady方法中调用此方法。
private fun getDeviceLocation() {
    /*
     * Get the best and most recent location of the device, which may be null in rare
     * cases when a location is not available.
     */
    try {
            val locationResult = fusedLocationProviderClient.lastLocation
            locationResult.addOnCompleteListener(context as Activity) { task ->
                if (task.isSuccessful) {
                    // Set the map's camera position to the current location of the device.
                    lastKnownLocation = task.result
                    if (lastKnownLocation != null) {
                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                LatLng(lastKnownLocation!!.latitude,
                                        lastKnownLocation!!.longitude), DEFAULT_ZOOM.toFloat()))
                    }
                } else {
                    logD("Current location is null. Using defaults.")
                    logD("Exception: ${task.exception}")
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(35.6892, 51.3890), 15.toFloat()))
                    mMap.uiSettings?.isMyLocationButtonEnabled = false
                }
            }
    } catch (e: SecurityException) {
        logD("Exception: ${e.message}")
    }
}

如果lastKnownLocation为空,你应该使用这个方法来更新它:
fun requestLocation(context: Context) {
        val mLocationRequest = LocationRequest.create()
        mLocationRequest.interval = 60000
        mLocationRequest.fastestInterval = 5000
        mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        val mLocationCallback: LocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                for (location in locationResult.locations) {
                    if (location != null && lastKnownLocation == null) {
                        lastKnownLocation = location
                    }
                }
            }
        }
        LocationServices.getFusedLocationProviderClient(context)
            .requestLocationUpdates(mLocationRequest, mLocationCallback, null)
    }

如果您愿意,您可以通过这种方式打开您的位置

mMap.isMyLocationEnabled = true
mMap.uiSettings.isMyLocationButtonEnabled = false

1
//check this condition if (Build.VERSION.SDK_INT < 23 ) 

在某些Android Studio中,虽然整个代码可以工作,但这一行却不起作用,因此请将其替换为以下内容:

if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 

我的项目正常运行。

1

在谷歌地图上获取当前位置的简单步骤:

1 - 创建地图活动,所以在onMap准备方法中创建LocationManager和LocationListener

2 - 在onMap准备中还要检查Android版本和用户权限 ==> 如果有权限,则提供位置更新或请求用户授权

3 - 在主类中检查权限结果(onRequestPermissionsResult)==>如果条件为真,则提供位置更新

4 - 在(onLocationChanged)方法中,我们创建LatLng变量,并从位置获取坐标,然后从mMap中(addMarker and moveCamera)为刚刚创建的变量,这样当用户移动时,我们就可以得到位置,所以我们仍然需要在onMap ready中创建新的LatLng,以便在应用程序启动时拥有用户的位置 ==>如果有权限(lastKnownLocation)。

注意:

1)不要忘记在清单中请求权限(位置和互联网)

2)不要忘记从Google APIs获取地图密钥

3)我们使用(mMap.clear)来避免每次(运行应用程序或更新位置)重复标记

编程部分

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    LocationManager locationManager;
    LocationListener locationListener;

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

        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
            }
        }
    }

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


    }

    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        locationManager  = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {

                mMap.clear();

                LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());

                mMap.addMarker(new MarkerOptions().position(userLocation).title("Marker"));

                mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));

                Toast.makeText(MapsActivity.this, userLocation.toString(), Toast.LENGTH_SHORT).show();
            }

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


            }

            @Override
            public void onProviderEnabled(String provider) {

            }

            @Override
            public void onProviderDisabled(String provider) {

            }


        };

        if (Build.VERSION.SDK_INT < 23 ){

            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

        }else if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

            Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            LatLng userLocation = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());

            mMap.clear();

            mMap.addMarker(new MarkerOptions().position(userLocation).title("Marker"));

            mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));

            Toast.makeText(MapsActivity.this, userLocation.toString(), Toast.LENGTH_SHORT).show();


        } else {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

        }


    }


    }
}

1
请在应用清单中添加权限
请将以下其中一项权限作为 Android 清单中元素的子级。可以选择粗略位置权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  ...
</manifest>

或者是精确位置权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  ...
</manifest>

以下代码示例在启用“我的位置”图层之前,使用支持库检查权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
    mMap.setMyLocationEnabled(true);
} else {
    // Show rationale and request permission.
}
The following sample handles the result of the permission request by implementing the ActivityCompat.OnRequestPermissionsResultCallback from the Support library:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == MY_LOCATION_REQUEST_CODE) {
      if (permissions.length == 1 &&
          permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION &&
          grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        mMap.setMyLocationEnabled(true);
    } else {
      // Permission was denied. Display an error message.
    }
}

这个示例使用GPS提供程序提供当前位置更新。整个Android应用程序代码如下所示:

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.widget.TextView;

import android.util.Log;

public class MainActivity extends Activity implements LocationListener{
protected LocationManager locationManager;
protected LocationListener locationListener;
protected Context context;
TextView txtLat;
String lat;
String provider;
protected String latitude,longitude; 
protected boolean gps_enabled,network_enabled;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtLat = (TextView) findViewById(R.id.textview1);

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
@Override
public void onLocationChanged(Location location) {
txtLat = (TextView) findViewById(R.id.textview1);
txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
}

@Override
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}

@Override
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
}

1
         import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationListener;
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.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnSuccessListener;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {

    private GoogleMap mMap;
    private FusedLocationProviderClient client;
    double latit;
    double longi;

    @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.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        client = LocationServices.getFusedLocationProviderClient(this);
    }
@RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;



        try {
            setupMap();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
 client = LocationServices.getFusedLocationProviderClient(this);

        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;
        }
        client.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) {

                            //    local=findViewById(R.id.tv5);

                            double la=location.getLatitude();
                            double lo=location.getLongitude();

                            LatLng curre=new LatLng(la,lo);
                            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curre,18));

                        }
                    }
                });



    }
    }

1
你能否解释一下这个答案,让它不只是一大块代码? - Ari Cooper-Davis

0
为什么不使用 FusedLocationApi 而选择 OnMyLocationChangeListener? 您需要初始化 GoogleApiClient 对象并使用 LocationServices.FusedLocationApi.requestLocationUpdates() 方法来注册位置更改侦听器。 需要注意的是,不要忘记移除已注册的侦听器并断开 GoogleApiClient 的连接。
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);
}

-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()));
    }
}
}

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