(1).增加权限
AndroidManifest.xml声明权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
(2).导入依赖库
build.gradle导入依赖声明
api 'com.linkedin.dexmaker:dexmaker:2.28.1' // ProxyBuilder依赖包
api 'com.github.getActivity:XXPermissions:16.2' // 权限申请依赖包
(3.)WiFi获取工具类
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class WifiApUtil {
public static final String TAG = WifiApUtil.class.getSimpleName();
// wifi热点开关
public static void setWifiApEnabled(boolean isEnable) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
Log.d(TAG, "安卓6.0及以下,使用setWifiApEnabled反射,开启关闭热点。");
WifiManager mWifiManager = (WifiManager) MyApplication.applicationContext.getSystemService(Context.WIFI_SERVICE);
try {
Method methodWifiApState = mWifiManager.getClass().getMethod("getWifiApState");
int getWifiApState = (Integer) methodWifiApState.invoke(mWifiManager);
// 获取属性值
Field field = mWifiManager.getClass().getDeclaredField("WIFI_AP_STATE_ENABLED");
int value = (int) field.get(mWifiManager);
if (isEnable) {
if (getWifiApState == value) {
Log.d(TAG, "热点已开启");
return;
}
}
Method methodWifiApConfiguration = mWifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration mWifiConfiguration = (WifiConfiguration) methodWifiApConfiguration.invoke(mWifiManager);
Method methodWifiApEnabled = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
boolean flag = (Boolean) methodWifiApEnabled.invoke(mWifiManager, mWifiConfiguration, isEnable);
Log.d(TAG, "热点" + (isEnable ? "开启" : "关闭") + "操作状态:" + flag);
if (flag) {
if (isEnable) {
Log.d(TAG, "热点成功开启");
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return;
}
TestOreoWifiManager mTestOreoWifiManager = new TestOreoWifiManager();
if (isEnable) {
Log.d(TAG, "安卓7.0以上,以proxy实现,开启关闭热点。");
TestOreoWifiManager.TestOnStartTetheringCallback mCallback = new TestOreoWifiManager.TestOnStartTetheringCallback() {
@Override
public void onTetheringStarted() {
Log.d(TAG, "热点开启状态:" + "onTetheringStarted");
}
@Override
public void onTetheringFailed() {
Log.d(TAG, "热点开启操作状态:" + "onTetheringFailed。");
Log.d(TAG, "onTetheringFailed");
}
};
mTestOreoWifiManager.startTethering(mCallback);
} else {
mTestOreoWifiManager.stopTethering();
}
}
// 关闭热点
public static void closeWifiAp() {
WifiApUtil.setWifiApEnabled(false);
}
}
(4)TestOreoWifiManager工具类
import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;
import com.android.dx.stock.ProxyBuilder;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestOreoWifiManager {
public static final String TAG = TestOreoWifiManager.class.getSimpleName();
public interface TestOnStartTetheringCallback {
/**
* Called when tethering has been successfully started.
*/
void onTetheringStarted();
/**
* Called when starting tethering failed.
*/
void onTetheringFailed();
}
private ConnectivityManager mConnectivityManager;
public TestOreoWifiManager() {
mConnectivityManager = MyApplication.applicationContext.getSystemService(ConnectivityManager.class);
}
/**
* Checks where tethering is on.
* This is determined by the getTetheredIfaces() method, that will return an empty array if not devices are tethered
*
* @return true if a tethered device is found, false if not found
*/
public boolean isTetherActive() {
try {
Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
if (method == null) {
Log.e(TAG, "getTetheredIfaces is null");
} else {
String[] res = (String[]) method.invoke(mConnectivityManager, null);
Log.d(TAG, "getTetheredIfaces invoked");
Log.d(TAG, Arrays.toString(res));
if (res.length > 0) {
return true;
}
}
} catch (Exception e) {
Log.e(TAG, "Error in getTetheredIfaces");
e.printStackTrace();
}
return false;
}
/**
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
* Does not require app to have system/privileged access
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
*/
public boolean startTethering(final TestOnStartTetheringCallback callback) {
// On Pie if we try to start tethering while it is already on, it will be disabled. This is needed when startTethering() is called programmatically.
if (isTetherActive()) {
Log.d(TAG, "Tether already active, returning");
return false;
}
File outputDir = MyApplication.applicationContext.getCodeCacheDir();
Object proxy;
try {
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass()).dexCache(outputDir).handler(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "onTetheringStarted":
callback.onTetheringStarted();
break;
case "onTetheringFailed":
callback.onTetheringFailed();
break;
default:
ProxyBuilder.callSuper(proxy, method, args);
}
return null;
}
}).build();
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering ProxyBuilder");
e.printStackTrace();
return false;
}
Method method = null;
try {
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
Log.d(TAG, "startTethering invoked");
}
return true;
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering");
e.printStackTrace();
}
return false;
}
public void stopTethering() {
try {
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
if (method == null) {
Log.e(TAG, "stopTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
Log.d(TAG, "stopTethering invoked");
}
} catch (Exception e) {
Log.e(TAG, "stopTethering error: " + e.toString());
e.printStackTrace();
}
}
private Class OnStartTetheringCallbackClass() {
try {
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
Log.e(TAG, "OnStartTetheringCallbackClass error: " + e.toString());
e.printStackTrace();
}
return null;
}
}
(5)权限申请方法
开启热点代码
public void requestSystemSetPermissionAndOptionWifiAp() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// 安卓6.0以下,不需要申请权限
WifiApUtil.setWifiApEnabled(true);
} else {
// 安卓6.0及以上,需要申请修改系统设置权限
XXPermissions.with(BaseActivity.this).permission(Permission.WRITE_SETTINGS).request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (all) {
// 已有权限,开启本地热点
WifiApUtil.setWifiApEnabled(true);
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
// 用户已禁止权限,弹框提示
showDialog("软件需要申请修改系统设置权限,是否去开启相关权限?", new OnDialogClickListener() {
@Override
public void cancelClick(DialogInterface dialog) {
// 用户拒绝进行授权
showToast("没有授予相关权限,部分功能将受影响");
}
@Override
public void okClick(DialogInterface dialog) {
// 用户同意再次请求权限
XXPermissions.startPermissionActivity(BaseActivity.this, permissions, new OnPermissionPageCallback() {
@Override
public void onGranted() {
requestSystemSetPermissionAndOptionWifiAp();
}
@Override
public void onDenied() {
requestSystemSetPermissionAndOptionWifiAp();
}
});
}
});
}
});
}
}
(7).关闭热点
关闭热点
WifiApUtil.setWifiApEnabled(false);