Android扫描周边Wifi
创建一个新项目
1、在AndroidManifest中添加以下权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cn.yang.scanwifilist">
<!--使用网络-->
<uses-permission android:name="android.permission.INTERNET" />
<!--网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--wifi状态权限-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--位置信息-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--wifi扫描权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--改变wifi权限-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ScanWifiList"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2、activity_main.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="vertical"
android:scrollbars="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="无数据"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/sh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="刷新" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="无数据"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</LinearLayout>
</ScrollView>
3、MainActivity.java中代码
package cn.yang.scanwifilist;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private final int UPDATE_UI_REQUEST_CODE = 1024;
private static WifiManager wifiManager = null;
private TextView txt; // 显示WiFi扫描结果的控件
private TextView txt2; // 显示WiFi扫描结果的控件
private Button btn1; // 显示WiFi扫描结果的控件
private StringBuffer mScanResultStr; // 暂存WiFi扫描结果的字符串
private Timer mTimer; // 启动定时任务的对象
private final int SAMPLE_RATE = 2000; // 采样周期,以毫秒为单位
private static List<ScanResult> resultList = null;
//权限列表
private static String[] permission = new String[]{
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CHANGE_WIFI_STATE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//一定要手动打开wifi和定位功能
txt = (TextView) findViewById(R.id.txt1);
txt2 = (TextView) findViewById(R.id.txt2);
btn1 = (Button) findViewById(R.id.sh);
RefWifi();
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
RefWifi();
Thread.sleep(5000);
} catch (Exception e) {
txt2.setText("5s后再试");
}
}
});
}
public void RefWifi() {
Check(permission);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
//判断WIFI是否打开
if (wifiManager.isWifiEnabled()) {
Toast.makeText(this, "wifi已打开", Toast.LENGTH_SHORT).show();
Log.i("wifi状态", "wifi已打开");
//设置广播监听
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(wifiScanReceiver, intentFilter);
//开启扫描功能
boolean success = wifiManager.startScan();
if (!success) {
scanFailure();
}
} else {
Toast.makeText(this, "请打开wifi开关", Toast.LENGTH_SHORT).show();
Log.i("wifi状态", "请打开wifi开关");
}
}
@SuppressLint("MissingPermission")
public void ShowInfo() {
//获取已连接wifi的信息
WifiInfo info = wifiManager.getConnectionInfo();
if (info.getIpAddress()>0) {
Log.i("SSID", String.valueOf(info.getSSID()));
Log.i("BSSID", info.getBSSID());
Log.i("MAC", info.getMacAddress());
Log.i("IP", intToInetAddress(info.getIpAddress()).getHostAddress());
Log.i("GateWay", intToInetAddress(wifiManager.getDhcpInfo().gateway).getHostAddress());
Log.i("WifiState", String.valueOf(wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING));
StringBuffer str = new StringBuffer();
str.append("SSID:").append(info.getSSID()).append("\n");
str.append("BSSID:").append(info.getBSSID()).append("\n");
str.append("MAC:").append(info.getMacAddress()).append("\n");
str.append("IP:").append(intToInetAddress(info.getIpAddress()).getHostAddress()).append("\n");
str.append("GateWay:").append(intToInetAddress(wifiManager.getDhcpInfo().gateway).getHostAddress()).append("\n");
txt.setText(str);
}
//获取扫描结果
List<ScanResult> results = wifiManager.getScanResults();
Log.i("scanSuccess", results.toString());
//[SSID: CMCC-Ps67, BSSID: d4:f7:56:b5:4c:46,
// capabilities: [WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][RSN-PSK-TKIP+CCMP][ESS],
// level: -61, frequency: 2447, timestamp: 2919902064, distance: ?(cm),
// distanceSd: ?(cm), passpoint: no, ChannelBandwidth: 0, centerFreq0: 2447,
// centerFreq1: 0, standard: 11n, 80211mcResponder: is not supported,
// Radio Chain Infos: [RadioChainInfo: id=0, level=-61]
if (results != null) {
mScanResultStr = new StringBuffer();
for (ScanResult sr : results) {
Log.i("SSID", String.valueOf(sr.SSID));
mScanResultStr.append("SSID:").append(sr.SSID).append("\n");
Log.i("MAC", sr.BSSID);
mScanResultStr.append("MAC:").append(sr.BSSID).append("\n");
Log.i("Level", String.valueOf(sr.level));
mScanResultStr.append("Level:").append(sr.level).append("\n\n");
}
txt2.setText(mScanResultStr);
}
}
//检查权限
public boolean Check(String[] permissions) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
list.add(permissions[i]);
}
Log.i("permissions" + i, String.valueOf(ContextCompat.checkSelfPermission(this, permissions[i])));
}
if (list.size() > 0) {
// 获取wifi连接需要定位权限,没有获取权限
ActivityCompat.requestPermissions(this, list.toArray(new String[list.size()]), 2);
return true;
}
Log.i("permission", "已授权");
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 2:
//判断权限是否获取成功
if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
// 不允许
Toast.makeText(this, "开启权限失败", Toast.LENGTH_SHORT).show();
Log.i("permissions", String.valueOf(grantResults[0]));
}
break;
default:
break;
}
}
//10进制树装ip地址
public static InetAddress intToInetAddress(int hostAddress) {
byte[] addressBytes = {(byte) (0xff & hostAddress), (byte) (0xff & (hostAddress >> 8)),
(byte) (0xff & (hostAddress >> 16)), (byte) (0xff & (hostAddress >> 24))};
try {
return InetAddress.getByAddress(addressBytes);
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
//广播监听
BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent intent) {
boolean success = intent.getBooleanExtra(
WifiManager.EXTRA_RESULTS_UPDATED, false);
Log.i("successReceiver:", String.valueOf(success));
if (success) {
scanSuccess();
} else {
scanFailure();
}
}
};
private void scanSuccess() {
ShowInfo();
}
private void scanFailure() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ShowInfo();
}
});
}
}
4、运行扫描
注意:一定要打开wifi开关和定位开关,如果只打开wifi开关只能获取到正在连接的WiFI,且获取不到wifi名称