在移动应用中,获取用户所在位置和周边热点的信号强度和其他信息是很常见的操作。下面将介绍如何使用Android SDK中的WifiManager类来扫描周围的WiFi网络,获取热点的SSID、BSSID和信号强度等信息,同时也会提供完整的代码示例。
一、准备工作
首先,你需要在AndroidManifest.xml文件中添加如下的权限声明,以便应用程序能够访问Wi-Fi网络:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
另外,由于Android系统的版本不同,对Wi-Fi扫描结果的格式也存在差异。如果应用程序需要支持多个版本的Android系统,建议使用Support Library。你需要在Gradle构建文件中添加以下依赖声明:
dependencies { compile 'com.android.support:support-v4:26.1.0' }
二、获取WiFi信息
我们可以使用Android SDK中的WifiManager类来获取周围WiFi信号的信息。接下来,我将通过代码来示范如何实现该功能。
1、初始化WifiManager
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
2、注册监听Wifi扫描结果的广播接收器
BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 处理扫描结果 ListwifiScanList = wifiManager.getScanResults(); for (ScanResult wifi : wifiScanList) { // 获取SSID、BSSID、信号强度等信息 String ssid = wifi.SSID; String bssid = wifi.BSSID; int rssi = wifi.level; // 处理数据 ... } } }; registerReceiver(wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
我们通过一个广播接收器来监听WIFI扫描结果。当扫描完成后,onReceive()方法就会被调用,我们就可以在这里读取并处理扫描结果的信息。
3、执行WiFi扫描操作
wifiManager.startScan();
在执行扫描操作之后,我们需要等待onReceive()方法被调用,从而读取WiFi扫描结果。注意,由于WiFi扫描操作需要一些时间,可能需要5~10秒的时间才能得到扫描结果。因此,在程序中也可以使用Handler和定时器来实现循环读取WiFi扫描结果。
三、完整代码示例
下面是使用WifiManager类实现WiFi扫描功能的完整代码示例:
public class MainActivity extends AppCompatActivity { WifiManager wifiManager; BroadcastReceiver wifiScanReceiver; ListView listView; List<ScanResult> wifiList; WifiAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); // 注册监听Wifi扫描结果的广播接收器 wifiScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { wifiList = wifiManager.getScanResults(); adapter = new WifiAdapter(getApplicationContext(), wifiList); listView.setAdapter(adapter); } }; registerReceiver(wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); // 执行WiFi扫描操作 wifiManager.startScan(); // 初始化ListView listView = (ListView) findViewById(R.id.listView); } @Override protected void onPause() { super.onPause(); unregisterReceiver(wifiScanReceiver); } @Override protected void onResume() { super.onResume(); registerReceiver(wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); } } class WifiAdapter extends BaseAdapter { private LayoutInflater inflater; private List<ScanResult> wifiList; public WifiAdapter(Context context, List<ScanResult> wifiList) { this.inflater = LayoutInflater.from(context); this.wifiList = wifiList; } @Override public int getCount() { return wifiList.size(); } @Override public Object getItem(int position) { return wifiList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item, parent, false); holder = new ViewHolder(); holder.ssidTextView = (TextView) convertView.findViewById(R.id.ssidTextView); holder.bssidTextView = (TextView) convertView.findViewById(R.id.bssidTextView); holder.rssiTextView = (TextView) convertView.findViewById(R.id.rssiTextView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } ScanResult wifi = wifiList.get(position); holder.ssidTextView.setText("SSID: " + wifi.SSID); holder.bssidTextView.setText("BSSID: " + wifi.BSSID); holder.rssiTextView.setText("Signal Strength: " + wifi.level); return convertView; } static class ViewHolder { TextView ssidTextView; TextView bssidTextView; TextView rssiTextView; } }
需要特别注意的是,当一个程序尝试执行WiFi扫描操作时,系统可能不会立即返回结果。因为系统可能正在执行其他WiFi扫描操作,或者系统正在关注的当前WiFi扫描列表太长。因此,结果返回的时间是不确定的。通过以上代码为App设置WiFi扫描的代码,可以扫描到附近的WiFi信号,并得到它们的SSID、BSSID和信号强度等信息。这些信息可以被应用程序用来决定用户位置并进行其他操作。