一、需求分析

最近电脑需要连接WiFi,却发现WiFi密码给忘记了。而手机里有保存过的WiFi密码,但是在手机的设置界面看不到。

虽然已经有一些可以查看WiFi密码的app,但是主要还是担心密码被那些app传到后台去。还是自己写一个比较放心。而且用app查看只需要点击一下,要比直接查找系统里保存了密码的文件更加方便。

二、主要功能实现

2.1 读取系统文件

Android系统保存了WiFi密码的文件保存在/data/misc/wifi/wpa_supplicant.conf中[1],通过在代码中运行命令行程序‘cat’来读取文件[3][4]。

  1. String commandResult=commandForResult("cat /data/misc/wifi/wpa_supplicant.conf");
    public String commandForResult(String command) {
  2.  
  3. try {
  4. Process process = Runtime.getRuntime().exec("su");
  5. DataOutputStream outputStream = null;
  6. outputStream = new DataOutputStream(process.getOutputStream());
  7. outputStream.writeBytes(command+"\n");
  8. outputStream.flush();
  9. outputStream.writeBytes("exit\n");
  10. outputStream.flush();
  11.  
  12. BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
  13. StringBuilder total = new StringBuilder();
  14. String line;
  15. while ((line = in.readLine()) != null) {
  16. total.append(line);
  17. total.append("\n");
  18. }
  19. return total.toString();
  20. } catch (IOException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. return "error";
  24. }
  25. }

2.2 对WiFi信息按照priority由大到小排序

wpa_supplicant.conf文件中保存的Wifi信息主要采用如下格式,每个网络信息以network开头。key_mgmt=NONE表示网络不需要密码。当key_mgmt=WPA-PSK时,会通过psk字段来标识密码信息。

目前看到的手机里wpa_supplicant.conf文件中并没有对不同的网络按照priority的值进行排序。而那些经常用的网络priority比较高,被放在了文件的后面,因此考虑对网络信息按照priority由大到小进行排序。

  1. String sortByPriority(String input){
  2. String [] stringPerLine=input.split("\n");
  3. ArrayList<NetworkPara> list=new ArrayList<MainActivity.NetworkPara>();
  4. int start=0,end=0;
  5. NetworkPara networkPara = null;
  6. for (int i = 0; i < stringPerLine.length; i++) {
  7. if (stringPerLine[i].contains("network={")) {
  8. start=1;
  9. end=0;
  10. networkPara=new NetworkPara();
  11. networkPara.paraString="";
  12. }
  13. if (start==1) {
  14. if (networkPara!=null) {
  15. networkPara.paraString=networkPara.paraString.concat(stringPerLine[i])+"\n";
  16. }
  17. if (stringPerLine[i].contains("priority")) {
  18. String []prioSplit=stringPerLine[i].split("=");
  19. networkPara.priority=Integer.parseInt(prioSplit[prioSplit.length-1]);
  20. }
  21. if (stringPerLine[i].contains("}")) {
  22. start=0;
  23. end=1;
  24. }
  25. }
  26. if (end==1) {
  27. list.add(networkPara);
  28. }
  29. }
  30. Collections.sort(list, new Comparator() {
  31. public int compare(Object o1, Object o2) {
  32. return ((Comparable) ((NetworkPara) (o2)).priority)
  33. .compareTo(((NetworkPara) (o1)).priority);
  34. }
  35. });
  36.  
  37. String result="";
  38. for (int i = 0; i < list.size(); i++) {
  39. result=result.concat(list.get(i).paraString);
  40. }
  41. return result;
  42. }

2.3 支持按照字符串进行搜索

字符串搜索的入口选择采用在actionar上增加搜索按钮,根据输入字符串进行逐行匹配。当有多个匹配结果时,在界面中显示前进后退按钮,以支持前后内容的选择。

2.3.1 Actionbar中显示搜索按钮

首先在menu item生成时增加搜索按钮,然后主activity implements OnQueryTextListener并实现onQueryTextChange和onQueryTextSubmit方法[2]。

  1. public boolean onCreateOptionsMenu(Menu menu) {
  2. // Inflate the menu; this adds items to the action bar if it is present.
  3. getMenuInflater().inflate(R.menu.main, menu);
  4.  
  5. searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
  6. searchView.setOnQueryTextListener(this);
  7. return true;
  8. }
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:app="http://schemas.android.com/apk/res-auto"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. tools:context="com.zhigao.all_connect.MainActivity" >
  5.  
  6. <item android:id="@+id/menu_search"
  7. android:title="Search"
  8. app:showAsAction="always"
  9. app:actionViewClass="android.support.v7.widget.SearchView"
  10. />
  11. </menu>

2.3.2 字符串匹配与结果保存

用户输入完待搜索的字符点击搜索之后,执行onQueryTextSubmit函数。采用stringSplit[i].toLowerCase().contains(arg0.toLowerCase())进行不区分大小写的匹配操作。使用scrollTo函数进行scrollview的跳转[5]。

  1. public boolean onQueryTextSubmit(String arg0) {
  2. // TODO Auto-generated method stub
  3. Log.v(TAG, "querysubmit"+arg0);
  4. matchedLine.clear();
  5. String []stringSplit=sortedResult.split("\n");
  6. for (int i = 0; i < stringSplit.length; i++) {
  7. //case insensitive match
  8. if (stringSplit[i].toLowerCase().contains(arg0.toLowerCase())) {
  9. matchedLine.add(i);
  10. }
  11. }
  12.  
  13. if (matchedLine.size()==0) {
  14. Toast.makeText(getApplicationContext(), "no match!", Toast.LENGTH_SHORT).show();
  15. return false;
  16. }else if (matchedLine.size()==1) {
  17.  
  18. }
  19. else {
  20. forwardButton.setVisibility(View.VISIBLE);
  21. backwardButton.setVisibility(View.VISIBLE);
  22. }
  23. scrollView.post(new Runnable() {
  24. @Override
  25. public void run() {
  26. int y = textView.getLayout().getLineTop(matchedLine.get(0));
  27. scrollView.scrollTo(0, y);
  28. }
  29. });
  30. searchView.clearFocus();
  31. return false;
  32. }

2.3.3 当有多个字符串可以匹配时的结果显示

基于relativelayout构造出button浮在textview上的效果,实现了当用户向下滑动scrollview时,button能够始终保持在右下方的位置[6]。用户点击按钮进行向前或者向后的搜索操作。点击textview之后取消按钮的显示。

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical">
  5. <ScrollView
  6. android:id="@+id/scrollView"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. >
  10. <TextView
  11. android:id="@+id/ssidTextView"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. />
  15. </ScrollView>
  16.  
  17. <Button
  18. android:id="@+id/backwardButton"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_alignParentBottom="true"
  22. android:layout_alignParentRight="true"
  23. android:background="@drawable/backward"
  24. />
  25. <Button
  26. android:id="@+id/forwardButton"
  27. android:layout_width="wrap_content"
  28. android:layout_height="wrap_content"
  29. android:layout_toLeftOf="@id/backwardButton"
  30. android:layout_alignParentBottom="true"
  31. android:background="@drawable/forward"
  32. />
  33. </RelativeLayout>

2.4 生成有签名apk时遇到的问题及目前解决方案

2.4.1 Duplicate id @+id/image问题[7]

生成签名apk运行lint检查时,提示由Duplicate id @+id/image问题。即使是将android support library更新到23.0.1之后仍然出现。目前先将abc_activity_chooser_view.xml中的第二个@+id/image修改为@+id/image2。

2.4.2 This class should be public (android.support.v7.internal.widget.ActionBarView.HomeView)问题

修改lint,让其将这个问题从error判断为warning。window->preferences -> Android Lint Preferences,搜索Instantiatable。将其设置为warning。

2.4.3 "abc_action_bar_home_description_format" is not translated in "mk-rMK" 问题

因为目前不考虑支持过多语言,而且android这个包之后有可能再会更新。因此目前考虑先将lint的missing chanslation设置为warning。

三、完整源码共享

https://github.com/jue-jiang/wifiAssist

四、apk下载

https://github.com/jue-jiang/wifiAssist/blob/master/wifiAssist.apk

五、参考材料

[1]安卓手机如何查看WIFI密码_百度经验

[2]searchView.setOnQueryTextListener(this);

[3]java - Android Reading from an Input stream efficiently - Stack Overflow

[4]java - execute shell command from android - Stack Overflow

[5]java - How to scroll to a given line number, TextView inside ScrollView - Stack Overflow

[6]How to add a floating button on scrolling in android? - Stack Overflow

[7]Issue 73197 - android - abc_activity_chooser_view_include.xml uses android:id="@+id/image" twice - Android Open Source Project - Issue Tracker - Google Project Hosting

安卓手机已保存WiFi密码查看助手(开源)的更多相关文章

  1. 忘记常访问网站密码怎么办?教你如何查看浏览器已保存的密码,如何简单查看Chome浏览器保存的密码?

    利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查看Chrome浏览器上保存的密码时,点击显示,会弹出一个对话框 ...

  2. 简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码

    简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码   利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查 ...

  3. 百度经验:Win10查看已存储WiFi密码的两种方法

    方法一:网络和共享中心查询 具体步骤可以参考:Win10查看WIFI密码的方法 方法二:命令提示符查询 1.右键单击开始按钮,选择“命令提示符(管理员)” 2.输入如下命令(下图①号命令): nets ...

  4. 第十八章节 BJROBOT 安卓手机 APP 建地图【ROS全开源阿克曼转向智能网联无人驾驶车】

    1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobotbringup.launch 2.在虚拟机端再打开一个终端,ssh 过去主控端启动ro ...

  5. 如何查看chrome浏览器已保存的密码

    该方法是针对在chrome中已经存储了登陆密码的情况. chrome版本是 66.0.3359.139(正式版本) (64 位),不知道哪天会改了这个bug. 一般来说,我们登陆chrome浏览器已经 ...

  6. windows查看已连接WIFI密码

    找到wifi图标. 右键,选择打开“网络和internet设置”,选择状态. 选择更改适配器设置. 选择你所连接的WIFI网络. 右键,选择状态. 选择无线属性. 选择安全. 勾选显示字符.

  7. win10家庭版查看已连接wifi密码

    点击屏幕右下角无线网路图标. 点击网络设置. 完成.

  8. Android WiFi密码(查看工具)

    纯手机端AIDE编写,现在分享出源码 & apk文件. 注: 使用此工具需要root权限. apk文件 : http://yunpan.cn/cHPLZ8zH5BQBV (提取码:9cd2) ...

  9. windows git 清除已保存的密码

    进入git目录 右键 git-bash.exe 执行命令: git config --system --unset credential.helper 然后执行git clone http://... ...

随机推荐

  1. [Java] Tomcat环境变量设置

    @echo off title Tomcat环境变量设置 color 0a set /p inputTH=D:\Work\024_Tomcat if /i "%inputTH%"= ...

  2. Java---Condition控制线程通信

    java中控制线程通信的方法有:1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Conditio ...

  3. iOS 7 与 Xamarin - MultiPeer Connectivity(转载)

    随着时代的改变,移动设备在生活工作都开始取代原有的pc.设备间的数据交互就成为了必备可少的功能.比较成熟的产品有NFC.这个啪啪的操作很流行,例如分享图片,分享文件等 .但是在iOS设备中还没有NFC ...

  4. 对URL编码

    url支持26个英文字母.数字和少数几个特殊字符,因此,对于url中包含非标准url的字符时,就需要对其进行编码.iOS中提供了函数stringByAddingPercentEscapesUsingE ...

  5. Android 从Gallery获取图片

    本文主要介绍Android中从Gallery获取图片 设计项目布局 <LinearLayout xmlns:android="http://schemas.android.com/ap ...

  6. android apk静默安装

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/47803149 之前有很多朋友都问过我,在Android系统中怎样才能实现静默安装呢 ...

  7. Android海康监控视频调用demo

    一. 开发环境 1. 操作系统:windows7(X64) 2. 开发工具:eclipse adt Build: v22.2.1-833290 JDK7 android SDK 3. 客户端设备版本: ...

  8. SQL Server(一)——数据库基础知识

    SQL:Structured Quety Language SQL SERVER是一个以客户/服务器(c/s)模式访问.使用Transact-SQL语言的关系型数据库管理子系统(RDBMS) DBMS ...

  9. Sql Server之旅——第十站 看看DML操作对索引的影响

    我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...

  10. maven-shade-plugin

    <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> ...