前言
在android開(kāi)發(fā)中地圖和定位是很多軟件不可或缺的內(nèi)容,這些特色功能也給人們帶來(lái)了很多方便。定位一般分為三種發(fā)方案:即GPS定位、Google網(wǎng)絡(luò)定位以及基站定位。
本文分別介紹GPS定位、以及基于Google的網(wǎng)絡(luò)Wifi定位的詳細(xì)步驟,(小米手機(jī)獲取位置信息locationManager.getLastKnownLocation(provider)的Location一直為空,查了資料換了種獲取手機(jī)getProviders的方式就可以了)
一、實(shí)現(xiàn)步驟
一般來(lái)說(shuō)我們實(shí)現(xiàn)原生定位的流程大概是:先判斷有無(wú)權(quán)限》有權(quán)限啟動(dòng)一個(gè)LocationSrevice去獲取定位》最后攜帶所需的定位信息返回,進(jìn)行開(kāi)發(fā)。
二、使用步驟
1.服務(wù)啟動(dòng)工具類(lèi)
代碼如下(示例):大概步驟如下,權(quán)限請(qǐng)求可自定義開(kāi)發(fā)關(guān)鍵的是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, "位置信息權(quán)限使用說(shuō)明", "為確保你能在******內(nèi)使用位置信息******,******需要獲取你的位置信息權(quán)限。允許后,你可以隨時(shí)通過(guò)手機(jī)系統(tǒng)設(shè)置對(duì)授權(quán)進(jìn)行管理。", "取消", "去授權(quán)");
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() {
// 創(chuàng)建 Service 實(shí)例
LocationService myService = new LocationService();
// 設(shè)置回調(diào)接口
myService.setCallback(this);
// 啟動(dòng) Service 并執(zhí)行操作
Intent serviceIntent = new Intent(context, LocationService.class);
context.startService(serviceIntent);
}
}
/**-------------------------/
不要忘了注冊(cè)
<service
android:name=".utils.LocationService"
android:enabled="true"
android:exported="false" />
2.實(shí)現(xiàn)LocationService
代碼如下(示例):
/**
* 獲取定位服務(wù)
*/
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); // 停止所有的定位服務(wù)
stopSelf(); // 獲取到經(jīng)緯度以后,停止該service
}
}
class MyLocationListener implements LocationListener {
// 位置改變時(shí)獲取經(jīng)緯度
@Override
public void onLocationChanged(Location location) {
if (ObjectUtils.isNotEmpty(location)) {
toGeocoder(location);
}
}
// 狀態(tài)改變時(shí)
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// 提供者可以使用時(shí)
@Override
public void onProviderEnabled(String provider) {
}
// 提供者不可以使用時(shí)
@Override
public void onProviderDisabled(String provider) {
}
}
/*
**系統(tǒng)內(nèi)容提供器介紹
**一共為四種方式"passive","network","fused","gps"
** "gps":GPS_PROVIDER(GNSS) GNSS HAL 接口和芯片打交道
** "network":NETWORK_PROVIDER 依賴(lài)設(shè)備廠商的具體實(shí)現(xiàn),Android 默認(rèn)實(shí)現(xiàn)依賴(lài) Google 提供的 GMS ** 實(shí)現(xiàn)國(guó)內(nèi)無(wú)法使用;一般廠商會(huì)實(shí)現(xiàn)為通過(guò)基站 / WIFI / 藍(lán)牙進(jìn)行融合定位
** "fused":調(diào)用 GMS(谷歌移動(dòng)服務(wù)) 進(jìn)行定位,國(guó)內(nèi)用不了
** "passive":使用 PassiveProvider 在系統(tǒng)位置更新時(shí)通知給應(yīng)用,分享其他 PROVIDER 的定位結(jié)果
*/
@SuppressLint("MissingPermission")
private Location getLastKnownLocation(LocationManager locationManager) {
Location bestLocation = null;
List<String> providers = locationManager.getProviders(true);
//由于國(guó)內(nèi)用不了fused 剔除他
if (providers.contains("fused")) providers.remove("fused");
//這里我們按照首字母排序,使內(nèi)容提供者調(diào)用順序?yàn)間ps network passive
Collections.sort(providers);
LogUtils.e("provider:" + GsonUtils.toJson(providers));
for (String provider : providers) {
Location location = locationManager.getLastKnownLocation(provider);
if (ObjectUtils.isEmpty(location)) {
LogUtils.e(provider + "定位服務(wù)不可用");
//執(zhí)行下一個(gè)
continue;
} else {
bestLocation = location;
LogUtils.e(provider + "定位服務(wù)成功");
//定位成功返回
break;
}
}
return bestLocation;
}
@SuppressLint("MissingPermission")
private void GPSLocation() {
Location location = getLastKnownLocation(locationManager);
if (location != null) {
//不為空,顯示地理位置經(jīng)緯度
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); // 停止所有的定位服務(wù)
stopSelf(); // 獲取到經(jīng)緯度以后,停止該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();
// 獲取區(qū)縣(area)
area = address.getSubLocality();
// 獲取詳細(xì)地址
featureName = address.getFeatureName();
// 獲取街道地址
String addressLine = address.getAddressLine(0);
// 打印詳細(xì)地址信息
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); // 停止所有的定位服務(wù)
stopSelf(); // 獲取到經(jīng)緯度以后,停止該service
} catch (Exception e) {
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服務(wù)
stopSelf(); // 獲取到經(jīng)緯度以后,停止該service
e.printStackTrace();
}
}
@SuppressLint("MissingPermission")
@Override
public void onDestroy() {
super.onDestroy();
if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
locationManager.removeUpdates(myLocationListener); // 停止所有的定位服務(wù)
stopSelf();
}
}
該處使用原生定位獲取經(jīng)緯度、省市縣等數(shù)據(jù)的詳細(xì)步驟。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-735340.html
總結(jié)
以上就是今天要講的使用Android原生獲取定位內(nèi)容,本文詳細(xì)展現(xiàn)了完整流程,希望對(duì)大家會(huì)有幫助,公司如果有實(shí)力大可不必如此,直接給第三方地圖交錢(qián)就好了,畢竟人家又快又準(zhǔn)(本文僅僅適用于只需經(jīng)緯度或者地址信息的同學(xué),有地圖展現(xiàn)需求的只能想別的方法了哈哈)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-735340.html
到了這里,關(guān)于Android 原生定位開(kāi)發(fā)(解決個(gè)別手機(jī)定位失敗問(wèn)題)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!