Android原生方式獲取經(jīng)緯度和城市信息

一、概述

在項(xiàng)目中需要獲取用戶(hù)所在位置的經(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ì)話框,詢(xún)問(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這樣就可以獲取到了剧蚣。

一點(diǎn)題外話:

我們有《Android學(xué)習(xí)、面試旋廷;文檔鸠按、視頻資源免費(fèi)獲取》,可復(fù)制鏈接后用石墨文檔 App 或小程序打開(kāi)鏈接或者私信我資料領(lǐng)取饶碘。

https://shimo.im/docs/TG8PDh9D96WGTT8W

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末目尖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扎运,更是在濱河造成了極大的恐慌瑟曲,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豪治,死亡現(xiàn)場(chǎng)離奇詭異测蹲,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鬼吵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)扣甲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人齿椅,你說(shuō)我怎么就攤上這事琉挖。” “怎么了涣脚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵示辈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我遣蚀,道長(zhǎng)矾麻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任芭梯,我火速辦了婚禮险耀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玖喘。我一直安慰自己甩牺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布累奈。 她就那樣靜靜地躺著贬派,像睡著了一般急但。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搞乏,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天波桩,我揣著相機(jī)與錄音,去河邊找鬼请敦。 笑死镐躲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冬三。 我是一名探鬼主播匀油,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勾笆!你這毒婦竟也來(lái)了敌蚜?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤窝爪,失蹤者是張志新(化名)和其女友劉穎弛车,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蒲每,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纷跛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了邀杏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贫奠。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖望蜡,靈堂內(nèi)的尸體忽然破棺而出唤崭,到底是詐尸還是另有隱情,我是刑警寧澤脖律,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布谢肾,位于F島的核電站,受9級(jí)特大地震影響小泉,放射性物質(zhì)發(fā)生泄漏芦疏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一微姊、第九天 我趴在偏房一處隱蔽的房頂上張望酸茴。 院中可真熱鬧,春花似錦柒桑、人聲如沸弊决。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)飘诗。三九已至,卻和暖如春界逛,著一層夾襖步出監(jiān)牢的瞬間昆稿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工息拜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溉潭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓少欺,卻偏偏與公主長(zhǎng)得像喳瓣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赞别,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容