android 反射调用其他apk中的方法

   最近在研究调用android原生界面进行拍照,尝试了很多方法均没有成功,刚开始想到了采用模拟按键的方式去实现,发现不可行,用Instrumentation 需要是system app,不能当做普通app,如果手机已被Root,采用Instrumentation 模拟KEYCODE_CAMERA按键的方式倒是可行的。在非Root设备上,是因为权限的问题而报错,想到采用JNI的方式,尝试发现还是不能绕开android系统的权限问题,也是不可行的,后面想到反射,尝试发现也是不可行的,因为有很多参数需要初始化,之前很少用到反射,现在记录下使用反射的过程。

1. 在使用反射的过程中,被第一个问题困扰,找不到com.android.camera这个包名,后面通过反编译发现这个包被打进了com.android.gallery3d这个包,也就是说,它把Camera和Gallery合成了一个apk,了解了这个问题以后就好办了。


2. 主要代码

Context mmsCtx = createPackageContext("com.android.gallery3d", 
			Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
Class<?> clazz = Class.forName("com.android.camera.manager.ShutterManager", true, mmsCtx.getClassLoader());
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
Constructor<?> constructor = null;
for (int i = 0; i < constructors.length; i++) {
	constructor = constructors[i];
	if (constructor.getGenericParameterTypes().length == 0)
	break;
}
constructor.setAccessible(true);
					
Class<?> camera = Class.forName("com.android.camera.Camera", true, mmsCtx.getClassLoader());
Object cameraObject = camera.newInstance();
					
Object maObject = constructor.newInstance(cameraObject);
Method[] methods = clazz.getMethods();
					
Method[] methodss = clazz.getDeclaredMethods();
for(Method meth : methodss) {
	Log.i(TAG,"name:" + meth.getName());
	/*if(meth.getName().equals("getView")) {
		meth.setAccessible(true);
		meth.invoke(maObject);
	}*/
}
					
for(Method meth : methods) {
	//Log.i(TAG,"name:" + meth.getName());
	if(meth.getName().equals("performPhotoShutter")) {
		meth.setAccessible(true);
		meth.invoke(maObject);
	}
}

这里面主要要注意的地方就是:

1. 因为这个相机apk比较特殊,他不是在com.android.camera这个包里,首先要找到包名:createPackageContext(com.android.gallery3d), 然后在查找类的时候,就不需要

外面的这层包名,直接用它的包名和类名就可以了:com.android.camera.manager.ShutterManager,如果还是加上外面层的包名会出现找不到类的异常。

2. 实例化类,通过newInstance 可以实现,而且可以传递参数,如上面就是constructor.newInstance(cameraObject); 给 ShutterManager 传递了 Camera 这个参数

3. getDeclaredMethods() 和 getMethods() 获取到的函数数组还是不一样的。


最后通过log发现com.android.camera.manager.ShutterManager 里的 performPhotoShutter()确实被调用了,但是因为该方法里有数据没有初始化,所以还是不能拍照的。


反射机制确实很强大。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值