献上代码
其中Utils.getContext()是来自application的context
控制热点:
public class WifiApUtils {
private static final String TAG = "WifiApUtils";
public static void openWifiAP(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断android系统版本,高于8.0
startTethering();
} else {
createWiFiAP(createWifiInfo("MyCar", "12345678", 3, "ap"), true);
}
}
public static void closeWifiAP(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断android系统版本,高于8.0
stopTethering();
} else {
closeWifiHotPoint();
}
}
private static WifiConfiguration createWifiInfo2(String ssid,
String password, int paramInt) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = ssid;
if (paramInt == 1) // WIFICIPHER_NOPASS 不加密
{
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
return config;
}
if (paramInt == 2) // WIFICIPHER_WEP WEP加密
{
config.hiddenSSID = true;
config.wepKeys[0] = password;
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
return config;
}
if (paramInt == 3) // WIFICIPHER_WPA wpa加密
{
config.preSharedKey = password;
config.hiddenSSID = true;
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
return config;
}
return null;// 返回null,创建热点失败
}
/**
* android8.0以上开启手机热点
*/
private static void startTethering() {
ConnectivityManager connectivityManager = ((ConnectivityManager) Utils.getContext().getSystemService(Context.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) {
Log.e(TAG,"打开热点失败");
e.printStackTrace();
}
}
/**
* android8.0以上关闭手机热点
*/
private static void stopTethering(){
ConnectivityManager connectivityManager = ((ConnectivityManager) Utils.getContext().getSystemService(Context.CONNECTIVITY_SERVICE));
try {
Method stopTethering = connectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
stopTethering.invoke(connectivityManager,0);
} catch (Exception e) {
Log.e(TAG,"关闭热点失败");
e.printStackTrace();
}
}
/**
* 创建WiFi热点
* @param config WiFi配置信息
* @param paramBoolean true为开启WiFi热点,false为关闭
* @return 返回开启成功状态,true为成功,false为失败
*/
private static boolean createWiFiAP(WifiConfiguration config, boolean paramBoolean) {
// 开启热点前,如果WiFi可用,先关闭WiFi
WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
Log.i(TAG, "into startWifiAp() 启动一个Wifi 热点!");
boolean ret = false;
try {
Method method = wifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
ret = (Boolean) method.invoke(wifiManager, config, paramBoolean);
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() IllegalArgumentException e");
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() IllegalAccessException e");
} catch (InvocationTargetException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() InvocationTargetException e");
} catch (SecurityException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() SecurityException e");
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() NoSuchMethodException e");
}
Log.i(TAG, "out startWifiAp() 启动一个Wifi 热点!");
return ret;
}
/**
* 创建WiFi热点
* @param wifiManager WiFi管理器
* @param config WiFi配置信息
* @param paramBoolean true为开启WiFi热点,false为关闭
* @return 返回开启成功状态,true为成功,false为失败
*/
private static boolean createWiFiAP(WifiManager wifiManager, WifiConfiguration config, boolean paramBoolean,String methodName) {
// 开启热点前,如果WiFi可用,先关闭WiFi
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
Log.i(TAG, "into startWifiAp() 启动一个Wifi 热点!");
boolean ret = false;
try {
Method method = wifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
ret = (Boolean) method.invoke(wifiManager, config, paramBoolean);
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() IllegalArgumentException e");
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() IllegalAccessException e");
} catch (InvocationTargetException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() InvocationTargetException e");
} catch (SecurityException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() SecurityException e");
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.d(TAG, "stratWifiAp() NoSuchMethodException e");
}
Log.i(TAG, "out startWifiAp() 启动一个Wifi 热点!");
return ret;
}
/**
* 配置WiFi或者热点信息
*
* @param ssid
* WiFi名称
* @param password
* WiFi密码
* @param paramInt
* WiFi加密方式 1为不加密,2为WEP加密,3为wpa加密
* @param wifiType
* “wifi”为打开普通WiFi连接,“ap”为创建WiFi热点
* @return
*/
private static WifiConfiguration createWifiInfo(String ssid, String password, int paramInt, String wifiType) {
WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
WifiConfiguration Config1 = new WifiConfiguration();
Config1.allowedAuthAlgorithms.clear();
Config1.allowedGroupCiphers.clear();
Config1.allowedKeyManagement.clear();
Config1.allowedPairwiseCiphers.clear();
Config1.allowedProtocols.clear();
if ("wifi".equals(wifiType)) {
Config1.SSID = ("\"" + ssid + "\"");
WifiConfiguration Config2 = isExsits(wifiManager, ssid);
if (Config2 != null) {
if (wifiManager != null) {
wifiManager.removeNetwork(Config2.networkId);
}
}
if (paramInt == 1) {
Config1.wepKeys[0] = "";
Config1.allowedKeyManagement.set(0);
Config1.wepTxKeyIndex = 0;
Config1.hiddenSSID=false;
Log.i(TAG, "1");
return Config1;
} else if (paramInt == 2) {
Config1.wepKeys[0] = ("\"" + password + "\"");
Log.i(TAG, "2");
Config1.hiddenSSID=false;
return Config1;
} else {
Config1.preSharedKey = ("\"" + password + "\"");
Config1.allowedAuthAlgorithms.set(0);
Config1.allowedGroupCiphers.set(2);
Config1.allowedKeyManagement.set(1);
Config1.allowedPairwiseCiphers.set(1);
Config1.allowedGroupCiphers.set(3);
Config1.allowedPairwiseCiphers.set(2);
Config1.hiddenSSID=false; //不隐藏设备
Log.i(TAG, "3");
return Config1;
}
} else {
WifiConfiguration wifiApConfig = new WifiConfiguration();
wifiApConfig.allowedAuthAlgorithms.clear();
wifiApConfig.allowedGroupCiphers.clear();
wifiApConfig.allowedKeyManagement.clear();
wifiApConfig.allowedPairwiseCiphers.clear();
wifiApConfig.allowedProtocols.clear();
wifiApConfig.SSID = ssid;
if (paramInt == 1) { // WIFICIPHER_NOPASS 不加密
wifiApConfig.wepKeys[0] = "";
wifiApConfig.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.NONE);
wifiApConfig.wepTxKeyIndex = 0;
return wifiApConfig;
}
if (paramInt == 2){ // WIFICIPHER_WEP WEP加密
wifiApConfig.hiddenSSID = true;
wifiApConfig.wepKeys[0] = password;
wifiApConfig.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
wifiApConfig.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.CCMP);
wifiApConfig.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.TKIP);
wifiApConfig.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP40);
wifiApConfig.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
wifiApConfig.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.NONE);
wifiApConfig.wepTxKeyIndex = 0;
return wifiApConfig;
}
if (paramInt == 3) {// WIFICIPHER_WPA wpa加密
wifiApConfig.preSharedKey = password;
wifiApConfig.hiddenSSID =false;
wifiApConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wifiApConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
Log.e(TAG,"是否小米:"+isMIUI());
if(isMIUI()){
wifiApConfig.allowedKeyManagement.set(6); //WPA2_PSK 小米系统为6,其它一般为4
}else {
wifiApConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
}
wifiApConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wifiApConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiApConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiApConfig.status = WifiConfiguration.Status.ENABLED;
return wifiApConfig;
}
}
return null;
}
private static boolean isMIUI() {
try {
String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
Properties prop = new Properties();
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (IOException e) {
return false;
}
}
/**8.0以下
* 关闭WiFi热点
* WiFi管理器
* @return 返回关闭状态
*/
private static boolean closeWifiHotPoint() {
Log.i(TAG, "into closeWifiAp() 关闭一个Wifi 热点!");
boolean ret = false;
WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
if (isWifiApEnabled()) {
try {
Method method = wifiManager.getClass().getMethod(
"getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration config = (WifiConfiguration) method
.invoke(wifiManager);
Method method2 = wifiManager.getClass().getMethod(
"setWifiApEnabled", WifiConfiguration.class,
boolean.class);
ret = (Boolean) method2.invoke(wifiManager, config, false);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
Log.i(TAG, "out closeWifiAp() 关闭一个Wifi 热点!");
return ret;
}
/**
* 检测WiFi热点是否可用
*
* @return 是否可用状态
*/
public static boolean isWifiApEnabled() {
WifiManager wifiManager = (WifiManager) Utils.getContext().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();
}
return false;
}
/**
* 通过反射,获取WiFi热点名称 SSID
* @return
*/
public static String getApSSID() {
WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
try {
Method localMethod = wifiManager.getClass().getDeclaredMethod(
"getWifiApConfiguration", new Class[0]);
if (localMethod == null)
return null;
Object localObject1 = localMethod
.invoke(wifiManager, new Object[0]);
if (localObject1 == null)
return null;
WifiConfiguration localWifiConfiguration = (WifiConfiguration) localObject1;
if (localWifiConfiguration.SSID != null)
return localWifiConfiguration.SSID;
Field localField1 = WifiConfiguration.class
.getDeclaredField("mWifiApProfile");
if (localField1 == null)
return null;
localField1.setAccessible(true);
Object localObject2 = localField1.get(localWifiConfiguration);
localField1.setAccessible(false);
if (localObject2 == null)
return null;
Field localField2 = localObject2.getClass()
.getDeclaredField("SSID");
localField2.setAccessible(true);
Object localObject3 = localField2.get(localObject2);
if (localObject3 == null)
return null;
localField2.setAccessible(false);
String str = (String) localObject3;
return str;
} catch (Exception localException) {
}
return null;
}
/**
* 获取WiFi热点的状态
*
*/
private int getWifiApState() {
WifiManager wifiManager = (WifiManager) Utils.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
try {
int i = ((Integer) wifiManager.getClass()
.getMethod("getWifiApState", new Class[0])
.invoke(wifiManager, new Object[0])).intValue();
return i;
} catch (Exception localException) {
}
return 4; // 未知wifi网卡状态
}
/**
* 判断选择的WiFi热点是否可以连接
*
* @param ssid
* WiFi热点名 SSID
* @param wifiList
* 附近的WiFi列表
* @return true 可以连接 false 不可以连接(不在范围内)
*/
public static boolean checkCoonectHotIsEnable(String ssid,
List<ScanResult> wifiList) {
for (ScanResult result : wifiList) {
if (result.SSID.equals(ssid)) {
return true;
}
}
return false;
}
/**
* 检查wifi列表中是否有以输入参数为名的wifi热点,如果存在,则在开始配置wifi网络之前将其移除,以避免ssid的重复
*
* @param wifiManager
* @param
* @return
*/
private static WifiConfiguration isExsits(WifiManager wifiManager,
String paramString) {
Iterator<WifiConfiguration> localIterator = wifiManager
.getConfiguredNetworks().iterator();
WifiConfiguration localWifiConfiguration;
do {
if (!localIterator.hasNext())
return null;
localWifiConfiguration = (WifiConfiguration) localIterator.next();
} while (!localWifiConfiguration.SSID.equals("\"" + paramString + "\""));
return localWifiConfiguration;
}
private static List<WifiConfiguration> getWifiConfigurations(
WifiManager wifiManager) {
List<WifiConfiguration> existingConfigs = wifiManager
.getConfiguredNetworks();
return existingConfigs;
}
}
android8.0以上需要使用到反射获取隐藏的系统api和动态代理隐藏的抽象类回调
。其中动态代理抽象类回调需要使用ProxyBuilder类,故依赖一个库:
在项目下的build.gradle添加依赖:
implementation 'com.linkedin.dexmaker:dexmaker-mockito:2.12.1'
控制wifi:
public class WifiUtils {
/**
* 打开或关闭wifi
* 需添加权限 {@code }
*
* @param enabled {@code true}: 打开
{@code false}: 关闭
*/
public static void setWifiEnabled( boolean enabled) {
WifiManager wifiManager = (WifiManager) Utils
.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
if (enabled) {
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
} else {
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
}
}
/**
* 判断wifi是否打开
* 需添加权限 {@code }
*
* @return {@code true}: 是
{@code false}: 否
*/
public static boolean getWifiEnabled() {
WifiManager wifiManager = (WifiManager) Utils
.getContext().getApplicationContext().getSystemService(
Context.WIFI_SERVICE);
return wifiManager.isWifiEnabled();
}
}
注册监听wifi和热点状态:
public class WifiManage {
private WifiReceiver wifiReceiver = new WifiReceiver();
public void registerWifiBroadcast(WifiReceiver.WifiStateListener wifiStateListener) {
//刚注册广播时立即收到一条当前状态的广播
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED");
Utils.getContext().registerReceiver(wifiReceiver, filter);
wifiReceiver.setWifiStateListener(wifiStateListener);
}
public void unregisterWifiBroadcast() {
wifiReceiver.setWifiStateListener(null);
Utils.getContext().unregisterReceiver(wifiReceiver);
}
public static void openOrCloseWifi() {
if (WifiApUtils.isWifiApEnabled()){
WifiApUtils.closeWifiAP();
};
WifiUtils.setWifiEnabled(!WifiUtils.getWifiEnabled());
ToastUtils.showShortToast(WifiUtils.getWifiEnabled() ? "正在关闭WiFi" : "正在打开WiFi");
}
}
public class WifiReceiver extends BroadcastReceiver {
private WifiStateListener wifiStateListener;
public void setWifiStateListener(WifiStateListener wifiStateListener) {
this.wifiStateListener = wifiStateListener;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null &&
intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
switch (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)) {
case WifiManager.WIFI_STATE_DISABLED: {
setWifiState(false);
ToastUtils.showShortToast("已关闭WiFi");
break;
}
case WifiManager.WIFI_STATE_DISABLING:
break;
case WifiManager.WIFI_STATE_ENABLED: {
setWifiState(true);
ToastUtils.showShortToast("已打开WiFi");
break;
}
case WifiManager.WIFI_STATE_ENABLING:
break;
case WifiManager.WIFI_STATE_UNKNOWN:
break;
}
}
if (intent.getAction() != null &&
intent.getAction().equals("android.net.wifi.WIFI_AP_STATE_CHANGED")) {
//热点的状态为:10---正在关闭;11---已关闭;12---正在开启;13---已开启
int state = intent.getIntExtra("wifi_state", 0);
switch (state) {
case 10://热点状态:正在关闭
break;
case 11://热点状态:已关闭
setHotpotState(false);
break;
case 12://热点状态:正在开启
break;
case 13://热点状态:已开启
setHotpotState(true);
break;
}
}
}
public interface WifiStateListener {
void onWifiOpen();
void onWifiClose();
void onHotpotOpen();
void onHotpotClose();
}
private void setWifiState(boolean b) {
if (wifiStateListener != null) {
if (b) {
wifiStateListener.onWifiOpen();
} else {
wifiStateListener.onWifiClose();
}
}
}
private void setHotpotState(boolean b) {
if (wifiStateListener != null) {
if (b) {
wifiStateListener.onHotpotOpen();
} else {
wifiStateListener.onHotpotClose();
}
}
}
}