一、需求分析

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

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

二、主要功能实现

2.1 读取系统文件

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

String commandResult=commandForResult("cat /data/misc/wifi/wpa_supplicant.conf");
public String commandForResult(String command) { try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = null;
outputStream = new DataOutputStream(process.getOutputStream());
outputStream.writeBytes(command+"\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder total = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
total.append(line);
total.append("\n");
}
return total.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "error";
}
}

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

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

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

    String sortByPriority(String input){
String [] stringPerLine=input.split("\n");
ArrayList<NetworkPara> list=new ArrayList<MainActivity.NetworkPara>();
int start=0,end=0;
NetworkPara networkPara = null;
for (int i = 0; i < stringPerLine.length; i++) {
if (stringPerLine[i].contains("network={")) {
start=1;
end=0;
networkPara=new NetworkPara();
networkPara.paraString="";
}
if (start==1) {
if (networkPara!=null) {
networkPara.paraString=networkPara.paraString.concat(stringPerLine[i])+"\n";
}
if (stringPerLine[i].contains("priority")) {
String []prioSplit=stringPerLine[i].split("=");
networkPara.priority=Integer.parseInt(prioSplit[prioSplit.length-1]);
}
if (stringPerLine[i].contains("}")) {
start=0;
end=1;
}
}
if (end==1) {
list.add(networkPara);
}
}
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((NetworkPara) (o2)).priority)
.compareTo(((NetworkPara) (o1)).priority);
}
}); String result="";
for (int i = 0; i < list.size(); i++) {
result=result.concat(list.get(i).paraString);
}
return result;
}

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

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

2.3.1 Actionbar中显示搜索按钮

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

    public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu); searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
searchView.setOnQueryTextListener(this);
return true;
}
<menu 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"
tools:context="com.zhigao.all_connect.MainActivity" > <item android:id="@+id/menu_search"
android:title="Search"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"
/>
</menu>

2.3.2 字符串匹配与结果保存

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

    public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
Log.v(TAG, "querysubmit"+arg0);
matchedLine.clear();
String []stringSplit=sortedResult.split("\n");
for (int i = 0; i < stringSplit.length; i++) {
//case insensitive match
if (stringSplit[i].toLowerCase().contains(arg0.toLowerCase())) {
matchedLine.add(i);
}
} if (matchedLine.size()==0) {
Toast.makeText(getApplicationContext(), "no match!", Toast.LENGTH_SHORT).show();
return false;
}else if (matchedLine.size()==1) { }
else {
forwardButton.setVisibility(View.VISIBLE);
backwardButton.setVisibility(View.VISIBLE);
}
scrollView.post(new Runnable() {
@Override
public void run() {
int y = textView.getLayout().getLineTop(matchedLine.get(0));
scrollView.scrollTo(0, y);
}
});
searchView.clearFocus();
return false;
}

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

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/ssidTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</ScrollView> <Button
android:id="@+id/backwardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/backward"
/>
<Button
android:id="@+id/forwardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/backwardButton"
android:layout_alignParentBottom="true"
android:background="@drawable/forward"
/>
</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. wordpress语言切换

    如果你想更改WordPress的语言,比如将英文版转换为中文版,或者将中文版转换为英文版,该如何操作?其实很简单,打开网站根目录下的 wp-config.php,然后搜索 define('WPLANG ...

  2. iOS 设置系统屏幕亮度

    // 设置系统屏幕亮度    //    [UIScreen mainScreen].brightness = value;    // 或者    [[UIScreen mainScreen] se ...

  3. c中的进制与内存分析

    一. 进制 1. 什么是进制 l 是一种计数的方式,数值的表示形式 数一下方块的个数 汉字:十一   十进制:11  二进制:1011  八进制:13 l 多种进制:十进制.二进制.八进制.十六进制. ...

  4. iOS中的小知识点

    1.tableView隐藏滚动条 self.tableView.showsVerticalScrollIndicator = NO; 2.关于属性     使用assign: 对基础数据类型 (NSI ...

  5. 基于ruby的watir自动化测试 笔记一

    基于Ruby的watir-webdriver自动化测试方案与实施(五)   基于Ruby的watir-webdriver自动化测试方案与实施(四)   基于Ruby的watir-webdriver自动 ...

  6. iOS 导航栏实现总结

    目标: 在UI界面中实现 整体效果的导航栏, 比如1 首页无导航条,次页有导航条, 2 导航条中不包含下方不包含黑边 3 导航条包含多个筛选项 等等 问题: 用系统带的NavigateBar 来实现时 ...

  7. SQL Server(三)——增、删、改、查

    一.数据库操作 create database 数据库名称 ——创建drop database 数据库名称 ——删除use 数据库名称 ——使用go 两条SQL语句之间分隔 二.表的操作 create ...

  8. MySQL 优化之 index merge(索引合并)

    深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...

  9. MongoDB3.0.x版本用户授权配置(单机环境)

    MongoDB数据库默认情况下是没有做权限控制的,只要能够连接所开放的端口就能进行访问,而且拥有root级别的权限:对于生产环境而言是极不安全的,所以需要建立用户,进行授权控制. 单机环境下的用户授权 ...

  10. 像编程一样写文章—Markdown

    Markdown是什么 是一种极其简单的标记语言,写的时候只需要普通编辑器即可: 它可以使文本内存具有某种格式: Markdown设计理念使文本易读.易写 文件后缀名:.md . .markdown. ...