公网IP地址获取:移动网络IP、Wifi IP
前言
因为项目中经常会遇到要上传一系列设备信息的功能,为了方便使用,所以就拆分成以下系列文章来单独介绍如何获取各类设备信息
手机运营商获取
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相关推荐
- golang 获取公网ip 内网ip 检测ip类型 校验ip区间 ip地址string和int转换 判断ip地区国家运营商
目录 简要简介net包 什么是外网IP和内网IP? 获取公网ip 获取本地ip 判断是否是公网ip ip地址string转int ip地址int转string 判断ip地址区间 通过淘宝接口根据公网i ...
- chrome web获取mac地址_老鬼傻瓜式讲解网络知识:网络设备如何通过IP地址获取设备MAC地址...
导读:在前面老鬼向各位好友介绍一些关于网络的基础知识,同时针对ICMP协议(常见使用的Ping测试网络就是使用该协议)进行了详细介绍.具体可参见<Ping是你经常测试工业智能制造网络的工具,但你 ...
- C# 网络编程之通过ip地址获取地理位置(补充)
前面我写过一篇文章"C# 网络编程之获取本机名.ip地址.域名.物理位置"里面可以根据输入的网址根据其ip地址获取器物理位置,其中该部分主要代码是通过有道网提供的在线第三方接口实现 ...
- android开发工具类之获得WIFI IP地址或者手机网络IP
有的时候我们需要获得WIFI的IP地址获得手机网络的IP地址,这是一个工具类,专门解决这个问题,这里需要两个权限: <uses-permission android:name="and ...
- java获取客户端请求IP地址 获取公网ip
这几天搞了用java获取ip地址,由于测试方法不对,一直没有成功,昨天终于想通了并不是方法不对,而是我的测试方法不对,下面这个方法,完全可以得到客户端的公网ip地址 但是在测试的时候注意:我用的是we ...
- VMware设置静态ip地址及不同网络模式讲解【Linux网络问题】
VMware设置静态ip地址及不同网络模式讲解 此处的静态IP配置选用的是使用NAT方式连接网络[如果之前配置有错误,可以尝试暴力方法:将虚拟机网络配置重新恢复为默认,然后从头开始配置] 1 将Lin ...
- 根据IP地址获取地理位置
之前做了一个天气预报,里面就用到了根据IP自动定位技术,今天就给大家分享一波:根据IP地址自动定位. 想要实现根据IP地址定位,你要做的事有如下两点: 第一:获取本机的IP地址 注意:这里指的是公网的 ...
- bat 切换网络适配器_Windows批处理自动切换IP地址设置无线网络和以太网的IP地址...
经常带着笔记本电脑来回公司与家里上网,会碰到要切换本地IP的情况,由于上班公司工作需要设置固定IP才能上网,而在家都是自动获取IP地址的,下面这个bat批处理文件,可以很方便切换IP地址. @echo ...
- JAVA程序 通过IP地址 获取MAC地址
转载自:https://blog.csdn.net/chwshuang/article/details/46958719 叙述 我们都知道通过在电脑上敲 cmd 后,输入ipconfig -all 来 ...
- Linux_网络_数据链路层协议 MAC帧/ARP协议 (以太网通信原理,MAC地址与IP地址的区分,MTU对IP/TCP/IP的影响,ARP协议及其通信过程)
文章目录 1. 以太网(基于碰撞区与碰撞检测的局域网通信标准) 2. 以太网的帧格式(MAC帧) MAC地址,IP地址的区分 MTU MTU对IP协议的影响 MTU对TCP/UDP协议的影响 3.AR ...
最新文章
- 皮克斯首款VR体验《寻梦环游记》登陆 Oculus Rift
- python opencv 等比例调整(缩放)图片分辨率大小代码 cv2.resize()
- 《大话移动 APP 测试》
- 第二阶段 工作总结 05
- linux 程序返回值 139,Linux系统监控之ssh登陆自动139邮件短信提醒
- 如何在画面中摆放大量图片
- thinkphp用来做什么项目_thinkphp第1课:使用thinkphp创建一个项目
- 目前用的java几_java目前常用的几种定时任务
- 某交规模拟考试系统验证绕路手记
- MS DTC服务无法启动解决方法
- 开源软件项目常用版本号标识
- 认识“腔体滤波器”一二三事
- WPS 页码设置为(前1...前3,后4...后6)
- 管理中的计算机应用0206,绩效管理那些事
- windows系统oracle11.2.0.4打补丁
- 大数据时代下的企业管理创新
- using runtime html4,为什么我不能在C#中引用System.Runtime.Serialization.Json
- 输入你的密码来连接到_手机无线网络可以连接但上不了网如何解决【详解】
- 如何给apk文件签名(一)
- Neutral Graph Collaborative Filtering——论文提炼
热门文章
- java金蝶云单据查询_金蝶云星空使用WebAPI来新增单据
- 好家伙,花了一个月时间写了个网易云,以后再也不用充VIP了!
- Scrapy框架-阳光政务平台爬虫(二)
- ads1110程序实测好用
- office 办公软件使用笔记
- springcloud阿里巴巴五大组件_阿里巴巴内部独家微服务全解手册已“重现江湖”大厂核心技术,你确定不了解一下?...
- python生成excel文件报扩展名错误_在python中打开扩展名为.xls的文本文件时出错
- iphone自动下载当天VOA
- css子元素选择父元素的实现
- java 写代码求导_OO_JAVA_表达式求导