如何在Android中获取移动设备的纬度和经度?

如何在Android中使用定位工具获取移动设备的当前纬度和经度?

338208 次浏览

使用LocationManager

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();

getLastKnownLocation()的调用不会阻塞-这意味着如果当前没有可用的位置,它将返回null-因此,您可能希望将LocationListener传递给requestLocationUpdates(),这将为您提供位置的异步更新。

private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
}
}


lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);

如果要使用GPS,您需要为应用程序提供ACCESS_FINE_LOCATION权限

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

当GPS不可用时,您可能还需要添加ACCESS_COARSE_LOCATION权限,并使用getBestProvider()选择您的位置提供商。

这里是类LocationFinder,用于查找GPS位置。这个类将调用MyLocation,它将执行业务。

位置查找器

public class LocationFinder extends Activity {


int increment = 4;
MyLocation myLocation = new MyLocation();


// private ProgressDialog dialog;


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intermediat);
myLocation.getLocation(getApplicationContext(), locationResult);


boolean r = myLocation.getLocation(getApplicationContext(),
locationResult);


startActivity(new Intent(LocationFinder.this,
// Nearbyhotelfinder.class));
GPSMyListView.class));
finish();
}


public LocationResult locationResult = new LocationResult() {


@Override
public void gotLocation(Location location) {
// TODO Auto-generated method stub
double Longitude = location.getLongitude();
double Latitude = location.getLatitude();


Toast.makeText(getApplicationContext(), "Got Location",
Toast.LENGTH_LONG).show();


try {
SharedPreferences locationpref = getApplication()
.getSharedPreferences("location", MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = locationpref.edit();
prefsEditor.putString("Longitude", Longitude + "");
prefsEditor.putString("Latitude", Latitude + "");
prefsEditor.commit();
System.out.println("SHARE PREFERENCE ME PUT KAR DIYA.");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};


// handler for the background updating


}

我的位置

public class MyLocation {


Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;


public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);


//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}


//Toast.makeText(context, gps_enabled+" "+network_enabled,     Toast.LENGTH_LONG).show();


//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;


if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();




timer1.schedule(new GetLastLocation(), 10000);
//    Toast.makeText(context, " Yaha Tak AAya", Toast.LENGTH_LONG).show();
return true;
}


LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};


LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};


class GetLastLocation extends TimerTask {
@Override


public void run() {


//Context context = getClass().getgetApplicationContext();
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);


//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}


if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}


public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}

上述解决方案也是正确的,但有时如果位置为空,则会使应用程序崩溃或无法正常工作。获取Android经度和纬度的最佳方法是:

 Geocoder geocoder;
String bestProvider;
List<Address> user = null;
double lat;
double lng;


LocationManager lm = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);


Criteria criteria = new Criteria();
bestProvider = lm.getBestProvider(criteria, false);
Location location = lm.getLastKnownLocation(bestProvider);


if (location == null){
Toast.makeText(activity,"Location Not found",Toast.LENGTH_LONG).show();
}else{
geocoder = new Geocoder(activity);
try {
user = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
lat=(double)user.get(0).getLatitude();
lng=(double)user.get(0).getLongitude();
System.out.println(" DDD lat: " +lat+",  longitude: "+lng);


}catch (Exception e) {
e.printStackTrace();
}
}

你可以用这个得到当前的LATLNG

`

  public class MainActivity extends ActionBarActivity {
private LocationManager locationManager;
private String provider;
private MyLocationListener mylistener;
private Criteria criteria;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);




locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);   //default


// user defines the criteria


criteria.setCostAllowed(false);
// get the best provider depending on the criteria
provider = locationManager.getBestProvider(criteria, false);


// the last known location of this provider
Location location = locationManager.getLastKnownLocation(provider);


mylistener = new MyLocationListener();


if (location != null) {
mylistener.onLocationChanged(location);
} else {
// leads to the settings because there is no last known location
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// location updates: at least 1 meter and 200millsecs change
locationManager.requestLocationUpdates(provider, 200, 1, mylistener);
String a=""+location.getLatitude();
Toast.makeText(getApplicationContext(), a, 222).show();


}


private class MyLocationListener implements LocationListener {


@Override
public void onLocationChanged(Location location) {
// Initialize the location fields






Toast.makeText(MainActivity.this,  ""+location.getLatitude()+location.getLongitude(),
Toast.LENGTH_SHORT).show()


}


@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Toast.makeText(MainActivity.this, provider + "'s status changed to "+status +"!",
Toast.LENGTH_SHORT).show();
}


@Override
public void onProviderEnabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " enabled!",
Toast.LENGTH_SHORT).show();


}


@Override
public void onProviderDisabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " disabled!",
Toast.LENGTH_SHORT).show();
}
}

`

对于google,事情经常发生变化:以前的答案对我都不起作用。

根据这个谷歌培训,下面介绍如何使用

融合位置提供程序

这需要设置Google Play服务

活动课

public class GPSTrackerActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {


private GoogleApiClient mGoogleApiClient;
Location mLastLocation;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}


}


protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}


protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}


@Override
public void onConnected(Bundle bundle) {
try {


mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Intent intent = new Intent();
intent.putExtra("Longitude", mLastLocation.getLongitude());
intent.putExtra("Latitude", mLastLocation.getLatitude());
setResult(1,intent);
finish();


}
} catch (SecurityException e) {


}


}


@Override
public void onConnectionSuspended(int i) {


}


@Override
public void onConnectionFailed(ConnectionResult connectionResult) {


}
}

使用

在你的活动中

 Intent intent = new Intent(context, GPSTrackerActivity.class);
startActivityForResult(intent,1);

还有这个方法

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){
Bundle extras = data.getExtras();
Double longitude = extras.getDouble("Longitude");
Double latitude = extras.getDouble("Latitude");
}
}

最好的办法是

添加权限清单文件

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

然后,您可以获取GPS位置,或者如果GPS位置不可用,则此函数返回网络位置

    public static Location getLocationWithCheckNetworkAndGPS(Context mContext) {
LocationManager lm = (LocationManager)
mContext.getSystemService(Context.LOCATION_SERVICE);
assert lm != null;
isGpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkLocationEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);


Location networkLoacation = null, gpsLocation = null, finalLoc = null;
if (isGpsEnabled)
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {


return null;
}gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (isNetworkLocationEnabled)
networkLoacation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);


if (gpsLocation != null && networkLoacation != null) {


//smaller the number more accurate result will
if (gpsLocation.getAccuracy() > networkLoacation.getAccuracy())
return finalLoc = networkLoacation;
else
return finalLoc = gpsLocation;


} else {


if (gpsLocation != null) {
return finalLoc = gpsLocation;
} else if (networkLoacation != null) {
return finalLoc = networkLoacation;
}
}
return finalLoc;
}

您可以使用FusedLocationProvider

要在您的项目中使用融合位置提供程序,您必须在我们的应用程序级别构建.gradle文件中添加Google Play服务位置依赖项

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
...
...
implementation 'com.google.android.gms:play-services-location:17.0.0'
}

清单中的权限

使用定位服务的应用必须请求定位权限。Android提供两种位置权限:访问_粗略_位置访问_精细_位置

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

正如你可能知道的,在Android 6.0(棉花糖)中,你必须在运行时请求重要访问的权限。因为这是一个安全问题,在安装应用程序时,用户可能不清楚其设备的重要权限。

ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_ID
)

然后,您可以使用FusedLocationProvider客户端获取所需位置的更新位置。

    mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
var location: Location? = task.result
if (location == null) {
requestNewLocationData()
} else {
findViewById<TextView>(R.id.latTextView).text = location.latitude.toString()
findViewById<TextView>(R.id.lonTextView).text = location.longitude.toString()
}
}

您还可以检查某些配置,如设备是否打开了位置设置。您还可以查看有关检测当前纬度&;经度在Android中使用Kotlin的文章,以了解更多功能。 如果没有缓存位置,则它将使用以下

命令捕获当前位置:
private fun requestNewLocationData() {
var mLocationRequest = LocationRequest()
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationRequest.interval = 0
mLocationRequest.fastestInterval = 0
mLocationRequest.numUpdates = 1


mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
)
}

即插即用位置管理器,既可用于基于XML的项目,也可用于Jetpack Compose项目(个人在JetpackCompose中使用)

class LocationManager(context: Context): LocationCallback() {


val context = context
var publicCompletion: ((Double, Double) -> Unit)? = null


var fusedLocationProviderClient = FusedLocationProviderClient(
context
)


fun requestLocationPermission() {
val activity = context as Activity?
ActivityCompat.requestPermissions(
activity!!,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION
),
101
)
}


fun checkIfLocationPermissionIsGranted(): Boolean {
return (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
)
}


fun getLatitudeLongitude(completion: (Double, Double) -> Unit) {
publicCompletion = { latitude, longitude ->
completion(latitude, longitude)
}


if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
val activity = context as Activity?
fusedLocationProviderClient.lastLocation.addOnCompleteListener(activity!!) { task ->
var location: Location? = task.result
if (location != null) {
publicCompletion?.let { it(location!!.latitude, location!!.longitude) }
} else {
requestLocationUpdates()
}
}
}
}


fun requestLocationUpdates() {
var request = LocationRequest()
request.priority = com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCURACY
request.fastestInterval = 0
request.numUpdates = 1


if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProviderClient.requestLocationUpdates(
request, this, Looper.myLooper()
)
}
}


override fun onLocationResult(p0: LocationResult?) {
super.onLocationResult(p0)


publicCompletion?.let { it(p0!!.lastLocation!!.latitude, p0!!.lastLocation!!.longitude) }
}


override fun onLocationAvailability(p0: LocationAvailability?) {
super.onLocationAvailability(p0)
}
}