一、需求分析

最近电脑需要连接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. Microsoft SharePoint Server 2013 Service Pack 1 (sp1)终于出来了!!!

    Microsoft SharePoint Server 2013 Service Pack 1 终于出来了!以下是下载地址如下,大小1.25G. http://www.microsoft.com/zh ...

  2. 如何更好的通过Inflate layout的方式来实现自定义view

    本篇文章讲的是如何用现有控件产生一个组合控件的方法,十分简单实用.现在开始! 一.需求 我们要实现一个有红点和文字的按钮控件,就像下面这样: 二.实现 我的思路是让一个button和一个textvie ...

  3. 【IOS】从android角度来实现(理解)IOS的UITableView

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3403124.html   本人从在学校开始到现在上班(13年毕 ...

  4. Android 中的编码与解码

    前言:今天遇到一个问题,一个用户在登录的时候,出现登录失败.但是其他用户登录都是正常的,经过调试发现登录失败的用户的密码中有两个特殊字符: * .#  . 特殊符号在提交表单的时候,出现了编码不一样的 ...

  5. APP 游戏审核改动

    广电总局封杀游戏 移动游戏将进入洗牌期 封杀了电影.电视剧.网络剧 现在轮到游戏了 新法速递 2016年7月1日,国家新闻出版广电总局办公厅<关于移动游戏出版服务管理的通知>(新广出办发[ ...

  6. Swift (if while)

    Swift 分支 if if后的括号可以省略 if后只能接bool值 if后的大括号不能省略 let num1 = 3.0 let num2 = 4.0 let bool : Bool = true ...

  7. Eclipse中jsp、js文件编辑时,卡死现象解决汇总

    使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...

  8. JSON字符串与JSON对象

    JSON对象是直接可以使用JQuery操作的格式,和js中的对象一样,可以用对象(类名)点出属性(方法). JSON字符串仅仅只是一个字符串,一个整体,不截取的话没办法取出其中存储的数据,不能直接使用 ...

  9. Spring为某个属性注入值或为某个方法的返回值

    项目中用到需要初始化一些数据,Spring提供了filed的值注入和method的返回值注入. 一.Field值的注入 filed值注入需要使用org.springframework.beans.fa ...

  10. C# MVC模式 404 500页面设置方法

    <customErrors mode="On" defaultRedirect="Controllers/Action"> <error st ...