admin管理员组文章数量:1599410
前言
最近在研究WiFi,顺便看了一下WiFi的API文档,然后衍生出一系列的脑洞大开,不过这篇文章不打算讲它的API,感兴趣的可以直接去看它的文档 android.wifi 。
既然能获取到手机连接到的WiFi信息,那么自然也能获取得到连接过的WiFi密码啦,不过前提是你的手机必须有root权限。
先贴个最终的效果图片~~~
1.获取手机root权限
现在有很多软件都可以获取root,不过我在获取root的时候是真的心塞,可能是手机太low了,机型不适配,试过很多软件都不行,最后下载了KingRoot,然后看着它不停的关机开机再关机再开机最后才root成功的(不过过了5分钟后又打回原形了,对这手机真的无语),不过这5分钟也已经够我测试的啦。所以大家如果一直失败的话也可以尝试一下KingRoot,当然这也不是百分百成功的。
2.获取本地已连接过的WiFi数据
当手机连接过WiFi时,连接的信息会保存在手机的/data/misc/wifi/wpa_supplicant.conf文件里,但是这个文件并不能直接打开,而是需要靠命令行的方式来打印出来,不多说,直接上代码~~~
MainActivity.java
//读取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,这里点击允许,反正是自己写的代码,也不怕它会干什么坏事是吧~
我们通过cat /data/misc/wifi/wpa_supplicant.conf打印出来的数据正是我们想得到的WiFi信息,但是由于里面的信息包含很多个字段,所以我们要筛选出我们需要的内容来。 wpa_supplicant.conf包含的字段为:
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.java
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;
}
}
复制代码
然后就可以往里面添加数据啦~~
private List<WiFiInfo> lists;
//通过创建一个正则表达式来匹配是否有需要的字段,有则进行下一步操作,慢慢看就能懂,不作解释
private void addWifiList() {
Pattern network = Patternpile("network=\\{([^\\}]+)\\}", Pattern.DOTALL);
Matcher networkMatcher = network.matcher(wifiConf.toString());
WiFiInfo wifiInfo;
while (networkMatcher.find()) {
String networkBlock = networkMatcher.group();
Pattern ssid = Patternpile("ssid=\"([^\"]+)\"");
Matcher ssidMatcher = ssid.matcher(networkBlock);
if (ssidMatcher.find()) {
wifiInfo = new WiFiInfo();
wifiInfo.setName(ssidMatcher.group(1));
Pattern psk = Patternpile("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/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/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,就都能知道别人的密码了~
转载于:https://juejin.im/post/5ca06b676fb9a05e425559cb
版权声明:本文标题:Android之WiFi密码查看器 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1728321098a1153840.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论