1.manfiest中添加权限
<!-- WiFi AP startTethering -->
<uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
2. android8.0 Ap开启关闭方法
public static void setWiFiApEnable(Context mContext, boolean value) {
ConnectivityManager mConnectivityManager= (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (value) {
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false, new ConnectivityManager.OnStartTetheringCallback() {
@Override
public void onTetheringStarted() {
Log.d(TAG, "onTetheringStarted");
// Don't fire a callback here, instead wait for the next update from wifi.
@Override
public void onTetheringFailed() {
Log.d(TAG, "onTetheringFailed");
// TODO: Show error.
} else {
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
3.WiFiApReceiver广播接收
private static int isWiFiApState = WifiManager.WIFI_AP_STATE_FAILED;
public static boolean isWiFiApOpened_O() {
return (isWiFiApState == WifiManager.WIFI_AP_STATE_ENABLING || isWiFiApState == WifiManager.WIFI_AP_STATE_ENABLED);
private final class WiFiApReceiver extends BroadcastReceiver {
private boolean mRegistered;
public void setListening(boolean listening) {
if (listening && !mRegistered) {
Log.d(TAG, "Registering receiver");
final IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
mContext.registerReceiver(this, filter);
mRegistered = true;
} else if (!listening && mRegistered) {
Log.d(TAG, "Unregistering receiver");
mContext.unregisterReceiver(this);
mRegistered = false;
public void onReceive(Context context, Intent intent) {
isWiFiApState = intent.getIntExtra(
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
String result = null;
switch (isWiFiApState) {
case WifiManager.WIFI_AP_STATE_DISABLED:
result = "DISABLED";
break;
case WifiManager.WIFI_AP_STATE_DISABLING:
result = "DISABLING";
break;
case WifiManager.WIFI_AP_STATE_ENABLED:
result = "ENABLED";
break;
case WifiManager.WIFI_AP_STATE_ENABLING:
result = "ENABLING";
break;
case WifiManager.WIFI_AP_STATE_FAILED:
result = "FAILED";
break;
Log.d(TAG, "WiFi state : " + result);
二.android11的wifi Hotspot开启关闭方式,以proxy实现
1.定义回调接口
public abstract class TestOnStartTetheringCallback {
* Called when tethering has been successfully started.
public abstract void onTetheringStarted();
* Called when starting tethering failed.
public abstract void onTetheringFailed();
2.proxy类
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.Log;
import com.android.dx.stock.ProxyBuilder;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@RequiresApi(api = Build.VERSION_CODES.O)
public class TestOreoWifiManager {
private static final String TAG = TestOreoWifiManager.class.getSimpleName();
private Context mContext;
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
public TestOreoWifiManager(Context c) {
mContext = c;
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
* This sets the Wifi SSID and password
* Call this before {@code startTethering} if app is a system/privileged app
* Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
public void configureHotspot(String name, String password) {
WifiConfiguration apConfig = new WifiConfiguration();
apConfig.SSID = name;
apConfig.preSharedKey = password;
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
try {
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
Log.d(TAG, "setWifiApConfiguration - success? " + status);
} catch (Exception e) {
Log.e(TAG, "Error in configureHotspot");
e.printStackTrace();
* 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 = mContext.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;
3.调用方法
@RequiresApi(api = Build.VERSION_CODES.O)
public static void setHotspotOnPhone(Context mContext, boolean isEnable) {
if (mTestOreoWifiManager ==null){
mTestOreoWifiManager = new TestOreoWifiManager(mContext);
if (isEnable){
TestOnStartTetheringCallback callback = new TestOnStartTetheringCallback() {
@Override
public void onTetheringStarted() {
@Override
public void onTetheringFailed() {
mTestOreoWifiManager.startTethering(callback);
}else{
mTestOreoWifiManager.stopTethering();
热点默认名称和密码都是在 WifiApConfigStore 类中定义可以自定修改默认热点名称是 AndroidAP + 随机生成的1000-9999的数字默认热点密码是15位随机生成的数字/字母普通字符串。
一、WiFi 开机自动打开流程
系统服务启动的时候会启动WifiService,在SystemService.PHASE_SYSTEM_SERVICES_READY的时候,会调用 WifiServiceImpl#checkAndStartWifi(),获取Wi-Fi开关,持久化存储的值。
然后判断是否需要打开WiFi。
* Check if we are ready to start wifi.
/方法名变化,使用null 对象开启热点//方法名再变化ActiveModeManager是接口类,会调用到SoftApManager.start()(12)根据硬件版本调用不同的接口实现:addAccessPoint_X_X热点的配置在SoftApManager.startSoftAp() 会有一定的修改,比如channel ==0 的情况是会在ApConfigUtil.java中,对应的band范围内随机生成一个channel值。
项目中有需要对WiFi热点需要进行某些操作,所以记录下一些有关WiFi热点的知识点
开启或者关闭热点
网上的大部分例子,都是通过反射,调用WifiManager的setWifiApEnabled方法,来开启或者关闭热点,如:
Android WiFi开发 (二)Wifi热点
三、Android开启wifi热点
//热点的配置类
WifiConfiguration apConfig = new WifiConfiguration();
//配置热点的名称(可以在名字后面加点随
一、关闭wifi命令 adb shell svc wifi disable二、打开wifi命令 adb shell svc wifi enable三、查看wifi连接状态
三、扫描热点 wpa_cli -iwlan0 scan
wpa_cli -iwlan0 scan_results四、添加热点 wpa_cli -iwlan0 add_network 0
wpa_cli -iwlan0 set_network 0 ssid "fuckyouw
在12.0的产品rom定制化开发中,在产品开发中,对于功能的开发的功能也是挺多的,而在对于wifi的功能定制需求,有要求需要通过系统属性来控制wifi开关是否可以打开
来控制是否可以连接wifi,打开控制wifi的功能,接下来分析wifi的开启流程来实现该功能的实现
梵蒂冈之花警告此方法在5.0以后将无法使用,这是一个过时的条目。您可以使用以下代码以编程方式启用,禁用和查询wifi直接状态。package com.kusmezer.androidhelper.networking;import java.lang.reflect.Method;import com.google.common.base.Preconditions;import android....