本文转载自:http://www.xwdoor.net/android-reflection-proxy-call-system-hidden-api-method-and-interface-class-wi-fi-connection/

有这样的需求:通过扫描二维码获取Wi-Fissid和密码,然后自动连接。我们先后出了两个版本,第一个版本,是通过网络搜索出来融合的初略版本,代码比较简陋,效果就是很多用户反馈联网的问题;第二个版本是我写的,基于充分了解联网逻辑的基础上,用kotlin实现的,效果马马虎虎,不过时不时还是有用户反馈联网的问题,大概1%左右吧;这次痛定思痛,采用反射调用系统framework的隐藏方法来实现连接wifi的功能。

因为是反射调用隐藏的方法 connect,且用到了一个隐藏的回调接口类ActionListener,所以在调用connect()方法前,需要先实现该接口,这就用到了委托、代理的原理

Note: 本文所有代码均是基于kotlin语言实现

1.实现 ActionListener 接口类

系统提供的连接wifi的方法有两个,分别是:

public void connect(WifiConfiguration config, ActionListener listener)
public void connect(int networkId, ActionListener listener)
  • 1
  • 2

可以看到,两个重载方法都需要传递一个ActionListener接口参数,这个接口的源代码如下:

/*** Interface for callback invocation on an application action* @hide*/
public interface ActionListener {/** The operation succeeded */public void onSuccess();/*** The operation failed* @param reason The reason for failure could be one of* {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}*/public void onFailure(int reason);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

简单来讲,接口类ActionListener有两个回调方法,分别是成功回调onSuccess和失败回调onFailure,跟我们平时使用的网络访问回调很像,麻烦在于它是隐藏的。

第一步,使用反射和代理实现 ActionListener 接口类,代码如下:

//通过反射获取 ActionListener 类
val actionListener = Class.forName("android.net.wifi.WifiManager\$ActionListener")
//实现 InvocationHandler 接口,所有的我们需要的回调方法,都是通过这个代理回调来实现的
//通过第二个参数可以判断回调的是什么方法
val invocationHandler = InvocationHandler { proxy, method, args ->Log.i("test", "代理回调: ${args.joinToString()}")//通过方法的名称判断回调的是什么方法if (method.name == "onSuccess") {Log.i("test", "联网成功")//等待获取ip地址Log.i("test", "wait ip address available")} else {Log.i("test", "联网失败: $args")}
}
//创建接口代理类,可以理解这个就是接口实现类(实现了接口 ActionListener 的类)
val proxy = Proxy.newProxyInstance(app.classLoader, arrayOf(actionListener), invocationHandler)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Note: ActionListener中有两个回调方法,这个时候我们可以通过第二个参数的属性值method.name来判断回调的是哪个方法

总结一下,创建代理的步骤如下:
1. 获取接口类的类型。如果是公开的(public),就直接类::java.class就行,比如:ActionListener::class.java,如果是隐藏的,就通过反射获取。
2. 实现接口InvocationHandlerActionListener中的回调方法的代码逻辑也是在里边实现。
3. 创建代理,关联ActionListenerInvocationHandler。此时的代理可以认为是ActionListener的实现类

一语概之,先通过反射获取隐藏接口类 ActionListener,然后通过代理实现该接口

2.获取 connect 方法实现联网操作

接下来就简单了,获取隐藏方法connect()连接Wi-Fi,代码如下:

//通过反射获取隐藏方法`connect()`
val connectMethod = context.wifiManager.javaClass.getDeclaredMethod("connect", WifiConfiguration::class.java, actionListener)
//第二个参数需要自己创建,具体的可以参考网络
connectMethod.invoke(context.wifiManager, config, proxy)
  • 1
  • 2
  • 3
  • 4

通过反射获取其中一个连接Wi-Fi的方法:public void connect(WifiConfiguration config, ActionListener listener),然后调用。需要注意的是,该方法的第一个参数是WifiConfiguration类型的,所以需要各位自己去创建了,创建过程比较麻烦,可以参考网络,我有空的话再写一篇文章,哈哈。

3.总结

好了,具体实现方法已经记录完毕,剩下的估计就是一些参数的创建,和回调方法中的具体代码逻辑了,最后,再归纳一下步骤吧:
1. 获取接口类的类型,方法:反射获取或者类::java.class
2. 继承实现接口InvocationHandler
3. 创建代理Proxy,作用是关联第一步中的接口类和第二步中的InvocationHandler
4. 反射获取隐藏方法connect()并调用

Android 反射、代理调用系统隐藏API方法与接口类连接Wi-Fi相关推荐

  1. Android开发中调用系统窗口的方法

    //直接拨号 Intent callIntent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:12345678")); start ...

  2. 拦截电话--- 关于利用反射 调用系统 hiden的 方法

    首先 需要知道  关于电话的操作 都在 TelephonyManager这个 类中 //初始化 TelephonyManager TelephonyManager mTelephonyManager ...

  3. python调用系统api_Python调用系统底层API播放wav文件的方法

    本文实例讲述了Python调用系统底层API播放wav文件的方法.分享给大家供大家参考,具体如下: 这里未使用其他库,只是使用 pywin32 调用系统底层 API 播放 wav 文件. 具体代码如下 ...

  4. android 订餐系统,一种基于Android平台手机订餐系统的实现方法

    一种基于Android平台手机订餐系统的实现方法[ 技术领域: ][0001]本发明涉及一种手机订餐系统,能够通过手机上的Android软件实现订餐.[ 背景技术: ][0002]目前已有的网上订餐系 ...

  5. android系统应用程序设置时间,Android应用程序设置系统时间的方法

    Android应用程序获取系统时间的方法: System.currentTimeMillis(); Android SDK虽然提供了设置系统时间的方法SystemClock.setCurrentTim ...

  6. ios 调用系统应用的方法 应用间跳转的方法

    声明一个私有方法: #pragma mark - 私有方法 -(void)openUrl:(NSString *)urlStr{//注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮 ...

  7. [Android多媒体二]调用系统录音机录音并存储到指定位置,适配安卓 7.0

    接上一篇文章,[Android多媒体一]调用系统相机拍照并存储到指定位置,适配安卓 7.0 本文讲述如何调用系统录音机,完成录音后,对录音进行指定位置的保存. 一.开始编写 首先,还是理清一下思路,在 ...

  8. 整理android调用系统相机的方法及遇到的问题

    在项目中遇到需要调用系统相机的功能点,整理方法如下 1.拍照完成之后直接存图片 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ...

  9. android 调用系统方法,android 调用系统功窗口方法

    1.  调用系统打电话功能 String tel = "tel:" + mTelNum.getText().toString(); Intent intent = new Inte ...

最新文章

  1. 超出了GC开销限制– Java堆分析
  2. 20165114 《网络对抗技术》 Exp0 Kali安装与配置 Week1
  3. 性能测试小总结(四) 结果分析(未完成)
  4. Opencv--仿射变换+投射变换+单应性矩阵
  5. linux下mycat测试安装
  6. C++ 使用引用捕获异常
  7. JVM 方法调用之动态分派
  8. LeetCode-Python-1386. 安排电影院座位(数组)
  9. rup 裁剪_建筑企业信息系统RUP裁剪模型及其应用研究
  10. 微信小程序-wxs实现时间格式化过滤器(正则)
  11. 卡片游戏 (Throwing cards away I)(队列+模拟)
  12. Luogu P3488 [POI2009]LYZ-Ice Skates
  13. Git 核心概念:工作区与暂缓区(添加提交及查看状态充分体现)
  14. nodejs调用java的jar包进行PPT转pdf
  15. mysql查询结果乘2倍_SQL查询总和乘以它应该的2倍
  16. c++ 判断回文,说实话,累赘
  17. ubuntu下启动wifi
  18. 为什么调用Dao层会报空指针异常
  19. HMI智能座舱自动化测试之性能测试
  20. linux lsmod命令 及相关信息

热门文章

  1. 【CentOS】磁盘管理与vim编译器
  2. SMACH专题(一)----安装与初探
  3. ubuntu_ftp_server配置方法
  4. linux 开机启动文件夹,Linux开机启动流程
  5. [云炬创业管理笔记]第二章成为创业者测试6
  6. 科大星云诗社动态20210508
  7. [:zh]<界面编程>任务二 用户注册界面设计[:]2018-01-24
  8. 台湾大学林轩田机器学习技法课程学习笔记13 -- Deep Learning
  9. matlab 现代信号处理,The-first-matlab-exercise 清华大学张旭东老师现代信号处理第一次matlab习题 - 下载 - 搜珍网...
  10. php怎么运行网页_PHP的作用是什么?