`

android 的wifi定位

阅读更多

这里列了很多,但是大致可以分为四个主要的类ScanResult wifiConfiguration WifiInfo WifiManager
(1)ScanResult,主要是通过wifi 硬件的扫描来获取一些周边的wifi 热点的信息。
在我们进行wifi 搜索的时候,一般会搜到这些信息,首先是接入点名字、接入点信息的强弱、还有接入点使用的安全模式,是WPA、WPE。
打开这个类,我们可以看到以下几个信息
BSSID 接入点的地址,这里主要是指小范围几个无线设备相连接所获取的地址,比如说两台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址。
SSID 网络的名字,当我们搜索一个网络时,就是靠这个来区分每个不同的网络接入点。
Capabilities 网络接入的性能,这里主要是来判断网络的加密方式等。
Frequency 频率,每一个频道交互的MHz 数。
Level 等级,主要来判断网络连接的优先数。
这里只提供了一个方法,就是将获得信息编程字符串toString()。
(2)wifiConfiguration 在我们连通一个wifi 接入点的时候,需要获取到的一些信息。大家可以跟我们有线的设备进行对比一下。
这里的数据相对来说比较复杂一下。
六个子类
WifiConfiguration.AuthAlgorthm 用来判断加密方法。
WifiConfiguration.GroupCipher 获取使用GroupCipher 的方法来进行加密。
WifiConfiguration.KeyMgmt 获取使用KeyMgmt 进行。
WifiConfiguration.PairwiseCipher 获取使用WPA 方式的加密。
WifiConfiguration.Protocol 获取使用哪一种协议进行加密。
wifiConfiguration.Status 获取当前网络的状态。
对于上述加密感兴趣的朋友,可以在网上搜索相关的内容。
设置WifiConfiguration的属性:
WifiConfiguration.AuthAlgorthm 设置加密方法。
可选参数:LEAP只用于leap,
OPEN 被wpa/wpa2需要,
SHARED需要一个静态的wep key
WifiConfiguration.GroupCipher 使用GroupCipher 的方法来进行加密。
可选参数:CCMP,TKIP,WEP104,WEP40
WifiConfiguration.KeyMgmt 键管理机制(keymanagerment),使用KeyMgmt 进行。
可选参数IEEE8021X,NONE,WPA_EAP,WPA_PSK
WifiConfiguration.PairwiseCipher 设置加密方式。
可选参数 CCMP,NONE,TKIP
WifiConfiguration.Protocol 设置一种协议进行加密。
可选参数 RSN,WPA,
wifiConfiguration.Status 设置当前网络的状态。
可选参数CURRENT,DISABLED,ENABLED,
(3)WifiInfo 在我们的wifi 已经连通了以后,可以通过这个类获得一些已经连通的wifi 连接的信息获取当前链接的信息,
这里信息就比较简单了,这里简单介绍一下这里的方法:
getBSSID() 获取BSSID
getDetailedStateOf() 获取客户端的连通性
getHiddenSSID() 获得SSID 是否被隐藏
getIpAddress() 获取IP 地址
getLinkSpeed() 获得连接的速度
getMacAddress() 获得Mac 地址
getRssi() 获得802.11n 网络的信号
getSSID() 获得SSID
getSupplicanState() 返回具体客户端状态的信息
(4)wifiManager 这个不用说,就是用来管理我们的wifi 连接,这里已经定义好了一些类,可以供我们使用。
这里来说相对复杂,里面的内容比较多,但是通过字面意思,我们还是可以获得很多相关的信息。这个类里面预先定义了许多常量,我们可以直接使用,不用再次创建。
这里还是简单介绍一下这里的方法:
addNetwork(WifiConfiguration config) 通过获取到的网络的链接状态信息,来添加网络
calculateSignalLevel(int rssi , int numLevels) 计算信号的等级
compareSignalLevel(int rssiA, int rssiB) 对比连接A 和连接B
createWifiLock(int lockType, String tag) 创建一个wifi 锁,锁定当前的wifi 连接
disableNetwork(int netId) 让一个网络连接失效
disconnect() 断开连接
enableNetwork(int netId, Boolean disableOthers) 连接一个连接
getConfiguredNetworks() 获取网络连接的状态
getConnectionInfo() 获取当前连接的信息
getDhcpInfo() 获取DHCP 的信息
getScanResulats() 获取扫描测试的结果
getWifiState() 获取一个wifi 接入点是否有效
isWifiEnabled() 判断一个wifi 连接是否有效
pingSupplicant() ping 一个连接,判断是否能连通
ressociate() 即便连接没有准备好,也要连通
reconnect() 如果连接准备好了,连通
removeNetwork() 移除某一个网络
saveConfiguration() 保留一个配置信息
setWifiEnabled() 让一个连接有效
startScan() 开始扫描
updateNetwork(WifiConfiguration config) 更新一个网络连接的信息
此外wifiManaer 还提供了一个内部的子类,也就是wifiManagerLock,WifiManagerLock 的作用是这样的,
在普通的状态下,如果我们的wifi 的状态处于闲置,那么网络的连通,将会暂时中断。
但是如果我们把当前的网络状态锁上,那么wifi 连通将会保持在一定状态,当然接触锁定之后,就会恢复常态

但是关于链接加密的wifi现在还没有成功……

附一个WifiAdmin 管理类:

package youcan.text;

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;

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();
}

// 得到WifiManager对象
public WifiManager GetWifiManager() {
   return mWifiManager;
}

// 打开WIFI
public void OpenWifi() {
   if (!mWifiManager.isWifiEnabled()) {
  mWifiManager.setWifiEnabled(true);
   }
 }
// 关闭WIFI
public void CloseWifi() {
   if (!mWifiManager.isWifiEnabled()) {
    mWifiManager.setWifiEnabled(false);
   }
}

// 锁定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() {
   mWifiManager.startScan();
   // 得到扫描结果
   mWifiList = mWifiManager.getScanResults();
   // 得到配置好的网络连接
   mWifiConfiguration = mWifiManager.getConfiguredNetworks();
}

// 得到网络列表
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);
   mWifiManager.enableNetwork(wcgID, true);
}

// 断开指定ID的网络
public void DisconnectWifi(int netId) {
   mWifiManager.disableNetwork(netId);
   mWifiManager.disconnect();
}
}

======================================android wifi启动过程======================================

初始化
在 SystemServer 启动的时候,会生成一个 ConnectivityService 的实例,
  try {
        Log.i(TAG, "Starting Connectivity Service.");
        ServiceManager.addService(Context.CONNECTIVITY_SERVICE, new ConnectivityService(context));
  } catch (Throwable e) {
        Log.e(TAG, "Failure starting Connectivity Service", e);
}
ConnectivityService 的构造函数会创建 WifiService,
  if (DBG) Log.v(TAG, "Starting Wifi Service.");
  mWifiStateTracker = new WifiStateTracker(context, handler);
  WifiService wifiService = new WifiService(context, mWifiStateTracker);
  ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
 
WifiStateTracker 会创建 WifiMonitor 接收来自底层的事件,
WifiService 和 WifiMonitor 是整个模块的核心。
WifiService 负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor 监视线程和把命令下发给 wpa_supplicant,
而 WifiMonitor 则负责从 wpa_supplicant 接收事件通知。
连接 AP
1. 使能 WIFI
WirelessSettings 在初始化的时候配置了由 WifiEnabler 来处理 Wifi 按钮,
 private void initToggles() {
      mWifiEnabler = new WifiEnabler(
   this,
            (WifiManager) getSystemService(WIFI_SERVICE),
            (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI)
   );
 }
当用户按下 Wifi 按钮后,Android 会调用 WifiEnabler 的 onPreferenceChange,
再由 WifiEnabler调用 WifiManager 的 setWifiEnabled 接口函数,
通过 AIDL,实际调用的是 WifiService 的setWifiEnabled 函数,
WifiService 接着向自身发送一条 MESSAGE_ENABLE_WIFI 消息,
在处理该消息的代码中做真正的使能工作:
首先装载 WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/wlan.ko" ),
然 后 启 动 wpa_supplicant ( 配 置 文 件 硬 编 码为"/data/misc/wifi/wpa_supplicant.conf")
再通过 WifiStateTracker 来启动 WifiMonitor 中的监视线程。
     private boolean setWifiEnabledBlocking(boolean enable) {
          final int eventualWifiState = enable ? WIFI_STATE_ENABLED : WIFI_STATE_DISABLED;
          updateWifiState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING);
          if (enable) {
                if (!WifiNative.loadDriver()) {
                       Log.e(TAG, "Failed to load Wi-Fi driver.");
                       updateWifiState(WIFI_STATE_UNKNOWN);
                       return false;
                }
                if (!WifiNative.startSupplicant()) {
                       WifiNative.unloadDriver();
                       Log.e(TAG, "Failed to start supplicant daemon.");
                       updateWifiState(WIFI_STATE_UNKNOWN);
                       return false;
                }
                mWifiStateTracker.startEventLoop();
          }
             // Success!
             persistWifiEnabled(enable);
             updateWifiState(eventualWifiState);
             return true;
      }
当使能成功后,会广播发送 WIFI_STATE_CHANGED_ACTION 这个 Intent 通知外界 WIFI 已经成功使能了。
WifiEnabler 创建的时候就会向 Android 注册接收WIFI_STATE_CHANGED_ACTION,
因此它会收到该 Intent,从而开始扫描。
          private void handleWifiStateChanged(int wifiState) {
             if (wifiState == WIFI_STATE_ENABLED) {
                  loadConfiguredAccessPoints();
                  attemptScan();
             }
2. 查找 AP
扫描的入口函数是 WifiService 的 startScan,它其实也就是往 wpa_supplicant 发送 SCAN 命令。
static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz)
{
      jboolean result;
      // Ignore any error from setting the scan mode.
      // The scan will still work.
      (void)doBooleanCommand("DRIVER SCAN-ACTIVE", "OK");
      result = doBooleanCommand("SCAN", "OK");
      (void)doBooleanCommand("DRIVER SCAN-PASSIVE", "OK");
      return result;
}
当 wpa_supplicant 处理完 SCAN 命令后,它会向控制通道发送事件通知扫描完成,
从而wifi_wait_for_event 函数会接收到该事件,
由此 WifiMonitor 中的 MonitorThread 会被执行来出来这个事件,
             void handleEvent(int event, String remainder) {
                        case SCAN_RESULTS:
                             mWifiStateTracker.notifyScanResultsAvailable();
                             break;
WifiStateTracker 则接着广播发送 SCAN_RESULTS_AVAILABLE_ACTION 这个 Intent
                  case EVENT_SCAN_RESULTS_AVAILABLE:
                        mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
WifiLayer 注册了接收 SCAN_RESULTS_AVAILABLE_ACTION 这个 Intent,所以它的相关
处理函数 handleScanResultsAvailable 会被调用,在该函数中,先会去拿到 SCAN 的结果(最
终是往 wpa_supplicant 发送 SCAN_RESULT 命令并读取返回值来实现的)                             ,
                List<ScanResult> list = mWifiManager.getScanResults();
对每一个扫描返回的 AP,WifiLayer 会调用 WifiSettings 的 onAccessPointSetChanged 函数,
从而最终把该 AP 加到 GUI 显示列表中。
     public void onAccessPointSetChanged(AccessPointState ap, boolean added) {
          AccessPointPreference pref = mAps.get(ap);
          if (added) {
                if (pref == null) {
                      pref = new AccessPointPreference(this, ap);
                      mAps.put(ap, pref);
                } else {
                      pref.setEnabled(true);
                }
                mApCategory.addPreference(pref);
          }
     }
3. 配置 AP 参数
当用户在 WifiSettings 界面上选择了一个 AP 后,会显示配置 AP 参数的一个对话框,
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
          if (preference instanceof AccessPointPreference) {
                AccessPointState state = ((AccessPointPreference) preference).getAccessPointState();
                showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
          }
     }
4. 连接
当用户在 AcessPointDialog 中选择好加密方式和输入密钥之后,再点击连接按钮,Android
就会去连接这个 AP。
     private void handleConnect() {
          String password = getEnteredPassword();
          if (!TextUtils.isEmpty(password)) {
                mState.setPassword(password);
          }
          mWifiLayer.connectToNetwork(mState);
     }
WifiLayer 会先检测这个 AP 是不是之前被配置过,这个是通过向 wpa_supplicant 发送
LIST_NETWORK 命令并且比较返回值来实现的,
          // Need WifiConfiguration for the AP
          WifiConfiguration config = findConfiguredNetwork(state);
如果 wpa_supplicant 没有这个 AP 的配置信息,则会向 wpa_supplicant 发送 ADD_NETWORK 命令来添加该 AP,
          if (config == null) {
                // Connecting for the first time, need to create it
                config = addConfiguration(state, ADD_CONFIGURATION_ENABLE|ADD_CONFIGURATION_SAVE);
          }
ADD_NETWORK 命 令 会 返 回 一 个 ID , WifiLayer 再用这个返回的ID作为参数向
wpa_supplicant 发送 ENABLE_NETWORK 命令,从而让 wpa_supplicant 去连接该 AP。
          // Make sure that network is enabled, and disable others
          mReenableApsOnNetworkStateChange = true;
          if (!mWifiManager.enableNetwork(state.networkId, true)) {
                Log.e(TAG, "Could not enable network ID " + state.networkId);
                error(R.string.error_connecting);
                return false;
          }
5. 配置 IP 地址
当 wpa_supplicant 成功连接上 AP 之后,它会向控制通道发送事件通知连接上 AP 了,从而
wifi_wait_for_event 函数会接收到该事件,由此 WifiMonitor 中的 MonitorThread 会被执行来
出来这个事件,
          void handleEvent(int event, String remainder) {
                     case CONNECTED:
                           handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);
                           break;
WifiMonitor 再调用 WifiStateTracker 的 notifyStateChange,WifiStateTracker 则接着会往自身
发送 EVENT_DHCP_START 消息来启动 DHCP 去获取 IP 地址,
     private void handleConnectedState() {
          setPollTimer();
          mLastSignalLevel = -1;
          if (!mHaveIPAddress && !mObtainingIPAddress) {
                mObtainingIPAddress = true;
                mDhcpTarget.obtainMessage(EVENT_DHCP_START).sendToTarget();
          }
     }
然后再广播发送 NETWORK_STATE_CHANGED_ACTION 这个 Intent
                case EVENT_NETWORK_STATE_CHANGED:
                     if (result.state != DetailedState.DISCONNECTED || !mDisconnectPending) {
                           intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                           intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
                          if (result.BSSID != null)
                                intent.putExtra(WifiManager.EXTRA_BSSID, result.BSSID);
                          mContext.sendStickyBroadcast(intent);
                     }
                     break;
WifiLayer 注册了接收 NETWORK_STATE_CHANGED_ACTION 这个 Intent,所以它的相关
处理函数 handleNetworkStateChanged 会被调用,
当 DHCP 拿到 IP 地址之后,会再发送 EVENT_DHCP_SUCCEEDED 消息,
     private class DhcpHandler extends Handler {
          public void handleMessage(Message msg) {
                switch (msg.what) {
                     case EVENT_DHCP_START:
                          if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
                                event = EVENT_DHCP_SUCCEEDED;
                                                      }
WifiLayer 处理 EVENT_DHCP_SUCCEEDED 消息 , 会再次广播发送
NETWORK_STATE_CHANGED_ACTION 这个 Intent,这次带上完整的 IP 地址信息。
                case EVENT_DHCP_SUCCEEDED:
                     mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
                     setDetailedState(DetailedState.CONNECTED);
                     intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                     intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
                     mContext.sendStickyBroadcast(intent);
                     break;

至此为止,整个连接过程完成


  WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
  WifiConfiguration wc = new WifiConfiguration();
  wc.SSID = ""test"";//ssid
  wc.preSharedKey = ""12345678"";//ssid密码
  wc.hiddenSSID = true;
  wc.status = WifiConfiguration.Status.ENABLED;
  wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
  wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
  wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
  wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
  wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
  wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
  int res = wifi.addNetwork(wc);
  Log.e("WifiPreference", "add Network returned " + res );
  boolean b = wifi.enableNetwork(res, true);
  Log.e("WifiPreference", "enableNetwork returned " + b );

=====================================================================

package src.hero.com;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

public class ListOk extends ListActivity implements OnItemClickListener
{

 private ListView lv;

 private WifiTester wifiTester;

 // -----------------------连接WIFI
 private ScanResult scanRet;

 private WifiConfiguration wc;

 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  this.setTitle("当前可用的WIFI列表");

  WifiTesterApp _TestActivityApp = (WifiTesterApp) this.getApplication();
  wifiTester = (_TestActivityApp).getWifiTester();

  wc = new WifiConfiguration();

  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_list_item_1,
    getString(wifiTester.getWifiList()));
  setListAdapter(adapter);
  lv = getListView();
  lv.setAdapter(adapter);
  lv.setOnItemClickListener(this);
 }

 public String[] getString(List<ScanResult> wifiList)
 {
  ArrayList<String> listStr = new ArrayList<String>();

  for (int i = 0; i < wifiList.size(); i++)
  {
   listStr.add(wifiList.get(i).toString());
  }
  return listStr.toArray(new String[0]);
 }

 @Override
 public void onItemClick(AdapterView<?> parent, View view, int position,
   long id)
 {

  scanRet = wifiTester.getWifiList().get(position);
  wc.SSID = """ + scanRet.SSID + """; // 配置wifi的SSID,即该热点的名称,如:TP-link_xxx
  wc.preSharedKey = ""7675781777""; // 该热点的密码
  wc.hiddenSSID = true;
  wc.status = WifiConfiguration.Status.ENABLED;
  wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
  wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
  wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
  wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
  wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
  wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
  // int res = wifiTester.getMainWifi().addNetwork(wc);
  // Log.d("Wif iPreference", "1111111add Network returned " + res);
  // boolean b = wifiTester.getMainWifi().enableNetwork(res, true);
  // Log.d("WifiPreference", "2222222222enableNetwork returned " + b);

 }
}

============================================================

package jmu84xu.all;

import java.net.Inet4Address;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class WifiSet extends Activity implements OnCheckedChangeListener {

 private WifiManager wifiManager;
 private WifiInfo wifiInfo;
 private CheckBox chkOpenCloseWifiBox;
 private List<WifiConfiguration> wifiConfigurations;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);// 获得WifiManager对象
  wifiInfo = wifiManager.getConnectionInfo();// 获得连接信息对象
  
  chkOpenCloseWifiBox = (CheckBox)findViewById(R.id.chkOpenCloseWifi);
  TextView tvWifiConfigurations = (TextView) findViewById(R.id.tvWifiConfigurations);
  TextView tvWifiInfo = (TextView) findViewById(R.id.tvWifiInfo);
  
  chkOpenCloseWifiBox.setOnCheckedChangeListener(this);
  // 根据当前WIFI的状态(是否被打开)设置复选框的选中状态
  if (wifiManager.isWifiEnabled()) {
   chkOpenCloseWifiBox.setText("Wifi已开启");
   chkOpenCloseWifiBox.setChecked(true);
  }
  else {
   chkOpenCloseWifiBox.setText("Wifi已关闭");
   chkOpenCloseWifiBox.setChecked(false);
  }
  // 获得WIFI信息
  StringBuffer sb = new StringBuffer();
  sb.append("Wifi信息n");
  sb.append("MAC地址:" + wifiInfo.getMacAddress() + "n");
  sb.append("接入点的BSSID:" + wifiInfo.getBSSID() + "n");
  sb.append("IP地址(int):" + wifiInfo.getIpAddress() + "n");
  sb.append("IP地址(Hex):" + Integer.toHexString(wifiInfo.getIpAddress()) + "n");
  sb.append("IP地址:" + ipIntToString(wifiInfo.getIpAddress()) + "n");

  sb.append("网络ID:" + wifiInfo.getNetworkId() + "n");
  tvWifiInfo.setText(sb.toString());
 // 得到配置好的网络
  wifiConfigurations = wifiManager.getConfiguredNetworks();
  tvWifiConfigurations.setText("已连接的无线网络n");
  for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
   tvWifiConfigurations.setText(tvWifiConfigurations.getText() + wifiConfiguration.SSID + "n"
   );
  }
 }
 // 将int类型的IP转换成字符串形式的IP
 private String ipIntToString(int ip) {
  try {
   byte[] bytes = new byte[4];
   bytes[0] = (byte) (0xff & ip);
   bytes[1] = (byte) ((0xff00 & ip) >> 8);
   bytes[2] = (byte) ((0xff0000 & ip)>> 16);
   bytes[3] = (byte) ((0xff000000 & ip)>> 24);
   return Inet4Address.getByAddress(bytes).getHostAddress();
  } catch (Exception e) {
   return"";
  }
 }
 @Override
 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  // 当选中复选框时打开WIFI
  if (isChecked) {
   wifiManager.setWifiEnabled(true);
   chkOpenCloseWifiBox.setText("Wifi已开启");
  }
  // 当取消复选框选中状态时关闭WIFI
  else {
   wifiManager.setWifiEnabled(false);
   chkOpenCloseWifiBox.setText("Wifi已关闭");
  }
 }
}
   在AndroidManifest.xml文件中要使用如下的代码打开相应的权限。
   Java代码:
XML/HTML代码
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permissionandroid:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

================================================================

package com.eoeandroid.demo.testcode;

import java.util.List;

import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.net.wifi.ScanResult;

import android.net.wifi.WifiManager;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.widget.TextView;

public class WifiTester extends Activity {

        TextView mainText;

        WifiManager mainWifi;

        WifiReceiver receiverWifi;

        List<ScanResult> wifiList;

        StringBuilder sb = new StringBuilder();

        public void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.WifiTester);

                setTitle("eoe教程: Wifi Test.  -by:IceskYsl");

                mainText = (TextView) findViewById(R.id.wifi);

                mainWifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

                receiverWifi = new WifiReceiver();

                registerReceiver(receiverWifi, new IntentFilter(

                                WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

                mainWifi.startScan();

                mainText.setText("nStarting Scan...n");

        }

        public boolean onCreateOptionsMenu(Menu menu) {

                menu.add(0, 0, 0, "Refresh");

                return super.onCreateOptionsMenu(menu);

        }

        public boolean onMenuItemSelected(int featureId, MenuItem item) {
                  mainWifi.startScan();

                mainText.setText("Starting Scan");

                return super.onMenuItemSelected(featureId, item);

        }

        protected void onPause() {

                unregisterReceiver(receiverWifi);

                super.onPause();

        }

        protected void onResume() {

                registerReceiver(receiverWifi, new IntentFilter(

                                WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

                super.onResume();

        }

        class WifiReceiver extends BroadcastReceiver {

                public void onReceive(Context c, Intent intent) {

                        sb = new StringBuilder();

                        wifiList = mainWifi.getScanResults();

                        for (int i = 0; i < wifiList.size(); i++) {

                                sb.append(new Integer(i + 1).toString() + ".");

                                sb.append((wifiList.get(i)).toString());

                                sb.append("nn");

                        }

                        mainText.setText(sb);

                }

        }

}

================================================================

1.wifi的五种状态:
WIFI_STATE_DISABLED   WIFI网卡不可用 
WIFI_STATE_DISABLING  WIFI网卡正在关闭 
WIFI_STATE_ENABLED     WIFI网卡可用 
WIFI_STATE_ENABLING    WIFI网卡正在打开 
WIFI_STATE_UNKNOWN    WIFI网卡状态不可知
2.要操作WiFi设备,就要使用Context.getSystemService(Context.WIFI_SERVICE)来获取WifiManager对象,并通过这个对象来管理WiFi设备。
addNetwork(WifiConfiguration config)

 添加一个config描述的WIFI网络,默认情况下,这个WIFI网络是DISABLE状态的。
calculateSignalLevel(int rssi , int numLevels)

 计算信号的等级
compareSignalLevel(int rssiA, int rssiB)

 对比网络A和网络B的信号强度
createWifiLock(int lockType, String tag)

 创建一个WIFI 锁,锁定当前的WIFI连接
disableNetwork(int netId)

 让一个网络连接失效
disconnect()

 断开当前的WIFI连接
enableNetwork(int netId, Boolean disableOthers)

 连接netId所指的WIFI网络,并是其他的网络都被禁用
getConfiguredNetworks()

 获取网络连接的状态
getConnectionInfo()

 获取当前连接的信息
getDhcpInfo()

 获取DHCP 的信息
getScanResulats()

 获取扫描测试的结果
getWifiState()

 获取当前WIFI设备的状态
isWifiEnabled()

 判断WIFI设备是否打开
pingSupplicant()

 ping操作,和PC的ping操作相同作用
ressociate()

 重新连接WIFI网络,即使该网络是已经被连接上的
reconnect()

 重新连接一个未连接上的WIFI网络
removeNetwork()

 移除某一个网络
saveConfiguration()

 保留一个配置信息
setWifiEnabled()

 让一个连接有效
startScan()

 开始扫描
updateNetwork(WifiConfiguration config)

 更新一个网络连接
3.如果要想得到周围的WIFI热点列表,可以使用WifiManager.getScanResults()返回一个ScanResult列表,ScanResult对象中,包含了以下几个属性:

BSSID 接入点的地址
SSID 网络的名字,唯一区别WIFI网络的名字
Capabilities 网络接入的性能
Frequency 当前WIFI设备附近热点的频率(MHz)
Level 所发现的WIFI网络信号强度
4.连接上自定义的WIFI?
//根据ID值来自动连接WIFI网络

//@param index ID值

public void ConnectWifiBySSID(int index) {

    // 索引大于配置好的网络索引返回

    if (index > mWifiConfiguration.size()) {

     return;

    }

    // 连接配置好的指定ID的网络

    mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,true);

 }

// 根据WifiConfiguration对象来自动连接WIFI网络

// @param wcg WifiConfiguration对象

 public void ConnectWifiByConfig(WifiConfiguration wifiConfiguration) {

    int wcgID = mWifiManager.addNetwork(wifiConfiguration);

    mWifiManager.enableNetwork(wcgID, true);

}

5.查看已经连接上的WIFI信息,在Android的SDK中为我们提供了一个叫做WifiInfo的对象,这个对象可以通过WifiManager.getConnectionInfo()来获取。WifiInfo中包含了当前连接中的相关信息。


getBSSID()  获取BSSID属性
getDetailedStateOf()  获取客户端的连通性
getHiddenSSID()  获取SSID 是否被隐藏
getIpAddress()  获取IP 地址
getLinkSpeed()  获取连接的速度
getMacAddress()  获取Mac 地址
getRssi()  获取802.11n 网络的信号
getSSID()  获取SSID
getSupplicanState()  获取具体客户端状态的信息

0
0
分享到:
评论

相关推荐

    Android WIFI 定位 简单DEMO实例代码

    打开清单文件,查看使用WiFi定位的权限; 打开程序文件MainActivity,查看检测WiFi是否打开及开启WiFi的代码; 查看位置管理器方法requestLocationUpdates()中位置监听器的用法,并与GPSLocation工程中的位置器用法...

    基于Android的WIFI室内定位技术研究

    基于此,本课题重点研究并改进指纹定位算法,设计实现基于Android的WIFI室内定位系统。 首先,通过阅读大量相关的文献资料,对比分析了当前国内外WIFI室内指纹定位技术的研究现状对其中涉及到的相关技术的原理和特点...

    Android Wifi Lbs 定位

    Android WiFi LBS(Location-Based Services,基于位置的服务)定位是通过结合WiFi网络信号和移动通信基站信息来确定设备的位置。这种定位方式在GPS信号不可用或者信号弱的室内环境尤为实用。下面将详细介绍Android ...

    wifi室内定位demo

    【Android WiFi定位原理】 1. **WiFi信号强度与距离关系**:WiFi信号强度通常随距离增加而减弱,通过测量到不同AP的信号强度,可以推算出设备与各个AP的距离或相对距离。 2. **指纹定位法**:这是最常见的WiFi室内...

    安卓Android源码——androidGPS及WIFI基站定位坐标源码.zip

    使用GPS和WIFI定位功能需要在AndroidManifest.xml中声明相应的权限: - `&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;`: 允许访问精细(GPS)位置信息。 - `&lt;uses-permission ...

    在Android里完美实现基站和WIFI定位

    在Android系统中,基站和WIFI定位是两种重要的位置服务技术,它们可以帮助应用程序获取设备的地理位置信息,即使在没有GPS的情况下也能实现定位。对于OPhone和部分国产Android定制机,由于默认不支持基站和WIFI定位...

    基于位置指纹算法的Android平台WiFi定位系统

    《基于位置指纹算法的Android平台WiFi定位系统》 在当今科技日新月异的时代,位置定位服务已经成为日常生活和工作中不可或缺的一部分。随着城市无线基础设施的快速发展,WiFi热点的覆盖率大幅度提升,这为WiFi定位...

    android google 定位程序 wifi基站GPS定位

    在Android平台上,Google提供了一套全面的定位服务,使得开发者能够轻松实现基于GPS、Wi-Fi基站和移动网络的综合定位功能。这篇文档将详细介绍如何在Android应用中利用这些技术进行定位。 首先,我们需要理解...

    androidgps基站与WIFI定位源码.zip

    本资源“androidgps基站与WIFI定位源码.zip”提供了一套实现GPS、基站和Wi-Fi定位功能的源代码,非常适合Android开发者学习和参考。 首先,我们要理解Android系统中的定位机制。Android提供了Location API,这是一...

    Android_GPS_WIFI_网络定位

    最后,网络定位结合了GPS和WiFi定位,同时考虑移动网络基站信息,提高了定位效率和覆盖率。在网络条件良好时,网络定位可以快速提供粗略的位置信息,适合应用场景如推送基于位置的服务。然而,由于依赖网络,其隐私...

    Android WIFI驱动工作流程

    Android WIFI驱动工作流程是一个复杂的主题,包含了硬件与软件的协作以及网络通信的原理。首先,Android设备的WIFI功能通常是由内置硬件模块实现的,如Marvell 8686。在硬件层面,它集成了802.11a/g/b RF、基带、CPU...

    android gps wifi 基站 定位齐全。源码

    Android的LocationManager同样支持WiFi定位,只需指定相应的PROVIDER即可。 基站定位,也称为Cell ID定位,是通过识别手机连接的移动通信基站来确定位置。当GPS信号弱或不可用时,这种方法可以提供粗略的位置信息。...

    Android的基站、WIFI、GPS定位集合【源码】.zip

    2. WIFI定位:WIFI定位利用已知的WIFI热点数据库,通过比较设备当前接收到的WIFI信号,匹配数据库中记录的信号特征来确定位置。在Android中,使用`WifiManager`类和`LocationManager`服务结合,通过`addWifiListener...

    Android-WIFI.rar_WiFi模块程序_android wifi_android wifi slam_android

    提供的"Android WIFI开发介绍.pdf"可能包含了对上述概念的详细讲解,可能涵盖如何解析WiFi扫描结果、处理连接事件、实现自定义的WiFi定位算法等内容。阅读源码可以帮助开发者更深入地理解Android WiFi系统的运作...

    androidGPS及WIFI基站定位坐标源码.zip

    在Android系统中,GPS(全球定位系统)和WIFI基站定位是两种常见的定位技术,用于获取设备的地理位置信息。这份“androidGPS及WIFI基站定位坐标源码.zip”压缩包包含了一些实现这两种定位方式的源代码,对于学习...

    Android-WiFiLocation是一款基于K-NN算法的简易WiFi定位系统SDK

    WiFiLocation是一款基于K-NN算法的简易WiFi定位系统。它借助 LitePal 建立本地的WiFi指纹数据库,通过一系列API实现目标地点的WiFi指纹搜集、更新、重置或删除,以及当前位置的定位识别。

    android定位(基站,GPS,wifi)齐全

    本文将详细介绍基于Android的三种定位方式:GPS(全球定位系统)、WiFi网络定位和基站定位,并结合提供的源码资源进行深入解析。 首先,GPS是全球卫星导航系统,用于提供精确的地理位置信息。`Android实现GPS定位....

    android studio wifi 扫描 连接代码

    注意,由于安全性原因,从Android 6.0(API级别23)开始,应用需要在运行时请求`ACCESS_FINE_LOCATION`或`ACCESS_COARSE_LOCATION`权限,因为扫描WiFi热点被认为是定位的一种形式。 在实际开发中,还需要考虑一些...

    安卓WiFi室内定位程序源码

    4. **定位服务**:除了WiFi定位,Android还提供了GPS、网络定位等多种定位服务。开发者需要理解如何开启和使用这些服务,并处理各种权限问题。 5. **数据处理和算法实现**:将收集到的WiFi信号强度转化为距离,然后...

    Android WIFI状态监控

    在Android平台上,对WIFI状态的监控是移动应用开发中的一个重要功能,特别是在涉及网络连接、定位服务或数据传输的应用中。本文将详细讲解如何在Android中监控WIFI的状态,并介绍相关知识点。 首先,Android提供了`...

Global site tag (gtag.js) - Google Analytics