1.WIFI核心类WifiManager
public class WifiManager
extends Object
↳ android.net.wifi.WifiManager
这个类提供了管理Wi-Fi连接的所有方面的主要API。通过调用得到这个类的一个实例 Context.getSystemService(Context.WIFI_SERVICE)。它涉及几类产品:
配置网络列表。该列表可以查看和更新,单个条目的属性进行修改。
当前活动的Wi-Fi网络,如果有的话。连接可以建立或拆除,并且有关网络的状态的动态信息可以查询。
接入点的扫描的结果,包含足够的信息来什么接入点连接到决策。
它定义了在任何类型的Wi-Fi状态变化的各种转播意向动作的名称。
Wi-Fi具体操作时要使用的API。要执行一些与在抽象的层面与网络连接操作,使用ConnectivityManager。
常用方法:
int addNetwork(WifiConfiguration config)添加一个新的网络描述为一套配置网络。
boolean disableNetwork(int netId)禁用配置的网络。
boolean disconnect()从当前活动的接入点撇清。
boolean enableNetwork(int netId, boolean disableOthers)允许之前配置的网络与关联。
List<WifiConfiguration> getConfiguredNetworks()返回请求者配置的所有网络的列表。
WifiInfo getConnectionInfo()返回有关当前Wi-Fi连接的动态信息,如果有的话是积极的。
DhcpInfo getDhcpInfo()从最后一次成功DHCP请求返回DHCP分配的地址,如果有的话。
List<ScanResult> getScanResults()返回最新的接入点扫描的结果。
int getWifiState()获取Wi-Fi功能的状态。
boolean isWifiEnabled()返回的Wi-Fi是否已启用或禁用。
boolean reconnect()重新连接到当前活动的访问点上,如果我们目前正在断开。
boolean removeNetwork(int netId)从配置网络的列表中删除指定的网络。
boolean setWifiEnabled(boolean enabled)启用或禁用无线网络连接。
boolean startScan()请求接入点的扫描。
int updateNetwork(WifiConfiguration config)更新现有配置的网络的网络描述。
2.添加权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
3.开始wifi功能
4.1.注册广播监听器
4.2.广播接收者
/**
* Wifi开关,信号,状态改变监听
*/
public class WifiStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case WifiManager.NETWORK_STATE_CHANGED_ACTION:
NetworkInfo networkInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
if (networkInfo != null) {
NetworkInfo.State state = networkInfo.getState();
if (state == NetworkInfo.State.CONNECTED) {
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "网络已经连接");
} else if (state == NetworkInfo.State.DISCONNECTED) {
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "网络已经断开");
} else if (state == NetworkInfo.State.CONNECTING) {
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "网络连接中");
}
}
break;
case WifiManager.WIFI_STATE_CHANGED_ACTION:
int wifiState = intent.getIntExtra(EXTRA_WIFI_STATE, 0);
if (wifiState == WIFI_STATE_ENABLED) {
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "wifi已经打开");
} else if (wifiState == WIFI_STATE_DISABLED) {
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "wifi已经关闭");
}
break;
case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
boolean b = intent.getBooleanExtra(EXTRA_RESULTS_UPDATED, false);
if(b){
List<ScanResult> searchWifiList = WifiHelper.getSingleton(getApplicationContext()).getSearchWifiList();
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "扫描成功");
}else{
Log.e(getClass().getSimpleName() + "xmg", "onReceive: " + "扫描附近Wifi失败");
}
break;
}
}
}
4.3.取消注册监听
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
unregisterReceiver(wifiReceiver);
}
5.关闭WiFi
6.添加并连接wifi
6.1点击连接wifi
6.2在wifiHelper中实现addNetWorkWAP这个方法
/**连接并添加保存该wifi
* @param wifiId
* @param password
*/
public void connectWifi(String wifiId,String password){
WifiConfiguration wifiInfo = createWifiConfig(wifiId,password);
int netWorkId = mWifiManager.addNetwork(wifiInfo);
mWifiManager.enableNetwork(netWorkId,true);
}
6.3创建一个wifi配置信息
/**
*创建一个wifi配置信息
* @param wifiId
* @param password
* @return
*/
private WifiConfiguration createWifiConfig(String ssid, String password) {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "\"" + ssid + "\"";
if(TextUtils.isEmpty(password)){
//无需密码
//配置成无需加密的wifi
//设置密码为空,没有加密
wifiConfiguration.wepKeys[0] = "\"\"";
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.wepTxKeyIndex = 0;
}else{
//配置成WPA加密的wifi
wifiConfiguration.preSharedKey = "\"" + password + "\"";
wifiConfiguration.hiddenSSID = true;
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConfiguration.status = WifiConfiguration.Status.ENABLED;
}
return wifiConfiguration;
}
7.测试网络(使用Ping命令来测试)
通过直接Ping一个网站来测试该wifi是否有网络
private void testConnect(final OnPingListener listener) {
Executors.newCachedThreadPool().execute(new Runnable() {
public void run() {
String url = "www.baidu.com";
try {
//ping -c 3 -w 10 -c 3 代表要ping 3次 -w 10代表超时的间隔为10000毫秒
Process process = Runtime.getRuntime().exec("ping -c 3 -w 10 " + url);
int i = process.waitFor();
InputStream input = process.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(input));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null){
buffer.append(line);
}
Log.e(getClass().getSimpleName() + "xmg", "run: " + buffer.toString());
if(i==0){
if(listener!=null){
listener.onSuccess();
}
}else{
if(listener!=null){
listener.onFail("ping 失败了"+i);
}
}
} catch (Exception e) {
e.printStackTrace();
if(listener!=null){
listener.onFail("ping 出现了异常:"+e.getMessage());
}
}
}
});
}
public interface OnPingListener{
void onSuccess();
void onFail(String s);
}
8.断开某个已经连接的wifi
9.搜索附近的wifi
在Android6.0以后,默认是搜索不要附近WIFI的列表的,需要将其APP加载到系统的APP安装目录(/system/app)下,也可以添加如下权限,但是该权限需要用户设置同意,所以我们可以引导用户去启动位置的权限。
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
在添加如下权限后,还需要提示用户让其打开手机的gps信号开关,否则将无法获取wifi列表。
9.1扫描附近wifi
9.2实现点击收索wifi
9.3编写WifiAdatper
10.点击连接附近wifi
10.1点击搜索出来的wifi
10.2初始化一个输入密码的对话框
private void initDialog() {
View inflate = View.inflate(getApplicationContext(),R.layout.input_dailog, null);
mTvTip = (TextView) inflate.findViewById(R.id.tv_tip);
mEtDialogPassword = (EditText) inflate.findViewById(R.id.et_password);
mBtn_ok = (Button) inflate.findViewById(R.id.btn_ok);
mAlertDialog = new AlertDialog.Builder(MainActivity.this)
.setView(inflate).create();
//设置对话框弹出监听,弹出对话框时自动显示软键盘
mAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mEtDialogPassword, InputMethodManager.SHOW_IMPLICIT);
}
});
}
10.3在item点击事件中弹出对话框:
xxx.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(View v, int position) {
ScanResult scanResult = mWifiListAdapter.getData().get(position);
boolean needPassword = checkAuth(scanResult);
if(!needPassword){
WifiHelper.getSingleton(getApplicationContext()).
connectWifi(scanResult.SSID,"",1);
return;
}
//看wifi是否为已经连接过的
boolean savedWifi = WifiHelper.getSingleton(getApplicationContext()).connectSavedWifi(scanResult.SSID);
if(savedWifi){
Toast.makeText(MainActivity.this, "正在连接wifi", Toast.LENGTH_SHORT).show();
}else{
//不是已经连接的,弹出对话框让其输入密码
showWifiDialog(scanResult);
}
}
});
10.4在wifiHelper中添加checkAuth方法,用来检查扫描出来的wifi是否需要密码
/**
* 检查扫描出来的wifi是否需要密码
* @param scanResult
* @return
*/
public static boolean checkAuth(ScanResult scanResult) {
boolean needPassword = false;
String capabilities = scanResult.capabilities;
if (!TextUtils.isEmpty(capabilities)) {
if (capabilities.contains("WEP") || capabilities.contains("WPA")) {
needPassword = true;
}
}
return needPassword;
}
10.5在wifiHelper中添加了方法connectSavedWifi,用来重连先前已经连接过的wifi:
/**
* 重连先前已经连接过的wifi,返回值为false则代表该wifi先前没有连接过
* @param ssid
* @return
*/
public boolean connectSavedWifi(String ssid){
boolean isSaved = false;
int netWorkId = getNetWorkId(ssid);
if(netWorkId!=-1){
mWifiManager.enableNetwork(netWorkId,true);
isSaved = true;
}
return isSaved;
}
/**
* 用来得知某个wifi在保存起来时所对应的id,如果是-1,则先前未保存过该wifi
* @param ssid
* @return
*/
public int getNetWorkId(String ssid){
int networkId = -1;
//configuredNetwork.SSID两边有加冒号,为了正确判断,传进来的参数ssid也在两边加上
ssid = "\""+ssid+"\"";
List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration configuredNetwork : configuredNetworks) {
Log.e(getClass().getSimpleName() + "xmg", "getNetWorkId: " + ssid+" "+configuredNetwork.SSID);
if(configuredNetwork.SSID.equals(ssid)){
networkId = configuredNetwork.networkId;
break;
}
}
return networkId;
}
10.6弹出对话框供用户输入密码:
private void showWifiDialog(final ScanResult scanResult) {
mTvTip.setText(scanResult.SSID);
mBtn_ok.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String pwd = mEtDialogPassword.getText().toString().trim();
if(TextUtils.isEmpty(pwd)){
return;
}
WifiHelper.getSingleton(getApplicationContext()).connectWifi(scanResult.SSID,pwd,3);
mAlertDialog.dismiss();
}
});
mAlertDialog.show();
}