当前位置:   article > 正文

Android获取连接到手机热点上的设备信息_android 实时显示接入wifi热点设备ip和设备名称

android 实时显示接入wifi热点设备ip和设备名称
主题:在手机开启热点网络的情况下,想要获取是哪个设备已经连接上了当前开启的热点。

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

方法缺陷:在某个热点网络断连后,不能实时更新已连接到的热点网络设备信息!

一. 方法逻辑:

  1. /**
  2. * 获取连接到手机热点上的设备信息
  3. * @return
  4. */
  5. public List<HashMap> getConnectedApInfo() {
  6. List<HashMap> connectedApInfo = new ArrayList<>();
  7. try {
  8. BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));
  9. String line;
  10. while ((line = br.readLine()) != null) {
  11. /**
  12. * 获取到的数组结果,示例:[192.168.227.138, 0x1, 0x2, 82:64:5e:01:49:fc, *, wlan2]
  13. */
  14. String[] splitted = line.split(" +");
  15. HashMap hashMap = new HashMap();
  16. //设备信息判断标准
  17. if (splitted.length >= 4 && splitted[3].contains(":")) {
  18. String ip = splitted[0]; //获取IP地址信息,代替设备名称
  19. String address = splitted[3]; //获取Mac地址信息
  20. hashMap.put("name", ip);
  21. hashMap.put("address", address);
  22. connectedApInfo.add(hashMap);
  23. Log.d(TAG, "getConnectedApInfo(),获取连接到手机热点上的设备信息:" + Arrays.toString(splitted) + " connectedApInfo:" + connectedApInfo.size() + " " + connectedApInfo);
  24. }
  25. }
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. return connectedApInfo;
  30. }
二. 拓展工具类,控制热点的开启和关闭,热点信息的获取:
  1. import static android.content.Context.CONNECTIVITY_SERVICE;
  2. import java.io.BufferedReader;
  3. import java.io.FileReader;
  4. import java.lang.reflect.InvocationHandler;
  5. import java.lang.reflect.Method;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import android.content.ComponentName;
  11. import android.content.Context;
  12. import android.content.Intent;
  13. import android.content.pm.PackageManager;
  14. import android.content.pm.ResolveInfo;
  15. import android.net.ConnectivityManager;
  16. import android.net.wifi.WifiConfiguration;
  17. import android.net.wifi.WifiManager;
  18. import android.os.Build;
  19. import android.util.Log;
  20. import com.android.dx.stock.ProxyBuilder;
  21. /**
  22. * Description:控制热点的开启和关闭,热点信息的获取
  23. * 所需权限:
  24. * <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
  25. * <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  26. * <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  27. * <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  28. * <uses-permission android:name="android.permission.WRITE_SETTINGS"
  29. * tools:ignore="ProtectedPermissions" /> <!-- 用于Android 6.0 (API 级别 23) 及以上版本 -->
  30. */
  31. public class WifiHotspotManager {
  32. private static final String TAG = WifiHotspotManager.class.getSimpleName();
  33. private WifiManager wifiManager;
  34. private Method method;
  35. public WifiHotspotManager(Context context) {
  36. wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
  37. }
  38. public boolean isApEnabled() {
  39. try {
  40. if (method == null) {
  41. method = wifiManager.getClass().getMethod("isWifiApEnabled");
  42. }
  43. return (boolean) method.invoke(wifiManager);
  44. } catch (Exception e) {
  45. Log.e(TAG, "Error checking if AP is enabled", e);
  46. return false;
  47. }
  48. }
  49. /**
  50. * 开启或关闭热点
  51. * @param enabled
  52. * @return
  53. */
  54. public boolean setApEnabled(boolean enabled) {
  55. if (enabled) {
  56. Log.d(TAG, "开启热点,Enabling hotspot");
  57. } else {
  58. Log.d(TAG, "关闭热点,Disabling hotspot");
  59. }
  60. try {
  61. if (method == null) {
  62. method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
  63. }
  64. return (boolean) method.invoke(wifiManager, null, enabled);
  65. } catch (Exception e) {
  66. Log.e(TAG, "开启或关闭热点 is error,enabling/disabling AP:" + e);
  67. return false;
  68. }
  69. }
  70. /**
  71. * 配置热点的设置(如SSID和密码)
  72. * 需要创建一个WifiConfiguration对象来配置你的热点设置,然后将其传递给configureApState方法
  73. * @param apConfig
  74. * @return
  75. */
  76. public boolean configureApState(WifiConfiguration apConfig) {
  77. try {
  78. Method method = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
  79. return (boolean) method.invoke(wifiManager, apConfig);
  80. } catch (Exception e) {
  81. Log.e(TAG, "Error setting AP configuration", e);
  82. return false;
  83. }
  84. }
  85. /**
  86. * 控制热点的开启和关闭(一步到位)
  87. */
  88. public boolean controlApSwitch(Context context, boolean flag){
  89. WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
  90. try{
  91. WifiConfiguration apConfig = new WifiConfiguration();
  92. String deviceModel = Build.MODEL; //设备型号
  93. apConfig.SSID = deviceModel; //配置热点的名称
  94. apConfig.preSharedKey = "12345678"; //配置热点的密码(至少8位)
  95. apConfig.allowedKeyManagement.set(4); //配置密码加密方式
  96. //通过反射调用设置热点
  97. Method method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
  98. Boolean rs = (Boolean) method.invoke(wifiManager, apConfig, flag); //true 开启热点 ,false 关闭热点
  99. Log.d(TAG, flag ? "当前设备:" + deviceModel + " 开启热点网络是否成功:" + rs : " 关闭热点网络是否成功:" + rs);
  100. return rs;
  101. } catch(Exception e){
  102. e.printStackTrace();
  103. return false;
  104. }
  105. }
  106. /**
  107. * 发送隐式广播。此方法会查询与给定意图相匹配的所有广播接收器,并向每个匹配的接收器发送一个显式广播。
  108. *
  109. * @param context 上下文,用于发送广播。
  110. * @param intent 需要发送的隐式广播意图。
  111. * @param action 执行的动作
  112. */
  113. public void sendImplicitBroadcast(Context context, Intent intent, String action) {
  114. // 获取包管理器,用于查询广播接收器
  115. PackageManager pm = context.getPackageManager();
  116. // 查询与intent相匹配的所有广播接收器
  117. List<ResolveInfo> matches = pm.queryBroadcastReceivers(intent, 0);
  118. // 遍历所有匹配的广播接收器
  119. for (ResolveInfo resolveInfo : matches) {
  120. // 创建一个新的意图,将其转换为显式意图,目标为当前接收器
  121. Intent explicit = new Intent(intent);
  122. // 设置组件名称,转换为显式意图
  123. ComponentName cn = new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName, resolveInfo.activityInfo.name);
  124. explicit.setComponent(cn);
  125. // 向每个匹配的广播接收器发送显式广播
  126. context.sendBroadcast(explicit);
  127. }
  128. Log.d(TAG, "sendImplicitBroadcast(),发送隐式广播,action:" + action);
  129. }
  130. /**
  131. * 打开手机的热点
  132. * 需要在build.gradle文件添加三方库依赖:implementation 'com.linkedin.dexmaker:dexmaker-mockito:2.12.1'
  133. * @param context
  134. */
  135. public void startTethering(Context context){
  136. ConnectivityManager connectivityManager = ((ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE));
  137. try{
  138. Class classOnStartTetheringCallback = Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
  139. Method startTethering=connectivityManager.getClass().getDeclaredMethod("startTethering",int.class,boolean.class,classOnStartTetheringCallback);
  140. Object proxy = ProxyBuilder.forClass(classOnStartTetheringCallback).handler(new InvocationHandler(){
  141. @Override
  142. public Object invoke(Object o,Method method,Object[]objects)throws Throwable{
  143. return null;
  144. }
  145. }).build();
  146. startTethering.invoke(connectivityManager,0,false,proxy);
  147. } catch(Exception e){
  148. e.printStackTrace();
  149. }
  150. Log.d(TAG, "startTethering(),打开手机的热点");
  151. }
  152. /**
  153. * 关闭手机的热点
  154. */
  155. public void stopTethering(Context context){
  156. ConnectivityManager connectivityManager=((ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE));
  157. try{
  158. Method stopTethering = connectivityManager.getClass().getDeclaredMethod("stopTethering",int.class);
  159. stopTethering.invoke(connectivityManager,0);
  160. }catch(Exception e){
  161. e.printStackTrace();
  162. }
  163. Log.d(TAG, "stopTethering(),关闭手机的热点");
  164. }
  165. /**
  166. * 判断是否开启手机的热点
  167. * @param context
  168. * @return
  169. */
  170. public boolean isWifiApEnabled(Context context){
  171. WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(
  172. Context.WIFI_SERVICE);
  173. try{
  174. Method method=wifiManager.getClass().getMethod("isWifiApEnabled");
  175. method.setAccessible(true);
  176. return(Boolean)method.invoke(wifiManager);
  177. }catch(NoSuchMethodException e){
  178. e.printStackTrace();
  179. }catch(Exception e){
  180. e.printStackTrace();
  181. }
  182. Log.d(TAG, "isWifiApEnabled(),判断是否开启手机的热点");
  183. return false;
  184. }
  185. /**
  186. * 获取手机的热点信息
  187. * @param context
  188. * @return
  189. */
  190. public String getApInfo(Context context){
  191. WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
  192. try{
  193. Method localMethod = wifiManager.getClass().getDeclaredMethod("getWifiApConfiguration", new Class[0]);
  194. Object config = localMethod.invoke(wifiManager);
  195. Log.d(TAG, "getApInfo(),获取手机的热点信息:" + config.toString());
  196. }catch(Exception localException){
  197. localException.printStackTrace();
  198. }
  199. return null;
  200. }
  201. /**
  202. * 获取连接到手机热点上的设备信息
  203. * @return
  204. */
  205. public List<HashMap> getConnectedApInfo() {
  206. List<HashMap> connectedApInfo = new ArrayList<>();
  207. try {
  208. BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp"));
  209. String line;
  210. while ((line = br.readLine()) != null) {
  211. /**
  212. * 获取到的数组结果,示例:[192.168.227.138, 0x1, 0x2, 82:64:5e:01:49:fc, *, wlan2]
  213. */
  214. String[] splitted = line.split(" +");
  215. HashMap hashMap = new HashMap();
  216. //设备信息判断标准
  217. if (splitted.length >= 4 && splitted[3].contains(":")) {
  218. String ip = splitted[0]; //获取IP地址信息,代替设备名称
  219. String address = splitted[3]; //获取Mac地址信息
  220. hashMap.put("name", ip);
  221. hashMap.put("address", address);
  222. connectedApInfo.add(hashMap);
  223. Log.d(TAG, "getConnectedApInfo(),获取连接到手机热点上的设备信息:" + Arrays.toString(splitted) + " connectedApInfo:" + connectedApInfo.size() + " " + connectedApInfo);
  224. }
  225. }
  226. } catch (Exception e) {
  227. e.printStackTrace();
  228. }
  229. return connectedApInfo;
  230. }
三. 调用示例:
  1. //返回的是一个数据形式是包含HahMap集合的List集合,可根据HashMap的键值对取值并显示
  2. WifiHotspotManager wifiHotspotManager = new WifiHotspotManager(requireActivity());
  3. List<HashMap> connectedApInfo = wifiHotspotManager.getConnectedApInfo();
  4. Log.d(TAG, "connectedApInfo:" + connectedApInfo.size() + " " + connectedApInfo);
四.手机热点已连接设备与功能效果图

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/827363
推荐阅读
相关标签
  

闽ICP备14008679号