在android开发中地图和定位是很多软件不可或缺的内容,这些特色功能也给人们带来了很多方便。定位一般分为三种发方案:即GPS定位、Google网络定位以及基站定位。
本文分别介绍GPS定位、以及基于Google的网络Wifi定位的详细步骤,(小米手机获取位置信息locationManager.getLastKnownLocation(provider)的Location一直为空,查了资料换了种获取手机getProviders的方式就可以了)
一般来说我们实现原生定位的流程大概是:先判断有无权限》有权限启动一个LocationSrevice去获取定位》最后携带所需的定位信息返回,进行开发。
代码如下(示例):大概步骤如下,权限请求可自定义开发关键的是LocationService
/**
* 获取定位
*/
public class MyLocationManager implements LocationService.LocationCallBack {
private Activity context;
private OnLocationListener onLocationListener;
private String[] stringsLocation = new String[]{Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION};
@Override
public void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName) {
onLocationListener.OnLocation(Location_latitude, Location_longitude, province, city, area, featureName);
}
public interface OnLocationListener {
void OnLocation(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);
}
public void setOnLocationListener(OnLocationListener onLocationListener) {
this.onLocationListener = onLocationListener;
}
public MyLocationManager(@NonNull Activity context) {
this.context = context;
if (!XXPermissions.isGranted(context, stringsLocation)) {
MessageDialog codeDialog = new MessageDialog(context, "位置信息权限使用说明", "为确保你能在******内使用位置信息******,******需要获取你的位置信息权限。允许后,你可以随时通过手机系统设置对授权进行管理。", "取消", "去授权");
codeDialog.setCancelable(false);
codeDialog.show();
codeDialog.setOnSumbitTextCodeListener(() -> {
doMainPermission();
codeDialog.dismiss();
});
codeDialog.setOnCancelListener(() -> {
codeDialog.dismiss();
});
} else {
initData();
}
}
private void doMainPermission() {
XXPermissions.with(context).permission(stringsLocation).request(new OnPermissionCallback() {
@Override
public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
if (allGranted) {
initData();
}
}
@Override
public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
if (doNotAskAgain) {
}
}
});
}
@SuppressLint("MissingPermission")
private void initData() {
// 创建 Service 实例
LocationService myService = new LocationService();
// 设置回调接口
myService.setCallback(this);
// 启动 Service 并执行操作
Intent serviceIntent = new Intent(context, LocationService.class);
context.startService(serviceIntent);
}
}
/**-------------------------/
不要忘了注册
代码如下(示例):
/**
* 获取定位服务
*/
public class LocationService extends Service {
private LocationManager locationManager;
private MyLocationListener myLocationListener;
public static LocationCallBack mCallBack = null;
public interface LocationCallBack {
void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);
}
public void setCallback(LocationCallBack callback) {
this.mCallBack = callback;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressLint("MissingPermission")
@Override
public void onCreate() {
super.onCreate();
myLocationListener = new MyLocationListener();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try {
GPSLocation();
} catch (Exception e) {
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
stopSelf(); // 获取到经纬度以后,停止该service
}
}
class MyLocationListener implements LocationListener {
// 位置改变时获取经纬度
@Override
public void onLocationChanged(Location location) {
if (ObjectUtils.isNotEmpty(location)) {
toGeocoder(location);
}
}
// 状态改变时
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// 提供者可以使用时
@Override
public void onProviderEnabled(String provider) {
}
// 提供者不可以使用时
@Override
public void onProviderDisabled(String provider) {
}
}
@SuppressLint("MissingPermission")
private Location getLastKnownLocation(LocationManager locationManager) {
List<String> providers = locationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = locationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = l;
}
}
return bestLocation;
}
@SuppressLint("MissingPermission")
private void GPSLocation() {
Location location = getLastKnownLocation(locationManager);
if (location != null) {
//不为空,显示地理位置经纬度
String longitude = "Longitude:" + location.getLongitude();
String latitude = "Latitude:" + location.getLatitude();
LogUtils.e("Location:" + longitude + latitude);
toGeocoder(location);
} else {
LogUtils.e("Location:" + "Location为空");
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
stopSelf(); // 获取到经纬度以后,停止该service
}
}
@SuppressLint("MissingPermission")
private void toGeocoder(Location location) {
String province = "";
String city = "";
String area = "";
String featureName = "";
try {
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (ObjectUtils.isNotEmpty(addresses) && 0 < addresses.size()) {
Address address = addresses.get(0);
if (ObjectUtils.isNotEmpty(address)) {
// 获取省份(province)
province = address.getAdminArea();
// 获取城市(City)
city = address.getLocality();
// 获取区县(area)
area = address.getSubLocality();
// 获取详细地址
featureName = address.getFeatureName();
// 获取街道地址
String addressLine = address.getAddressLine(0);
// 打印详细地址信息
LogUtils.e("AddressInfo", "province: " + province);
LogUtils.e("AddressInfo", "City: " + city);
LogUtils.e("AddressInfo", "area: " + area);
LogUtils.e("AddressInfo", "FeatureName: " + featureName);
LogUtils.e("AddressInfo", "Address Line: " + addressLine);
}
mCallBack.Location_Return(location.getLatitude(), location.getLongitude(), province, city, area, featureName);
}
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
stopSelf(); // 获取到经纬度以后,停止该service
} catch (Exception e) {
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
stopSelf(); // 获取到经纬度以后,停止该service
e.printStackTrace();
}
}
@SuppressLint("MissingPermission")
@Override
public void onDestroy() {
super.onDestroy();
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
stopSelf();
}
}
该处使用原生定位获取经纬度、省市县等数据的详细步骤。
以上就是今天要讲的使用Android原生获取定位内容,本文详细展现了完整流程,希望对大家会有帮助,公司如果有实力大可不必如此,直接给第三方地图交钱就好了,毕竟人家又快又准(本文仅仅适用于只需经纬度或者地址信息的同学,有地图展现需求的只能想别的方法了哈哈)。