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.清单文件中配置权限:

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!--危险-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

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

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

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

  • 20
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值