我的使用場景:新買的盒子無屏如何通過手機讓盒子連上wifi
1、首先依賴AndServer,添加權限,開啓服務
github地址-https://github.com/yanzhenjie/AndServer
implementation 'com.yanzhenjie:andserver:1.0.2'//該版本不是最新版本
<!--wifi 網絡權限 -->
<uses-permission android:name="android.permission.CHANGE_NETWORKE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
//創建並開啓服務
private void createWebServer(){
AssetManager mAssetManager = getAssets();
//如果xx.html在assets下填""即可,如果在assets子目錄下填子目錄的文件名
WebSite wesite = new AssetsWebsite(mAssetManager, path);
AndServer andServer = new AndServer.Build()
.port(8080) // 默認是8080,Android平臺允許的端口號都可以。
.timeout(10 * 1000) // 默認10 * 1000毫秒。
.website(wesite)
.registerHandler("wifi", new RequestWifiHandler())
.registerHandler("login", new RequestLoginHandler())
.listener(mListener)
.build();
Server mServer = andServer.createServer();
mServer.start();
}
//服務狀態監聽
private Server.Listener mListener = new Server.Listener() {
@Override
public void onStarted() {
// 服務器啓動成功.
LogUtils.d("服務器啓動成功");
}
@Override
public void onStopped() {
// 服務器停止了,一般是開發者調用server.stop()纔會停止。
LogUtils.d("服務器停止了");
}
@Override
public void onError(Exception e) {
// 服務器啓動發生錯誤,一般是端口被佔用。
LogUtils.d("服務器啓動發生錯誤");
}
};
2、創建並開啓熱點
private void createWifiHot(String name, String password) {
WifiManager mWifiManager = (WifiManager) LemonConfig.getApplicationContext().getSystemService(WIFI_SERVICE);
try {
//wifi和熱點不能同時打開,所以先判斷wifi是否打開,打開則關閉
if (mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(false);
}
//java反射機制得到Method
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class, boolean.class);
//配置熱點信息
WifiConfiguration config = new WifiConfiguration();
config.SSID = name;
config.preSharedKey = password;
config.hiddenSSID = true;
config.status = WifiConfiguration.Status.ENABLED;
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
/*****如果連接熱點需要密碼,則解開註釋,將config.allowedKeyManagement.set(0);註釋掉****/
// int indexOfWPA2_PSK = 4;
////從WifiConfiguration.KeyMgmt數組中查找WPA2_PSK的值
// for (int i = 0; i < WifiConfiguration.KeyMgmt.strings.length; i++) {
// if (WifiConfiguration.KeyMgmt.strings[i].equals("WPA2_PSK")) {
// indexOfWPA2_PSK = i;
// break;
// }
// }
config.allowedKeyManagement.set(0);
//通過java反射調用WifiManager的setWifiApEnabled方法
method.invoke(mWifiManager, config, true);
} catch (Exception e) {
e.printStackTrace();
}
}
3、手機連上熱點,這樣開啓服務的設備與連上熱點的手機就形成了一個局域網,通過http://ip:port/xxx.html就可以訪問我們寫好的html頁面
4、html要提交給本地服務器通過第一步創建服務註冊名來進行訪問
5、在RequestWifiHandler類中接受html頁面提交過來的信息,得到wifi名稱和wifi密碼進行連接
public class RequestWifiHandler implements RequestHandler {
private WifiManager mWifiManager;
@Override
public void handle(HttpRequest req, HttpResponse res, HttpContext con) {
Map<String, String> params = null;
try {
params = HttpRequestParser.parse(req);
} catch (IOException e) {
e.printStackTrace();
}
// 在這裏得到html頁面提交過來的參數,字段與html的name屬性值對應上
String ssid = params.get("username");
String pwd = params.get("password");
LogUtils.d( "wifi!");
openWifi(ssid,pwd,res);
}
//關閉熱點,打開wifi
private void openWifi(String userName, String password,HttpResponse res) {
mWifiManager = (WifiManager) LemonConfig.getApplicationContext().getSystemService(WIFI_SERVICE);
closeWifiHot();
// 調用函數打開/關閉WiFi,status爲boolean變量true/false
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
// 指定對應的SSID
config.SSID = "\"" + userName + "\"";
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.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
int netId = mWifiManager.addNetwork(config);
// 這個方法的第一個參數是需要連接wifi網絡的networkId,第二個參數是指連接當前wifi網絡是否需要斷開其他網絡
boolean isConnection=mWifiManager.enableNetwork(netId, true);
if (isConnection) {
// ProcessBuilder.Redirect.
StringEntity stringEntity = null;
try {
stringEntity = new StringEntity("連接成功", "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
res.setEntity(stringEntity);
}else {
//它不能夠立馬連接上,所以要從頭再走一遍
openWifi(userName, password, res);
}
}
//關閉熱點
public void closeWifiHot() {
try {
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class, boolean.class);
method.invoke(mWifiManager, null, false);
} catch (Exception e) {
e.printStackTrace();
}
}
}