Android获取连接到手机热点上的设备信息

主题:在手机开启热点网络的情况下,想要获取是哪个设备已经连接上了当前开启的热点。

实现思路:Android通过读取  /proc/net/arp 文件可以得到连接当前热点的设备信息,包括Mac地址、IP地址等信息。

一. 方法逻辑:

    /*** 获取连接到手机热点上的设备信息* @return*/public List<HashMap> getConnectedApInfo() {List<HashMap> connectedApInfo = new ArrayList<>();try {BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));String line;while ((line = br.readLine()) != null) {/*** 获取到的数组结果,示例:[192.168.227.138, 0x1, 0x2, 82:64:5e:01:49:fc, *, wlan2]*/String[] splitted = line.split(" +");HashMap hashMap = new HashMap();//设备信息判断标准if (splitted.length >= 4 && splitted[3].contains(":")) {String ip = splitted[0];          //获取IP地址信息,代替设备名称String address = splitted[3];     //获取Mac地址信息hashMap.put("name", ip);hashMap.put("address", address);connectedApInfo.add(hashMap);Log.d(TAG, "getConnectedApInfo(),获取连接到手机热点上的设备信息:" + Arrays.toString(splitted) + "    connectedApInfo:" + connectedApInfo.size() + "  " + connectedApInfo);}}} catch (Exception e) {e.printStackTrace();}return connectedApInfo;}
二. 拓展工具类,控制热点的开启和关闭,热点信息的获取:
import static android.content.Context.CONNECTIVITY_SERVICE;
import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log;
import com.android.dx.stock.ProxyBuilder;/*** Description:控制热点的开启和关闭,热点信息的获取* 所需权限:* <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />* <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />* <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />* <uses-permission android:name="android.permission.WRITE_SETTINGS"*     tools:ignore="ProtectedPermissions" /> <!-- 用于Android 6.0 (API 级别 23) 及以上版本 -->*/
public class WifiHotspotManager {private static final String TAG = WifiHotspotManager.class.getSimpleName();private WifiManager wifiManager;private Method method;public WifiHotspotManager(Context context) {wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);}public boolean isApEnabled() {try {if (method == null) {method = wifiManager.getClass().getMethod("isWifiApEnabled");}return (boolean) method.invoke(wifiManager);} catch (Exception e) {Log.e(TAG, "Error checking if AP is enabled", e);return false;}}/*** 开启或关闭热点* @param enabled* @return*/public boolean setApEnabled(boolean enabled) {if (enabled) {Log.d(TAG, "开启热点,Enabling hotspot");} else {Log.d(TAG, "关闭热点,Disabling hotspot");}try {if (method == null) {method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);}return (boolean) method.invoke(wifiManager, null, enabled);} catch (Exception e) {Log.e(TAG, "开启或关闭热点 is error,enabling/disabling AP:" + e);return false;}}/*** 配置热点的设置(如SSID和密码)* 需要创建一个WifiConfiguration对象来配置你的热点设置,然后将其传递给configureApState方法* @param apConfig* @return*/public boolean configureApState(WifiConfiguration apConfig) {try {Method method = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);return (boolean) method.invoke(wifiManager, apConfig);} catch (Exception e) {Log.e(TAG, "Error setting AP configuration", e);return false;}}/*** 控制热点的开启和关闭(一步到位)*/public boolean controlApSwitch(Context context, boolean flag){WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);try{WifiConfiguration apConfig = new WifiConfiguration();String deviceModel = Build.MODEL;     //设备型号apConfig.SSID = deviceModel;          //配置热点的名称apConfig.preSharedKey = "12345678";   //配置热点的密码(至少8位)apConfig.allowedKeyManagement.set(4); //配置密码加密方式//通过反射调用设置热点Method method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);Boolean rs = (Boolean) method.invoke(wifiManager, apConfig, flag);        //true 开启热点 ,false 关闭热点Log.d(TAG, flag ? "当前设备:" + deviceModel + " 开启热点网络是否成功:" + rs : " 关闭热点网络是否成功:" + rs);return rs;} catch(Exception e){e.printStackTrace();return false;}}/*** 发送隐式广播。此方法会查询与给定意图相匹配的所有广播接收器,并向每个匹配的接收器发送一个显式广播。** @param context 上下文,用于发送广播。* @param intent 需要发送的隐式广播意图。* @param action 执行的动作*/public void sendImplicitBroadcast(Context context, Intent intent, String action) {// 获取包管理器,用于查询广播接收器PackageManager pm = context.getPackageManager();// 查询与intent相匹配的所有广播接收器List<ResolveInfo> matches = pm.queryBroadcastReceivers(intent, 0);// 遍历所有匹配的广播接收器for (ResolveInfo resolveInfo : matches) {// 创建一个新的意图,将其转换为显式意图,目标为当前接收器Intent explicit = new Intent(intent);// 设置组件名称,转换为显式意图ComponentName cn = new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName, resolveInfo.activityInfo.name);explicit.setComponent(cn);// 向每个匹配的广播接收器发送显式广播context.sendBroadcast(explicit);}Log.d(TAG, "sendImplicitBroadcast(),发送隐式广播,action:" + action);}/*** 打开手机的热点* 需要在build.gradle文件添加三方库依赖:implementation 'com.linkedin.dexmaker:dexmaker-mockito:2.12.1'* @param context*/public void startTethering(Context context){ConnectivityManager connectivityManager = ((ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE));try{Class classOnStartTetheringCallback = Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");Method startTethering=connectivityManager.getClass().getDeclaredMethod("startTethering",int.class,boolean.class,classOnStartTetheringCallback);Object proxy = ProxyBuilder.forClass(classOnStartTetheringCallback).handler(new InvocationHandler(){@Overridepublic Object invoke(Object o,Method method,Object[]objects)throws Throwable{return null;}}).build();startTethering.invoke(connectivityManager,0,false,proxy);} catch(Exception e){e.printStackTrace();}Log.d(TAG, "startTethering(),打开手机的热点");}/*** 关闭手机的热点*/public void stopTethering(Context context){ConnectivityManager connectivityManager=((ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE));try{Method stopTethering = connectivityManager.getClass().getDeclaredMethod("stopTethering",int.class);stopTethering.invoke(connectivityManager,0);}catch(Exception e){e.printStackTrace();}Log.d(TAG, "stopTethering(),关闭手机的热点");}/*** 判断是否开启手机的热点* @param context* @return*/public boolean isWifiApEnabled(Context context){WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);try{Method method=wifiManager.getClass().getMethod("isWifiApEnabled");method.setAccessible(true);return(Boolean)method.invoke(wifiManager);}catch(NoSuchMethodException e){e.printStackTrace();}catch(Exception e){e.printStackTrace();}Log.d(TAG, "isWifiApEnabled(),判断是否开启手机的热点");return false;}/*** 获取手机的热点信息* @param context* @return*/public String getApInfo(Context context){WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);try{Method localMethod = wifiManager.getClass().getDeclaredMethod("getWifiApConfiguration", new Class[0]);Object config = localMethod.invoke(wifiManager);Log.d(TAG, "getApInfo(),获取手机的热点信息:" + config.toString());}catch(Exception localException){localException.printStackTrace();}return null;}/*** 获取连接到手机热点上的设备信息* @return*/public List<HashMap> getConnectedApInfo() {List<HashMap> connectedApInfo = new ArrayList<>();try {BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));String line;while ((line = br.readLine()) != null) {/*** 获取到的数组结果,示例:[192.168.227.138, 0x1, 0x2, 82:64:5e:01:49:fc, *, wlan2]*/String[] splitted = line.split(" +");HashMap hashMap = new HashMap();//设备信息判断标准if (splitted.length >= 4 && splitted[3].contains(":")) {String ip = splitted[0];          //获取IP地址信息,代替设备名称String address = splitted[3];     //获取Mac地址信息hashMap.put("name", ip);hashMap.put("address", address);connectedApInfo.add(hashMap);Log.d(TAG, "getConnectedApInfo(),获取连接到手机热点上的设备信息:" + Arrays.toString(splitted) + "    connectedApInfo:" + connectedApInfo.size() + "  " + connectedApInfo);}}} catch (Exception e) {e.printStackTrace();}return connectedApInfo;}
三. 调用示例:
//返回的是一个数据形式是包含HahMap集合的List集合,可根据HashMap的键值对取值并显示
WifiHotspotManager wifiHotspotManager = new WifiHotspotManager(requireActivity());List<HashMap> connectedApInfo = wifiHotspotManager.getConnectedApInfo();Log.d(TAG, "connectedApInfo:" + connectedApInfo.size() + "  " + connectedApInfo);
四.手机热点已连接设备与功能效果图

参考文章:Android获取实时连接热点的设备IP_安卓设备获取ip-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/302696.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

权限管理系统【BUG】

1.1.简介 忙里偷闲&#xff0c;学点Java知识。越发觉得世界语言千千万&#xff0c;最核心的还是思想&#xff0c;一味死记硬背只会让人觉得很死板不灵活&#xff0c;嗯~要灵活~ 1.2.问题 permission.js:37 [Vue warn]: Error in render: "TypeError: Cannot read prope…

Django--admin 后台管理站点

Django最大的优点之一&#xff0c;就是体贴的提供了一个基于项目model创建的一个后台管理站点admin。这个界面只给站点管理员使用&#xff0c;并不对大众开放。虽然admin的界面可能不是那么美观&#xff0c;功能不是那么强大&#xff0c;内容不一定符合你的要求&#xff0c;但是…

【Spring】SpringBoot整合ShardingSphere并实现多线程分批插入10000条数据(进行分库分表操作)。

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、ShardingSphere简介 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar&#xff08;计划中&#xff09;这3款相互独立的产品组成…

hadoop在linux上启动成功了,但是浏览器访问不了

根据网上的资料进行安装hadoop的伪集群 都安装成功&#xff0c;并且启动也成功了&#xff0c;如下图所示&#xff1a; 2、但是在浏览器上确是怎么也访问不了&#xff0c; 解决思路&#xff0c; 2.1、根据网上的一些文章处理解决是关闭防火墙&#xff0c; 2.1.1、我根据操作步骤…

Redis系列之主从复制集群搭建

在上一篇博客&#xff0c;我们已经知道怎么搭建一个redis单机版&#xff0c;这篇博客基于之前的基础&#xff0c;来搭建一个redis主从同步&#xff0c;本博客框架是一主二从&#xff0c;一个主节点&#xff0c;其它两个从节点 实验环境 CentOS7Xshell6XFtp6Redis6.2.2 主从关…

四、书城开发--3、书城图书部分的开发

书城图书部分 首先我们做书城首页搜索栏下面的图片展示 我们在书城首页组件中通过home请求方法中获取回来的数据中&#xff0c;打印出来可以看到那个banner就是我们现在要的图片 我们在data中定义一个变量banner用来存放获取回来的数据中的banner 然后把它展示出来就可以了&a…

JVM_垃圾收集器

GC垃圾收集器 文章目录 GC垃圾收集器GC垃圾回收算法和垃圾收集器关系GC算法主要有以下几种四种主要的垃圾收集器SerialParallelCMSG1垃圾收集器总结查看默认垃圾收集器 默认垃圾收集器有哪些各垃圾收集器的使用范围部分参数说明 新生代下的垃圾收集器并行GC(ParNew)并行回收GC&…

25.11 MySQL 视图

1. 常见的数据库对象 对象描述表(TABLE)存储数据的逻辑单元, 以行和列的形式存在, 列就是字段, 行就是记录.数据字典系统表, 存放数据库相关信息的表. 数据通常由数据库系统维护, 程序员通常不可修改, 只可查看.约束(CONSTRAINT)执行数据校验的规则, 用于保证数据完整性的规则…

基于单片机体温心率检测仪系统设计

**单片机设计介绍&#xff0c; 基于单片机体温心率检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机体温心率检测仪系统设计是一个综合性的项目&#xff0c;旨在通过单片机及其外围电路实现对人体体温和心…

850. Dijkstra求最短路 II

850. Dijkstra求最短路 II 代码&#xff1a; #include<algorithm> #include<iostream> #include<cstring> #include<queue> #include<cmath>using namespace std; //用pair存储编号和距离 typedef pair<int,int> PII;int n,m; const int …

HarmonyOS 应用开发-ArkUI(ets)仿“腾讯新闻”APP

一、效果演示 1、新闻列表页 2、新闻详情页、图片展示页 3、视频页 4、动态页 二、 流程图 –本来自定义了视频的控制栏的&#xff0c;但是发现VideoController()控制器的bug会导致控制器失效&#xff0c;所以没继续做。视频页先不搞了。 三、文件组织&#xff08;“我的页面…

openharmony launcher 调研笔记(03)UI 数据装配

最近在看launcher&#xff0c;把自己调研的点做个笔记&#xff0c;持续修改更新中&#xff0c;个人笔记酌情参考。 桌面上半部分包含父子逻辑&#xff1a; Column() { PageDesktopLayout(); } PageDesktopLayout->GridSwiper->Swiper->SwiperPage 1.PageDe…

jmeter压测websocket协议

一、jmeter 安装websocket插件 1、选项--插件管理 2、搜索WebSocket Samplers by Peter Doornbosch插件 进行安装 3、 重启 jmeter 二、jmeter压测websocket协议实战 2.1、以网站为例&#xff1a; websocket在线测试 1、断开连接 2、打开F12&#xff0c;查看WS数据 3、…

Microsoft Visio 参与者 [actor] - 人的形状图标

Microsoft Visio 参与者 [actor] - 人的形状图标 1. 更多形状 -> 搜索形状2. 参与者References 1. 更多形状 -> 搜索形状 2. 参与者 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

LeetCode-139. 单词拆分【字典树 记忆化搜索 数组 哈希表 字符串 动态规划】

LeetCode-139. 单词拆分【字典树 记忆化搜索 数组 哈希表 字符串 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;Python动态规划五部曲&#xff1a;定推初遍举【先遍历背包 后遍历物品】必须是排列解题思路二&#xff1a;Python动态规划版本二解题思路三&#xff1a;回…

电脑打开游戏的时候提示缺少.dll文件?照着这个来就行。

前言 小白曾经也是一个很喜欢玩游戏的人&#xff0c;但那只是曾经。那时候宿舍里一共6个人&#xff0c;都是比较喜欢玩游戏的小伙子。 话题好像偏了…… 有些小伙伴下载玩游戏之后&#xff0c;高高兴兴地想要开始玩。结果游戏根本没办法运行&#xff0c;可恶&#xff01;这该…

数据库-root密码丢失的重置方案(win11环境)

当在windows系统中安装的mysql由于操作不当&#xff0c;或者密码遗忘&#xff0c;今天测试了一下&#xff0c;可以用以下方法重置root的密码。 mysqlwindows环境root密码重置问题 在win10/11环境下mysql8密码遗忘后的重置密码方案。 停止mysql服务 查找windows中的mysql服务名称…

达梦备份与恢复

达梦备份与恢复 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 设置bak_path路径 --创建备份文件存放目录 su - dmdba mkdir -p /dm8/backup--修改dm.ini 文件…

FreeRTOS源码精简

理解堆的概念和栈的概念 堆 栈 精简FreeRTOS源码 这个源文件的工程是使用KEIL4进行编写的这里我们将它更新为KEIL5 更新之后关闭并重启工程 上面的Commom这个文件实际上是不能删除的&#xff0c;删除会出现很多的错误但是可以对这个文件进行精简 编译后通过

file_get_contents(‘php://input‘); 这个postman要如何传参

在 Postman 中传递参数给 file_get_contents(php://input); 是通过请求的 Body 部分来实现的。使用 Postman 进行 API 接口测试时&#xff0c;可以按照以下步骤来传递参数&#xff1a; 打开 Postman 并创建一个新的请求。在请求的 URL 地址栏输入你的 API 地址。选择请求方法为…