安卓手机已保存WiFi密码查看助手(开源)
一、需求分析
最近电脑需要连接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
五、参考材料
[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
安卓手机已保存WiFi密码查看助手(开源)的更多相关文章
- 忘记常访问网站密码怎么办?教你如何查看浏览器已保存的密码,如何简单查看Chome浏览器保存的密码?
利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查看Chrome浏览器上保存的密码时,点击显示,会弹出一个对话框 ...
- 简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码
简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码 利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查 ...
- 百度经验:Win10查看已存储WiFi密码的两种方法
方法一:网络和共享中心查询 具体步骤可以参考:Win10查看WIFI密码的方法 方法二:命令提示符查询 1.右键单击开始按钮,选择“命令提示符(管理员)” 2.输入如下命令(下图①号命令): nets ...
- 第十八章节 BJROBOT 安卓手机 APP 建地图【ROS全开源阿克曼转向智能网联无人驾驶车】
1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobotbringup.launch 2.在虚拟机端再打开一个终端,ssh 过去主控端启动ro ...
- 如何查看chrome浏览器已保存的密码
该方法是针对在chrome中已经存储了登陆密码的情况. chrome版本是 66.0.3359.139(正式版本) (64 位),不知道哪天会改了这个bug. 一般来说,我们登陆chrome浏览器已经 ...
- windows查看已连接WIFI密码
找到wifi图标. 右键,选择打开“网络和internet设置”,选择状态. 选择更改适配器设置. 选择你所连接的WIFI网络. 右键,选择状态. 选择无线属性. 选择安全. 勾选显示字符.
- win10家庭版查看已连接wifi密码
点击屏幕右下角无线网路图标. 点击网络设置. 完成.
- Android WiFi密码(查看工具)
纯手机端AIDE编写,现在分享出源码 & apk文件. 注: 使用此工具需要root权限. apk文件 : http://yunpan.cn/cHPLZ8zH5BQBV (提取码:9cd2) ...
- windows git 清除已保存的密码
进入git目录 右键 git-bash.exe 执行命令: git config --system --unset credential.helper 然后执行git clone http://... ...
随机推荐
- linux集群运维工具:clustershell和pssh
由于需要安装hadoop集群,有10台机器需要安装,一开始打算用SCP复制,后来觉得不可接受(实际现场可能数倍的机器集群,就是10台也不想干).后来在网上找了,发现了clustershell和pssh ...
- vncserver安装
我的环境是centos6.5,如果没有安装桌面,先执行: # yum groupinstall "X Window System" "Desktop" # yu ...
- GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样?
GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样? 先了解一下 高德地图 采用: GCJ-02 (不可逆) 百度百科: http://baike.baidu.com/link?url ...
- Java中“==”与equals方法的区别
1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...
- c++中的数据类型
1.数据类型简介 c++中数据类型分为两种:预定义类型和自定义数据类型. 预定义类型:整型(int 4个字节) 字符型 布尔型 (bool) 浮点型(4个字节) 空类型:关键字void,不能用于普通变 ...
- 自定义圆形控件 RoundImageView
1.自定义圆形控件 RoundImageView package com.ronye.CustomView; import android.content.Context; import androi ...
- 【C语言】C语言简介
目录: 1. [什么是C语言?] 2. [C语言历史] 3. [C语言标准] 4. [C语言特点] 1. 什么事C语言? · C语言是一门高级编程语言,用于人与计算机之间的沟通,就如同人与人之间沟通时 ...
- 网络邂逅&网络异步请求
什么是卡,网络慢,且你只能等着它加载完不能做别的事 这里便引申出网络异步请求的概念 #import "ViewController.h" @interface ViewContro ...
- yii2 rbac权限控制详细操作步骤
作者:白狼 出处:http://www.manks.top/article/yii2_rbac_description本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 ...
- 清理DBA_DATAPUMP_JOBS中的孤立数据泵作业
今天在重构数据库时(将表空间中的表.索引转移到其它表空间)时,发现有两个奇怪的对象SYS_EXPORT_FULL_01.SYS_EXPORT_FULL_02搜索了一下,发现这个可能是EXPDP导出异常 ...