Android 手机app三种方法获取定位地址(自带API,外接SDK,获取外网IP)

一、手机App定位在我看来有三种方法:
1.通过Android自带的API:LocationManager获取到经纬度,再通过Geocoder反地理位置查询到所在的地址。
2.外接SDK,如高德SDK,百度SDK直接获得到经纬度和地址
3.通过外部接口获取到外网IP,再通过百度API或者聚合数据的API得出地址
1、Android自带API,它有三种定位方式可以通过GPS,网络和WIFI定位。

1.1步骤:

a.清单文件中配置权限:

  1. <uses-permission android:name='android.permission.ACCESS_WIFI_STATE' />
  2. <uses-permission android:name='android.permission.INTERNET' />
  3. <uses-permission android:name='android.permission.ACCESS_NETWORK_STATE' />
  4. <!--危险-->
  5. <uses-permission android:name='android.permission.ACCESS_COARSE_LOCATION' />
  6. <uses-permission android:name='android.permission.ACCESS_FINE_LOCATION' />

b.定位util(从stackoverflow扒来的~顺带改了下)

  1. package co.chexiao.itwarehouse.util;
  2. import android.Manifest;
  3. import android.content.Context;
  4. import android.content.pm.PackageManager;
  5. import android.location.Location;
  6. import android.location.LocationListener;
  7. import android.location.LocationManager;
  8. import android.os.Bundle;
  9. import android.support.v4.app.ActivityCompat;
  10. import java.util.Timer;
  11. import java.util.TimerTask;
  12. import co.chexiao.itwarehouse.app.App;
  13. /**
  14. * Author: xx
  15. * Time:2018/4/23 19:37.
  16. * Description:stackoverflower上的定位
  17. */
  18. public class MyLocation {
  19. Timer timer1;
  20. LocationManager lm;
  21. LocationResult locationResult;
  22. boolean gps_enabled = false;
  23. boolean network_enabled = false;
  24. boolean passive_enabled = false;
  25. public boolean getLocation(Context context, LocationResult result) {
  26. // I use LocationResult callback class to pass location value from MyLocation to user code.
  27. locationResult = result;
  28. if (lm == null)
  29. lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
  30. //是否可用
  31. try {
  32. gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
  33. } catch (Exception ex) {
  34. }
  35. try {
  36. network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
  37. } catch (Exception ex) {
  38. }
  39. try {
  40. passive_enabled = lm.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
  41. } catch (Exception ex) {
  42. }
  43. //如果gps和网络还有wifi不行就不开监听
  44. if (!gps_enabled && !network_enabled&& !passive_enabled)
  45. return false;
  46. //压制警告
  47. if (ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  48. && ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  49. return true;
  50. }
  51. if (gps_enabled)
  52. lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
  53. if(network_enabled)
  54. lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
  55. if(passive_enabled)
  56. lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, locationListenerpassive);
  57. timer1=new Timer();
  58. timer1.schedule(new GetLastLocation(), 20000);
  59. return true;
  60. }
  61. //关闭定位
  62. public void cancelTimer() {
  63. timer1.cancel();
  64. lm.removeUpdates(locationListenerGps);
  65. lm.removeUpdates(locationListenerNetwork);
  66. lm.removeUpdates(locationListenerpassive);
  67. }
  68. LocationListener locationListenerGps = new LocationListener() {
  69. public void onLocationChanged(Location location) {
  70. timer1.cancel();
  71. locationResult.gotLocation(location);
  72. lm.removeUpdates(this);
  73. lm.removeUpdates(locationListenerNetwork);
  74. lm.removeUpdates(locationListenerpassive);
  75. }
  76. public void onProviderDisabled(String provider) {}
  77. public void onProviderEnabled(String provider) {}
  78. public void onStatusChanged(String provider, int status, Bundle extras) {}
  79. };
  80. LocationListener locationListenerNetwork = new LocationListener() {
  81. public void onLocationChanged(Location location) {
  82. timer1.cancel();
  83. locationResult.gotLocation(location);
  84. lm.removeUpdates(this);
  85. lm.removeUpdates(locationListenerGps);
  86. lm.removeUpdates(locationListenerpassive);
  87. }
  88. public void onProviderDisabled(String provider) {}
  89. public void onProviderEnabled(String provider) {}
  90. public void onStatusChanged(String provider, int status, Bundle extras) {}
  91. };
  92. LocationListener locationListenerpassive = new LocationListener() {
  93. public void onLocationChanged(Location location) {
  94. timer1.cancel();
  95. locationResult.gotLocation(location);
  96. lm.removeUpdates(this);
  97. lm.removeUpdates(locationListenerGps);
  98. lm.removeUpdates(locationListenerNetwork);
  99. }
  100. public void onProviderDisabled(String provider) {}
  101. public void onProviderEnabled(String provider) {}
  102. public void onStatusChanged(String provider, int status, Bundle extras) {}
  103. };
  104. class GetLastLocation extends TimerTask {
  105. @Override
  106. public void run() {
  107. lm.removeUpdates(locationListenerGps);
  108. lm.removeUpdates(locationListenerNetwork);
  109. lm.removeUpdates(locationListenerpassive);
  110. Location net_loc=null, gps_loc=null,passive_loc=null;
  111. //压制警告
  112. if (ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  113. && ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  114. return;
  115. }
  116. if(gps_enabled)
  117. gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
  118. if(network_enabled)
  119. net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
  120. if(passive_enabled)
  121. passive_loc=lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
  122. //使用最近的一条
  123. if(gps_loc!=null && net_loc!=null&&passive_loc!=null){
  124. if(gps_loc.getTime()>net_loc.getTime()&&gps_loc.getTime()>passive_loc.getTime()){
  125. locationResult.gotLocation(gps_loc);
  126. } else if (net_loc.getTime()>gps_loc.getTime()&&net_loc.getTime()>passive_loc.getTime()){
  127. locationResult.gotLocation(net_loc);
  128. }else {
  129. locationResult.gotLocation(passive_loc);
  130. }
  131. return;
  132. }
  133. if(gps_loc!=null){
  134. locationResult.gotLocation(gps_loc);
  135. return;
  136. }
  137. if(net_loc!=null){
  138. locationResult.gotLocation(net_loc);
  139. return;
  140. }
  141. if(passive_loc!=null){
  142. locationResult.gotLocation(passive_loc);
  143. return;
  144. }
  145. locationResult.gotLocation(null);
  146. }
  147. }
  148. public static abstract class LocationResult{
  149. public abstract void gotLocation(Location location);
  150. }
  151. }
c.申请权限获取到经纬度
  1. private void requirePermission() {
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  3. if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  4. && ActivityCompat.checkSelfPermission(MyApplication.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  5. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION},
  6. MY_PERMISSIONS_REQUEST_CALL_PHONE);
  7. }else{
  8. MyLocation.LocationResult locationResult = new MyLocation.LocationResult(){
  9. @Override
  10. public void gotLocation(Location location){
  11. setLocation(location);
  12. }
  13. };
  14. MyLocation myLocation = new MyLocation();
  15. myLocation.getLocation(MainActivity.this, locationResult);
  16. }
  17. }
  18. }
  19. @Override
  20. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  21. if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE){
  22. for (int i = 0; i < grantResults.length; i++) {
  23. if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
  24. //判断是否勾选禁止后不再询问
  25. boolean showRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permissions[i]);
  26. if (showRequestPermission) {
  27. MyToast.showToast('权限未申请');
  28. }
  29. }else {
  30. MyLocation.LocationResult locationResult = new MyLocation.LocationResult(){
  31. @Override
  32. public void gotLocation(Location location){
  33. setLocation(location);
  34. }
  35. };
  36. MyLocation myLocation = new MyLocation();
  37. myLocation.getLocation(MainActivity.this, locationResult);
  38. }
  39. }
  40. }
  41. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  42. }

d.将经纬度查询到地址

  1. private void setLocation(Location location) {
  2. if (location!=null) {
  3. String mfeatureName = null;
  4. Geocoder geocoder = new Geocoder(MainActivity.this);
  5. List<Address> addList = null;// 解析经纬度
  6. try {
  7. addList = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. }
  11. if (addList != null && addList.size() > 0) {
  12. for (int i = 0; i < addList.size(); i++) {
  13. Address add = addList.get(i);
  14. mfeatureName = add.getFeatureName();
  15. tvLocaiton.setText(mfeatureName);
  16. }
  17. }
  18. }
  19. }

e.关闭定时器

myLocation.cancelTimer();
1.2评价:精确度较强,稳定性一般,300行代码搞定,对app体积影响较小,基本满足普通用户的需求。

2、外接sdk

2.1步骤:自己去高德sdk,百度sdk官网接入吧,文档都写的很好。
2.2评价:精确度强,稳定性强,因为需要导入第三方sdk,只用定位这个功能app会增加3、400k的大小,如果需要精准快速定位可以外接SDK
3.通过外部接口获取到外网ip,通过百度api或者聚合数据api将ip解析地址
3.1步骤:
a.请求下面的两个接口,将返回结果通过匹配正则表达式获取到外网IP

CMYIP

TAOBAOIP

  1. public static String getOuterNetFormCmyIP(String response) {
  2.     Pattern pattern = Pattern .compile('((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))');
  3.     Matcher matcher = pattern.matcher(response.toString());
  4.     if (matcher.find()) {
  5.         String group = matcher.group(); return group;
  6.     }
  7.     return null;
  8. }

或者直接请求这个接口获取到IP

CHANAZ

b.获取到IP后,再通过百度API或者聚合数据API将IP解析为地址

百度API


3.2 评价:精确度差,稳定性差,代码量少,对app体积影响较小,不建议使用。

二、说点啥
以上的三种方法都是我瞎编的...哈哈哈

(0)

相关推荐