安卓手机已保存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

五、参考材料

[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

时间: 10-02

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

Windows小技巧 -- 已连接wifi密码查看

部分情况,想和朋友分享连接过的Wifi密码,可能不知道怎么来查询,下面记录几种查询已连接的Wifi密码方法,具体如下: 方式一 :无线属性页面查询 快捷键 Win + R ,打开运行窗口,输入 ncpa.cpl 快速打开 网络连接 页面,找到 WIFI 右键状态,弹出的 WLAN 状态 窗口点击 无线属性, 在弹出的 xxx 无线网络属性 窗口中,点击 安全 选项卡勾选 显示字符 就可以在 网络安全秘钥 后看到当前wifi的密码,如下图: 方式二 :netsh命令查询 netsh(Network

360极速浏览器如何看已保存的密码

http://chrome.360.cn/help/codesave.html 头像区---个人网络收藏夹帐号登录口---设置---选项---个人资料---密码---管理已保存的密码---查看备份资料 浏览器右上角处---小齿轮工具按钮---右侧倒三角按钮图标---下拉列表---帐号(当前登录的个人网络收藏夹帐号)---选项---个人资料---密码---管理已保存的密码---查看备份资料 桌面---开始---搜索---Cookies---查看本地所有个人账户备份资料---360极速浏览器Cook

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

简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码 利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查看Chrome浏览器上保存的密码时,点击显示,会弹出一个对话框来要求输入Windows密码来验证你的权限. 绕过方法: 在地址栏输入chrome://settings/passwords来查看所有已保存的密码列表,搜索感兴趣的目标站点. 进入目标站点的登录页面,输入用户名前几位字符,让浏览器自动填充.右

自己动手实现WIFI密码查看器

最近搬了家,还没来得及装上宽带,于是乎手机上用**万能钥匙偷偷连接了几个WIFI,可是电脑也想用的话,就必须借助工具来查看密码了,之前一贯的做法是使用RE管理器进入系统文件夹查看WIFI配置文件(/data/misc/wifi/wpa_supplicant.conf),后来嫌麻烦又下载了好些WIFI密码查看器,但始终不满意,广告太多了哈哈! 刚好最近自学了不少安卓相关的知识,何不自己实现一个呢? 先来看看成果图吧: 界面布局非常简单,整个程序就只有一个Activity,使用LinearLayou

android 获取手机里面的WIFI密码

获取手机里面的WIFI密码??刚看到的时候我也没明白这个有什么用,自己的手机不会不知道wifi密码吧,所以到现在我也没用到个这个功能 ,在这里权当记录一下,以备以后再找. 话说怎么获取WIFI密码还得从小米手机说起,记得小米推出了个Wifi密码共享的功能:比如在一个咖啡厅,只要一个人向服务员获取了密码,然后他打开wifi密码共享,那么其他人就可以直接连上wifi,而不需要再向服务员询问密码.但是后来安全什么的东西,最后这项功能好像也就无疾而终了.. 不过我们还是可以看一下小米是怎么实现的: 1.

安卓手机中wifi密码查看器,查看wifi密码教程

市场上有很多查看wifi密码的软件,都是只能查看本地已经连过的wifi密码而已,大家都觉得没啥用, 但是呢 我告诉大家,确实能用的, 只是您不会使用而已. 大家都知道<wifi万能钥匙>,<wifi伴侣>,<360的wifi>等软件都能让您免费连wifi, 但是不会显示密码是多少, 那么这时候<查看wifi密码>这种软件就有作用了, 直接查看之前用wifi万能钥匙啥的连过的密码, 然后你就能快乐的玩耍啦! 但是使用<查看wifi密码>等软件需要r

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

方法一:网络和共享中心查询 具体步骤可以参考:Win10查看WIFI密码的方法 方法二:命令提示符查询 1.右键单击开始按钮,选择“命令提示符(管理员)” 2.输入如下命令(下图①号命令): netsh wlan show profiles 密码会在下方“密钥内容(key content)”中给出,本图不再列出 3.在给出的曾经使用过的WiFi连接中选择你想查询的连接名称,然后套入如下命令(上图②号命令)中查询密码: netsh wlan show profile name=“连接名” key=

笔记本电脑已连接wifi密码

有时候,想登陆自己家的无线网络(尤其朋友来家里突然需要连接无线网络),但这时脑子一片空白想不起来密码,怎么办呢? 其实,我们可以通过电脑来查看网络的密码,现在分享如何在笔记本电脑上查看连接过的无线网络密码. [1]界面操作方式 1.打开笔记本电脑的无线网连接列表,如下图所示界面: 2.查看已连接网络的属性.鼠标右击->选择属性. 3.切换到安全栏. 4.勾上显示字符的框.显示字符启用,密码会从加密状态切换到明文状态. [2]命令行查询方式 通过命令行查询方法步骤: 1.命令:cmd 2.命令:n

安卓手机开启通过wifi使用adb

先用数据线连接手机和电脑运行 adb tcpip 5555 ,然后在手机的wifi设置里找到IP地址,我的是192.168.199.102,然后直接运行 adb connect 192.168.199.102 就已经连接到手机了,可以通过 adb devices 来看到设备.如果手机重启过,需要重新执行上述步骤. 原文地址:https://www.cnblogs.com/skyfly0/p/10699969.html