1.开发意图

由于最近要进行室内定位的实习,需要采集室内的WiFi信息来进行定位。需要采集的WiFi信息有WiFi名称(SSID)、WiFi信号的Mac地址(BSSID)、WiFi的频率(frequency)和WiFi的信号强度(level)。由于网上的大多是给出用于连接的软件,也就是说并没有注意WiFi的Mac地址和定量的信号强度。而且还有很多不能导出为txt文件,这些缺点对于后期的室内定位数据处理来说是很麻烦的。因此打算自己去利用Android Studio写一个专门用于采集WiFi信号的APP。界面不是很美丽,也暂时只能采集WiFi信号强度和将采集到的文件导出为txt文本,后续会加上采集蓝牙信号强度的代码。

2.采用的主要的类

wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

Android SDK中自带有能够调用设备本身的WiFi信号处理器的类,也就是WifiManager类。

List<ScanResult> WifiList;
wifiManager.startScan();
WifiList = wifiManager.getScanResults();//返回的是用于存储WiFi信息的列表

上面的代码片就是如何获取设备感知到的WiFi信息。ScanResult也是一个类,用来储存得到的WiFi信号的基本信息。其中我们想要的就是SSID,BSSID,frequency,level。在得到列表之后,遍历列表就可以得到WiFi的信息。这个类是不要求与手机与WiFi相连接的,在室内定位建立指纹库的过程中,总不能挨个去连接WiFi。而是要每次自动扫描出附近的WiFi信号。把上述的结果放入一个字符串中,后续要将这个字符串写入文件中。代码如下:

ScanResult scanResult;
for (int i = 0; i < WifiList.size(); i++) {scanResult = WifiList.get(i);stringBuffer.append(scanResult.SSID).append("   ").append(scanResult.BSSID).append("    ").append(scanResult.frequency).append("  ").append(scanResult.level).append("\n");
}

如果想要采集某一时刻的WiFi信息,上面的代码足够了,但是由于室内定位的建库阶段需要在一个时间段内不断地进行WiFi信息的搜集,因此还需要设置实时更新一下。网上有好多关于每隔一定的时间间隔采集一次数据的教程,但是我用的应该是最笨的一种方法。也就是说设计了一个计时器,然后为计时器的时间更新监听器绑定一个扫描时间,这样就可以达到一秒一次的采集效果。
下面就应该是文件的读写了。
在Android平台上文件的读写本质上就是利用了Java的IO流进行,当然也有Android的创新的地方。创新的地方就是引入了openFileOutput和openFileInput两个函数用来读写内部存储的数据。说到这里,还得插一嘴什么是内部存储和外部存储。不管在日常的生活中如何称呼外存和内存,在Android开发过程中,将应用自带的文件成为内存,将自己手机有的文件成为外存。也就是说内存中的一切东西都会随着APP的卸载被删除,随着APP的安装被写入。在手机内是无法直接看到APP内部自带的数据的,也就是无法直接看到内存。而我们的手机能够看到的是外存,也就是在SD卡中的东西。不过现在的大多数手机都没有SD卡。但是这并不妨碍手机拥有外存。没有外存的手机的获取外部存储路径得到的路径大多是手机的/storage/emulated/0这个目录下。

state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {//path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);path=Environment.getExternalStorageDirectory().getAbsolutePath();
}

上面的代码是用来获取手机的外部存储的绝对路径,返回的path是一个String,再利用下面的代码在该路径中创建相应的文本文件来存储获得的WiFi信息。

File file = new File(path,"wifi0.txt");
try{file.createNewFile();
}catch (IOException e){e.printStackTrace();
}

最后再将上面的WiFi信息利用FileOutputStream来写入文件中就可以了。

3.遇到的问题

虽然流程只有那么简单,但是由于我是刚刚入门的,所以在实际的开发过程中还是有不少问题的。下面就一一列举我的问题,记录下来防止下次写的时候忘记了。

(1)动态申请权限的问题

由于在WiFi信号采集的时候需要用到位置服务和读写外部存储的危险权限,因此需要动态申请权限。首先要在AndroidManefest.xml中添加如下代码

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

然后需要在MainActivity.java文件中添加如下代码

String[] permissions=new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE};//用于存储需要申请的危险权限
List<String> mPermissions=new ArrayList<>();//用于存储未申请的危险权限
//下面的函数用于动态申请危险权限,需要在主函数中调用initPermission函数才能申请动态权限
private  void initPermission(){mPermissions.clear();for(int i=0;i<permissions.length;i++){if(ContextCompat.checkSelfPermission(this,permissions[i])!=PackageManager.PERMISSION_GRANTED)mPermissions.add(permissions[i]);}if(mPermissions.size()>0){ActivityCompat.requestPermissions(this,permissions,1);}
}

注意一定要按照上面的方法动态申请权限,否则在首次安装应用的时候并不会弹出请求位置服务和读写存储的对话框。切记切记!!!!因为我就在这个地方卡住了好几天。我最开始的时候是按照下面的方式动态申请权限的

/*if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)){}else{ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}
}if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_COARSE_LOCATION)){}else {ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);}
}*/

因为我看到申请一个权限可以这样申请,所以就类推了一下,以为申请多个权限也可以这样申请。结果废了好长时间…上面那样申请的结果就是不会弹出对话框,至于为什么这样,我也不知道。学艺不精…

(2)组件初始化的问题


上面的图片是我的页面布局。开始的时候我在下面用到了判断这几个按钮的文本是否等于一个字符串的判断语句,而且我只在布局文件中定义了按钮的text,并没有在函数中进行初始化,也就是说没有在主函数中使用setText操作。这样做会使我的按钮点击两次才反应过来,也就说第一次点击才进行初始化,第二次点击才执行事件。这个也花了好长时间才改过来。

(3)文件存储位置的问题

我的手机是OPPO R11splus,在调试的时候显示文件的存储路径还是/storage/emulated/0,这就要了我这个不懂手机的人的命了。。。后来用室友(狐朋狗友,哈哈哈)的华为手机发现文件并没有存在相应的文件夹中,而是直接存在了“手机存储/”这个文件夹下,然后又用了另外一个室友的小米手机,发现存在了/storage/emulated/0这个目录下。然后我再反过来看我的手机,发现我的手机也是存在了“手机存储/”目录下。我不明白这个里面的原理,但是在调试的时候确实是显示在/storage/emulated/0目录下的,而且我判断文件是存在的,就是结果莫名其妙地出现在了另外一个目录下。哎,还是学艺不精啊。。。要是有大佬知道这个里面的原理,还请多多指教呀!

总结

这次的开发让我知道了,果然代码都是相通的。上次我问老师这个代码对我们专业来说究竟掌握到什么程度才算合适呢,老师说看个人经历吧。我以前总感觉自己太过于深究代码为什么这样编写,自己的专业并不需要这样,这是计算机学院的学生应该做的。但是通过这次的APP开发我知道了,如果平时不深究代码,不掌握基本的语法,到关键的时候就看不懂别人的东西,只能拿来别人的东西一个一个试,耗时又耗力,还不如平时多深究一点(例如我上面的动态权限申请就偷懒了,一偷懒就出错啊)。而且看不下去代码,更别提自己写了。任何的代码写上两万行都会掌握的。还是多写多练吧。加油!!!!
后续我会把蓝牙的代码也写了,看看有没有什么大坑等着我跳。

Android环境下WiFi信号采集器的设计相关推荐

  1. opencv生成日志_OpenCV在Android环境下的使用方法

    按照使用语言角度,在Android下使用OpenCV有以下几种方式: 完全使用Java语言 完全使用C++语言 混合使用Java和C++语言 下面分别讲一下怎么做,并说明这样做可能需要注意的问题. 完 ...

  2. android媒体播放器设计报告,基于Android的多媒體播放器课程设计报告.doc

    基于Android的多媒體播放器课程设计报告 基于Android的多媒体播放器课程设计报告 (2014-01-02 22:46:52) HYPERLINK "javascript:;&quo ...

  3. 小学计算机教育实习教案,信息技术环境下小学综合实践活动课教学设计

    摘要: 综合实践活动课是为了让学生得到真正意义上的全面发展而设的.它在诸多方面为我国的小学教育开辟了崭新的天地.如今,人类已经进入信息时代.信息时代的综合实践活动要把信息技术有机地融入综合实践活动的内 ...

  4. Android环境下通过C框架层控制WIFI【转】

    本文转载自:https://blog.csdn.net/edw200/article/details/52192631 本人是从事Linux嵌入式开发的,安卓wifi控制在安卓JAVA层已经做得非常成 ...

  5. 桂电在linux、Mac OS环境下使用出校器(支持2.14)

    这是guetsec学长在三院科协学长所抓包逆向分析1.81版出校器的基础上,用python写的一款为Mac和linux环境开发的出校器. 最后我做了略微修改,支持暂时最新版本2.14.下面有直接从源码 ...

  6. android登录加密传输,android环境下两种md5加密方式(示例代码)

    在平时开发过程中,MD5加密是一个比較经常使用的算法,最常见的使用场景就是在帐号注冊时,用户输入的password经md5加密后,传输至server保存起来.尽管md5加密经经常使用.可是md5的加密 ...

  7. 流量计脉冲计数器开关量信号采集器

    应用: ● 流量计脉冲计数或流量测量 ● LED灯光控制或电机控制 ● 智能楼宇控制.安防工程等应用系统 ● 以太网工业自动化控制系统 ● 工业现场信号隔离及长线传输 ● 设备运行监测与控制 ● 传感 ...

  8. 【积沙成塔】Android 环境下编译后出现乱码错误的情况

    如果在Android Studio下,编译有中文备注或者含中文的程序时,会出现包含有UTF-8的看不懂的乱码错误,原因是Android Studio编码问题,在file -> setting - ...

  9. 复杂电磁环境下的信号分选与识别关键技术研究与实现--读后感(1)

    论文提出了取长补短整合高阶累积量.时域特征参数以及幅度矩的算法,共同对无线数字信号进行识别的算法.验证算法的理论可行性并使用 Simulink对算法进行实现仿真实验.最终得到仿真结果能够对 2ASK. ...

最新文章

  1. Yolov3Yolov4网络结构与源码分析
  2. 调整JVM堆内存解决OutOfMemoryError
  3. DayDayUp:发明专利授予条件、撰写发明专利的注意事项以及申辩模板
  4. diff git 代码实现_Git diff 算法
  5. C#设计模式(5)-Factory Method Pattern
  6. 实验8 SQL Server 的存储过程
  7. 人类心理学中几乎没有人知道的东西是什么?
  8. 超简单的内网邮件服务器搭建(CentOS7 postfix+dovecot)
  9. 电脑功耗监测_VOCS在线监测系统
  10. visio付款流程图_visio流程图软件
  11. dematel matlab,决策与实验室方法,DEMATEL分析方法介绍
  12. 文件包含漏洞+php伪协议
  13. RedHat认证笔记-RH124
  14. 【SDOI2010】【BZOJ1924】所驼门王的宝藏
  15. 蓝牙技术|防丢背包获奖,Find My产品受追捧
  16. 头脑王者服务器维护,微信头脑王者请求超时及查询服务器失败的解决方法
  17. 中标麒麟学习笔记0:安装极点五笔输入法
  18. Mysql数据库存储ip地址
  19. Mogafx通胀与英镑的关系
  20. 京东H5小游戏《疯狂足球》Android外挂实现

热门文章

  1. 火狐浏览器,谷歌浏览器使用深色主题,安装深色主题插件
  2. z-library应急办法
  3. 学习SVG(八)文本
  4. 完全卸载PHP,重新安装
  5. 基于QTGUI图像界面的空战游戏设计
  6. 《JSP》JSP学习(一)——以虚拟机为平台发布、访问JSP网页
  7. 量化交易入门阶段——布林带的真正用法
  8. 2021-2027全球与中国企业移动云计算市场现状及未来发展趋势
  9. html字体阴影怎么设置6,css怎么设置字体阴影,
  10. dnf压爆服务器挑战网站,DNF手游压爆服务器挑战