需要全部代码请点赞关注收藏后评论区留言私信~~~

一、检查是否连接WiFi以及输出WiFi信息

传统的定位方式不适用于室内的垂直定位,原因如下: (1)卫星定位要求没有障碍物遮挡,它在户外比较精准,在室内信号就变差。 (2)基站定位依赖于运营商的通讯服务,如果身处基站信号尚未覆盖的偏僻空间,就无法使用基站定位。 室内WiFi定位纳入了IEEE的802.11标准,名叫WLAN RTT (IEEE 802.11mc)。

RTT是Round-Trip-Time的缩写,即往返时间,可以用于计算网络两端的距离

室内WiFi定义的实现步骤有以下三步

(1)检查是否连接无线网络 通过无线网络管理器WifiManager获取WiFi信息。

(2)扫描周围的无线网络 用到无线网络管理器的startScan和getScanResults两个方法。

(3)计算WiFi路由器的往返时延 通过WifiRttManager对目标路由器测距。

上网方式主要有两种 即数据连接和WiFi,不过连接管理器ConnectivityManager只能笼统地判断能否上网,并不能获知WiFi连接的详细信息,在当前网络类型是WiFi时,要想得知WiFi上网的具体信息,还需另外通过无线网络管理器WifiManager获取 它的部分方法如下

isWifiEnabled 判断WLAN功能是否开启

setWifiEnabled 开启或关闭WLAN功能

getWifiState 获取当前的WiFi连接状态

实战效果如下 会输出所连接Wifi的相关信息

代码如下

package com.example.location;import com.example.location.util.IPv4Util;
import com.example.location.util.NetUtil;import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;import android.os.Looper;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.widget.TextView;@SuppressLint("DefaultLocale")
public class WifiInfoActivity extends AppCompatActivity {private static final String TAG = "WifiInfoActivity";private TextView tv_info; // 声明一个文本视图对象private Handler mHandler = new Handler(Looper.myLooper()); // 声明一个处理器对象private String[] mWifiStateArray = {"正在断开", "已断开", "正在连接", "已连接", "未知"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_wifi_info);tv_info = findViewById(R.id.tv_info);mHandler.postDelayed(mRefresh, 50); // 延迟50毫秒后启动网络刷新任务}// 定义一个网络刷新任务private Runnable mRefresh = new Runnable() {@Overridepublic void run() {getAvailableNet(); // 获取可用的网络信息// 延迟1秒后再次启动网络刷新任务mHandler.postDelayed(this, 1000);}};// 获取可用的网络信息private void getAvailableNet() {String desc = "";// 从系统服务中获取电话管理器TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);// 从系统服务中获取连接管理器ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);// 通过连接管理器获得可用的网络信息NetworkInfo info = cm.getActiveNetworkInfo();if (info != null && info.getState() == NetworkInfo.State.CONNECTED) { // 有网络连接if (info.getType() == ConnectivityManager.TYPE_WIFI) { // WiFi网络(无线热点)// 从系统服务中获取无线网络管理器WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);int state = wm.getWifiState(); // 获得无线网络的状态WifiInfo wifiInfo = wm.getConnectionInfo(); // 获得无线网络信息String SSID = wifiInfo.getSSID(); // 获得无线网络的名称if (TextUtils.isEmpty(SSID) || SSID.contains("unknown")) {desc = "\n当前联网的网络类型是WiFi,但未成功连接已知的WiFi信号";} else {desc = String.format("当前联网的网络类型是WiFi,状态是%s。\nWiFi名称是:%s\n路由器MAC是:%s\nWiFi信号强度是:%d\n连接速率是:%s\n手机的IP地址是:%s\n手机的MAC地址是:%s\n网络编号是:%s\n",mWifiStateArray[state], SSID, wifiInfo.getBSSID(),wifiInfo.getRssi(), wifiInfo.getLinkSpeed(),IPv4Util.intToIp(wifiInfo.getIpAddress()),wifiInfo.getMacAddress(), wifiInfo.getNetworkId());}} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) { // 移动网络(数据连接)int net_type = info.getSubtype();desc = String.format("\n当前联网的网络类型是%s %s",NetUtil.getNetworkTypeName(tm, net_type),NetUtil.getClassName(tm, net_type));} else {desc = String.format("\n当前联网的网络类型是%d", info.getType());}} else { // 无网络连接desc = "\n当前无上网连接";}tv_info.setText(desc);}}

二、扫描周围的无线网络

扫描周边Wifi主要用到WiFi滚力气的startScan方法和getScanResults方法,前者表示开始扫描周围的网络,后者表示获取扫描的结果列表,它们两个方法不能紧跟着,因为扫描动作是异步进行的,必须等到收到扫描结束的广播,然后在广播接收器中才能获取扫描结果

点击开始扫描后结果如下 会输出附近的WiFi信息

代码如下

package com.example.location;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;import com.example.location.adapter.ScanListAdapter;import java.util.HashMap;
import java.util.List;
import java.util.Map;@RequiresApi(api = Build.VERSION_CODES.M)
public class WifiScanActivity extends AppCompatActivity {private final static String TAG = "WifiScanActivity";private TextView tv_result; // 声明一个文本视图对象private ListView lv_scan; // 声明一个列表视图对象private WifiManager mWifiManager; // 声明一个WiFi管理器对象private WifiScanReceiver mWifiScanReceiver = new WifiScanReceiver(); // 声明一个WiFi扫描接收器对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_wifi_scan);tv_result = findViewById(R.id.tv_result);lv_scan = findViewById(R.id.lv_scan);findViewById(R.id.btn_scan).setOnClickListener(v -> mWifiManager.startScan());// 从系统服务中获取WiFi管理器mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);}@Overrideprotected void onResume() {super.onResume();IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);registerReceiver(mWifiScanReceiver, filter); // 注册WiFi扫描的广播接收器}@Overrideprotected void onPause() {super.onPause();unregisterReceiver(mWifiScanReceiver); // 注销WiFi扫描的广播接收器}// 定义一个扫描周边WiFi的广播接收器private class WifiScanReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 获取WiFi扫描的结果列表List<ScanResult> scanList = mWifiManager.getScanResults();if (scanList != null) {// 查找符合80211标准的WiFi路由器集合Map<String, ScanResult> m80211mcMap = find80211mcResults(scanList);runOnUiThread(() -> showScanResult(scanList, m80211mcMap));}}}// 查找符合80211标准的WiFi路由器集合private Map<String, ScanResult> find80211mcResults(List<ScanResult> originList) {Map<String, ScanResult> resultMap = new HashMap<>();for (ScanResult scanResult : originList) { // 遍历扫描发现的WiFi列表if (scanResult.is80211mcResponder()) { // 符合80211标准resultMap.put(scanResult.BSSID, scanResult); // BSSID表示MAC地址}}return resultMap;}// 显示过滤后的WiFi扫描结果private void showScanResult(List<ScanResult> list, Map<String, ScanResult> map) {tv_result.setText(String.format("找到%d个WiFi热点,其中有%d个支持RTT。",list.size(), map.size()));lv_scan.setAdapter(new ScanListAdapter(this, list, map));}}

三、计算往返时延RTT

这个要求路由器具备RTT功能,还要求手机支持室内wifi定位 效果如下

代码如下

package com.example.location;import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.RangingResultCallback;
import android.net.wifi.rtt.WifiRttManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import java.util.ArrayList;
import java.util.List;@RequiresApi(api = Build.VERSION_CODES.P)
public class WifiRttActivity extends AppCompatActivity {private final static String TAG = "WifiRttActivity";private TextView tv_result; // 声明一个文本视图对象private WifiManager mWifiManager; // 声明一个WiFi管理器对象private WifiScanReceiver mWifiScanReceiver = new WifiScanReceiver(); // 声明一个WiFi扫描接收器对象private WifiRttManager mRttManager; // 声明一个RTT管理器对象private WifiRttReceiver mWifiRttReceiver = new WifiRttReceiver(); // 声明一个RTT接收器对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_wifi_rtt);tv_result = findViewById(R.id.tv_result);findViewById(R.id.btn_indoor_rtt).setOnClickListener(v -> mWifiManager.startScan());// 从系统服务中获取WiFi管理器mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);// 从系统服务中获取RTT管理器mRttManager = (WifiRttManager) getSystemService(Context.WIFI_RTT_RANGING_SERVICE);if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)) {tv_result.setText("当前设备支持室内WiFi定位");} else {tv_result.setText("当前设备不支持室内WiFi定位");}}@Overrideprotected void onResume() {super.onResume();IntentFilter filterScan = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);registerReceiver(mWifiScanReceiver, filterScan); // 注册Wifi扫描的广播接收器IntentFilter filterRtt = new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);registerReceiver(mWifiRttReceiver, filterRtt); // 注册RTT状态变更的广播接收器}@Overrideprotected void onPause() {super.onPause();unregisterReceiver(mWifiScanReceiver); // 注销Wifi扫描的广播接收器unregisterReceiver(mWifiRttReceiver); // 注销RTT状态变更的广播接收器}// 定义一个扫描周边WiFi的广播接收器private class WifiScanReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 获取WiFi扫描的结果列表List<ScanResult> scanList = mWifiManager.getScanResults();if (scanList != null) {// 查找符合80211标准的WiFi路由器集合List<ScanResult> m80211mcList = find80211mcResults(scanList);runOnUiThread(() -> {String desc = String.format("找到%d个Wifi热点,其中有%d个支持RTT。",scanList.size(), m80211mcList.size());tv_result.setText(desc);});if (m80211mcList.size() > 0) {rangingRtt(m80211mcList.get(0)); // 测量与RTT节点之间的距离}}}}// 查找符合80211标准的WiFi路由器集合private List<ScanResult> find80211mcResults(List<ScanResult> originList) {List<ScanResult> resultList = new ArrayList<>();for (ScanResult scanResult : originList) { // 遍历扫描发现的WiFi列表if (scanResult.is80211mcResponder()) { // 符合80211标准resultList.add(scanResult);}}return resultList;}// 测量与RTT节点之间的距离private void rangingRtt(ScanResult scanResult) {if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {tv_result.setText("请先授予定位权限");return;}RangingRequest.Builder builder = new RangingRequest.Builder();builder.addAccessPoint(scanResult); // 添加测距入口,参数为ScanResult类型
//            builder.addWifiAwarePeer(); // MacAddress类型RangingRequest request = builder.build();// 开始测量当前设备与指定RTT节点(路由器)之间的距离mRttManager.startRanging(request, getMainExecutor(), new RangingResultCallback() {// 测距失败时触发@Overridepublic void onRangingFailure(int code) {Log.d(TAG, "RTT扫描失败,错误代码为"+code);}// 测距成功时触发@Overridepublic void onRangingResults(List<RangingResult> results) {for (RangingResult result : results) {if (result.getStatus() == RangingResult.STATUS_SUCCESS&& scanResult.BSSID.equals(result.getMacAddress().toString())) {result.getDistanceMm(); // 获取当前设备与路由器之间的距离(单位毫米)result.getDistanceStdDevMm(); // 获取测量偏差(单位毫米)result.getRangingTimestampMillis(); // 获取测量耗时(单位毫秒)result.getRssi(); // 获取路由器的信号}}}});}private class WifiRttReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (mRttManager.isAvailable()) {runOnUiThread(() -> tv_result.setText("室内WiFi定位功能可以使用"));} else {runOnUiThread(() -> tv_result.setText("室内WiFi定位功能不可使用"));}}}}

创作不易 觉得有帮助请点赞关注收藏~~~

【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)相关推荐

  1. 【Android App】二维码的讲解及生成属于自己的二维码实战(附源码和演示 超详细必看)

    需要全部代码请点赞关注收藏后评论区留言~~~ 一.二维码基本内容介绍 条形码只能表达十几位数字编码,无法表示更复杂的数据. 二维码在二维方格上描出一个个黑点,从而表达更丰富的信息. 二维码早已在手机A ...

  2. 【Android App】实战项目之仿微信的视频通话(附源码和演示 超详细必看)

    需要源码请点赞关注收藏后评论区留言私信~~~ 虽然手机出现许多年了,它具备的功能也越来越丰富,但是最基本的通话功能几乎没有变化.从前使用固定电话的时候,通话就是听声音:如今使用最新的智能手机,通话仍旧 ...

  3. 【Android App】实战项目之仿拼多多的直播带货(附源码和演示 超详细必看)

    需要源码请点赞关注收藏后评论区留言私信~~~ 近年来电商业态发生了不小的改变,传统的电商平台把商品分门别类,配上精美的图文说明供消费者挑选,新潮的电商平台则请来明星网红,开启直播秀向广大粉丝推销商品, ...

  4. 【Android App】给三维的地球仪贴上动物贴纸实战(附源码和演示 超详细必看)

    需要源码和图片集请点赞关注收藏后评论区留言~~~ 一.纹理贴图 给三维物体穿衣服的动作,通常叫做给三维图形贴图,更专业地说叫纹理渲染. 渲染纹理的过程主要由三大项操作组成,分别说明如下: (1)启用纹 ...

  5. 【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.开启定位功能 手机定位分为卫星定位和网络定位两大类. (1)卫星定位 卫星定位服务由几个全球卫星导航系统提供. 卫星定位的原理是根据多颗卫星与导航芯片 ...

  6. 【Android App】获取照片里的位置信息及使用全球卫星导航系统(GNSS)获取位置实战(附源码和演示 超详细)

    需要全部代码请点赞关注收藏后评论区留言私信~~~ 一.获取照片里的位置信息 手机拍摄的相片还保存着时间.地点.镜头参数等信息,这些信息由相片接口工具ExifInterface管理,它的常用方法说明如下 ...

  7. 【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言~~~ 一.传感器的种类 传感器Sensor是一系列感应器的总称,是Android设备用来感知周围环境和运动信息的工具. 因为具体的感应信息依赖于相关硬件,所以虽然A ...

  8. 【Android App】实战项目之仿微信的附近的人(附源码和演示 超详细)

    需要全部源码请点赞关注收藏后评论区留言私信~~~ 艺术家常说"距离产生美",其实距离近才是优势,谁不希望自己的工作事少钱多离家近呢?不光是工作,像租房买房.恋爱交友,大家都希望找个 ...

  9. 【Android App】物联网实战项目之自动驾驶的智能小车(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言私信~~~~ 当今社会正在步入一个万物互联的时代,它的技术基石主要来自5G.物联网和人工智能. 三者融合产生了许多新产品,其中最璀璨的当数自动驾驶的电动车:它汇聚了最 ...

最新文章

  1. Python之闭包、装饰器及相关习题练习
  2. 简化 MongoDB 关联运算
  3. 控制车辆运行的19个神经元
  4. 阿里云服务器怎么安装docker
  5. oracle set feedback off,Oracle数据库之Oracle导出数据中的prompt,set feedback 等是什么意思...
  6. [OS复习]设备管理2
  7. MyBatis实现SaveOrUpdate
  8. block size in download header
  9. Markdown简介和基本语法
  10. 定义加密函数程序python_一个python自定义的加密解密函数
  11. 安卓开发学习笔记(六):如何实现指定图片定时开屏功能?
  12. 连锁零售行业ERP解决方案
  13. 2021华为秋招算法工程师面试经历(实习过)
  14. vue批量打包下载图片
  15. Espresso Idling Resource
  16. uniapp轻松集成极光推送自定义消息+通知 Android极光 IOS极光 两行代码集成极光SDK
  17. python文本框事件_文本框事件
  18. 几行代码,复杂Excel 导入导出,真心强大!
  19. Coding and Paper Letter(八十七)
  20. php菜单无限极分类

热门文章

  1. Linux测试环境搭建步骤
  2. 大华播放器退出时发生assert原因
  3. 微服务 RocketMQ-延时消息 消息过滤 管控台搜索问题
  4. 新装Ubuntu配置及部分软件安装
  5. 证书系统64驱动签名工具64Signer
  6. 汉仪尚巍手书_汉仪尚巍手书字体下载|
  7. 建模系统编程语言c 有限元,基于CATIA二次开发的渐开线直齿轮参数化设计.pdf
  8. 向日葵远程软件连不上服务器
  9. 【Golang】生成随机数,指定区间随机数
  10. 简单脉搏波波形分析系统设计与实现