Android之WiFi密碼查看器

前言

最近在研究WiFi,順便看了一下WiFi的API文檔,而後衍生出一系列的腦洞大開,不過這篇文章不打算講它的API,感興趣的能夠直接去看它的文檔 android.net.wifi
既然能獲取到手機鏈接到的WiFi信息,那麼天然也能獲取獲得鏈接過的WiFi密碼啦,不過前提是你的手機必須有root權限。html

先貼個最終的效果圖片~~~java

1.獲取手機root權限
如今有不少軟件均可以獲取root,不過我在獲取root的時候是真的心塞,多是手機太low了,機型不適配,試過不少軟件都不行,最後下載了KingRoot,而後看着它不停的關機開機再關機再開機最後才root成功的(不過過了5分鐘後又打回原形了,對這手機真的無語),不過這5分鐘也已經夠我測試的啦。因此你們若是一直失敗的話也能夠嘗試一下KingRoot,固然這也不是百分百成功的。   android

2.獲取本地已鏈接過的WiFi數據
當手機鏈接過WiFi時,鏈接的信息會保存在手機的/data/misc/wifi/wpa_supplicant.conf文件裏,可是這個文件並不能直接打開,而是須要靠命令行的方式來打印出來,很少說,直接上代碼~~~正則表達式

MainActivity.javabash

//讀取WiFi配置文件
private static final String CAT_WIFI_CONF = "cat /data/misc/wifi/wpa_supplicant.conf\n";
//退出
private static final String EXIT = "exit\n";

Process process;
DataOutputStream dataOutputStream;
DataInputStream dataInputStream;

StringBuffer wifiConf = new StringBuffer();
private void getWiFiInfo() {
    try {
        //使當前進程得到root權限
        process = Runtime.getRuntime().exec("su");
        dataOutputStream = new DataOutputStream(process.getOutputStream());
        dataInputStream = new DataInputStream(process.getInputStream());
        
        //使用cat來打印該文件的數據
        dataOutputStream.writeBytes(CAT_WIFI_CONF);
        //打印完後退出
        dataOutputStream.writeBytes(EXIT);
        dataOutputStream.flush();

        //讀取字節並解碼成指定格式的字符
        InputStreamReader inputStreamReader = new InputStreamReader(dataInputStream, "UTF-8");
        //讀取字符流
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        String line = null;
        //每讀取一行則拼接一次
        while ((line = bufferedReader.readLine()) != null) {
            wifiConf.append(line);
        }
        
        //關閉流並釋放資源
        bufferedReader.close();
        inputStreamReader.close();
        process.waitFor();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        if (TextUtils.isEmpty(wifiConf.toString())) {
            tips.setVisibility(View.VISIBLE);
            Toast.makeText(getApplicationContext(), "您還未獲取Root權限", Toast.LENGTH_LONG).show();
        }
        try {
            if (dataOutputStream != null) {
                dataOutputStream.close();
            }
            if (dataInputStream != null) {
                dataInputStream.close();
            }
            process.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //添加WiFi信息
    addWifiList();
}
複製代碼

咱們經過Runtime.getRuntime().exec("su")爲當前進程得到root環境後,當你運行打開APP後,會彈出一個框,提示你是否容許當前應用使用root,這裏點擊容許,反正是本身寫的代碼,也不怕它會幹什麼壞事是吧~app

咱們經過cat /data/misc/wifi/wpa_supplicant.conf打印出來的數據正是咱們想獲得的WiFi信息,可是因爲裏面的信息包含不少個字段,因此咱們要篩選出咱們須要的內容來。 wpa_supplicant.conf包含的字段爲:ide

network={
    ssid="wifi_SU"
    psk="Su1ddsfs235sdf82"
    key_mgmt=WPA-PSK
    priority=117
    disabled=1
    id_str="%7B%22creatorUid%22%3A%221000%22%2C%22configKey%22%3A%22%fi_SU%5C%22WPA_PSK%22%7D"
}
其中ssid爲WiFi名稱,psk爲WiFi密碼,key_mgmt爲WiFi的加密類型
咱們須要的最重要數據就是前兩個字段了
複製代碼

3.建立存儲的對象並添加數據
當知道咱們想要的信息後,就能夠添加進咱們的列表裏的,首先須要建立一個bean類存儲咱們要添加的內容,這個很簡單,就直接貼代碼了:測試

WiFiInfo.javaui

public class WiFiInfo {
    private String name;
    private String pwd;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
複製代碼

而後就能夠往裏面添加數據啦~~this

private List<WiFiInfo> lists;

//經過建立一個正則表達式來匹配是否有須要的字段,有則進行下一步操做,慢慢看就能懂,不做解釋
private void addWifiList() {
    Pattern network = Pattern.compile("network=\\{([^\\}]+)\\}", Pattern.DOTALL);
    Matcher networkMatcher = network.matcher(wifiConf.toString());
    WiFiInfo wifiInfo;
    while (networkMatcher.find()) {
        String networkBlock = networkMatcher.group();
        Pattern ssid = Pattern.compile("ssid=\"([^\"]+)\"");
        Matcher ssidMatcher = ssid.matcher(networkBlock);
        if (ssidMatcher.find()) {
            wifiInfo = new WiFiInfo();
            wifiInfo.setName(ssidMatcher.group(1));
            Pattern psk = Pattern.compile("psk=\"([^\"]+)\"");
            Matcher pskMatcher = psk.matcher(networkBlock);
            if (pskMatcher.find()) {
                wifiInfo.setPwd(pskMatcher.group(1));
            } else {
                wifiInfo.setPwd("無密碼");
            }
            lists.add(wifiInfo);
        }
    }
    // 列表倒序,看着方便~
    Collections.reverse(lists);
    adapter.notifyDataSetChanged();
}
複製代碼

4.顯示數據
添加完以後就能夠顯示數據了,我這裏的activity_main.xml使用的是recyclerview,比較簡單,而後adapter我使用的是BaseRecyclerViewAdapterHelper,固然個人重點是獲取WiFi密碼,因此其餘代碼能簡單就簡單啦~下面我就直接貼出這些代碼了:

activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/wifi_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <!--當未獲取root權限時的tips-->
    <TextView
        android:id="@+id/tips"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="請先獲取Root權限"
        android:layout_centerInParent="true"
        android:visibility="gone"/>

</RelativeLayout>
複製代碼

WiFiAdapter.java

public class WiFiAdapter extends BaseQuickAdapter<WiFiInfo, BaseViewHolder> {

    public WiFiAdapter(int layoutResId, @Nullable List<WiFiInfo> data) {
        super(layoutResId, data);
    }
    
    @Override
    protected void convert(BaseViewHolder helper, WiFiInfo item) {
        helper.setText(R.id.item_name, "名稱:" + item.getName())
                .setText(R.id.item_pwd, "密碼:" + item.getPwd());
    }
}
複製代碼

item_wifi.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="10dp">
        <TextView
            android:id="@+id/item_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/wifi_name" />
        <TextView
            android:id="@+id/item_pwd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="@string/wifi_pwd" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#30000000" />
        
</LinearLayout>
複製代碼

而後剩下的就是在MainActivity中配置adapter啦,這些就不貼了,比較簡單。當你手機未得到root權限時,則列表會爲空,由於你沒法讀取wpa_supplicant.conf文件。

好啦,之後不再怕忘記密碼啦,只要是你的WiFi萬能鑰匙能連得上的WiFi,就都能知作別人的密碼了~

相關文章
相關標籤/搜索