最近在做类似面对面通信,需要一台手机作为AP端开启热点,另一台手机作为STA端连接热点,然后AP端告诉STA端它的IP地址,进行socket通信。
手机在联网时,就会被分配一个IP地址,它在开启热点时,它本身作为一个“路由器”也会生成一个IP地址,我们需要的就是后面这个IP地址,目前论坛上关于手机IP地址的帖子都是获取手机被分配的IP地址。我在解决这个问题时参考了蓝牙的配置IP地址,函数是configureBtIface(),在/frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java里。可以看到它也是先获取然后配置,参考这个,我写了获取热点IP地址的函数。
代码链接

private String configureBtIface(boolean enable, String iface) {Log.i(TAG, "configureBtIface: " + iface + " enable: " + enable);IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);ConnectivityManager cm =(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();InterfaceConfiguration ifcg = null;String address = null;try {ifcg = service.getInterfaceConfig(iface);if (ifcg != null) {InetAddress addr = null;LinkAddress linkAddr = ifcg.getLinkAddress();if (linkAddr == null || (addr = linkAddr.getAddress()) == null || addr.equals(NetworkUtils.numericToInetAddress("0.0.0.0")) || addr.equals(NetworkUtils.numericToInetAddress("::0"))) {address = BLUETOOTH_IFACE_ADDR_START;addr = NetworkUtils.numericToInetAddress(address);}ifcg.setLinkAddress(new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH));if (enable) {ifcg.setInterfaceUp();} else {ifcg.setInterfaceDown();}ifcg.clearFlag("running");service.setInterfaceConfig(iface, ifcg);if (enable) {int tetherStatus = cm.tether(iface);if (tetherStatus != ConnectivityManager.TETHER_ERROR_NO_ERROR) {Log.e(TAG, "Error tethering " + iface + " tetherStatus: " + tetherStatus);return null;}} else {int untetherStatus = cm.untether(iface);Log.i(TAG, "Untethered: " + iface + " untetherStatus: " + untetherStatus);}}}return address;}

下面getIpAddress()就是我写的开启热点以后获取AP端IP地址的函数,主要就是把蓝牙那边的参数改成了wlan0,就ok了。经过测试,log打出来的IP地址和手机执行ifconfig里wlan0里面的IP地址一模一样。当然,这个IP地址每次打开热点都是不一样的。在Android8.0以及之前这个IP地址是固定的,好像是"192.168.43.1"。9.0以后随机分配,可能是为了安全吧。

private String getIpAddress() {IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);InterfaceConfiguration ifcg = null;String address = null;try {ifcg = service.getInterfaceConfig("wlan0");if (ifcg != null) {LinkAddress linkAddr = ifcg.getLinkAddress();Log.d("test" , "linkAddr" + linkAddr.toString());if (linkAddr != null) {InetAddress Inetaddr = linkAddr.getAddress();Log.d("test" , "Inetaddr" + Inetaddr.toString());if (Inetaddr != null) {address = Inetaddr.getHostAddress();if (address != null) {Log.d("test" , "address " + address.toString());}}}}} catch (Exception e) {Log.e("test", "Error configuring interface :" + e);return null;}return address;}

这里贴上Android9.0上开启热点时分配IP地址(ipv4)的代码:/frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java里的configureIPv4()函数。
代码链接

private boolean configureIPv4(boolean enabled) {if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");// TODO: Replace this hard-coded information with dynamically selected// config passed down to us by a higher layer IP-coordinating element.String ipAsString = null;int prefixLen = 0;if (mInterfaceType == ConnectivityManager.TETHERING_USB) {ipAsString = USB_NEAR_IFACE_ADDR;prefixLen = USB_PREFIX_LENGTH;} else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {ipAsString = getRandomWifiIPv4Address();prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;} else {// Nothing to do, BT does this elsewhere.return true;}final LinkAddress linkAddr;try {final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName);if (ifcg == null) {mLog.e("Received null interface config");return false;}InetAddress addr = NetworkUtils.numericToInetAddress(ipAsString);linkAddr = new LinkAddress(addr, prefixLen);ifcg.setLinkAddress(linkAddr);if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {// The WiFi stack has ownership of the interface up/down state.// It is unclear whether the Bluetooth or USB stacks will manage their own// state.ifcg.ignoreInterfaceUpDownStatus();} else {if (enabled) {ifcg.setInterfaceUp();} else {ifcg.setInterfaceDown();}}ifcg.clearFlag("running");mNMService.setInterfaceConfig(mIfaceName, ifcg);} catch (Exception e) {mLog.e("Error configuring interface " + e);return false;}// Directly-connected route.final RouteInfo route = new RouteInfo(linkAddr);if (enabled) {mLinkProperties.addLinkAddress(linkAddr);mLinkProperties.addRoute(route);} else {mLinkProperties.removeLinkAddress(linkAddr);mLinkProperties.removeRoute(route);}return true;}

关注公众号,获取更多开发必备知识

Android开启热点后作为路由器,获取AP端IP地址相关推荐

  1. php获取用户真实ip_开启CDN后,PHP获取用户真实IP的方法

    因为近日需要几个小项目上CDN,但上CDN的同时,要获取到用户的真实IP地址.虽然网上有很多关于网站在CDN加速的情况下,PHP获取用户真实IP地址的方法,但总觉的不可靠,还是自己测试一下最好. PH ...

  2. httpservlet获取请求端IP地址

    request.getRemoteAddr(); 转载于:https://www.cnblogs.com/panxuejun/p/7623850.html

  3. 水星路由器wan口ip显示0_水星路由器WAN口获取不到ip地址怎么办?

    [www.xinr41319.cn--IP地址] 有的小伙伴问:家里新买了一个水星无线路由器,按照说明书设置后不能上网:并且在"上网设置"选项处,查看到WAN口没有获取到IP地址. ...

  4. 水星路由器wan口ip显示0_水星路由器WAN口获取不到ip地址如何解决

    家里新买了一个水星无线路由器,按照说明书设置后不能上网;并且在"上网设置"选项处,查看到WAN口没有获取到IP地址.遇到这种问题的时候应该怎么办呢?下面整理了一下水星路由器WAN口 ...

  5. //获取本地IP地址和对端IP地址

    1 //获取本地IP地址 2 CHAR * GetLocalIpAdrr(int fd) 3 { 4 struct sockaddr_in stHost; 5 memset(&stHost, ...

  6. php获取本机IP地址

    <?php function get_local_ip() {$preg = "/\A((([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5 ...

  7. android udp 广播通信,Android开启热点进行UDP通信中的坑

    1.写在前面: 2018年的第一篇文章,最近在使用UDP协议进行硬件通信,大家都知道UDP协议通信必须在同一个局域网内,但是每个用户家的wifi都是不一样的,硬件设备是无法只值连接到用户家的wifi的 ...

  8. wifi udp android,Android开启热点进行UDP通信中的坑

    1.写在前面: 2018年的第一篇文章,最近在使用UDP协议进行硬件通信,大家都知道UDP协议通信必须在同一个局域网内,但是每个用户家的wifi都是不一样的,硬件设备是无法只值连接到用户家的wifi的 ...

  9. Win10笔记本开启热点后无法正常联网怎么办?

    Win10笔记本开启热点后无法正常联网怎么办? Win10笔记本开启热点后无法正常联网解决方法: 方法一:下载Win10专版 ipnat.sys文件 方法二:设置卸载最近的更新 方法三:系统之家装机大 ...

最新文章

  1. 【SQL编程】Greenplum 与 MySQL 数据库获取周几函数及函数结果保持一致的方法
  2. iOS基础知识点总结
  3. 手把手教你用CAB发布OCX的简单办法
  4. mysql无法连接server 2008_SQL Server 2008登录错误:无法连接到(local)解决方法
  5. iOS10 CallKit简单开发
  6. 云图说|图解DGC:基于华为智能数据湖解决方案的一体化数据治理平台
  7. 二、2.4版本之前的apache的安装
  8. Cocos Creator 使用 Android Studio 打包 APK 遇到的坑
  9. html计算选定的金额,计算总金额
  10. js+svg实现的一个环图
  11. Leetcode431.将N叉树编码为二叉树(golang)
  12. 用VB.net编写的Windows服务管理程序(堪称经典)全部源代码
  13. [经验分享] 收费版文字转语音,免费使用
  14. kindle看pdf不清楚_无法在Kindle上阅读PDF格式的电子书,该怎么办呢?
  15. 什么是计算机的超级用户账号,administrator是什么意思
  16. HarmonyOS resources目录中“限定词目录”命名要求
  17. 天津市建筑物矢量数据(Shp格式+带高度)
  18. office 所有后缀对应的 content-type
  19. uniapp 上传图片到华为云obs
  20. paypal开发者账户申请步骤(最新最实用)

热门文章

  1. form表单使用put方式提交
  2. 三年308%投资回报!IDC点评戴尔科技存储家族
  3. 照片太大上传不了怎么缩小?
  4. ORBSLAM3阅读笔记1 System
  5. ORACLE 闩锁介绍
  6. EDC大展览,你的EDC是什么呢
  7. 服务器如何配置ssl证书
  8. asp.net+C#助学贷款管理系统
  9. SpringBoot 日志总结
  10. 错题-阅读理解-逻辑填空1