一直有个问题,就是清除非本APP 连接的wifi保存的密码,很想像Android系统那样可以直接在WIFI设置那里直接取消保存,于是做了以下尝试。
是在sdk 19以上哦,19以下(包括)是可以直接清除的。

清除wifi密码比较通常的用法是:

WifiManager mWifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mWifiManager.removeNetwork(config.networkId);
mWifiManager.saveConfiguration();

这样可以清除掉本来是你这个APP连接的WIFI,意思是这个WIFI是别人连接上的你是不能清除掉的。
目前也没有看到其他三方App能够做到这样。

于是开始寻找其他方法。
然后看到了 WifiManager 的这个方法 froget(看起来好像很有希望哦):
这里写图片描述 说的是替代 removeNetwork 和 saveConfiguration 方法,可是这是hide的,我们显式是调用不了的。

那先试试反射吧。

首先去拿到WifiManager:

        Class<?> clazz = null;
        try {
            clazz = Class.forName("android.net.wifi.WifiManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            KLog.e(e);
        }

然后构造forget方法:

        Class<?> actionListener = null;
        try {
            actionListener = Class.forName("android.net.wifi.WifiManager$ActionListener");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            KLog.e(e);
        }
        KLog.e("actionListener:" + actionListener);

        Method method = null;
        try {
            method = clazz.getMethod("forget", int.class, actionListener);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            KLog.e(e);
        }

然后构造WifiManager的构造函数:

        Class<?> im = null;
        try {
            im = Class.forName("android.net.wifi.IWifiManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            KLog.e(e);
        }
        KLog.e(im);

        Constructor[] constructor = clazz.getConstructors();
        Object ob = null;
        try {
            ob = constructor[0].newInstance(context, im);
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            KLog.e(e);
        }

最后调用方法:

 try {
            method.invoke(ob, config.networkId, actionListener);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            KLog.e(e);
        }

But !! 在构造类函数的时候,这个IwifiManager明明都拿到了,但是还是没有正确。
搞了好久还是没对,可能是我哪里弄错了?,暂时先换种方法吧。
这里写图片描述

现在试试open-sdk:

先去github clone https://github.com/anggrayudi/android-hidden-api
这是把设备上的 /system/framework/framework.jar 提取出来,经过一系列转换,最终得到完整的 android.jar。 这里写图片描述 找到项目对应的编译版本,我用的是26,拿到android.jar
这里写图片描述 然后放到项目的libs下。

在app 的build.gradle 下 dependencies:
这里写图片描述 这样的话就不会将open-sdk打包到apk中,只是编译时使用,最终代码还是运行在手机的framework.jar中,不会影响其他。

在根目录下的 build.gradle下添加这个:

project('app'){
    gradle.projectsEvaluated{
        tasks.withType(JavaCompile){
            // Xbootclasspath/p:是 Java 编译的寻址优先设置,先找缺省路径还是全路径
            options.compilerArgs.add('-Xbootclasspath/p:app/libs/android.jar')
        }
    }
}

编译后可直接调用 wifiManager.forget(netId,null)了,就算显示红色的也没关系,也是编译的通的。

转折点来了~ 你会发现还是不能清除掉通过其他应用设置的wifi。
比如手机设置密码连接wifi后,你再来操作清除,是无效的,还是只能清除掉自己App连接的。
如果哪位大神知道的一定要告诉我啊,感激不尽~

不过以后再遇到类似hide的问题,就可以试下这两种方式啦。

参考:https://www.jianshu.com/p/fbf45770ecc8