zoukankan      html  css  js  c++  java
  • 安卓手机已保存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+" "); outputStream.flush(); outputStream.writeBytes("exit "); 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(" "); } 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("
    ");
            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])+"
    ";    
                    }
                    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("
    ");
            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

  • 相关阅读:
    Linux下查找软件,rpm命令 dpkg命令 apt命令
    python3 requests的content和text方法
    python3爬虫超简单实例
    python3 爬取深圳主板公司名称,公司网址
    python3 类的学习
    ubuntu16.04同时使用 pyhton2.7和3.5,并随意切换
    (4)puppet常用的资源及其常用属性
    (3)puppet清单定义资源的语法
    (2)puppet单机测试命令apply
    lvs+keepalived高可用负载均衡
  • 原文地址:https://www.cnblogs.com/jiangz/p/4848194.html
Copyright © 2011-2022 走看看