Using internal (com.android.internal) and hidden (@hide) APIs [Part 2, customizing android.jar]
[note: if you don’t have time to follow this post, you can go here and download the final results]
In previous post I explained why there is no easy way to use com.android.internal package (internal API) or anything marked with @hide attribute (hidden API) without using reflection. That’s because android.jar file does not contain classes from internal and hidden API and because of this nobody can reference those classes in compile time.
This part describes how to restore original android.jar. This will allow usage of internal and hidden APIs as if they were public APIs.
How to get original (uncut) version of android.jar?
We need to modify android.jar so it contains all original *.class files (including Internal and Hidden API classes). There are two ways:
1) Android is an open source project. We can download the source code and customize build system so it does not exclude internal & hidden classes from android.jar. This is a hard way.
2) Each emulator or real device must have some equivalent of android.jar that is used in runtime. We can get this jar from device, extract original .class files and copy them into android.jar from Android SDK.
I’ll stick with second approach. It’s easier to start with and does not require setting up Linux machine (if you are working on Windows), building all source code tree, customizing build system and so on.
Getting framework.jar from device
You can download files from device or emulator using command line ( adb pull ) or using DDMS (from eclipse or as standalone application from android sdk).
(Note: Emulator always contains code in .dex files, while real devices usually contain their code in optimized version of dex – odex files. Working with odex files is harder, and that’s why I prefer emulator in this post.)
The runtime equivalent of Android SDK’s android.jar file is framework.jar. This file is located at /system/framework/framework.jar on a device.
adb pull /system/framework/framework.jar
When framework.jar is downloaded from device, rename it to framework.zip and unzip it to separate folder. You should get something like this:
File classes.dex is what we need.
First we need to convert .dex file to .jar file format. This can be done using a small utility called dex2jar. You just need to run:
When conversion is done you should have classes.dex.dex2jar.jar file. Just rename it to framework-classes.zip. Using zip file viewer, go to framework-classes.zip/com/android/internal:
Voilà. We’ve got all the .class files for internal and hidden API (though screenshot only confirms the internal part).
Android SDK’s android.jar is located at ANDROID_SDK/platforms/android-X/android.jar (where X is API Level of your interest, in my case X == 9).
Copy android.jar as custom-android.zip. Unzip to folder custom-android. Copy all .class files from framework-classes.zip to custom-android folder (you’ll need to replace all already existing .class files).
Then zip custom-android folder back as original-android.zip. Rename to original-android.jar.
Summary of steps
- Choose your target android platform X (I used API Level 9 platform, X == 9)
- Create emulator that targets platform X
- Start emulator, download /system/framework/framework.jar file from it.
- Rename framework.jar –> framework.zip
- Extract classes.dex from framework.zip
- Using dex2jar convert classed.dex to classes.jar
- Rename classes.jar as framework-classes.zip
- Copy android.jar from ANDROID_SDK/platforms/android-X/ as custom-android.zip
- Extract custom-android.zip to custom-android folder.
- Copy everything from framework-classes.zip into custom-android folder (replacing all existing files).
- Zip custom-android folder as original-android.zip
- Rename original-android.zip as original-android.jar
We restored original android.jar so it contains .class files from internal and hidden APIs. This is only first step. Next step is to create custom android platform that uses this uncut version of android.jar and add it to Android SDK plarforms directory.
( Next post )