前言

因为项目中经常会遇到要上传一系列设备信息的功能,为了方便使用,所以就拆分成以下系列文章来单独介绍如何获取各类设备信息

  • 手机运营商获取

  • AndroidID、IMEI、OAID获取

  • 地理位置信息经纬度获取

  • 公网IP地址获取:移动网络IP、Wifi IP

  • Build类获取相关设备信息

  • 屏幕相关信息:密度、物理尺寸获取

  • BuildConfig获取的一系列基础信息

  • UA、网络状态…等持续更新

1. 移动流量IP地址获取

通过NetworkInterface的getNetworkInterfaces()方法和getInetAddresses()方法可以得到该节点的所有IP地址

1.1 步骤

  • 通过NetworkInterface.getNetworkInterfaces()获取该机器上关于NetworkInterface的枚举
  • 遍历该枚举,通过getInetAddress()获取该节点的所有IP地址
  • 从IP地址列表中获取是IPV4且不是回路地址的正确IP地址

1.2 具体实现

private fun getMobileIP(): String? {try {//返回本机的所有接口,枚举类型;//至少包含一个元素,代表回路isLoopbackAddress;//只支持该机器内实体间能进行通信的接口//getNetworkInterfaces()+getInetAddresses()可以获取该节点的所有IP地址val networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces()//枚举进行遍历while (networkInterfaceEnumeration.hasMoreElements()) {val networkInterface = networkInterfaceEnumeration.nextElement()val inetAddressEnumeration = networkInterface.inetAddresses//枚举进行遍历while (inetAddressEnumeration.hasMoreElements()) {val inetAddress = inetAddressEnumeration.nextElement()//当不是回路地址且是IPV4时if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {return inetAddress.getHostAddress()}}}} catch (e: SocketException) {return nulle.printStackTrace()}return null
}
::1      IPv6形式,对应IPV4的127.0.0.1
127.0.0.1
fe80::c4eb:7d14:a746:a087%wlan0
192.168.20.20

1.3 注意

该方法仅适用于只开启了移动流量未开启WIFI的时候使用,因为我们在遍历并判断是IPV4的地址时,获取到了第一个就直接返回了,而且该方法获取到的也是内网A类地址

while (inetAddressEnumeration.hasMoreElements()) {val inetAddress = inetAddressEnumeration.nextElement()//当不是回路地址且是IPV4时if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {return inetAddress.getHostAddress()}
}

当同时连接WIFI和移动流量时,将其打印,可以得到以下地址

10.98.193.41
192.168.137.21

可以看到,其实是有两个IP的,一个是A类的内网地址,是移动流量的,另一个则是Wifi的C类内网地址。

如果我们想要移动流量WIFI同时连接时使用,那么就将上面的判断改一下,去除掉C类地址后,得到的就是移动运营商的内网IP。

2. Wifi下IP地址获取

2.1 内网IP地址获取

2.1.1 方法一

通过小结1中的方法获取

2.1.2 方法二

通过WifiManager来获取Wifi信息

2.1.2.1 所需权限

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

2.1.2.2 步骤

  • 通过WifiManager的getConnectionInfo()方法来获取WifiInfo信息
  • 通过WifiInfo的getIpAddress()方法获取IP地址
  • 将Int类型的IPv4转为String类型

2.1.2.3 具体实现

private fun getWifiIP(): Int {val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManagerval wifiInfo = wifiManager.connectionInforeturn wifiInfo.ipAddress
}
private fun intIP2StringIP(ip: Int): String? {return (ip and 0xFF).toString() + "." +(ip shr 8  and 0xFF) + "." +(ip shr 16 and 0xFF) + "." +(ip shr 24 and 0xFF)
}
-------------------------------------IP转Int数值------------------------------------------
192(10)=1100 0000(2)
168(10)=1010 1000(2)
1(10)  =0000 0001(2)
100(10)=0110 0100(2)连在一起就是
11000000101010000000000101100100
对应的int数字是-1062731420192左移24位        11000000 00000000 00000000 00000000
168左移16位        00000000 10101000 00000000 00000000
1  左移8位     00000000 00000000 00000001 00000000
100左移0位     00000000 00000000 00000000 01100100
-----------------------------------------Int转IP------------------------------------------
1100 0000 1010 1000 0000 0001 0110 0100 (-1062731420)右移24位(-64)                                  and 1111 1111  后为:
1111 1111 1111 1111 1111 1111 1100 0000         192
右移16位(-16216)
1111 1111 1111 1111 1100 0000 1010 1000         168
右移8位(-4151295)
1111 1111 1100 0000 1010 1000 0000 0001         1
右移0位(-1062731420)
1100 0000 1010 1000 0000 0001 0110 0100         100
位运算,只能是Int和Long类型,
shl 左移位<<
shr 右移位>>(用符号位的值来填充)        1是负数0是正数

2.2 外网IP地址获取

2.2.1 思路

在本地,通过WifiManager获取到是内网IP,无法获取到外网IP,需要借助服务器,所以我们通过网络请求来获取

这里我们通过Get请求访问http://pv.sohu.com/cityjson搜狐的地址,即可得到以下内容

var returnCitySN = {"cip": "202.97.159.66","cid": "140100","cname": "山西省太原市"
};

对该字符串进行解析即可得到本机的外网IP

val start: Int = msg.indexOf("{")
val end: Int = msg.indexOf("}")
val ip = JSONObject(msg.substring(start, end + 1)).get("cip") as String

在具体项目中,可以让后端出个接口来返回我们的外网IP,毕竟别人的接口什么时候不通了也说不准。

2.2.2 具体实现

interface IPService {@GETfun getIP(@Url url: String): Call<ResponseBody>
}
val retrofit= Retrofit.Builder()
.baseUrl("http://a")
.build()
val api =retrofit.create(IPService::class.java)
api.getIP("http://pv.sohu.com/cityjson").enqueue(object :Callback<ResponseBody>{override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {response.body()?.string()?.let {val start: Int = it.indexOf("{")val end: Int = it.indexOf("}")val ip = JSONObject(it.substring(start, end + 1)).get("cip") as StringLog.i(TAG, "网络请求下的IP为:$ip")}}override fun onFailure(call: Call<ResponseBody>, t: Throwable) {Toast.makeText(this@IPActivity,"获取IP失败:${t.message}",Toast.LENGTH_SHORT).show()}
})

3. 判断网络类型

判断是移动网络还是Wifi,这里我们用到了ConnectivityManager类,该类可以监测网络的连接

3.1所需权限

ACCESS_NETWORK_STATE

3.2 方法

getActiveNetwork()只能Android6以上才能调用,所以Android 6以下,我们使用getActiveNetworkInfo()方法来获取。

/**
* 判断是移动网络还是Wifi
* 0:未知网络
* 1:移动网络
* 2:Wifi
* 3:没有网络
*/
private fun judgeNetType():Int{val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerif (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){//安卓6以下val mNetworkInfo = connectivityManager.activeNetworkInforeturn if (mNetworkInfo != null) {when (mNetworkInfo.type) {ConnectivityManager.TYPE_MOBILE -> {1}ConnectivityManager.TYPE_WIFI -> {2}else -> {0}}}else{3}}else{val network = connectivityManager.activeNetworkif (network != null) {val nc = connectivityManager.getNetworkCapabilities(network)return if (nc != null){when {nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {1}nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {2}else -> {0}}}else{3}}else{return 3}}
}

4. 总结

获取IP的方式无非就是以下3种

  • NetworkInterface.getNetworkInterfaces()+getInetAddress()可以得到该节点的所有IP地址,筛选是IPv4的即我们所要的IP,得到的都是内网IP

  • 通过WifiManager的getConnectionInfo()+getIpAddress()即可得到WIFI下的IP地址,同样,得到的是内网IP

  • 通过访问外部服务器,由服务器通过接口告诉我们自己的外网IP地址

所以我们在项目中使用时,如果想要获取外网IP,只能通过访问外部服务器;如果想要获取WIFI的内网IP,第一二种方式均行;想要获取移动网络的的内网IP,用第一种方式,并筛选是10段的内网IP(不同地方的运营商可能会有区别)。

项目地址

如果本文对你有帮助,请别忘记点赞start,如果有不恰当的地方也请提出来,下篇文章见。

5. 参考文章

Java实现ip地址和int数字的相互转换

公网IP地址获取:移动网络IP、Wifi IP相关推荐

  1. golang 获取公网ip 内网ip 检测ip类型 校验ip区间 ip地址string和int转换 判断ip地区国家运营商

    目录 简要简介net包 什么是外网IP和内网IP? 获取公网ip 获取本地ip 判断是否是公网ip ip地址string转int ip地址int转string 判断ip地址区间 通过淘宝接口根据公网i ...

  2. chrome web获取mac地址_老鬼傻瓜式讲解网络知识:网络设备如何通过IP地址获取设备MAC地址...

    导读:在前面老鬼向各位好友介绍一些关于网络的基础知识,同时针对ICMP协议(常见使用的Ping测试网络就是使用该协议)进行了详细介绍.具体可参见<Ping是你经常测试工业智能制造网络的工具,但你 ...

  3. C# 网络编程之通过ip地址获取地理位置(补充)

    前面我写过一篇文章"C# 网络编程之获取本机名.ip地址.域名.物理位置"里面可以根据输入的网址根据其ip地址获取器物理位置,其中该部分主要代码是通过有道网提供的在线第三方接口实现 ...

  4. android开发工具类之获得WIFI IP地址或者手机网络IP

    有的时候我们需要获得WIFI的IP地址获得手机网络的IP地址,这是一个工具类,专门解决这个问题,这里需要两个权限: <uses-permission android:name="and ...

  5. java获取客户端请求IP地址 获取公网ip

    这几天搞了用java获取ip地址,由于测试方法不对,一直没有成功,昨天终于想通了并不是方法不对,而是我的测试方法不对,下面这个方法,完全可以得到客户端的公网ip地址 但是在测试的时候注意:我用的是we ...

  6. VMware设置静态ip地址及不同网络模式讲解【Linux网络问题】

    VMware设置静态ip地址及不同网络模式讲解 此处的静态IP配置选用的是使用NAT方式连接网络[如果之前配置有错误,可以尝试暴力方法:将虚拟机网络配置重新恢复为默认,然后从头开始配置] 1 将Lin ...

  7. 根据IP地址获取地理位置

    之前做了一个天气预报,里面就用到了根据IP自动定位技术,今天就给大家分享一波:根据IP地址自动定位. 想要实现根据IP地址定位,你要做的事有如下两点: 第一:获取本机的IP地址 注意:这里指的是公网的 ...

  8. bat 切换网络适配器_Windows批处理自动切换IP地址设置无线网络和以太网的IP地址...

    经常带着笔记本电脑来回公司与家里上网,会碰到要切换本地IP的情况,由于上班公司工作需要设置固定IP才能上网,而在家都是自动获取IP地址的,下面这个bat批处理文件,可以很方便切换IP地址. @echo ...

  9. JAVA程序 通过IP地址 获取MAC地址

    转载自:https://blog.csdn.net/chwshuang/article/details/46958719 叙述 我们都知道通过在电脑上敲 cmd 后,输入ipconfig -all 来 ...

  10. Linux_网络_数据链路层协议 MAC帧/ARP协议 (以太网通信原理,MAC地址与IP地址的区分,MTU对IP/TCP/IP的影响,ARP协议及其通信过程)

    文章目录 1. 以太网(基于碰撞区与碰撞检测的局域网通信标准) 2. 以太网的帧格式(MAC帧) MAC地址,IP地址的区分 MTU MTU对IP协议的影响 MTU对TCP/UDP协议的影响 3.AR ...

最新文章

  1. 皮克斯首款VR体验《寻梦环游记》登陆 Oculus Rift
  2. python opencv 等比例调整(缩放)图片分辨率大小代码 cv2.resize()
  3. 《大话移动 APP 测试》
  4. 第二阶段 工作总结 05
  5. linux 程序返回值 139,Linux系统监控之ssh登陆自动139邮件短信提醒
  6. 如何在画面中摆放大量图片
  7. thinkphp用来做什么项目_thinkphp第1课:使用thinkphp创建一个项目
  8. 目前用的java几_java目前常用的几种定时任务
  9. 某交规模拟考试系统验证绕路手记
  10. MS DTC服务无法启动解决方法
  11. 开源软件项目常用版本号标识
  12. 认识“腔体滤波器”一二三事
  13. WPS 页码设置为(前1...前3,后4...后6)
  14. 管理中的计算机应用0206,绩效管理那些事
  15. windows系统oracle11.2.0.4打补丁
  16. 大数据时代下的企业管理创新
  17. using runtime html4,为什么我不能在C#中引用System.Runtime.Serialization.Json
  18. 输入你的密码来连接到_手机无线网络可以连接但上不了网如何解决【详解】
  19. 如何给apk文件签名(一)
  20. Neutral Graph Collaborative Filtering——论文提炼

热门文章

  1. java金蝶云单据查询_金蝶云星空使用WebAPI来新增单据
  2. 好家伙,花了一个月时间写了个网易云,以后再也不用充VIP了!
  3. Scrapy框架-阳光政务平台爬虫(二)
  4. ads1110程序实测好用
  5. office 办公软件使用笔记
  6. springcloud阿里巴巴五大组件_阿里巴巴内部独家微服务全解手册已“重现江湖”大厂核心技术,你确定不了解一下?...
  7. python生成excel文件报扩展名错误_在python中打开扩展名为.xls的文本文件时出错
  8. iphone自动下载当天VOA
  9. css子元素选择父元素的实现
  10. java 写代码求导_OO_JAVA_表达式求导