Android連續獲取當前所連線WiFi及周圍熱點列表資訊的解決方案
阿新 • • 發佈:2019-02-15
基礎知識:
Android的wifi資訊獲取先要自學相關基礎知識,下面是相關基礎知識。
獲取系統wifi服務
// 獲取系統wifi服務
WifiManage wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
// 獲取當前所連線wifi的資訊
WifiInfo wi = wm.getConnectionInfo();
// 獲取掃描到的所有wifi資訊
List<ScanResult> scanResults = wm.getScanResults();
獲取wifi資訊的各種方法及異同
這裡只簡略地提及WifiManage, WifiInfo, ScanResult 這三個類的一些方法,如果非常感興趣可以去安卓社群看看。廢話不多說,Here we go!
WifiManage類wifi資訊獲取方法
wm.getConnectionInfo(); // 獲取當前連線資訊
wm.getWifiState(); // 獲取當前手機wifi網絡卡狀態
wm.getScanResults(); // 獲取掃描到的wifi資訊列表(返回型別是連結串列)
- 手機wifi網絡卡狀態分五種情況
wifi網絡卡狀態 詳細說明 WifiManager.WIFI_STATE_ENABLED
wifi網絡卡可用 WifiManager.WIFI_STATE_DISABLED
wifi網絡卡不可用 WifiManager.WIFI_STATE_DISABLING
wifi網絡卡正關閉 WifiManager.WIFI_STATE_ENABLING
wifi網絡卡正開啟 WifiManager.WIFI_STATE_UNKNOWN
狀態未知
- 對應手機要開的許可權如下:
許可權程式碼 詳細說明 ACCESS_WIFI_STATE 允許程式獲得wifi的狀態資訊 INTERNET 允許程式獲得手機網路許可權 CHANGE_NETWORK_STATE 允許應用程式改變wifi連線狀態
WifiInfo類方法
wi.getSSID(); // 獲取當前連線wifi的名詞
wi.getBSSID(); // 獲取路由器Mac地址,String型別
wi.getMacAddress(); // 獲取本機Mac地址
wi.getRssi(); // 獲取當前連線wifi的訊號強度
wi.getLinkSpeed(); // 獲取連線速度
WifiInfo.LINK_SPEED_UNITS; // 連線速度單位
wi.getRssi()
獲取的就是所連線wifi的RSSI1
ScanResult類方法
scanResult.SSID();
scanResult.BSSID();
scanResult.level(); // 訊號強度(原始資料)
WifiManager.calculateSignalLevel(scanResult.level(),5); // 計算強度等級,此處分5級。
利用多執行緒實現資料的持續性採集
安卓中事件處理的原則:所有可能耗時的操作都放到其他執行緒去處理。根據這一原則,我們將wifi系統服務獲取、資訊獲取等都放在一個執行緒中實現,定義每500ms取樣一次。這樣為主執行緒瘦身就能大大加快應用程式響應時間,改善使用者體驗。由於自己也剛接觸Android多執行緒,這裡就不多說了,感興趣的同學可以去上網搜尋相關內容。
程式碼展示
下面的是activity_main.xml檔案中的程式碼,第二個佈局控制元件LinearLayout設為垂直滾動檢視,以便顯示足夠多的wifi資訊。
<?xml version="1.0" encoding="utf-8"?
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.lenovo.wifi_bluetooth.MainActivity">
<RelativeLayout
android:id="@+id/relativelayout1"
android:gravity="start|center_vertical"
android:layout_width="368dp"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/Curr_connected_wifi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="vertical">
<TextView
android:id="@+id/testView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str2"/>
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/Curr_connected_wifi"
android:scrollbars="vertical"
android:fadingEdge="vertical">
<LinearLayout
android:id="@+id/list_wifi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/testView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str1" />
<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
接下來是檔案MActivity.java程式碼:
package com.example.lenovo.wifi_bluetooth;
import android.net.wifi.ScanResult;
import java.util.List;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private WifiManager wm;
EditText editText1 ;
EditText editText2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new tvThread().start();
}
private class tvThread extends Thread {
@Override
public void run() {
while (true) {
runOnUiThread(new Runnable() {
@Override
public void run() {
obtainListInfo();
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void obtainListInfo(){
//---------------------------------------------->
editText1 = (EditText) findViewById(R.id.et1);
editText2 = (EditText) findViewById(R.id.et2);
//顯示掃描到的所有wifi資訊
wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
WifiInfo wi = wm.getConnectionInfo();
int strength = wi.getRssi();
int speed = wi.getLinkSpeed();
String designation = wi.getSSID();
String addr = wi.getBSSID();
String unit = WifiInfo.LINK_SPEED_UNITS;
if (wm.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
StringBuilder listinfo = new StringBuilder();
//搜尋到的wifi列表資訊
List<ScanResult> scanResults = wm.getScanResults();
for (ScanResult sr:scanResults){
listinfo.append("wifi網路ID:");
listinfo.append(sr.SSID);
listinfo.append("\nwifi MAC地址:");
listinfo.append(sr.BSSID);
listinfo.append("\nwifi訊號強度:");
listinfo.append(sr.level+"\n\n");
}
editText2.setText(listinfo.toString());
String curr_connected_wifi=null;
curr_connected_wifi="Currently connecting WiFi \'"+designation+"\' \nRssi: "+strength+
"\nMac addr: "+addr+"\nspeed: "+speed+" "+unit;
editText1.setText(curr_connected_wifi.toString());
}
//------------------------------------------------------------------->
}
}
在AndroidManifest.xml檔案中新增如下程式碼以開啟許可權:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
大功告成,這是我的測試結果:
- “RSSI”全稱為“Received Signal Strength Indication”,即(接收)訊號強度指示。在這裡返回一個0~-100之間的int型資料。一般而言,大小在0~-50表示訊號最好,-50~-70訊號較差,小於-70訊號最差,可能連線不上或掉線,通常值為-200時表示wifi已斷。 ↩