使用Android的 hidden API
Hidden API之所以被隐藏,是想阻止开发者使用SDK中那些未完成或不稳定的部分(接口或架构)。举个例子,Bluetooth API在API 5上才开放;在API 3 和4上都是用@hide属性隐藏了。当这些API被验证和清理后,Google的开发者会移除@hide属性,并让其在API 5官方化。很多地方在API 4 和5之间发生了变化。如果你的程序依赖某些隐藏的API,当其部署到新的平台上时,就有可能陷入困境。
当你使用Android SDK进行开发的时候,你引用了一个非常重要的jar文件——android.jar。它位于Android SDK平台的文件夹中(SDK_DIR/platforms/platform-X/android.jar,其中,X表示API等级)。这个 android.jar移掉了com.android.internal包中所有的类,也移掉了所有标记有@hide的类,枚举,字段和方法。
但当你在设备上启动应用程序时,它将加载framework.jar(简单来说,它和android.jar等同),而其未移掉internal API和hidden API。(但它对开发者来说,并不能友好地访问,因此,我将向大家展示不通过反射如何使用这些API)。
这篇文章将描述如何还原最初的android.jar。这将允许我们像使用公开的API那样使用hiddenAPI。
如何得到原版android.jar?
我们需要修改android.jar,这样它才能包含所有的*.class文件(包括internal和hiddenAPI类)。有两种办法:
1)Android是一个开源工程。我们可以下载源码并搭建编译环境,这样它就不能移除那些internal和hidden的类了。这个办法比较困难;
2)每个模拟器或真机在运行时都会有一个等同android.jar的东西。我们可以从这里拿到jar文件,提取出原始的.class文件,并拷贝到AndroidSDK的android.jar中。
我将采用方案2。它易于开始,还不需要搭建Linux环境及编译环境等。
从设备上获取framework.jar
你可以使用命令行(adbpull)从模拟器或设备上下载文件,或者使用DDMS(借助Eclipse或SDK中的应用)。
注意:模拟器通常在.dex文件中包含代码,而真机一般在优化版的dex文件中包含代码——odex文件。操作odex文件比较困难,这也是为什么我选择模拟器的原因。
与AndroidSDK中的android.jar等同的文件是framework.jar。这个文件位于设的:/system/framework/framework.jar
adb pull /system/framework/framework.jar当framework.jar从设备上下下来之后,重命名为framework.zip并解压到独立的文件夹中。classes.dex正是我们需要的。
创建framework-classes.zip
首先,我们需要把.dex文件转换成.jar格式。你可以使用通用的工具dex2jar。只需要运行:
dev2jar classes.dex
当转换结束时,你应该得到了classes.dex.dex2jar.jar文件。重命名为framework-classes.zip。使用zip查看器,进入到framework-classes.zip/com/android/internal/
创建original-android.jar
Android SDK的android.jar位于ANDROID_SDK/platforms/android-X/android.jar(X表示API等级)。
拷贝android.jar成custom-android.jar。解压至custom-android文件夹。将framework- classes.zip中所有的.class文件拷贝到custom-android文件夹中(你需要覆盖所有已经存在的.class文件)。
然后,压缩custom-android文件成original-android.zip。
步骤总结
1.选择你的目标平台X
2.创建目标平台X的模拟器
3.启动模拟器,下载/system/framework/framework.jar
4.重命名framework.jar->framework.zip
5.从framework.zip中抽取classes.dex
6.使用dex2jar工具,将其转换成classes.jar
7.重命名classes.jar->framework-classes.zip
8.拷贝android.jar–>custom-android.zip
9.解压custom-android.zip至custom-android文件夹
10.将framework-classes.zip中所有文件拷贝至custom-android文件夹(覆盖存在的文件)
11.压缩custom-android文件夹成original-android.zip
12.重命名original-android.zip->original-android.jar