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

admin2025-06-04 02:41:589595

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

二、说点啥

以上的三种方法都是我瞎编的...哈哈哈