欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-03-28 07:56:33
一、手机app定位在我看来有三种方法: 1.通过android自带的api:locationmanager获取到经纬度,再通过geocoder反地理位置查询到所在的地址。 2.外接sdk,如高德sd...

一、手机app定位在我看来有三种方法:

1.通过android自带的api:locationmanager获取到经纬度,再通过geocoder反地理位置查询到所在的地址。

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

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

1、android自带api,它有三种定位方式可以通过gps,网络和wifi定位。

1.1步骤:

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

    
    
    

    
    
    

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

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:*er上的定位
 */

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 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体积影响较小,不建议使用。