android開發步步為營之48:通過WifiManager自動連上某個wifi熱點,androidwifimanager
最近參加了個某個創業公司的面試,他們做了個應用,就是使用者開啟他們的應用就可以提供免費上網的功能,然後面試的過程中,那哥們說,你對wifi這些協議你懂嗎?需要用到比較底層的東西哦,我勒個去,就這麼一個上網功能就需要很底層嗎?搞得很高深的樣子,真是底層是涉及到修改android的架構了,修改手機ROM了,你們做到這一步了嗎?沒有吧,只是在android架構提供api基礎上實現的,為此,我今天特意實驗了一把。也就10幾分鐘就搞定的事情,我被你們懵到了,額。。。
開發過程中主要用到WifiManager這個系統內建的服務,它有如下幾個狀態
WifiManager.WIFI_STATE_DISABLED: //wifi不可用
WifiManager.WIFI_STATE_DISABLING://wifi 正在關閉或者斷開
WifiManager.WIFI_STATE_ENABLED://wifi已經開啟可用
WifiManager.WIFI_STATE_ENABLING://wifi正在開啟或者串連
WifiManager.WIFI_STATE_UNKNOWN://未知訊息
好,開始我們的實驗:
第一步:AndroidManifest.xml添加相關許可權
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
第二步:建立測試頁面/study/res/layout/activity_wifi.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="@+id/btnWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="47dp"
android:text="自動連上wifi" />
</RelativeLayout>
第三步:實現Activity,WifiManagerTestActivity.java
/**
* 自動選擇連上某個wifi訊號
*/
package com.figo.study;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* @author zhuzhifei
*/
public class WifiManagerTestActivity extends Activity {
private Button btnWifi;
WifiManager wifiManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wifi);
//擷取wifi管理服務
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
btnWifi = (Button) findViewById(R.id.btnWifi);
btnWifi.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WEP);
//啟動wifi
connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WPA);
}
});
}
private static final String TAG = WifiManagerTestActivity.class
.getSimpleName();
// 定義幾種加密方式,一種是WEP,一種是WPA,還有沒有密碼的情況
public enum WifiCipherType {
WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
}
// 提供一個外部介面,傳入要串連的無線網ssid,password,
public void connect(String ssid, String password, WifiCipherType type) {
Thread thread = new Thread(new ConnectRunnable(ssid, password, type));
thread.start();
}
// 查看以前是否也配置過這個網路
private WifiConfiguration isExsits(String SSID) {
List<WifiConfiguration> existingConfigs = wifiManager
.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
return null;
}
private WifiConfiguration createWifiInfo(String SSID, String Password,
WifiCipherType Type) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
// nopass
if (Type == WifiCipherType.WIFICIPHER_NOPASS) {
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
// wep
if (Type == WifiCipherType.WIFICIPHER_WEP) {
if (!TextUtils.isEmpty(Password)) {
if (isHexWepKey(Password)) {
config.wepKeys[0] = Password;
} else {
config.wepKeys[0] = "\"" + Password + "\"";
}
}
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
// wpa
if (Type == WifiCipherType.WIFICIPHER_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;
}
// 開啟wifi功能
private boolean openWifi() {
boolean bRet = true;
if (!wifiManager.isWifiEnabled()) {
bRet = wifiManager.setWifiEnabled(true);
}
return bRet;
}
//啟動一個新線程開啟wifi
class ConnectRunnable implements Runnable {
private String ssid;
private String password;
private WifiCipherType type;
public ConnectRunnable(String ssid, String password, WifiCipherType type) {
this.ssid = ssid;
this.password = password;
this.type = type;
}
@Override
public void run() {
// 開啟wifi
openWifi();
// 開啟wifi功能需要一段時間(我在手機上測試一般需要1-3秒左右),所以要等到wifi
// 狀態變成WIFI_STATE_ENABLED的時候才能執行下面的語句
while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
try {
// 為了避免程式一直while迴圈,讓它睡個100毫秒檢測……
Thread.sleep(100);
} catch (InterruptedException ie) {
}
}
WifiConfiguration wifiConfig = createWifiInfo(ssid, password, type);
//
if (wifiConfig == null) {
Log.d(TAG, "wifiConfig is null!");
return;
}
WifiConfiguration tempConfig = isExsits(ssid);
if (tempConfig != null) {
wifiManager.removeNetwork(tempConfig.networkId);
}
int netID = wifiManager.addNetwork(wifiConfig);
boolean enabled = wifiManager.enableNetwork(netID, true);
Log.d(TAG, "enableNetwork status enable=" + enabled);
boolean connected = wifiManager.reconnect();
Log.d(TAG, "enableNetwork connected=" + connected);
}
}
private static boolean isHexWepKey(String wepKey) {
final int len = wepKey.length();
// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
if (len != 10 && len != 26 && len != 58) {
return false;
}
return isHex(wepKey);
}
private static boolean isHex(String key) {
for (int i = key.length() - 1; i >= 0; i--) {
final char c = key.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a'
&& c <= 'f')) {
return false;
}
}
return true;
}
}
android開發中如果我想代碼實現開啟wifi熱點怎實現
1·申請許可權:
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.WAKE_LOCK
2·擷取WifiManager
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
3·開啟、關閉wifi
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
} else {
wifiManager.setWifiEnabled(true);
}
4·注意
如果遇到force-close, 選wait即可, 因為啟動wifi需要幾秒鐘, UI如果5妙鐘還沒反映的話, 系統會給你這個force close exception
PS:我以前做過設計讀取系統硬體資訊的時候用過,但是很長時間沒用了,這段注釋是從網上來的,希望能幫到你。
android wifi 開發中 怎判斷成功串連上了指定的wifi熱點?
把訊號關了,看看試試看是否還有訊號互動,有的話,不就是聯上了嘛.