1. 程式人生 > >Android連續獲取當前所連線WiFi及周圍熱點列表資訊的解決方案

Android連續獲取當前所連線WiFi及周圍熱點列表資訊的解決方案

基礎知識:

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"/>

大功告成,這是我的測試結果:

  1. “RSSI”全稱為“Received Signal Strength Indication”,即(接收)訊號強度指示。在這裡返回一個0~-100之間的int型資料。一般而言,大小在0~-50表示訊號最好,-50~-70訊號較差,小於-70訊號最差,可能連線不上或掉線,通常值為-200時表示wifi已斷。