一、准備工作
開發環境:
jdk1.8
AS(3.0.1)
運行環境:
華為V10(Android8.0)、華為p20(Android8.1)、華為mate10(Android8.0)
實現功能:
Wifi熱點的開啟關閉。
二、代碼結構
三、代碼詳解
Android 7.0及以前Wifi熱點
Android 7.1、8.0Wifi熱點
看之前評論發現Android7.1以上的手機開啟Wifi熱點后不能正常使用,故研究了一下如何解決次問題。
Android 7.0 開啟Wifi熱點
在Android7.0及以前的版本開啟Wifi熱點的方式如下:
WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
//反射
method.invoke(mWifiManager, null, false);
Android 7.1 開啟Wifi熱點
對於Android7.1、8.0的設備,通過WifiManager setWifiApEnabled,可以打開Wifi熱點,但是會發現此熱點,連接不上(由於DHCP沒有開啟),所以不會分配ip地址,也就導致不能正常使用。
在Android7.1系統應用Settings,發現其開啟熱點的方式是通過ConnectivityManager的startTethering方法來開啟的。
查看ConnectivityManager的方法
startTethering 是隱藏的方法,並且第三個參數OnStartTetheringCallback是ConnectivityManager內部抽象類,也是隱藏的。
/**
* Callback for use with {@link #startTethering} to find out whether tethering succeeded.
* @hide
*/
@SystemApi
public static abstract class OnStartTetheringCallback {
/**
* Called when tethering has been successfully started.
*/
public void onTetheringStarted() {};
/**
* Called when starting tethering failed.
*/
public void onTetheringFailed() {};
}
通過反射的方式並沒有找到方式獲取startTethering方法,以及創建OnStartTetheringCallback子對象。
后來通過另一種方式實現了。
配置jar包
首先修改ConnectivityManager源碼,將TETHERING_WIFI字段、startTethering方法及OnStartTetheringCallback類中隱藏相關的標志去掉,然后單獨編譯一個jar包。
將jar包拷貝到工程中,如下所示:
該jar包會和官方sdk中的android.jar會有沖突,所以需要配置jar包的優先級。
在app的build.gradle中配置
provided files('src/main/libs/WifiAp8.jar')
在工程下的build.gradle中添加如下配置:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
//設置jar相對包路徑或絕對路徑
options.compilerArgs.add('-Xbootclasspath/p:app/src/main/libs/WifiAp8.jar')
}
}
}
編寫代碼
開啟熱點
if(getWifiAPState() != WIFI_AP_STATE_ENABLED){
//Android7.1及以上版本
if (Build.VERSION.SDK_INT >= 25) {
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI,
true, new ONStartTetheringCallback());
}
}
在AS中上述代碼會有紅色顯示,但是不影響編譯使用。可以正常編譯生成apk。使用該方法不需要提前關閉wifi。
ONStartTetheringCallback類繼承了OnStartTetheringCallback抽象類。
class ONStartTetheringCallback extends
ConnectivityManager.OnStartTetheringCallback {
}
關閉熱點
if(getWifiAPState() != WIFI_AP_STATE_DISABLED){
//Android7.1及以上版本
if (Build.VERSION.SDK_INT >= 25) {
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
}
}
權限
使用上述功能需要這三個權限:
<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" />
還需要在代碼中申請WRITE_SETTINGS權限,否則不能正常使用。
這樣就可以了,不只是系統應用可以使用,平成的應用也可以正常使用。親測(華為P20、華為mate10、華為V10都可以正常使用)。
歡迎大家關注、評論、點贊。
你們的支持是我堅持的動力。
Android WiFi熱點7.1以上版本適配
注:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權