在平常开发中经常会涉及到wifi相关的内容,在此将之前所用到的整理一下,以免忘记。
操作wifi的相关类,主要放在android.net.wifi包下面。使用wifi相关方法需要申请一些权限:
ACCESS_WIFI_STATE 获取WiFi状态。
CHANGE_WIFI_STATE 改变WiFi状态。
CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态
申请权限方式:在AndroidManifest.xml文件中填写
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
wifi相关操作所需要用到的类。
先说一下wifi的基本使用情况。
- import java.util.List;
- 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.net.wifi.WifiManager.WifiLock;
- import android.widget.Toast;
- public class WifiAdmin {
- // 定义WifiManager对象
- private WifiManager mWifiManager;
- // 定义WifiInfo对象
- private WifiInfo mWifiInfo;
- // 扫描出的网络连接列表
- private List<ScanResult> mWifiList;
- // 网络连接列表
- private List<WifiConfiguration> mWifiConfiguration;
- // 定义一个WifiLock
- WifiLock mWifiLock;
- // 构造器
- public WifiAdmin(Context context) {
- // 取得WifiManager对象
- mWifiManager = (WifiManager) context
- .getSystemService(Context.WIFI_SERVICE);
- // 取得WifiInfo对象
- mWifiInfo = mWifiManager.getConnectionInfo();
- }
- // 打开WIFI
- public void openWifi(Context context) {
- if (!mWifiManager.isWifiEnabled()) {
- mWifiManager.setWifiEnabled(true);
- }else if (mWifiManager.getWifiState() == 2) {
- Toast.makeText(context,"亲,Wifi正在开启,不用再开了", Toast.LENGTH_SHORT).show();
- }else{
- Toast.makeText(context,"亲,Wifi已经开启,不用再开了", Toast.LENGTH_SHORT).show();
- }
- }
- // 关闭WIFI
- public void closeWifi(Context context) {
- if (mWifiManager.isWifiEnabled()) {
- mWifiManager.setWifiEnabled(false);
- }else if(mWifiManager.getWifiState() == 1){
- Toast.makeText(context,"亲,Wifi已经关闭,不用再关了", Toast.LENGTH_SHORT).show();
- }else if (mWifiManager.getWifiState() == 0) {
- Toast.makeText(context,"亲,Wifi正在关闭,不用再关了", Toast.LENGTH_SHORT).show();
- }else{
- Toast.makeText(context,"请重新关闭", Toast.LENGTH_SHORT).show();
- }
- }
- // 检查当前WIFI状态
- public void checkState(Context context) {
- if (mWifiManager.getWifiState() == 0) {
- Toast.makeText(context,"Wifi正在关闭", Toast.LENGTH_SHORT).show();
- } else if (mWifiManager.getWifiState() == 1) {
- Toast.makeText(context,"Wifi已经关闭", Toast.LENGTH_SHORT).show();
- } else if (mWifiManager.getWifiState() == 2) {
- Toast.makeText(context,"Wifi正在开启", Toast.LENGTH_SHORT).show();
- } else if (mWifiManager.getWifiState() == 3) {
- Toast.makeText(context,"Wifi已经开启", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(context,"没有获取到WiFi状态", Toast.LENGTH_SHORT).show();
- }
- }
- // 锁定WifiLock
- public void acquireWifiLock() {
- mWifiLock.acquire();
- }
- // 解锁WifiLock
- public void releaseWifiLock() {
- // 判断时候锁定
- if (mWifiLock.isHeld()) {
- mWifiLock.acquire();
- }
- }
- // 创建一个WifiLock
- public void creatWifiLock() {
- mWifiLock = mWifiManager.createWifiLock("Test");
- }
- // 得到配置好的网络
- public List<WifiConfiguration> getConfiguration() {
- return mWifiConfiguration;
- }
- // 指定配置好的网络进行连接
- public void connectConfiguration(int index) {
- // 索引大于配置好的网络索引返回
- if (index > mWifiConfiguration.size()) {
- return;
- }
- // 连接配置好的指定ID的网络
- mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
- true);
- }
- public void startScan(Context context) {
- mWifiManager.startScan();
- // 得到扫描结果
- mWifiList = mWifiManager.getScanResults();
- // 得到配置好的网络连接
- mWifiConfiguration = mWifiManager.getConfiguredNetworks();
- if (mWifiList == null) {
- if(mWifiManager.getWifiState()==3){
- Toast.makeText(context,"当前区域没有无线网络", Toast.LENGTH_SHORT).show();
- }else if(mWifiManager.getWifiState()==2){
- Toast.makeText(context,"WiFi正在开启,请稍后重新点击扫描", Toast.LENGTH_SHORT).show();
- }else{
- Toast.makeText(context,"WiFi没有开启,无法扫描", Toast.LENGTH_SHORT).show();
- }
- }
- }
- // 得到网络列表
- public List<ScanResult> getWifiList() {
- return mWifiList;
- }
- // 查看扫描结果
- public StringBuilder lookUpScan() {
- StringBuilder stringBuilder = new StringBuilder();
- for (int i = 0; i < mWifiList.size(); i++) {
- stringBuilder
- .append("Index_" + new Integer(i + 1).toString() + ":");
- // 将ScanResult信息转换成一个字符串包
- // 其中把包括:BSSID、SSID、capabilities、frequency、level
- stringBuilder.append((mWifiList.get(i)).toString());
- stringBuilder.append("/n");
- }
- return stringBuilder;
- }
- // 得到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();
- }
- // 添加一个网络并连接
- public void addNetwork(WifiConfiguration wcg) {
- int wcgID = mWifiManager.addNetwork(wcg);
- boolean b = mWifiManager.enableNetwork(wcgID, true);
- System.out.println("a--" + wcgID);
- System.out.println("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, int Type)
- {
- WifiConfiguration config = new WifiConfiguration();
- config.allowedAuthAlgorithms.clear();
- config.allowedGroupCiphers.clear();
- config.allowedKeyManagement.clear();
- config.allowedPairwiseCiphers.clear();
- config.allowedProtocols.clear();
- config.SSID = "\"" + SSID + "\"";
- WifiConfiguration tempConfig = this.IsExsits(SSID);
- if(tempConfig != null) {
- mWifiManager.removeNetwork(tempConfig.networkId);
- }
- if(Type == 1) //WIFICIPHER_NOPASS
- {
- config.wepKeys[0] = "";
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- config.wepTxKeyIndex = 0;
- }
- if(Type == 2) //WIFICIPHER_WEP
- {
- config.hiddenSSID = true;
- config.wepKeys[0]= "\""+Password+"\"";
- config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
- config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
- config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
- config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
- config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
- config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- config.wepTxKeyIndex = 0;
- }
- if(Type == 3) //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;
- }
- private WifiConfiguration IsExsits(String SSID)
- {
- List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
- for (WifiConfiguration existingConfig : existingConfigs)
- {
- if (existingConfig.SSID.equals("\""+SSID+"\""))
- {
- return existingConfig;
- }
- }
- return null;
- }
- }
俩bug
这些代码看起来没有什么问题,但是通过不同环境的测试,发现了一些问题。
1 测试到的wifi热点,有的ssid为”“,也就是ssid != null,获取不到said。
2 wifi列表中有许多同名的wifi热点,也就是扫描的结果中有重合部分,并不是有多个同名的wifi热点。
第一个问题ssid为“”,这个看设置中并没有多余wifi,但这个热点点其它信息可以获取到,说明这个热点是存在的,应该是该热点隐藏了,所以获取不到。这也就是手机设置中为什么会有添加网路的按钮了。
第二个问题,当附近wifi热点比较少时不会出现此问题,当附近wifi网络比较多时会出现此问题。这就需要将同名的热点进行删除,但是如果真有两个ssid名相同的wifi,那就可以通过capabilities去区分吧,如果capabilities也相同就没办法了,系统设置里面也不显示同名的。
修改上面的方法 startScan()。
- public void startScan(Context context) {
- mWifiManager.startScan();
- //得到扫描结果
- List<ScanResult> results = mWifiManager.getScanResults();
- // 得到配置好的网络连接
- mWifiConfiguration = mWifiManager.getConfiguredNetworks();
- if (results == null) {
- if(mWifiManager.getWifiState()==3){
- Toast.makeText(context,"当前区域没有无线网络",Toast.LENGTH_SHORT).show();
- }else if(mWifiManager.getWifiState()==2){
- Toast.makeText(context,"wifi正在开启,请稍后扫描", Toast.LENGTH_SHORT).show();
- }else{Toast.makeText(context,"WiFi没有开启", Toast.LENGTH_SHORT).show();
- }
- } else {
- 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);
- }
- }
- }
- }
代码
- public class MainActivity extends Activity implements OnClickListener {
- public static final String TAG = "MainActivity";
- private Button check_wifi,open_wifi,close_wifi,scan_wifi;
- private ListView mlistView;
- protected WifiAdmin mWifiAdmin;
- private List<ScanResult> mWifiList;
- public int level;
- protected String ssid;
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mWifiAdmin = new WifiAdmin(MainActivity.this);
- initViews();
- IntentFilter filter = new IntentFilter(
- WifiManager.NETWORK_STATE_CHANGED_ACTION);
- //="android.net.wifi.STATE_CHANGE" 监听wifi状态的变化
- registerReceiver(mReceiver, filter);
- mlistView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- AlertDialog.Builder alert=new AlertDialog.Builder(MainActivity.this);
- ssid=mWifiList.get(position).SSID;
- alert.setTitle(ssid);
- alert.setMessage("输入密码");
- final EditText et_password=new EditText(MainActivity.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(MainActivity.this, "密码至少8位", Toast.LENGTH_SHORT).show();
- return;
- }
- Editor editor=preferences.edit();
- editor.putString(ssid, pw); //保存密码
- editor.commit();
- mWifiAdmin.addNetwork(mWifiAdmin.CreateWifiInfo(ssid, et_password.getText().toString(), 3));
- }
- });
- alert.setNegativeButton("取消", new DialogInterface.OnClickListener(){
- @Override
- public void onClick(DialogInterface dialog, int which) {
- //
- //mWifiAdmin.removeWifi(mWifiAdmin.getNetworkId());
- }
- });
- alert.create();
- alert.show();
- }
- });
- }
- /*
- * 控件初始化
- * */
- private void initViews() {
- check_wifi=(Button) findViewById(R.id.check_wifi);
- open_wifi=(Button) findViewById(R.id.open_wifi);
- close_wifi=(Button) findViewById(R.id.close_wifi);
- scan_wifi=(Button) findViewById(R.id.scan_wifi);
- mlistView=(ListView) findViewById(R.id.wifi_list);
- check_wifi.setOnClickListener(MainActivity.this);
- open_wifi.setOnClickListener(MainActivity.this);
- close_wifi.setOnClickListener(MainActivity.this);
- scan_wifi.setOnClickListener(MainActivity.this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.check_wifi:
- mWifiAdmin.checkState(MainActivity.this);
- break;
- case R.id.open_wifi:
- mWifiAdmin.openWifi(MainActivity.this);
- break;
- case R.id.close_wifi:
- mWifiAdmin.closeWifi(MainActivity.this);
- break;
- case R.id.scan_wifi:
- mWifiAdmin.startScan(MainActivity.this);
- mWifiList=mWifiAdmin.getWifiList();
- if(mWifiList!=null){
- mlistView.setAdapter(new MyAdapter(this,mWifiList));
- new Utility().setListViewHeightBasedOnChildren(mlistView);
- }
- break;
- default:
- 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);
- 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;
- }
- }
- /*设置listview的高度*/
- public class Utility {
- public void setListViewHeightBasedOnChildren(ListView listView) {
- ListAdapter listAdapter = listView.getAdapter();
- if (listAdapter == null) {
- return;
- }
- int totalHeight = 0;
- for (int i = 0; i < listAdapter.getCount(); i++) {
- View listItem = listAdapter.getView(i, null, listView);
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }
- ViewGroup.LayoutParams params = listView.getLayoutParams();
- params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
- listView.setLayoutParams(params);
- }
- }
- //监听wifi状态
- private BroadcastReceiver mReceiver = new BroadcastReceiver (){
- @Override
- public void onReceive(Context context, Intent intent) {
- 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+"连接成功", 1).show();
- }
- }
- };
- }
ScanResult类
这个类主要是通过Wifi硬件的扫描来获取一些周边的wifi热点(access point)的信息。该类主要有5个域,
返回类型 | 域名 | 解释 |
public String | BSSID | 接入点的地址 |
public String | SSID | 网络的名字 |
public String | capabilities | 网络性能,包括接入点支持的认证、密钥管理、加密机制等 |
public int | frequency | 以MHz为单位的接入频率 |
public int | level | 以dBm为单位的信号强度。 |
打印信息如下所示:
WifiConfiguration类
通过该类获取一个wifi网络的网络配置,包括安全配置等。它包含6个子类,如下所示:
子类 | 解释 |
WifiConfiguration.AuthAlgorthm | 获取IEEE 802.11的加密方法 |
WifiConfiguration.GroupCipher | 获取组密钥 |
WifiConfiguration.KeyMgmt | 获取密码管理体制 |
WifiConfiguration.PairwiseCipher | 获取WPA方式的成对密钥 |
WifiConfiguration.Protocol | 获取加密协议 |
WifiConfiguration.Status | 获取当前网络状态 |
WifiInfo类
该类可以获得已经建立的或处于活动状态的wifi网络的状态信息。常用方法如下:
代码:
- mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
- mWifiInfo = mWifiManager.getConnectionInfo();
- 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");
- }
WifiManager类
该类用于管理Wifi连接,定义了许多常量和方法,这里就不一一说了。
常用方法。
需要指出的是getWifiState()方法是反悔wifi的状态,有整型常量表示,