Android 反射、代理调用系统隐藏API方法与接口类连接Wi-Fi
本文转载自:http://www.xwdoor.net/android-reflection-proxy-call-system-hidden-api-method-and-interface-class-wi-fi-connection/
有这样的需求:通过扫描二维码获取Wi-Fi
的ssid
和密码,然后自动连接。我们先后出了两个版本,第一个版本,是通过网络搜索出来融合的初略版本,代码比较简陋,效果就是很多用户反馈联网的问题;第二个版本是我写的,基于充分了解联网逻辑的基础上,用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. 实现接口InvocationHandler
,ActionListener
中的回调方法的代码逻辑也是在里边实现。
3. 创建代理,关联ActionListener
和InvocationHandler
。此时的代理可以认为是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相关推荐
- Android开发中调用系统窗口的方法
//直接拨号 Intent callIntent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:12345678")); start ...
- 拦截电话--- 关于利用反射 调用系统 hiden的 方法
首先 需要知道 关于电话的操作 都在 TelephonyManager这个 类中 //初始化 TelephonyManager TelephonyManager mTelephonyManager ...
- python调用系统api_Python调用系统底层API播放wav文件的方法
本文实例讲述了Python调用系统底层API播放wav文件的方法.分享给大家供大家参考,具体如下: 这里未使用其他库,只是使用 pywin32 调用系统底层 API 播放 wav 文件. 具体代码如下 ...
- android 订餐系统,一种基于Android平台手机订餐系统的实现方法
一种基于Android平台手机订餐系统的实现方法[ 技术领域: ][0001]本发明涉及一种手机订餐系统,能够通过手机上的Android软件实现订餐.[ 背景技术: ][0002]目前已有的网上订餐系 ...
- android系统应用程序设置时间,Android应用程序设置系统时间的方法
Android应用程序获取系统时间的方法: System.currentTimeMillis(); Android SDK虽然提供了设置系统时间的方法SystemClock.setCurrentTim ...
- ios 调用系统应用的方法 应用间跳转的方法
声明一个私有方法: #pragma mark - 私有方法 -(void)openUrl:(NSString *)urlStr{//注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮 ...
- [Android多媒体二]调用系统录音机录音并存储到指定位置,适配安卓 7.0
接上一篇文章,[Android多媒体一]调用系统相机拍照并存储到指定位置,适配安卓 7.0 本文讲述如何调用系统录音机,完成录音后,对录音进行指定位置的保存. 一.开始编写 首先,还是理清一下思路,在 ...
- 整理android调用系统相机的方法及遇到的问题
在项目中遇到需要调用系统相机的功能点,整理方法如下 1.拍照完成之后直接存图片 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ...
- android 调用系统方法,android 调用系统功窗口方法
1. 调用系统打电话功能 String tel = "tel:" + mTelNum.getText().toString(); Intent intent = new Inte ...
最新文章
- 超出了GC开销限制– Java堆分析
- 20165114 《网络对抗技术》 Exp0 Kali安装与配置 Week1
- 性能测试小总结(四) 结果分析(未完成)
- Opencv--仿射变换+投射变换+单应性矩阵
- linux下mycat测试安装
- C++ 使用引用捕获异常
- JVM 方法调用之动态分派
- LeetCode-Python-1386. 安排电影院座位(数组)
- rup 裁剪_建筑企业信息系统RUP裁剪模型及其应用研究
- 微信小程序-wxs实现时间格式化过滤器(正则)
- 卡片游戏 (Throwing cards away I)(队列+模拟)
- Luogu P3488 [POI2009]LYZ-Ice Skates
- Git 核心概念:工作区与暂缓区(添加提交及查看状态充分体现)
- nodejs调用java的jar包进行PPT转pdf
- mysql查询结果乘2倍_SQL查询总和乘以它应该的2倍
- c++ 判断回文,说实话,累赘
- ubuntu下启动wifi
- 为什么调用Dao层会报空指针异常
- HMI智能座舱自动化测试之性能测试
- linux lsmod命令 及相关信息
热门文章
- 【CentOS】磁盘管理与vim编译器
- SMACH专题(一)----安装与初探
- ubuntu_ftp_server配置方法
- linux 开机启动文件夹,Linux开机启动流程
- [云炬创业管理笔记]第二章成为创业者测试6
- 科大星云诗社动态20210508
- [:zh]<界面编程>任务二 用户注册界面设计[:]2018-01-24
- 台湾大学林轩田机器学习技法课程学习笔记13 -- Deep Learning
- matlab 现代信号处理,The-first-matlab-exercise 清华大学张旭东老师现代信号处理第一次matlab习题 - 下载 - 搜珍网...
- php怎么运行网页_PHP的作用是什么?