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. 主要代码

  1. Context mmsCtx = createPackageContext("com.android.gallery3d",   
  2.             Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);  
  3. Class<?> clazz = Class.forName("com.android.camera.manager.ShutterManager"true, mmsCtx.getClassLoader());  
  4. Constructor<?>[] constructors = clazz.getDeclaredConstructors();  
  5. Constructor<?> constructor = null;  
  6. for (int i = 0; i < constructors.length; i++) {  
  7.     constructor = constructors[i];  
  8.     if (constructor.getGenericParameterTypes().length == 0)  
  9.     break;  
  10. }  
  11. constructor.setAccessible(true);  
  12.                       
  13. Class<?> camera = Class.forName("com.android.camera.Camera"true, mmsCtx.getClassLoader());  
  14. Object cameraObject = camera.newInstance();  
  15.                       
  16. Object maObject = constructor.newInstance(cameraObject);  
  17. Method[] methods = clazz.getMethods();  
  18.                       
  19. Method[] methodss = clazz.getDeclaredMethods();  
  20. for(Method meth : methodss) {  
  21.     Log.i(TAG,"name:" + meth.getName());  
  22.     /*if(meth.getName().equals("getView")) { 
  23.         meth.setAccessible(true); 
  24.         meth.invoke(maObject); 
  25.     }*/  
  26. }  
  27.                       
  28. for(Method meth : methods) {  
  29.     //Log.i(TAG,"name:" + meth.getName());  
  30.     if(meth.getName().equals("performPhotoShutter")) {  
  31.         meth.setAccessible(true);  
  32.         meth.invoke(maObject);  
  33.     }  
  34. }  

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

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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值