Android开发——WiFi信号检测

Posted lee-01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发——WiFi信号检测相关的知识,希望对你有一定的参考价值。

1.首先在androidManifest.xml文件中添加如下代码以开启权限:

<!-- 获取WiFi状态的权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 改变网络状态的权限 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 获取网络权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
2.Android有三个跟获取WiFi信息相关的类:WifiManager,WifiInfo,ScanResult
  • WifiManage
 1 // 获取系统wifi服务
 2 WifiManage wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
 3 // 获取当前所连接wifi的信息
 4 WifiInfo wi = wm.getConnectionInfo();
 5 // 获取扫描到的所有wifi信息
 6 List<ScanResult> scanResults = wm.getScanResults();
 7 // 获取当前手机wifi网卡状态
 8 int state = wm.getWifiState();    //state值为以下宏定义
 9 WifiManager.WIFI_STATE_ENABLED    wifi网卡可用
10 WifiManager.WIFI_STATE_DISABLED    wifi网卡不可用
11 WifiManager.WIFI_STATE_DISABLING    wifi网卡正关闭
12 WifiManager.WIFI_STATE_ENABLING    wifi网卡正打开
13 WifiManager.WIFI_STATE_UNKNOWN    状态未知
技术分享图片
  • WifiInfo
1 WifiInfo wifiInfo = wifi_service.getConnectionInfo();    // 获取当前所连接wifi的信息
2 wi.getSSID();        // 获取当前连接wifi的名词
3 wi.getBSSID();       // 获取路由器Mac地址,String类型
4 wi.getMacAddress();  // 获取本机Mac地址
5 wi.getRssi();        // 获取当前连接wifi的信号强度,返回一个0~-100之间的int型数据
6 wi.getLinkSpeed();   // 获取连接速度
7 WifiInfo.LINK_SPEED_UNITS; // 连接速度单位
技术分享图片

注:RSSI,得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好,-50到-70表示信号偏差,小于-70表示最差,有可能连接不上或者掉线,一般Wifi已断则值为-200。

  • ScanResult
scanResult.SSID();
scanResult.BSSID();
scanResult.level;    // 信号强度(原始数据)
WifiManager.calculateSignalLevel(scanResult.level(),5); // 计算强度等级,此处分5级。

3.代码

  • activity_main.xml资源文件
<?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.lee.rss_collector.MainActivity">

    <RelativeLayout
        android:id="@+id/relative_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:gravity="start|center_vertical">

        <Button
            android:id="@+id/start_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_marginStart="20dp"
            android:text="@string/start_scan" />

        <Button
            android:id="@+id/stop_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_toEndOf="@+id/start_button"
            android:text="@string/stop_scan" />

        <Button
            android:id="@+id/save_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_toEndOf="@+id/stop_button"
            android:text="@string/save_button" />

        <LinearLayout
            android:id="@+id/curr_connected"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/start_button"
            android:layout_marginTop="10dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/text_view_curr_connected"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/curConnectWiFi" />

            <EditText
                android:id="@+id/edit_text_curr_connected"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:cursorVisible="false"
                android:focusable="false"
                android:focusableInTouchMode="false" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/scan_result"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_below="@+id/curr_connected">

            <TextView
                android:id="@+id/text_view_scan_result"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="20dp"
                android:text="@string/scanResult" />
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fadingEdge="vertical"
                android:scrollbars="vertical">

                <LinearLayout
                    android:id="@+id/list_wifi"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <EditText
                        android:id="@+id/edit_view_scan_result"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:cursorVisible="false"
                        android:focusable="false"
                        android:focusableInTouchMode="false" />
                </LinearLayout>
            </ScrollView>
        </LinearLayout>

    </RelativeLayout>

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="20dp" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="20dp" />

    <android.support.constraint.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
  • MainActivity.java主程序
package com.lee.rss_collector;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.io.FileOutputStream;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    // private Context mContext = getApplicationContext();  // 加这一句会闪退
    public boolean mFlag = true;    // 控制线程终止
    private String mCurrentConnect; // 保存当前所连WiFi信息
    private StringBuilder mListInfo;// 保存扫描的WiFi列表信息
    private ScanThread mScanThread; // WiFi扫描的线程

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 显示主页面
        setContentView(R.layout.activity_main);

        // 监听三个按钮
        findViewById(R.id.start_button).setOnClickListener(mOnClickListener);
        findViewById(R.id.stop_button).setOnClickListener(mOnClickListener);
        findViewById(R.id.save_button).setOnClickListener(mOnClickListener);
    }

    public View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.start_button:
                    mFlag = true;   // 标志位置为true,允许线程运行
                    mScanThread = new ScanThread(); // 新建WiFi扫描线程
                    mScanThread.start();    // 启动线程
                    break;
                case R.id.stop_button:
                    mFlag = false;  // 标志位置为false,终止线程
                    break;
                case R.id.save_button:
                    String filename = "wifi_data.txt";
                    String fileContent = mListInfo.toString();
                    try{
                        savaFileToSD(filename,fileContent);
                        Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
                    }catch (Exception e){
                        e.printStackTrace();
                        Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
        }
    };

    private class ScanThread extends Thread {
        @Override
        public void run() {
            while (mFlag) {
                // 在UI线程中获取WiFi信息,并更新UI
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        obtainListInfo();
                    }
                });
                // 采样频率500ms
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void obtainListInfo(){

        WifiManager wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
        WifiInfo wi = wm.getConnectionInfo();
        String ssid = wi.getSSID();
        String bssid = wi.getBSSID();
        int rssi = wi.getRssi();
        int speed = wi.getLinkSpeed();

        // 记录当前所连WiFi信息
        mCurrentConnect = "SSID: " + ssid +
                                "
MAC Address: " + bssid +
                                "
Signal Strength(dBm): " + rssi +
                                "
speed: " + speed + " " + WifiInfo.LINK_SPEED_UNITS;
        // 记录扫描的WiFi列表信息
        if (wm.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
            mListInfo = new StringBuilder();
            List<ScanResult> scanResults = wm.getScanResults();
            for (ScanResult sr:scanResults){
                mListInfo.append("SSID: ");
                mListInfo.append(sr.SSID);
                mListInfo.append("
MAC Address: ");
                mListInfo.append(sr.BSSID);
                mListInfo.append("
Signal Strength(dBm): ");
                mListInfo.append(sr.level);
                mListInfo.append("

");
            }

            // 更新UI上显示的WiFi信息
            EditText editTextCurr = findViewById(R.id.edit_text_curr_connected);
            EditText editTextList = findViewById(R.id.edit_view_scan_result);
            editTextCurr.setText(mCurrentConnect);
            editTextList.setText(mListInfo.toString());
        }
    }
    //往SD卡写入文件的方法
    public void savaFileToSD(String filename,String fileContent) throws Exception {
        // 先判断是否有SD卡以及是否有读取SD卡的权限
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            // 设置文件路径
            String filePath = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
            // new一个文件输出流对象
            FileOutputStream output = new FileOutputStream(filePath);
            //将String字符串以字节流的形式写入到输出流中
            output.write(fileContent.getBytes());
            output.close();     //关闭输出流
        } else {
            Toast.makeText(MainActivity.this, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();
        }
    }
}

技术分享图片

以上是关于Android开发——WiFi信号检测的主要内容,如果未能解决你的问题,请参考以下文章

android里有获取周围所有wifi ap 的信号强度的方法么?

如何在 iOS 中检测 wifi 或 3G 信号强度?

Android - 检测用户已离开网络无线范围并关闭 WiFi

如何在android中找到另一台设备的wifi信号方向?

Android网络开发之WIFI

如何检测 WiFi 网络中是不是存在设备?