Android熱點相關功能開發
阿新 • • 發佈:2019-02-13
本文中所用到的方法,在MT6582平臺、API19測試可行,其它平臺不一定可以,要具體測。
下面我把我封裝的熱點管理類貼出來,可以實現熱點相關的所有功能(除了設定最大允許連線數和一定時間無裝置連線後關閉熱點的功能),包括開啟、關閉熱點,設定熱點名稱、密碼,禁用、解除禁用某個裝置。
注:
1.HotspotClient類,在原始碼中放在android.net.wifi包下,所以新建android.net.wifi的包用來存放,否則可能會出問題;
2.這裡面好幾個方法我都是通過遍歷WifiManager的所有方法獲取的,因為我在直接獲取的時候總會報NoSuchMethodException,不明白原因;
3.使用的時候,mWifiManager根據自己專案的實際情況不要忘記初始化就好。
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import android.util.Log; import android.net.wifi.HotspotClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; public class HotspotManager { private static final String Tag = "HotspotManager"; public static WifiManager mWifiManager; /** * 設定熱點狀態,會對應的開啟或關閉WiFi * * @param state * 要設定的狀態 * @param ssid * 熱點名稱,can be null * @param pwd * 熱點密碼,can be null * @return 設定成功與否 */ public static boolean setHotPotState(boolean state, String ssid, String pwd) { boolean isOpened = isHotPotTurnedOn(); if (state == isOpened) { Log.i(Tag, "-> Set state is equal with hotpot state!"); return false; } Log.i(Tag, "set hot pot state : " + state); try { WifiConfiguration apConfig = getHotPotConfig(); // 通過反射呼叫設定熱點 Method method = WifiManager.class.getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class); mWifiManager.setWifiEnabled(!state); if (ssid != null) { apConfig.SSID = ssid; } if (pwd != null) { apConfig.preSharedKey = pwd; } return (boolean) method.invoke(mWifiManager, apConfig, state); } catch (Exception e) { Log.e(Tag, "Set hot pot " + state + " got exception : " + e.getLocalizedMessage()); return false; } } /** * 熱點是否開啟 * @return */ public static boolean isHotPotTurnedOn() { try { Method method = mWifiManager.getClass().getDeclaredMethod("isWifiApEnabled"); // 呼叫getWifiApState() ,獲取返回值 return (boolean) method.invoke(mWifiManager); } catch (Exception e) { Log.i(Tag, "Get hot pot state exception -> " + e.getLocalizedMessage()); return false; } } /** * 獲取當前熱點的配置引數 * * @return */ public static HotspotParam getHotPotParams() { try { HotspotParam param = new HotspotParam(); WifiConfiguration config = getHotPotConfig(); if (config.SSID != null && !config.SSID.equals("")) { param.hotspotSSID = new String(config.SSID); } else { config.SSID = ""; } if (config.preSharedKey != null && !config.preSharedKey.equals("")) { param.hotspotPwd = new String(config.preSharedKey); } else { param.hotspotPwd = ""; } param.encryptionType = config.allowedKeyManagement.get(4) ? 4 : 0; List<?> tmp = getHotspotClients(); if (tmp != null && tmp.size() > 0) { param.connectedClientsNum = 0; param.blackListNum = 0; for (int i = 0; i < tmp.size(); i++) { HotspotClient client = (HotspotClient) tmp.get(i); Log.d(Tag, "Got hotspot client -> " + client.deviceAddress); if (!client.isBlocked) { if (param.connectedClients == null) { param.connectedClients = new String[tmp.size()]; } param.connectedClients[param.connectedClientsNum] = new String(client.deviceAddress); param.connectedClientsNum++; } else { if (param.blackList == null) { param.blackList = new String[tmp.size()]; } param.blackList[param.blackListNum] = new String(client.deviceAddress); param.blackListNum++; } } } return param; } catch (IllegalAccessException e) { Log.e(Tag, "getHotPotParams IllegalAccessException : " + e.getMessage()); return null; } catch (NoSuchMethodException e) { Log.e(Tag, "getHotPotParams NoSuchMethodException : " + e.getMessage()); return null; } catch (IllegalArgumentException e) { Log.e(Tag, "getHotPotParams IllegalArgumentException : " + e.getMessage()); return null; } catch (InvocationTargetException e) { Log.e(Tag, "getHotPotParams InvocationTargetException : " + e.getMessage()); return null; } } /** * 設定熱點名稱 * * @param length * 名稱長度 1-32bytes * @param ssid * 名稱 */ public static boolean setHotPotSSID(String ssid) { try { WifiConfiguration config = getHotPotConfig(); String former = config.SSID; Log.i(Tag, "former ssid:" + former + " set ssid:" + ssid); config.SSID = ssid; Log.i(Tag, "pwd:" + config.preSharedKey); return setWifiApConfiguration(config); } catch (NoSuchMethodException e) { Log.e(Tag, "setHotPotSSID NoSuchMethodException : " + e.getLocalizedMessage()); return false; } catch (IllegalAccessException e) { Log.e(Tag, "setHotPotSSID IllegalAccessException : " + e.getLocalizedMessage()); return false; } catch (IllegalArgumentException e) { Log.e(Tag, "setHotPotSSID IllegalArgumentException : " + e.getLocalizedMessage()); return false; } catch (InvocationTargetException e) { Log.e(Tag, "setHotPotSSID InvocationTargetException : " + e.getLocalizedMessage()); return false; } } /** * 設定熱點密碼 * * @param pwd * @return */ public static boolean setHotPotPwd(String pwd) { try { WifiConfiguration config = getHotPotConfig(); String former = config.preSharedKey; Log.d(Tag, "former pwd:" + former + " set pwd:" + pwd); config.preSharedKey = pwd; return setWifiApConfiguration(config); } catch (NoSuchMethodException e) { Log.e(Tag, "setHotPotPwd NoSuchMethodException : " + e.getLocalizedMessage()); return false; } catch (IllegalAccessException e) { Log.e(Tag, "setHotPotPwd IllegalAccessException : " + e.getLocalizedMessage()); return false; } catch (IllegalArgumentException e) { Log.e(Tag, "setHotPotPwd IllegalArgumentException : " + e.getLocalizedMessage()); return false; } catch (InvocationTargetException e) { Log.e(Tag, "setHotPotPwd InvocationTargetException : " + e.getLocalizedMessage()); return false; } } /** * 設定加密方式 * * @param type * 0代表不加密,4代表WPA2_PSK * @return */ public static boolean setHotPotEncryption(int type) { int tmp = 0; if (type == 0) { tmp = 0; } else { tmp = 4; } try { WifiConfiguration config = getHotPotConfig(); int oldEnc = config.allowedKeyManagement.get(4) ? 4 : 0; Log.d(Tag, "former encryption:" + oldEnc + " set encryption:" + tmp); if (oldEnc == -1) { Log.e(Tag, "Unexpected here!!!加密方式只有兩種選擇,檢查程式碼"); oldEnc = 0; } if (oldEnc == tmp) { return true; } config.allowedKeyManagement.clear(); config.allowedKeyManagement.set(tmp); if (tmp == 4) { config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); // WPA2_PSK } else { config.wepTxKeyIndex = 0; config.wepKeys[0] = ""; } return setWifiApConfiguration(config); } catch (NoSuchMethodException e) { Log.e(Tag, "setHotPotEncryption NoSuchMethodException : " + e.getLocalizedMessage()); return false; } catch (IllegalAccessException e) { Log.e(Tag, "setHotPotEncryption IllegalAccessException : " + e.getLocalizedMessage()); return false; } catch (IllegalArgumentException e) { Log.e(Tag, "setHotPotEncryption IllegalArgumentException : " + e.getLocalizedMessage()); return false; } catch (InvocationTargetException e) { Log.e(Tag, "setHotPotEncryption InvocationTargetException : " + e.getLocalizedMessage()); return false; } } /** * 設定黑名單 * @param deviceAddr * @return */ public static boolean blockClient(String deviceAddr) { try { // 獲取當前連線的客戶端 List<?> list = getHotspotClients(); if (list == null || (list != null && list.size() == 0)) { Log.e(Tag, "blockClient current connected clients is null!"); return false; } // 通過反射獲取設定黑名單方法 Method method = null; Method[] methods = WifiManager.class.getMethods(); for (Method method2 : methods) { if (method2.getName().equals("blockClient")) { method = method2; break; } } if (method == null) { Log.e(Tag, "blockClient cannot find blockClient method"); return false; } for (int i = 0; i < list.size(); i++) { HotspotClient client = (HotspotClient) list.get(i); if (client.deviceAddress.equals(deviceAddr) && !client.isBlocked) { return (boolean) method.invoke(mWifiManager, client); } } return false; } catch (IllegalAccessException e) { Log.e(Tag, "blockClient exception : " + e.getLocalizedMessage()); return false; } catch (IllegalArgumentException e) { Log.e(Tag, "blockClient exception : " + e.getLocalizedMessage()); return false; } catch (InvocationTargetException e) { Log.e(Tag, "blockClient exception : " + e.getLocalizedMessage()); return false; } } /** * 移出黑名單 * @param addr * @return */ public static boolean unblockClient(String addr) { // 通過反射獲取設定黑名單方法 Method method = null; Method[] methods = WifiManager.class.getMethods(); for (Method method2 : methods) { if (method2.getName().equals("unblockClient")) { method = method2; break; } } if (method == null) { Log.e(Tag, "unblockClient cannot find unblockClient method"); return false; } Log.d(Tag, "unblock client -> " + addr); HotspotClient client = new HotspotClient(addr, true); try { return (boolean) method.invoke(mWifiManager, client); } catch (IllegalAccessException e) { Log.e(Tag, "unblockClient exception : " + e.getLocalizedMessage()); return false; } catch (IllegalArgumentException e) { Log.e(Tag, "unblockClient exception : " + e.getLocalizedMessage()); return false; } catch (InvocationTargetException e) { Log.e(Tag, "unblockClient exception : " + e.getLocalizedMessage()); return false; } } /** * 設定熱點配置 * @param config * @return */ private static boolean setWifiApConfiguration(WifiConfiguration config) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method method = null; Method[] methods = WifiManager.class.getMethods(); for (Method method2 : methods) { if (method2.getName().equals("setWifiApConfiguration")) { method = method2; break; } } if (method == null) { return false; } return (boolean) method.invoke(mWifiManager, config); } @SuppressWarnings("unused") private static ArrayList<String> getCurrentConnectedClients() { ArrayList<String> connected = null; try { File file = new File("/proc/net/arp"); if (!file.exists()) { return null; } connected = new ArrayList<>(); FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr); String line = reader.readLine(); while ((line = reader.readLine()) != null) { String[] tokens = line.split("[ ]+"); if (tokens != null && tokens.length >= 4) { String flag = tokens[2];// 連線狀態,這個也不準確 String HWAddr = tokens[3];// 地址 if (!HWAddr.equals("00:00:00:00:00:00")) { connected.add(HWAddr); Log.d(Tag, "地址:" + HWAddr + ",狀態:" + flag); } } } reader.close(); if (connected.size() > 0) { return connected; } else return null; } catch (Exception e) { Log.e(Tag, "Get connected clients exception : " + e.getLocalizedMessage()); return null; } } /** * 獲取當前連線到熱點的客戶端 * @return */ private static List<?> getHotspotClients() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method method = null; Method[] methods = WifiManager.class.getMethods(); for (Method method2 : methods) { if (method2.getName().equals("getHotspotClients")) { method = method2; break; } } if (method == null) { return null; } return (List<?>) method.invoke(mWifiManager); } /** * 獲取當前熱點配置 * @return */ private static WifiConfiguration getHotPotConfig() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method method = WifiManager.class.getDeclaredMethod("getWifiApConfiguration"); method.setAccessible(true); WifiConfiguration config = (WifiConfiguration) method.invoke(mWifiManager); return config; } }
package android.net.wifi; import android.os.Parcel; import android.os.Parcelable; /** * A class representing a hotspot client * @hide */ public class HotspotClient implements Parcelable { /** * The MAC address of the client * @hide * @internal */ public String deviceAddress; /** * The flag indicates whether this client is blocked or not * @hide * @internal */ public boolean isBlocked = false; /** * @hide */ public HotspotClient(String address, boolean blocked) { deviceAddress = address; isBlocked = blocked; } /** * @hide */ public HotspotClient(HotspotClient source) { if (source != null) { deviceAddress = source.deviceAddress; isBlocked = source.isBlocked; } } /** * @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append(" deviceAddress: ").append(deviceAddress); sbuf.append('\n'); sbuf.append(" isBlocked: ").append(isBlocked); sbuf.append("\n"); return sbuf.toString(); } /** Implement the Parcelable interface {@hide} */ public int describeContents() { return 0; } /** Implement the Parcelable interface {@hide} */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(deviceAddress); dest.writeByte(isBlocked ? (byte)1 : (byte)0); } /** Implement the Parcelable interface {@hide} */ public static final Creator<HotspotClient> CREATOR = new Creator<HotspotClient>() { public HotspotClient createFromParcel(Parcel in) { HotspotClient result = new HotspotClient(in.readString(), in.readByte() == 1 ? true : false); return result; } public HotspotClient[] newArray(int size) { return new HotspotClient[size]; } }; }
public class HotspotParam {
public String hotspotSSID;
// 密碼最少8個位元組最多32個位元組
public String hotspotPwd;
// 加密方式
public int encryptionType;
// 最大連線數(1-8之間)
public int maxClientsNum;
// 已連線的數量
public int connectedClientsNum;
// 已連線的裝置名稱
public String[] connectedClients;
// 黑名單,最多設定10個
public String[] blackList;
// 黑名單數量
public int blackListNum;
/*--------------------------------------------------------------------------------*/
}