Android通過(guò)原生方式獲取經(jīng)緯度與城市信息的方法
一、概述
在項(xiàng)目中需要獲取用戶所在位置的經(jīng)緯度和城市上送給風(fēng)控系統(tǒng)。一般來(lái)說(shuō),定位有兩種方式:
- 用第三方SDK定位,如百度地圖、高德地圖、谷歌地圖;
- 用Android原生SDK中的api定位;
本文講述定位的第二種方式--用Android原生的SDK中的api定位,如果項(xiàng)目定位要求較高還是建議使用第三方地圖庫(kù)。
二、Android原生SDK中的api定位
Android原生方式獲取經(jīng)緯度兩種定位方式:GPS定位和Wifi定位
- GPS定位相比Wifi定位更精準(zhǔn)且可在無(wú)網(wǎng)絡(luò)情況下使用,但在室內(nèi)基本暴斃無(wú)法使用。
- WiFi定位沒(méi)有室內(nèi)外限制,也不需要開(kāi)啟GPS但需要聯(lián)網(wǎng)。但測(cè)試發(fā)現(xiàn)WiFi定位時(shí)onLocationChanged函數(shù)(用于監(jiān)聽(tīng)經(jīng)緯度變化)觸發(fā)間隔無(wú)法小于30s。
示例代碼如下:
public class TestLocationActivity extends AppCompatActivity {
public static final int LOCATION_CODE = 301;
private LocationManager locationManager;
private String locationProvider = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLocation();
}
private void getLocation(){
//1.獲取位置管理器
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//2.獲取位置提供器,GPS或是NetWork
List<String> providers = locationManager.getProviders(true);
if (providers.contains(LocationManager.GPS_PROVIDER)) {
//如果是GPS
locationProvider = LocationManager.GPS_PROVIDER;
Log.v("TAG", "定位方式GPS");
} else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//如果是Network
locationProvider = LocationManager.NETWORK_PROVIDER;
Log.v("TAG", "定位方式Network");
}else {
Toast.makeText(this, "沒(méi)有可用的位置提供器", Toast.LENGTH_SHORT).show();
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//獲取權(quán)限(如果沒(méi)有開(kāi)啟權(quán)限,會(huì)彈出對(duì)話框,詢問(wèn)是否開(kāi)啟權(quán)限)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//請(qǐng)求權(quán)限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_CODE);
} else {
//3.獲取上次的位置,一般第一次運(yùn)行,此值為null
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location!=null){
Toast.makeText(this, location.getLongitude() + " " +
location.getLatitude() + "",Toast.LENGTH_SHORT).show();
Log.v("TAG", "獲取上次的位置-經(jīng)緯度:"+location.getLongitude()+" "+location.getLatitude());
getAddress(location);
}else{
//監(jiān)視地理位置變化,第二個(gè)和第三個(gè)參數(shù)分別為更新的最短時(shí)間minTime和最短距離minDistace
locationManager.requestLocationUpdates(locationProvider, 3000, 1,locationListener);
}
}
} else {
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location!=null){
Toast.makeText(this, location.getLongitude() + " " +
location.getLatitude() + "", Toast.LENGTH_SHORT).show();
Log.v("TAG", "獲取上次的位置-經(jīng)緯度:"+location.getLongitude()+" "+location.getLatitude());
getAddress(location);
}else{
//監(jiān)視地理位置變化,第二個(gè)和第三個(gè)參數(shù)分別為更新的最短時(shí)間minTime和最短距離minDistace
locationManager.requestLocationUpdates(locationProvider, 3000, 1,locationListener);
}
}
}
public LocationListener locationListener = new LocationListener() {
// Provider的狀態(tài)在可用、暫時(shí)不可用和無(wú)服務(wù)三個(gè)狀態(tài)直接切換時(shí)觸發(fā)此函數(shù)
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// Provider被enable時(shí)觸發(fā)此函數(shù),比如GPS被打開(kāi)
@Override
public void onProviderEnabled(String provider) {
}
// Provider被disable時(shí)觸發(fā)此函數(shù),比如GPS被關(guān)閉
@Override
public void onProviderDisabled(String provider) {
}
//當(dāng)坐標(biāo)改變時(shí)觸發(fā)此函數(shù),如果Provider傳進(jìn)相同的坐標(biāo),它就不會(huì)被觸發(fā)
@Override
public void onLocationChanged(Location location) {
if (location != null) {
//如果位置發(fā)生變化,重新顯示地理位置經(jīng)緯度
Toast.makeText(TestLocationActivity.this, location.getLongitude() + " " +
location.getLatitude() + "", Toast.LENGTH_SHORT).show();
Log.v("TAG", "監(jiān)視地理位置變化-經(jīng)緯度:"+location.getLongitude()+" "+location.getLatitude());
}
}
};
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case LOCATION_CODE:
if(grantResults.length > 0 && grantResults[0] == getPackageManager().PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "申請(qǐng)權(quán)限", Toast.LENGTH_LONG).show();
try {
List<String> providers = locationManager.getProviders(true);
if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//如果是Network
locationProvider = LocationManager.NETWORK_PROVIDER;
}else if (providers.contains(LocationManager.GPS_PROVIDER)) {
//如果是GPS
locationProvider = LocationManager.GPS_PROVIDER;
}
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location!=null){
Toast.makeText(this, location.getLongitude() + " " +
location.getLatitude() + "", Toast.LENGTH_SHORT).show();
Log.v("TAG", "獲取上次的位置-經(jīng)緯度:"+location.getLongitude()+" "+location.getLatitude());
}else{
// 監(jiān)視地理位置變化,第二個(gè)和第三個(gè)參數(shù)分別為更新的最短時(shí)間minTime和最短距離minDistace
locationManager.requestLocationUpdates(locationProvider, 0, 0,locationListener);
}
}catch (SecurityException e){
e.printStackTrace();
}
} else {
Toast.makeText(this, "缺少權(quán)限", Toast.LENGTH_LONG).show();
finish();
}
break;
}
}
//獲取地址信息:城市、街道等信息
private List<Address> getAddress(Location location) {
List<Address> result = null;
try {
if (location != null) {
Geocoder gc = new Geocoder(this, Locale.getDefault());
result = gc.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
Toast.makeText(this, "獲取地址信息:"+result.toString(), Toast.LENGTH_LONG).show();
Log.v("TAG", "獲取地址信息:"+result.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onDestroy() {
super.onDestroy();
locationManager.removeUpdates(locationListener);
}
}
在AndroidManifest.xml加權(quán)限
<!-- 粗略的位置權(quán)限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!-- 精確的位置權(quán)限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission>
三、總結(jié)
首先將手機(jī)定位服務(wù)設(shè)置,調(diào)到下圖所示:

這可能會(huì)獲取不到經(jīng)緯度。為什么在網(wǎng)絡(luò)和GPS都可用的情況下只執(zhí)行GPS而不是網(wǎng)絡(luò)?也許是從精確度考慮的,但是走GPS進(jìn)入監(jiān)聽(tīng)的listener后,不會(huì)執(zhí)行onLocationChanged()方法,因?yàn)槲沂窃谑覂?nèi),沒(méi)有移動(dòng),所以如果你獲取不到經(jīng)緯度,就要將定位服務(wù)調(diào)到僅使用網(wǎng)絡(luò)定位或者關(guān)閉手機(jī)GPS這樣就可以獲取到了。

總結(jié)
到此這篇關(guān)于Android通過(guò)原生方式獲取經(jīng)緯度與城市信息的文章就介紹到這了,更多相關(guān)Android原生獲取經(jīng)緯度與城市信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android GPS獲取當(dāng)前經(jīng)緯度坐標(biāo)
- Android通過(guò)原生APi獲取所在位置的經(jīng)緯度
- Android編程實(shí)現(xiàn)根據(jù)經(jīng)緯度查詢地址并對(duì)獲取的json數(shù)據(jù)進(jìn)行解析的方法
- Android獲取當(dāng)前位置的經(jīng)緯度數(shù)據(jù)
- android通過(guò)gps獲取定位的位置數(shù)據(jù)和gps經(jīng)緯度
- Android獲取經(jīng)緯度計(jì)算距離介紹
- Android 通過(guò)當(dāng)前經(jīng)緯度獲得城市的實(shí)例代碼
- android手機(jī)獲取gps和基站的經(jīng)緯度地址實(shí)現(xiàn)代碼
- Android獲取經(jīng)緯度的完美解決方案
相關(guān)文章
解決Android解析圖片的OOM問(wèn)題的方法!!!
我們?cè)诰帉?xiě)Android程序的時(shí)候經(jīng)常要用到許多圖片,不同圖片總是會(huì)有不同的形狀、不同的大小,程序占用了過(guò)高的內(nèi)存就容易出現(xiàn)OOM(OutOfMemory)異常。本篇文章主要講訴了解決Android解析圖片的OOM問(wèn)題,有興趣的可以了解一下。2016-11-11
Android MarkTipsView文字標(biāo)識(shí)控件使用方法
這篇文章主要為大家詳細(xì)介紹了Android MarkTipsView文字標(biāo)識(shí)控件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
Android實(shí)現(xiàn)隱藏狀態(tài)欄和標(biāo)題欄
這篇文章主要介紹了Android實(shí)現(xiàn)隱藏狀態(tài)欄和標(biāo)題欄的相關(guān)資料,需要的朋友可以參考下2015-06-06
淺析android studio3.5中使用recycleview的包
這篇文章主要介紹了android studio3.5中使用recycleview的包,本文雖然內(nèi)容不長(zhǎng),但是給出了思路,需要的朋友可以參考下2019-11-11
Android實(shí)現(xiàn)老虎機(jī)小游戲代碼示例
大家好,本篇文章主要講的是Android實(shí)現(xiàn)老虎機(jī)小游戲代碼示例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Android手勢(shì)操作簡(jiǎn)單實(shí)例講解
這篇文章主要為大家詳細(xì)介紹了Android手勢(shì)操作簡(jiǎn)單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Flutter應(yīng)用框架運(yùn)行微信小程序方法
這篇文章主要介紹了在Flutter?App內(nèi)運(yùn)行微信小程序的過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-02-02

