Android中Wi-Fi扫描、连接和信息(一)
1.Wi-Fi介绍
Wi-Fi是一种允许电子设备连接到一个无线局域网(WLAN)的技术,通常使用2.4G UHF或5G SHF ISM 射频频段。连接到无线局域网通常是有密码保护的;但也可是开放的,这样就允许任何在WLAN范围内的设备可以连接上。Wi-Fi是一个无线网络通信技术的品牌,由Wi-Fi联盟所持有。目的是改善基于IEEE 802.11标准的无线网路产品之间的互通性。有人把使用IEEE 802.11系列协议的局域网就称为无线保真。甚至把Wi-Fi等同于无线网际网路(Wi-Fi是WLAN的重要组成部分)。
2.Wi-Fi关键类说明
2.1Wi-Fi相关包说明
做过Wi-Fi开发的人应该都熟悉android.net.wifi包;
android.net.wifi包的简介:
提供在设备上管理Wi-Fi功能的类。
Wi-Fi api提供了一种方式,应用程序可以与提供Wi-Fi网络接入的低层无线栈进行通信。几乎所有来自设备请求者的信息都是可用的,包括连接的网络的链路速度、IP地址、协商状态,以及其他可用的其他网络的信息。其他一些API功能包括扫描、添加、保存、终止和启动Wi-Fi连接。
2.2常用关键类说明
2.2.1WifiManager
WifiManager:这个类提供了管理Wi-Fi连接所有操作的主要API。
定义了许多的常量和方法,查看官网SDK了解;
Wi-Fi连接用到的主要状态,用整型值表示,如下:
2.2.2ScanResult
ScanResult:描述探测到的访问点(Wi-Fi)的信息。
ScanResult中关键字段说明:
返回类型 | 域名 | 解释 |
public String | BSSID | 接入点的地址 |
public String | SSID | 网络的名字(在Wi-Fi列表中看的名字) |
public String | capabilities | 网络性能,包括接入点支持的认证、**管理、加密机制等 |
public int | frequency | 以MHz为单位的接入频率 |
public int | level | 以dBm为单位的信号强度。 |
2.2.3WifiInfo
WifiInfo:描述已经连接或者活动的Wifi连接状态和信息。
调用WifiInfo类中方法代码:
mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
mWifiInfo = mWifiManager.getConnectionInfo(); //获取当前连接Wi-Fi的信息
if(null != mWifiInfo && null != mWifiInfo.getSSID()){
String info = "getSSID()="+mWifiInfo.getSSID()+"\n"
+"getBSSID()="+mWifiInfo.getBSSID()+"\n"
+"getHiddenSSID()="+mWifiInfo.getHiddenSSID()+"\n"
+"getLinkSpeed()="+mWifiInfo.getLinkSpeed()+"\n"
+"getMacAddress()="+mWifiInfo.getMacAddress()+"\n"
+"getNetworkId()="+mWifiInfo.getNetworkId()+"\n"
+"getRssi()="+mWifiInfo.getRssi()+"\n"
+"getSupplicantState()="+mWifiInfo.getSupplicantState()+"\n"
+"getDetailedStateOf()="+mWifiInfo.getDetailedStateOf(mWifiInfo.getSupplicantState());
mTVWifiInfo.setText(info);
}else {
mTVWifiInfo.setText("没有连接到wifi");
2.2.4WifiConfigration
WifiConfigration:一个表示配置的Wi-Fi网络的类,包括安全配置。
该类主要包含网络配置和安全配置信息,如下:
子类 | 解释 |
WifiConfiguration.AuthAlgorthm | 获取IEEE 802.11的加密方法 |
WifiConfiguration.GroupCipher |
获取组** |
WifiConfiguration.KeyMgmt |
获取密码管理体制 |
WifiConfiguration.PairwiseCipher |
获取WPA方式的成对** |
WifiConfiguration.Protocol |
获取加密协议 |
WifiConfiguration.Status |
获取当前网络状态 |
2.2.5使用Wi-Fi用到的权限
ACCESS_WIFI_STATE:允许应用程序获取Wi-Fi连接的状态;
CHANGE_WIFI_STATE:允许应用程序改变Wi-Fi的连接状态;
CHANGE_WIFI_MULTICAST_STATE:允许改变Wi-Fi组播状态;
具体使用,申请Wi-Fi的操作权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
这块在6.0及以后版本仅添加这两个权限会发现mWifiManager.getScanResults()返回的是空Wi-Fi列表,没有Wi-Fi信息返回;
3.具体实现测试
3.1管理Wi-Fi的关键代码
package com.dress.gold.interconnected.checkphone.utils; import android.content.Context; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.util.Log; import android.widget.Toast; import com.dress.gold.interconnected.checkphone.zxing.decoding.Intents; import java.util.ArrayList; import java.util.List; /** * Wi-Fi常见操作类 * Wi-Fi状态值:One of WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED, WIFI_STATE_ENABLING, WIFI_STATE_UNKNOWN */ public class WifiOperator { // 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况 public enum WifiCipherType { WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID } //定义管理Wi-Fi连接所有功能类的对象 private WifiManager mWifiManager; //定义存放Wi-Fi信息的对象 private WifiInfo mWifiInfo; //扫描可以访问的Wi-Fi热点的列表 private List<ScanResult> mWifiList; //各个Wi-Fi热点的网络配置的列表 private List<WifiConfiguration> mWifiConfigration; //定义允许应用程序保持Wi-Fi无线电波保持唤醒状态对象 private WifiManager.WifiLock mWifiLock; //构造器 public WifiOperator(Context context){ //获取管理Wi-Fi连接所有功能类的对象 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); //返回当前Wi-Fi连接的动态信息,如果有的话。 mWifiInfo = mWifiManager.getConnectionInfo(); } //打开Wi-Fi public void openWifi(Context context){ //检测打开Wi-Fi功能 if(!mWifiManager.isWifiEnabled()){ mWifiManager.setWifiEnabled(true); }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING){ Toast.makeText(context,"Wi-Fi正在开启中,请勿重复开启", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"Wi-Fi已经开启,请勿重复开启", Toast.LENGTH_SHORT).show(); } } //关闭Wi-Fi public void closeWifi(Context context){ //检测关闭Wi-Fi功能 if(mWifiManager.isWifiEnabled()){ mWifiManager.setWifiEnabled(false); }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING){ Toast.makeText(context,"Wi-Fi正在关闭中,请勿重复关闭", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"Wi-Fi已经关闭,请勿重复关闭", Toast.LENGTH_SHORT).show(); } } //检车当前Wi-Fi的状态 public void checkState(Context context){ if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING) { Toast.makeText(context,"Wifi正在关闭中", Toast.LENGTH_SHORT).show(); } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) { Toast.makeText(context,"Wifi已经关闭", Toast.LENGTH_SHORT).show(); } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) { Toast.makeText(context,"Wifi正在开启中", Toast.LENGTH_SHORT).show(); } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { Toast.makeText(context,"Wifi已经开启", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context,"没有获取到WiFi状态", Toast.LENGTH_SHORT).show(); } } //锁定Wi-FiLock public void acquireWifiLock(){ mWifiLock.acquire(); } //解锁Wi-FiLock public void releaseWifiLock(){ //判断是否还持有锁 if(mWifiLock.isHeld()){ mWifiLock.release(); } } //创建一个Wi-FiLock public void createWifiLock(){ mWifiLock = mWifiManager.createWifiLock("TAG"); } //得到配置好的网络 public List<WifiConfiguration> getConfigration() { return mWifiConfigration; } //指定配合找的网络进行连接 public void connectionConfigration(int index){ //索引大于配置好的网络索引返回 if(index>mWifiConfigration.size()){ return; } mWifiManager.enableNetwork(mWifiConfigration.get(index).networkId, true); } public void startScan(Context context) { mWifiManager.startScan(); // 得到扫描结果 mWifiList = mWifiManager.getScanResults(); // 得到配置好的网络连接 mWifiConfigration = mWifiManager.getConfiguredNetworks(); if (mWifiList == null) { if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLED){ Toast.makeText(context,"当前区域没有无线网络", Toast.LENGTH_SHORT).show(); }else if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLING){ Toast.makeText(context,"WiFi正在开启,请稍后重新点击扫描", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"WiFi没有开启,无法扫描", Toast.LENGTH_SHORT).show(); } } } //得到网络列表 public List<ScanResult> getWifiList(){ // if(mWifiList == null || mWifiList.size() == 0){ // return mWifiManager.getScanResults(); // } return mWifiList; } //查看扫描结果 public StringBuilder lookUpScan(){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < mWifiList.size(); i++) { sb .append("Index_" + new Integer(i + 1).toString() + ":"); // 将ScanResult信息转换成一个字符串包 // 其中把包括:BSSID、SSID、capabilities、frequency、level sb.append((mWifiList.get(i)).toString()); sb.append("/n"); } return sb; } //添加一个网络并连接 public void addNetworkWifiConfiguration(WifiConfiguration wc){ int wcgID = mWifiManager.addNetwork(wc); boolean b = mWifiManager.enableNetwork(wcgID, true); Log.i(WifiOperator.class.getName(), "wcgID:"+wcgID); Log.i(WifiOperator.class.getName(), "b:"+b); } //断开指定ID网络 public void disconnectWifi(int netId){ mWifiManager.disableNetwork(netId); mWifiManager.disconnect(); } public void removeWifi(int netId){ disconnectWifi(netId); mWifiManager.removeNetwork(netId); } public WifiConfiguration createWifiInfo(String SSID, String password, WifiCipherType type){ WifiConfiguration configuration = new WifiConfiguration(); configuration.allowedAuthAlgorithms.clear(); configuration.allowedGroupCiphers.clear(); configuration.allowedKeyManagement.clear(); configuration.allowedPairwiseCiphers.clear(); configuration.allowedProtocols.clear(); configuration.SSID = "\"" + SSID + "\""; WifiConfiguration tempConfiguration = this.isExists(SSID); if(tempConfiguration != null){ mWifiManager.removeNetwork(tempConfiguration.networkId); } if(type == WifiCipherType.WIFICIPHER_NOPASS){ configuration.wepKeys[0] = ""; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); configuration.wepTxKeyIndex = 0; } if(type == WifiCipherType.WIFICIPHER_WEP){ configuration.hiddenSSID = true; configuration.wepKeys[0] = "\""+password+"\""; configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); configuration.wepTxKeyIndex = 0; } if(type == WifiCipherType.WIFICIPHER_WPA){ configuration.preSharedKey = "\""+password+"\""; configuration.hiddenSSID = true; configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); //config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); configuration.status = WifiConfiguration.Status.ENABLED; } return configuration; } //判断某个Wi-Fi是否存在 private WifiConfiguration isExists(String SSID){ List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks(); for(WifiConfiguration existingConfig : existingConfigs){ if(existingConfig.SSID.equals("\""+SSID+"\"")){ return existingConfig; } } return null; } // 得到MAC地址 public String getMacAddress() { return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress(); } // 得到接入点的BSSID public String getBSSID() { return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID(); } // 得到IP地址 public int getIPAddress() { return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress(); } // 得到连接的ID public int getNetworkId() { return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId(); } // 得到WifiInfo的所有信息包 public String getWifiInfo() { return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString(); } }
3.2通过调用上面的方法会发现一些问题,如下图
1.问题1,SSID有获取不到的情况,即SSID为空串"",SSID!=null的情况;
2.问题2,wifi列表中有许多同名的wifi热点,也就是扫描的结果中有重合部分,并不是有多个同名的wifi热点;
问题1的原因:第一个问题ssid为空串,这个看设置中并没有多余wifi,但这个热点点其它信息可以获取到,说明这个热点是存在的,应该是该热点隐藏了,所以获取不到。这也就是手机设置中为什么会有添加网路的按钮了。
问题2的原因:当附近wifi热点比较少时不会出现此问题,当附近wifi网络比较多时会出现此问题。这就需要将同名的热点进行删除,但是如果真有两个ssid名相同的wifi,那就可以通过capabilities去区分吧,如果capabilities也相同就没办法了,系统设置里面也不显示同名的;
因此扫描代码需要做一些调整,调整如下:
//扫描Wi-Fi列表 public void startScan(Context context){ //启动Wi-Fi扫描 mWifiManager.startScan(); //得到Wi-Fi热点扫描结果列表 List<ScanResult> results = mWifiManager.getScanResults(); //得到配置好的网络连接 mWifiConfigration = mWifiManager.getConfiguredNetworks(); if(results == null){ if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED){ Toast.makeText(context,"当前区域没有扫描到无线Wi-Fi网络", Toast.LENGTH_SHORT).show(); }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING){ Toast.makeText(context,"Wi-Fi正在开启中,请稍后重新扫描", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"Wi-Fi没有开启,暂时无法扫描,请打开Wi-Fi以后点击扫描", Toast.LENGTH_SHORT).show(); } }else{ // Toast.makeText(context,"当前可连接Wi-Fi数量:"+mWifiList.size(), Toast.LENGTH_SHORT).show(); //过滤掉重复Wi-Fi名称 mWifiList = new ArrayList(); for(ScanResult result : results){ if (result.SSID == null || result.SSID.length() == 0 || result.capabilities.contains("[IBSS]")) { continue; } boolean found = false; for(ScanResult item:mWifiList){ if(item.SSID.equals(result.SSID)&&item.capabilities.equals(result.capabilities)){ found = true;break; } } if(!found){ mWifiList.add(result); } } } }
修改后的效果:
3.2调用Wi-Fi工具类的代码
package com.dress.gold.interconnected.checkphone.ui.testui; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.dress.gold.interconnected.checkphone.R; import com.dress.gold.interconnected.checkphone.base.ToolbarActivity; import com.dress.gold.interconnected.checkphone.ui.MainActivity; import com.dress.gold.interconnected.checkphone.utils.WifiOperator; import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; /** * 测试Wi-Fi管理功能 */ public class WifiOperatorActivity extends ToolbarActivity { private WifiOperator mwifiOperator; private List<ScanResult> mWifiList; @Bind(R.id.wifilistView) ListView wifilistView; public int level; protected String ssid; @Override protected int provideContentViewId() { return R.layout.activity_wifi; } @Override public boolean canBack() { return false; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ButterKnife.bind(this); mwifiOperator = new WifiOperator(this); addWifiConnectionListener(); addListViewClick(); } private void addListViewClick() { wifilistView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { AlertDialog.Builder alert=new AlertDialog.Builder(WifiOperatorActivity.this); ssid=mWifiList.get(position).SSID; alert.setTitle(ssid); // alert.setMessage("输入密码"); final TextView tv = new TextView(WifiOperatorActivity.this); // ScanResult scanResult = mWifiList.get(position); // tv.setText("SSID:"+scanResult.SSID+"\n" // +"BSSID:"+scanResult.BSSID+"\n" // +"capabilities:"+scanResult.capabilities+"\n" // +"frequency:"+scanResult.frequency+"\n" // +"level:"+scanResult.level+"\n"); // alert.setView(tv); final EditText et_password=new EditText(WifiOperatorActivity.this); final SharedPreferences preferences=getSharedPreferences("wifi_password",Context.MODE_PRIVATE); et_password.setText(preferences.getString(ssid, "")); alert.setView(et_password); //alert.setView(view1); alert.setPositiveButton("连接", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { String pw = et_password.getText().toString(); if(null == pw || pw.length() < 8){ Toast.makeText(WifiOperatorActivity.this, "密码至少8位", Toast.LENGTH_SHORT).show(); return; } SharedPreferences.Editor editor=preferences.edit(); editor.putString(ssid, pw); //保存密码 editor.commit(); mwifiOperator.addNetworkWifiConfiguration(mwifiOperator.createWifiInfo(ssid, et_password.getText().toString(), WifiOperator.WifiCipherType.WIFICIPHER_WPA)); } }); alert.setNegativeButton("取消", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { // //mWifiAdmin.removeWifi(mWifiAdmin.getNetworkId()); } }); alert.create(); alert.show(); } }); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); } public void addWifiConnectionListener(){ IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); //="android.net.wifi.STATE_CHANGE" 监听wifi状态的变化 registerReceiver(mReceiver, filter); } @OnClick({R.id.detectstatus, R.id.openwifi, R.id.closewifi, R.id.scanwifi}) public void onClick(Button button){ switch (button.getId()){ case R.id.detectstatus: mwifiOperator.checkState(this); break; case R.id.openwifi: mwifiOperator.openWifi(this); break; case R.id.closewifi: mwifiOperator.closeWifi(this); break; case R.id.scanwifi: mwifiOperator.startScan(this); mWifiList = mwifiOperator.getWifiList(); if(mWifiList != null){ wifilistView.setAdapter(new MyAdapter(this,mWifiList)); } break; } } public class MyAdapter extends BaseAdapter { LayoutInflater inflater; List<ScanResult> list; public MyAdapter(Context context, List<ScanResult> list){ this.inflater=LayoutInflater.from(context); this.list=list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @SuppressLint({ "ViewHolder", "InflateParams" }) @Override public View getView(int position, View convertView, ViewGroup parent) { View view=null; view=inflater.inflate(R.layout.wifi_listitem, null); ScanResult scanResult = list.get(position); TextView wifi_ssid=(TextView) view.findViewById(R.id.ssid); // ImageView wifi_level=(ImageView) view.findViewById(R.id.wifi_level); wifi_ssid.setText(scanResult.SSID+"("+scanResult.capabilities+")"); // Log.i(TAG, "scanResult.SSID="+scanResult); // level= WifiManager.calculateSignalLevel(scanResult.level,5); // if(scanResult.capabilities.contains("WEP")||scanResult.capabilities.contains("PSK")|| // scanResult.capabilities.contains("EAP")){ // wifi_level.setImageResource(R.drawable.wifi_signal_lock); // }else{ // wifi_level.setImageResource(R.drawable.wifi_signal_open); // } // wifi_level.setImageLevel(level); //判断信号强度,显示对应的指示图标 return view; } } //监听wifi状态 private BroadcastReceiver mReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); // wifi已成功扫描到可用wifi。 if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { Toast.makeText(context, "Wi-Fi已成功扫描到可用wifi", Toast.LENGTH_LONG).show(); //mwifiOperator.startScan(WifiOperatorActivity.this); mWifiList = mwifiOperator.getWifiList(); if(mWifiList != null){ wifilistView.setAdapter(new MyAdapter(WifiOperatorActivity.this,mWifiList)); } // Toast.makeText(context,"当前可连接Wi-Fi数量:"+mWifiList.size(), Toast.LENGTH_SHORT).show(); }//系统wifi的状态 else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { Toast.makeText(context, "Wi-Fi状态有变化", Toast.LENGTH_LONG).show(); ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if(wifiInfo.isConnected()){ WifiManager wifiManager = (WifiManager) context .getSystemService(Context.WIFI_SERVICE); String wifiSSID = wifiManager.getConnectionInfo() .getSSID(); Toast.makeText(context, wifiSSID+"连接成功", Toast.LENGTH_LONG).show(); } } } }; }
具体注意事项:
在注册监听Wi-Fi相关信息广播时,主要添加两个Action,一个是监听扫描附近Wi-Fi的Action:
SCAN_RESULTS_AVAILABLE_ACTION,另一个是时监听Wi-Fi状态(Wi-Fi关闭,打开,连接成功)变化的Action
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
调用mWifiManager.getScanResults();方法时一直获取不到附近的Wi-Fi列表,可以通过源代码发现逻辑判断中需要打开定位功能;
试了一最笨的方法,添加定位权限,如下:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
发现添加这两个权限以后还是获取不到附近的Wi-Fi列表,我手动打开定位功能,重新扫描获取可以得到,当然这种办法还是比较low的;
这篇文章分析了为什么需要打开定位的可以查看一下:
https://www.jianshu.com/p/3400ca0deeee
代码中做一下修改即可:
加入上面两个权限的同时,动态打开定位而不是人为手动打开定位即可:
4.其他说明
参考:
https://blog.****.net/vnanyesheshou/article/details/50771698
https://developer.android.google.cn/reference/android/net/wifi/package-summary
测试代码:
https://download.****.net/download/ahou2468/10401108