Android开发——WiFi信号检测
程序员文章站
2022-06-16 20:55:48
1.首先在AndroidManifest.xml文件中添加如下代码以开启权限: 2.三个与WiFi相关的类:WifiManager,WifiInfo,ScanResult WifiManager 注:API文档中提到使用List getScanResults()时,最好额外添 ......
1.首先在androidmanifest.xml文件中添加如下代码以开启权限:
1 <!-- 获取wifi状态的权限 --> 2 <uses-permission android:name="android.permission.access_wifi_state"/> 3 <!-- 改变wifi状态的权限 --> 4 <uses-permission android:name="android.permission.change_wifi_state"/> 5 <!-- 获取网络的权限 --> 6 <uses-permission android:name="android.permission.internet"/> 7 <!-- 获取网络状态的权限 --> 8 <uses-permission android:name="android.permission.access_network_state"/> 9 <!-- 改变网络状态的权限 --> 10 <uses-permission android:name="android.permission.change_network_state"/> 11 12 <!-- 往sdcard写入数据权限 --> 13 <uses-permission android:name="android.permission.write_external_storage"/> 14 <!-- 从sdcard读取数据权限 --> 15 <uses-permission android:name="android.permission.read_external_storage"/> 16 <!-- 在sdcard中创建与删除文件权限 --> 17 <uses-permission android:name="android.permission.mount_unmount_filesystems"/>
1 // 获取系统wifi服务 2 wifimanage wm = (wifimanager) getapplicationcontext().getsystemservice(wifi_service); 3 4 // 获取当前所连接wifi的信息 5 wifiinfo wi = wm.getconnectioninfo(); 6 7 // 获取扫描到的所有wifi信息 8 list<scanresult> scanresults = wm.getscanresults(); 9 10 // 将rssi分为numlevels个等级,返回rssi处在哪一个等级 11 int level = wm.calculatesignallevel (int rssi,int numlevels); 12 13 // 获取当前手机wifi网卡状态 14 int state = wm.getwifistate(); 15 返回值为以下宏定义 16 wifimanager.wifi_state_enabled wifi网卡可用 17 wifimanager.wifi_state_disabled wifi网卡不可用 18 wifimanager.wifi_state_disabling wifi网卡正关闭 19 wifimanager.wifi_state_enabling wifi网卡正打开 20 wifimanager.wifi_state_unknown 状态未知 21 22 // 判断wifi是否打开 23 boolean flag = iswifienabled(); 24 // 打开wifi 25 boolean flag = setwifienabled(true); 26 // 关闭wifi 27 boolean flag = setwifienabled(false);
注:api文档中提到使用list<scanresult> getscanresults()时,最好额外添加两个权限(保护等级:危险),详见链接
an app must hold access_coarse_location or access_fine_location permission in order to get valid results
access_coarse_location:allows an app to access approximate location.
access_fine_location:allows an app to access precise location.
- activity_main.xml资源文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <relativelayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 tools:context=".mainactivity" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 android:orientation="vertical"> 9 10 <button 11 android:id="@+id/start_btn" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:layout_marginstart="45dp" 15 android:text="@string/start_scan" 16 android:onclick="doclick"/> 17 18 <button 19 android:id="@+id/stop_btn" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:layout_marginstart="10dp" 23 android:layout_toendof="@+id/start_btn" 24 android:text="@string/stop_scan" 25 android:onclick="doclick"/> 26 27 <button 28 android:id="@+id/save_btn" 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:layout_marginstart="10dp" 32 android:layout_toendof="@+id/stop_btn" 33 android:text="@string/save_data" 34 android:onclick="doclick"/> 35 36 <linearlayout 37 android:layout_width="match_parent" 38 android:layout_height="wrap_content" 39 android:layout_below="@+id/start_btn" 40 android:layout_margintop="10dp" 41 android:orientation="vertical"> 42 43 <textview 44 android:id="@+id/connected_wifi_tv" 45 android:layout_width="match_parent" 46 android:layout_height="wrap_content" 47 android:text="@string/connected_wifi" /> 48 49 <textview 50 android:id="@+id/connected_wifi_info_tv" 51 android:layout_width="match_parent" 52 android:layout_height="wrap_content" 53 android:layout_margintop="10dp" 54 android:text=""/> 55 56 <textview 57 android:layout_width="match_parent" 58 android:layout_height="2dp" 59 android:layout_margintop="5dp"/> 60 61 <textview 62 android:id="@+id/scan_results_tv" 63 android:layout_width="match_parent" 64 android:layout_height="wrap_content" 65 android:layout_margintop="5dp" 66 android:text="@string/scan_results" /> 67 68 <scrollview 69 android:layout_width="match_parent" 70 android:layout_height="wrap_content" 71 android:layout_margintop="10dp" 72 android:fadingedge="vertical" 73 android:scrollbars="vertical"> 74 75 <textview 76 android:id="@+id/scan_results_info_tv" 77 android:layout_width="match_parent" 78 android:layout_height="wrap_content" 79 android:text=""/> 80 </scrollview> 81 </linearlayout> 82 </relativelayout>
1 package com.lee.rss_sampler; 2 3 import android.app.activity; 4 import android.net.wifi.scanresult; 5 import android.net.wifi.wifiinfo; 6 import android.net.wifi.wifimanager; 7 import android.os.environment; 8 import android.os.bundle; 9 import android.view.view; 10 import android.widget.textview; 11 import android.widget.toast; 12 13 import java.io.fileoutputstream; 14 import java.util.list; 15 16 public class mainactivity extends activity { 17 18 public boolean mflag = true; // 控制线程终止 19 private stringbuilder mlistinfo;// 保存扫描的wifi列表信息 20 private textview mtextviewcurrwifiinfo; // 显示当前所连wifi信息的组件 21 private textview mtextviewscanwifiinfo; // 显示扫描到的wifi信息的组件 22 23 @override 24 protected void oncreate(bundle savedinstancestate) { 25 super.oncreate(savedinstancestate); 26 setcontentview(r.layout.activity_main); 27 mtextviewcurrwifiinfo = findviewbyid(r.id.connected_wifi_info_tv); 28 mtextviewscanwifiinfo = findviewbyid(r.id.scan_results_info_tv); 29 } 30 31 public void doclick(view view){ 32 switch (view.getid()){ 33 case r.id.start_btn: 34 mflag = true; // 标志位置为true,允许线程运行 35 // 启动wifi扫描的线程 36 scanthread scanthread = new scanthread(); 37 scanthread.start(); 38 break; 39 case r.id.stop_btn: 40 mflag = false; // 标志位置为false,终止线程 41 break; 42 case r.id.save_btn: 43 string filename = "wifi_data.txt"; 44 string filecontent = mlistinfo.tostring(); 45 try{ 46 savefiletosd(filename,filecontent); 47 toast.maketext(getapplicationcontext(), "数据写入成功", toast.length_short).show(); 48 }catch (exception e){ 49 e.printstacktrace(); 50 toast.maketext(getapplicationcontext(), "数据写入失败", toast.length_short).show(); 51 } 52 break; 53 } 54 } 55 56 private class scanthread extends thread { 57 @override 58 public void run() { 59 while (mflag) { 60 // 在ui线程中获取wifi信息,并更新ui 61 runonuithread(new runnable() { 62 @override 63 public void run() { 64 obtainlistinfo(); 65 } 66 }); 67 // 采样频率500ms 68 try { 69 thread.sleep(500); 70 } catch (interruptedexception e) { 71 e.printstacktrace(); 72 } 73 } 74 } 75 } 76 77 private void obtainlistinfo(){ 78 // 获取wifi管理器 79 wifimanager wifimanager = (wifimanager) getapplicationcontext().getsystemservice(wifi_service); 80 81 // 如果wifi未打开,先打开wifi 82 /*if (wifimanager.getwifistate() != wifimanager.wifi_state_enabled) { 83 wifimanager.setwifienabled(true); 84 }*/ 85 if(!wifimanager.iswifienabled()){ 86 wifimanager.setwifienabled(true); 87 } 88 89 // 获取并保存当前所连wifi信息 90 wifiinfo wifiinfo = wifimanager.getconnectioninfo(); 91 string mcurrentconnect = "ssid: " + wifiinfo.getssid() + 92 "\nmac address: " + wifiinfo.getbssid() + 93 "\nsignal strength(dbm): " + wifiinfo.getrssi() + 94 "\nspeed: " + wifiinfo.getlinkspeed() + " " + wifiinfo.link_speed_units; 95 96 // 获取并保存扫描的wifi列表信息 97 mlistinfo = new stringbuilder(); 98 list<scanresult> scanresults = wifimanager.getscanresults(); 99 for (scanresult sr:scanresults){ 100 mlistinfo.append("ssid: "); 101 mlistinfo.append(sr.ssid); 102 mlistinfo.append("\nmac address: "); 103 mlistinfo.append(sr.bssid); 104 mlistinfo.append("\nsignal strength(dbm): "); 105 mlistinfo.append(sr.level); 106 mlistinfo.append("\n\n"); 107 } 108 109 // 更新ui上显示的wifi信息 110 mtextviewcurrwifiinfo.settext(mcurrentconnect); 111 mtextviewscanwifiinfo.settext(mlistinfo.tostring()); 112 } 113 114 //往sd卡写入文件的方法 115 public void savefiletosd(string filename, string filecontent) throws exception { 116 // 先判断是否有sd卡以及是否有读取sd卡的权限 117 if (environment.getexternalstoragestate().equals(environment.media_mounted)) { 118 // 设置文件路径 119 string filepath = environment.getexternalstoragedirectory().getcanonicalpath() + "/" + filename; 120 // new一个文件输出流对象 121 fileoutputstream output = new fileoutputstream(filepath); 122 //将string字符串以字节流的形式写入到输出流中 123 output.write(filecontent.getbytes()); 124 output.close(); //关闭输出流 125 } else { 126 toast.maketext(mainactivity.this, "sd卡不存在或者不可读写", toast.length_short).show(); 127 } 128 } 129 130 // 从sd卡中读取文件的方法 131 public string readfilefromsd(string filename){ 132 // todo 133 return null; 134 } 135 }