赞
踩
主题:在手机开启热点网络的情况下,想要获取是哪个设备已经连接上了当前开启的热点。
实现思路: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(){
- @Override
- public 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);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。