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.mzph.cn/news/803272.shtml

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

相关文章

ruoyi-vue-pro 前端vue js直接import导入本地文件使用方法

我的xml文件名称叫w2101.xml 第一步&#xff0c;删除所有依赖&#xff0c;否则配置以后就会启动报错&#xff1a; 第二步配置对应的文件格式&#xff0c;我当前使用的是xml文件 config.module.rule(xml).test(/\.xml$/).use(xml-loader).loader(xml-loader).end();第三步…

你应该知道的21个html小技巧

本文翻译自 21 HTML Tips You Must Know About&#xff0c;作者&#xff1a;Shefali&#xff0c; 略有删改。 在这篇文章中&#xff0c;我将分享21个HTML技巧和代码片段&#xff0c;可以提高你的编码技能。 链接联系人 使用HTML创建可点击的电子邮件、电话和短信链接&#xf…

转圈游戏——快速幂

目录 题目 思路 代码 题目 思路 每个小朋友移动一次的位置为&#xff0c;移动 q 次的位置则为。那么题目要求移动 &#xff0c;最后的位置为 。 但 的范围是&#xff0c;而总的移动次数是 。时间复杂度是在&#xff0c;因此是一定不能硬算的&#xff0c;肯定会超时。那么该…

长期通配符证书介绍

长期通配符证书是指有效期较长的泛域名证书&#xff0c;这种证书允许您使用单一证书为一个主域名及其所有相关子域名提供长期的HTTPS加密服务。获取长期通配符证书的过程与普通通配符证书相似&#xff0c;但需要注意选择具有较长有效期的证书产品&#xff0c;并确保符合CA机构及…

私域电商客户要挨一刀的“订单发货管理”,微信:必须强制接入

文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 引言&#xff1a;超90%的私域运营商家都见到了或者说遇到了这个问题&#xff0c;如果没有读懂这个微信的模型机制&#xff0c;一定会懵逼&#xff0c;微三云营销总监胡佳…

SpringBoot整合MyBatis四种常用的分页方式

目录 方式1 一、准备工作 1. 创建表结构 2. 导入表数据 3. 导入pom.xml依赖 4. 配置application.yml文件 5. 创建公用的实体类 项目结构 2. 创建controller层 3. 创建service层 4. 创建mapper层 5. 创建xml文件 6. 使用postman进行测试&#xff0c;测试结果如下…

DNS 各记录类型说明及规则

各记录类型使用目的 记录类型使用目的A 记录将域名指向一个 IP 地址。CNAME 记录将域名指向另一个域名&#xff0c;再由另一个域名提供 IP 地址。MX 记录设置邮箱&#xff0c;让邮箱能收到邮件。NS 记录将子域名交给其他 DNS 服务商解析。AAAA 记录将域名指向一个 IPv6 地址。…

MQTT的学习

近期构建物联网平台&#xff0c;学习到MQTT&#xff0c;这里使用的是uniapp作为连接MQTT broker的&#xff0c;这里使用的是国产的EMQX。 MQTT的认识 MQTT 协议入门&#xff1a;基础知识和快速教程 | EMQ&#xff08;简单的认识&#xff09; 创建 MQTT 连接时如何设置参数&am…

从ChatGPT到多模态大模型:现状与未来(多模态)

ChatGPT 训练的核心技术主要包括: 预训练语言模型;有监督微调;基于人类反馈的 强 化 学 习 (ReinforcementLearningfrom Human Feedback,RLHF) 首先,通过自监督预训练使语言模型从大规模语料库中学习语言规律,具备基础 理解和生成能力;然后,通过构造指令微调数据集 并对模型进…

【科研相关知识】梯度下降算法(Gradient Descent)

梯度下降算法(Gradient Descent)梯度下降算法几种变体 梯度下降算法(Gradient Descent) 梯度下降算法是一种用于求解函数最小值的一阶优化算法。在机器学习和深度学习中&#xff0c;梯度下降算法被广泛用于模型训练&#xff0c;通过迭代的方式调整模型参数&#xff0c;以最小…

常见的mq产品和优点

常见的mq产品和优点 一、什么是mq? MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信&#xff0c;解耦。 二、常见的mq产品 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq …

【学习】注意力机制(Attention)和 自注意力机制(self-Attention)

参考B站&#xff1a;09 Transformer 之什么是注意力机制&#xff08;Attention&#xff09; 1. 注意力机制&#xff08;Attention&#xff09; 红色的是科学家们发现&#xff0c;如果给你一张这个图&#xff0c;你眼睛的重点会聚焦在红色区域 人–》看脸 文章看标题 段落看…

弹幕功能1

今天看pure-admin的时候发现有个弹幕功能 GitHub - hellodigua/vue-danmaku: 基于 Vue 的弹幕交互组件 | A danmaku component for Vue

业主看完当场签约的神仙地产大屏,搞物业的你不来get同款么

各行各业都有可视化大屏的应用场景&#xff0c;不少同志曾私戳我&#xff1a;能不能给我XX行业的大屏示例哇&#xff0c;我展示的指标领导怎么都不满意哇&#xff01; 于是俺在行业顾问大哥那苦苦哀求&#xff0c;终于给大家带来这个地产行业的“营销战图大屏”方案&#xff0…

《QT实用小工具·二十一》鼠标十字线

1、概述 源码放在文章末尾 该项目实现了界面绘制十字线并跟随鼠标移动的过程&#xff0c;下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget>namespace Ui { class Widget; }class Widget : public QWidg…

C++类与对象中(个人笔记)

类与对象中 类的6个默认成员函数1.构造函数1.1特性 2.析构函数2.1特性 3.拷贝构造函数3.1特性 4.赋值运算符重载4.1特性 5.日期类的实现6.const成员6.1const成员的几个问题 7.取地址及const取地址操作符重载 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为…

嵌入式学习51-单片机4

知识零碎&#xff1a; nop空指令 CRC校验 为了保证51单片与温度传感18b20 之间的高电平 采用一个上拉电阻改变电平的高低 温度寄存器原理

Jackson 2.x 系列【15】序列化器 JsonSerializer

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 概述2. 方法2.1 构造2.2 序列化2.3 其他 3. 实现类3.1 StdSerializer3.1.1 源…

因为使用ArrayList.removeAll(List list)导致的机器重启

背景 先说一下背景&#xff0c;博主所在的业务组有一个核心系统&#xff0c;需要同步两个不同数据源给过来的数据到redis中&#xff0c;但是每次同步之前需要过滤掉一部分数据&#xff0c;只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由…

tmux 替换 nohup

替换方案 tmux 训练PyTorch模型的时候一个基本步骤&#xff1a; [terminal]: tmux new -s model-ft # 创建一个会话&#xff0c;并设置会话名:model-ft [tmux]: conda activate your_env # 在tmux会话中&#xff0c;我们激活我们要使用的conda环境 [tmux]: pyth…