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

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net 一、手机 App 定位在我看来有三种方法:

  1. 通过 Android 自带的 API:LocationManager 获取到经纬度,再通过 Geocoder 反地理位置查询到所在的地址。

  2. 外接 SDK,如高德 SDK,百度 SDK 直接获得到经纬度和地址

  3. 通过外部接口获取到外网 IP, 再通过百度 API 或者聚合数据的 API 得出地址

1、Android 自带 API, 它有三种定位方式可以通过 GPS,网络和 WIFI 定位。

1.1 步骤:

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

    <uses-permission android: />
    <uses-permission android: />
    <uses-permission android: />
 
    <!--危险-->
    <uses-permission android: />
    <uses-permission android: />

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

package co.chexiao.itwarehouse.util;
 
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
 
import java.util.Timer;
import java.util.TimerTask;
 
import co.chexiao.itwarehouse.app.App;
 
/**
 * Author: xx
 * Time:2018/4/23 19:37.
 * Description:stackoverflower上的定位
 */
 
public class MyLocation {
    Timer timer1;
    LocationManager lm;
    LocationResult locationResult;
    boolean gps_enabled = false;
    boolean network_enabled = false;
    boolean passive_enabled = false;
 
    public boolean getLocation(Context context, LocationResult result) {
        // I use LocationResult callback class to pass location value from MyLocation to user code.
        locationResult = result;
        if (lm == null)
            lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
 
        //是否可用
        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
        }
        try {
            network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }
        try {
            passive_enabled = lm.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
        } catch (Exception ex) {
        }
 
        //如果gps和网络还有wifi不行就不开监听
        if (!gps_enabled && !network_enabled&& !passive_enabled)
            return false;
 
        //压制警告
        if (ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return true;
        }
 
        if (gps_enabled)
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        if(network_enabled)
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        if(passive_enabled)
            lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, locationListenerpassive);
 
        timer1=new Timer();
        timer1.schedule(new GetLastLocation(), 20000);
        return true;
    }
 
    //关闭定位
    public void cancelTimer() {
        timer1.cancel();
        lm.removeUpdates(locationListenerGps);
        lm.removeUpdates(locationListenerNetwork);
        lm.removeUpdates(locationListenerpassive);
    }
 
    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
            lm.removeUpdates(locationListenerpassive);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };
 
    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
            lm.removeUpdates(locationListenerpassive);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };
 
    LocationListener locationListenerpassive = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };
 
    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
            lm.removeUpdates(locationListenerGps);
            lm.removeUpdates(locationListenerNetwork);
            lm.removeUpdates(locationListenerpassive);
 
            Location net_loc=null, gps_loc=null,passive_loc=null;
 
            //压制警告
            if (ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(App.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            if(gps_enabled)
                gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if(network_enabled)
                net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if(passive_enabled)
                passive_loc=lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
 
            //使用最近的一条
            if(gps_loc!=null && net_loc!=null&&passive_loc!=null){
                if(gps_loc.getTime()>net_loc.getTime()&&gps_loc.getTime()>passive_loc.getTime()){
                    locationResult.gotLocation(gps_loc);
                } else if (net_loc.getTime()>gps_loc.getTime()&&net_loc.getTime()>passive_loc.getTime()){
                    locationResult.gotLocation(net_loc);
                }else {
                    locationResult.gotLocation(passive_loc);
                }
                return;
            }
 
            if(gps_loc!=null){
                locationResult.gotLocation(gps_loc);
                return;
            }
            if(net_loc!=null){
                locationResult.gotLocation(net_loc);
                return;
            }
            if(passive_loc!=null){
                locationResult.gotLocation(passive_loc);
                return;
            }
            locationResult.gotLocation(null);
        }
    }
 
    public static abstract class LocationResult{
        public abstract void gotLocation(Location location);
    }
}

c. 申请权限获取到经纬度

  private void requirePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(MyApplication.getInstance(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_CALL_PHONE);
            }else{
                MyLocation.LocationResult locationResult = new MyLocation.LocationResult(){
                    @Override
                    public void gotLocation(Location location){
                        setLocation(location);
                    }
                };
                MyLocation myLocation = new MyLocation();
                myLocation.getLocation(MainActivity.this, locationResult);
            }
        }
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE){
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    //判断是否勾选禁止后不再询问
                    boolean showRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permissions[i]);
                    if (showRequestPermission) {
                        MyToast.showToast("权限未申请");
                    }
                }else {
                    MyLocation.LocationResult locationResult = new MyLocation.LocationResult(){
                        @Override
                        public void gotLocation(Location location){
                            setLocation(location);
                        }
                    };
                    MyLocation myLocation = new MyLocation();
                    myLocation.getLocation(MainActivity.this, locationResult);
                }
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

d. 将经纬度查询到地址

  private void setLocation(Location location) {
        if (location!=null) {
            String mfeatureName = null;
            Geocoder geocoder = new Geocoder(MainActivity.this);
            List<Address> addList = null;// 解析经纬度
            try {
                addList = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (addList != null && addList.size() > 0) {
                for (int i = 0; i < addList.size(); i++) {
                    Address add = addList.get(i);
                    mfeatureName = add.getFeatureName();
                    tvLocaiton.setText(mfeatureName);
                }
            }
        }
    }

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

public static String getOuterNetFormCmyIP(String response) {
    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))))");
    Matcher matcher = pattern.matcher(response.toString());
    if (matcher.find()) {
        String group = matcher.group(); return group;
    }
    return null;
}

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

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

3.2 评价:精确度差,稳定性差,代码量少,对 app 体积影响较小,不建议使用。
二、说点啥
以上的三种方法都是我瞎编的… 哈哈哈

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值