当前位置: 移动技术网 > 移动技术>移动开发>Android > Android 手机app三种方法获取定位地址(自带API,外接SDK,获取外网IP)

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

2018年11月01日  | 移动技术网移动技术  | 我要评论

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

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

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

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

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

1.1步骤:

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

    
    
    

    
    
    

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网