Home > Android, hacks > Using internal (com.android.internal) and hidden (@hide) APIs [Part 5, summary and example]

Using internal (com.android.internal) and hidden (@hide) APIs [Part 5, summary and example]

(Parts 1, 2, 3, 4, 5)

In order to enable usage of Internal and Hidden APIs without reflection you need:

  1. Create custom original-android.jar that includes all required .class files (details here)
  2. Create custom android platform that uses original-android.jar (details here).
  3. Modify ADT to allow usage of com.android.internal package (only for Internal API, details here).
  4. Create project that references custom android platform (example in this post)

In this post I’ll show how to actually use those Internal and Hidden APIs.

And as a bonus there is a list of already prepared custom android platforms with Internal and Hidden APIs enabled at the end of the post. I added them just in case you don’t have too much free time but want to try something out quickly.

Example project

Create new project, select 2.3.extended platform:

image

And here is code:

image

(you can copy actual code from here)

This code shows an example of Internal API usage (PowerProfile) and Hidden API usage (isWifiApEnabled). I can compile and run this code without using reflection.

Custom platforms

Here is a bunch of platforms that I created for myself. Just copy them over to your SDK_DIR\platforms directory. This will enable Hidden API instantly. You’ll need to customize your ADT (see this post) to additionally enable Internal API.

API Level 3 platform.

API Level 4 platform.

API Level 7 platform.

API Level 8 platform.

API Level 9 platform.

API Level 10 platform.

UPDATE:

Sorry, megaupload is currently down (and most likely will never be recovered). So the above links are not valid anymore.

But luckily I also have uploaded platforms 7, 8, 10 and 15 to github.

Categories: Android, hacks
  1. leon
    May 18, 2011 at 19:00 | #1

    That’s an excellent job. Thank you for saving so much time for me.

  2. soliax
    June 8, 2011 at 15:17 | #2

    Ditto on the comment above. This article was great and saved me days worth of work! Thank you very much.

  3. June 20, 2011 at 19:46 | #4

    Great tutorial! Is there any way you know of to use the server API? I tried doing basically the same things as in the beginning: “adb pull system/framework/services.jar” to get all the server class and then I put them into my “android.jar”. com.android.server shows up in eclipse if I look at the android.jar but I am still not able to do “import com.android.server.AlarmManagerService;”

    • June 20, 2011 at 19:58 | #5

      Why do you need access to AlarmManagerService?

      I don’t think you can get anything useful from importing it into your package. Because even if you do import this service, you won’t have access to the instance that currently running in OS. And you won’t have permissions to start your own AlaramManagerService also.

      This actually similar to all internal Android Services. The only thing you can do is to bind to those Android internal services.

      • June 20, 2011 at 20:16 | #6

        I’m working on something and I am trying to figure out a way to access every android class without having to use reflection. Thanks to your tutorial, I have access to internal and hidden APIs. Now I would like the server API as well. I don’t only want to use AlarmManagerService that is just an example. I want to be able to create objects of all those server classes and call all their methods.
        ClipboardService clip = new ClipboardService(this.getApplicationContext());
        CharSequence test = clip.getClipboardText();

      • June 20, 2011 at 20:32 | #7

        The problem is that having access to those classes will not allow you to instantiate them. I actually just tried your code but using reflection:

        AlarmManagerService:

        Class clazz = Class.forName("com.android.server.AlarmManagerService");
        Constructor ctor = clazz.getDeclaredConstructor(Context.class);
        ctor.setAccessible(true);
        Object clip = ctor.newInstance(this.getApplicationContext());

        Error:


        06-20 21:30:52.855: ERROR/ERROR(28762): Caused by: java.lang.UnsatisfiedLinkError: init
        06-20 21:30:52.855: ERROR/ERROR(28762): at com.android.server.AlarmManagerService.init(Native Method)
        06-20 21:30:52.855: ERROR/ERROR(28762): ... 17 more

        ConnectivityService:

        Class clazz = Class.forName("com.android.server.ConnectivityService");
        Constructor ctor = clazz.getDeclaredConstructor(Context.class);
        ctor.setAccessible(true);
        Object clip = ctor.newInstance(this.getApplicationContext());

        Error:

        06-20 21:32:35.879: ERROR/ERROR(28809): Caused by: java.lang.SecurityException: ConnectivityService: Neither user 10092 nor current process has android.permission.ACCESS_NETWORK_STATE.
        06-20 21:32:35.879: ERROR/ERROR(28809): at android.app.ContextImpl.enforce(ContextImpl.java:1365)
        06-20 21:32:35.879: ERROR/ERROR(28809): at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1400)
        06-20 21:32:35.879: ERROR/ERROR(28809): at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:395)
        06-20 21:32:35.879: ERROR/ERROR(28809): at com.android.server.ConnectivityService.enforceAccessPermission(ConnectivityService.java:841)
        06-20 21:32:35.879: ERROR/ERROR(28809): at com.android.server.ConnectivityService.getMobileDataEnabled(ConnectivityService.java:792)
        06-20 21:32:35.879: ERROR/ERROR(28809): ... 17 more

        So, even access to those classes will not give anything useful.

      • EnderX
        July 1, 2011 at 07:13 | #8

        Hi Inazaruk, nice work.
        I have been using reflection to invoke methods that the SDK has been hiding, like setForegroundActivity() in class com.android.settings.bluetooth.LocalBluetoothManager, but it gave me the ClassNotFound exception, any thought?

        Here’s the code,
        localBluetoothManager = Class.forName(“com.android.settings.bluetooth.LocalBluetoothManager”);
        Constructor ctor = localBluetoothManager.getDeclaredConstructor(Context.class);
        ctor.setAccessible(true);
        Object clip = ctor.newInstance(context);
        Method setForegroundActivityMethod = clip.getClass().getMethod(“setForegroundActivity”);
        setForegroundActivityMethod.invoke(context.getApplicationContext());

  4. June 20, 2011 at 21:14 | #9

    Alright so it looks like the reason I was not able to see classes like AlarmManagerService is because it is package visibility. Reflection would offer a way around this but it obviously won’t work because of the Native Method.. thanks for all your help, I need to continue to think about this.

  5. EnderX
    July 1, 2011 at 07:21 | #10

    EnderX :
    Hi Inazaruk, nice work.
    I have been using reflection to invoke methods that the SDK has been hiding, like setForegroundActivity() in class com.android.settings.bluetooth.LocalBluetoothManager, but it gave me the ClassNotFound exception, any thought?
    Here’s the code,
    localBluetoothManager = Class.forName(“com.android.settings.bluetooth.LocalBluetoothManager”);
    Constructor ctor = localBluetoothManager.getDeclaredConstructor(Context.class);
    ctor.setAccessible(true);
    Object clip = ctor.newInstance(context);
    Method setForegroundActivityMethod = clip.getClass().getMethod(“setForegroundActivity”);
    setForegroundActivityMethod.invoke(context.getApplicationContext());

    BTW, I’m using 2.2, the device has been rooted. I could invoke hidden method setSconMode from class “android.bluetooth.BluetoothAdapter” successfully usinig the same way, Actually I was trying to do automatic pairing of bluetooth in my project, which I know the pin code at the first place so I try to set the pin code and make the request pin code dialog dismiss to not involving any user interaction. Any idea I could do this right?

  6. Rudi
    July 5, 2011 at 16:42 | #11

    Hi, I get two errors creating a new project which uses the extended platform and can’t compile the project.
    [Framework Resource Parser] Collect permissions failed, class android.Manifest$permission not found in C:\Documents and Settings\User\Desktop\android-sdk-windows\platforms\android-10\android.jar
    [Android Framework Parser] failed to collect preference classes
    Does somebody has a solution for this?

    • July 5, 2011 at 16:43 | #12

      Upload your android.jar somewhere and post link here.

      • Rudi
        July 5, 2011 at 20:36 | #13

        I solved the problem using android.jar you created. I don’t know why my file didn’t work, but I probably made something wrong. Thanks for your great article.

      • Mr K.
        November 16, 2011 at 11:44 | #14

        Hi.
        I have the same problem as Rudi had. I wanted to unlock the hidden parts of the 2.3.6 build of Android for Samsung Nexus S. For getting the framework.jar i used an deodexed ROM downloaded somewhere from the net. I followed all the steps from the first three parts of Your tutorial. What is more, i downloaded Your custom SDK 10 platform, and my eclipse does not recognize it (it does not list it in available targets when creating a new project). Could You help me? Do you need me to upload my platform folder?

      • Dan
        November 20, 2012 at 02:09 | #15

        Hi inazaruk,

        I got the same error when I tried to make a platform-16-internals.

        Here is the link for my android.jar and build.prop
        https://www.box.com/shared/nc5vri22kyn94ba36wzo
        https://www.box.com/shared/f9gl0nil8hd0boupr74a

        Look forward to your reply.

        Thanks

  7. Shaffooo
    July 6, 2011 at 23:15 | #16

    Hi inazaruk,

    I did step 4 correct and I unzipped your zip file for API level 7 containing uncut android.jar to the androidSDK/platforms folder but when I start eclipse and create new project I cant see this option in new project GUI. Can you help me?

    Thanks.

    • Shaffooo
      July 6, 2011 at 23:18 | #17

      To be more precise, I cant see the Target Name : Android 2.1-internal and API Level 7. to select from build Target menu.

  8. Shaffooo
    July 7, 2011 at 16:17 | #18

    Ok My problem was that I updated the ADT earlier so I had two adt files named “com.android.ide.eclipse.adt_9.0.0.v201101191456-93220.jar” and “com.android.ide.eclipse.adt_11.0.0.v201105251008-128486.jar”. Previously I was modifying the com/android/internal in the corresponding file of both jars. When I modified it in the *_11.*, problem got fixed.

    Now workspace is loading correct BUT I still can’t use the hidden and internal APIs. I want to import “android.speech.srec” and “android.provider.Telephony”. I created new project and followed your steps but still no success. Please see the snapshots of relevant folders in the following URL: http://tinyurl.com/5wb3g4a. Any help would be appreciated.

  9. A_C
    July 30, 2011 at 02:32 | #19

    @inazaruk
    Thanks for the article. It really save a lot of works. But could you upload those custom platform files to other free hosting sites? My country ip cannot download anything from megaupload. Thanks.

  10. August 30, 2011 at 11:17 | #21

    Great job! Thanks a lot.

  11. September 23, 2011 at 06:07 | #22

    Hi inazaruk!

    Thanks for your awesome tutorials! It saved my time.
    But i have a problem when try to make new class extends an internal android service. My code is very simple:

    public class myPhoneInterfaceManager extends ITelephony.Stub {


    }

    Eclipse show an error notification as “No enclosing instance of type ITelephony is available due to some intermediate constructor invocation”

    Can you show me some way to fix that!

    Thanks and Regards!

  12. November 30, 2011 at 21:41 | #23

    If I copy your file over (API 10) I also cant see it in Eclipse. Am I missing something? :(

  13. Chris Cross
    December 1, 2011 at 15:20 | #24

    Wish this technique worked with Android 4 but it doesnt as far as I can tell.
    Any chance you could upload an android.jar for that platform (and let us know how you did it?)

  14. dar
    December 26, 2011 at 22:59 | #25

    First , That is awesome !
    Do you know any changes of IActivityWatcher class between api 6 to api 10 , cuz i want to use this class in my application that supports Android 2.1.x to Android 2.3.4 ?

  15. Walter
    December 29, 2011 at 20:46 | #26

    !!WARNING!! Before you go to the effort of writing an app that needs ITelephony (as I did), be advised that it will not work for Android versions 2.3 and newer. Google has blocked permission MODIFY_PHONE_STATE on these versions. My app works on 2.2 but gets the following warning message on 2.3 and 4.0: W/System.err(362): java.lang.SecurityException:
    Neither user 10034 nor current process has android.permission.MODIFY_PHONE_STATE.

    To confirm this either do a Google search on: ‘Android MODIFY_PHONE_STATE’ or look at:
    http://stackoverflow.com/questions/4715250/how-to-grant-modify-phone-state-permission-for-apps-ran-on-gingerbread

    Or look at open issue:
    http://code.google.com/p/android/issues/detail?id=15031
    There are over 400 complaints listed there…

  16. paul
    December 31, 2011 at 12:41 | #27

    Thanks for this. Everything works also great with the Android 4.0 framework. I’ve encountered only one (but serious) problem. Class constants or inherited constants may have a different value than expected. For example the constant ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED has a totally different value than the originally declared constant value. I had to replace this reference with the actual hard coded value.

    Anyone having the same problem? Notice that everything compiles well, but you may encounter unexpected problems because some constants just don’t match if you use them in your program.

    • paul
      December 31, 2011 at 13:01 | #28

      Lol … fixed 15 minutes after writing this post. I struggled with it for days :)
      It seems that dex2jar tool on a mac produces this problem. I used the tool on a windows box to build up the internal class library again and all problems are gone.

      So, be careful when using the dex2jar port on a mac. (better yet, don’t use it )

  17. Jason
    January 25, 2012 at 05:12 | #29

    Hi,

    can you upload it to another site? the one provided above are all blocked/shut down.

    Thanks in advance.

    • February 6, 2012 at 02:43 | #30

      I’ve updated the post with new links to github.

  18. Jason
    January 25, 2012 at 16:30 | #31

    I’m working with the NfcAdapter and trying to call enable and disable. I finally got the package to build and the code recognizes these hidden functions. But when I go and execute the code on the device it gives me the ” WRITE_SECURE_SETTINGS permission” error.

    Does anyone know how to get around this?

    • February 6, 2012 at 02:43 | #32

      That must be a system application to have WRITE_SECURE_SETTINGS permissions granted. This is usually impossible for real-life devices. Remember, that having access to some internal classes does not grant you permissions to some security critical functionality.

  19. January 28, 2012 at 14:03 | #33

    hi,
    thank you for this awoseme post but megaupload is down . could you upload it another site ? pls.

  20. Akshat
    February 21, 2012 at 07:20 | #35

    Thank you for sharing,
    Can I do the same for android 3.2 ?

  21. Dominik Maier
    March 1, 2012 at 17:33 | #36

    THANK YOU SO MUCH!
    Thanks to this it is possible to using the WebView with private key and ssl…

    by overriding the private API:

    public void onReceivedClientCertRequest(WebView view,
    ClientCertRequestHandler handler, String host_and_port) {

    in WebViewClient.
    I almost gave up…

  22. Ahmad Hasan
    May 24, 2012 at 20:30 | #37

    Thanks for your all efforts,
    Could u help me, How I can get an instance of Phone using PhoneFactory class
    I tried
    import com.android.internal.telephony.Phone;
    import com.android.internal.telephony.PhoneFactory;
    …………
    Phone mPhone;
    if(mPhone==null){
    PhoneFactory.makeDefaultPhones(this);
    mPhone = PhoneFactory.getDefaultPhone();
    }
    but I have exceptions and I can’t get Phone instance.

  23. Jack Copac
    June 14, 2012 at 05:18 | #38

    Thanks for your good work. This method make things way easier than reflection.
    Now I’ve got a bit of a strange problem: I’m trying to use com.android.internal.os.BatteryStatsImpl which extends android.os.BatteryStats, an abstract class. While most of the methods I used seem to work, when I do a call getUidStats() on a BatteryStatsImpl object compilation fails with the error: “The type BatteryStats cannot be resolved. It is indirectly referenced from required .class files”. This error is usually generated when the compiler cannot find the library containing the respective class, but in this case i can see both the BatteryStatsImpl.class and getUidStats() method inside it when i looked at the android.jar file. And as expected BatteryStats does not exist as it is an abstract class and only it’s non-abstract extension are added to the jar. Anyone has any clue about what’s going on here?

  24. August 18, 2012 at 20:01 | #39

    I don’t have a SDK 16 Jellybean device, and emulator framework.jar doesn thave classes.dex. Can someone make it for me?

  25. Vijay Arora
    August 24, 2012 at 14:25 | #40

    Hello inazaruk

    Thanks for your wonderful posting. It helps us a lot.

    But we are facing few issues:
    1) I have followed steps for Custom Android Framework but our device framework is not having all the files in it. Even after following exact steps, it is not showing custom version in project active android packages.

    2) Then I download internal android – 8 version it successfully shows us internal version in active android packages but then it is showing “[Framework Resource Parser] Collect preferences failed” which was also faced by others in this blog.

    3) I also tried to change BytesCode with notepad++ but that also not work and it crashes android.

    I need this for internal files for one of app for battery consumption by apps. It will be great if you provide me complete project setup with internal package setting.

    I really appreciate your help.

    Thanks
    Vijay

  26. Vijay
    August 25, 2012 at 15:37 | #41

    Can anyone help how can I edit art file as last step for use on internal API. I have used Notepad++, other editors also but every time it shows error when I replaced edited file. Can anyone help. Even without change , if we save that file in any of these editors Code doesn’t work, please help this is urgent!

  27. September 3, 2012 at 21:23 | #42

    love this man! I tried the tutorial and tried to create my own android.jar for API 15 and 16, but I got the infamous “Collect permissions failed” error. So I thought I would just download your jars and build.prop files and start from there, but these don’t show up in Eclipse, where my own version did, but threw errors in Eclipse…odd.

    Do you have any ideas? :)

  28. Raja
    September 7, 2012 at 15:02 | #43

    Good Article, Appreciate your work..

  29. September 8, 2012 at 12:35 | #44

    fixed it…forgot to copy the resources and other files, silly me.
    I have another question though: any idea why using the hidden methods only seems to work in .class files and not in .xml files? Trying to access hidden Android dimension attributes for an example will still not work…odd

    • September 8, 2012 at 12:39 | #45

      I wouldn’t expect resources to work. There is only a list of public resources available in customized androis.jar files. And even if someone builds android.jar with private resources made public, there is no guarantee that ids for those resources will be the same as in runtime on different devices. And since different vendors tend to customize Android, there is a much greater possibility in breaking resource ids than private APIs (this is what I would expect, but I haven’t verified this myself).

  30. September 8, 2012 at 18:07 | #46

    well, if I try to view the xml file, dimens.xml in res/values of platform, there’s no difference between the other items. I need ?android:dimen/preference_item_padding_side, which should have been a public resource anyway, and I guess I’ll take my chances when it comes to this resource (padding is different between API 15 and 16, and might even change in future versions of the API). Google limits a bit to much imo

  31. September 15, 2012 at 13:16 | #48

    Can you upload a modified API Level 16 platform?

    Using 15 version to compile JB browser many errors are gone away but some hidden class still remain:

    The import com.android.common cannot be resolved
    The import android.webkit.WebSettingsClassic cannot be resolved

    • Renaud
      October 8, 2012 at 17:40 | #49

      Up! I’d love to have API 16 =)

    • June 13, 2013 at 07:57 | #50

      Hi, have you managed to fix this ?
      I’m trying to compile the AOSP browser with AP Level 17 and facing the same errors now.

      It seems it’s missing extra static libraries like: com.android.common

      I’ve followed all the steps here (+ deodexing the framework.jar to get the classes.dex) and it seems to work. But there seem to be other dependencies.
      Does anyone know if it’s possible to get them somehow without building the entire code ?

  32. Nik
    September 26, 2012 at 13:46 | #51

    Hi Inazaruk! Great tuttorial. But I have a problem with my current project. I downloaded android.jar for v10 platform from the git. Edited adt plugin to allow using internal classes. It seems work ok, but… Here is one problem string from my project that throws error:
    WindowManager.LayoutParams params=new WindowManager.LayoutParams();
    The error is: “No enclosing instance of type WindowManager is accessible. Must qualify the allocation with an enclosing instance of type WindowManager (e.g. x.new A() where x is an instance of WindowManager)”
    It seems that i’m trying to instantiate inner non-static class from static place, but LayoutParams is a static inner class. And the project works fine with original android.jar.
    Can anybody help me with this?

  33. Nik
    September 26, 2012 at 16:26 | #52

    upd:
    So I replace v10 framework to v15 (from git) and now all works fine.

  34. Fuad Ahmed Hasni
    December 13, 2012 at 12:54 | #53

    You are a champ man, definitely saved my time and frustration i had to overcome while doing this :)

    Thanks alot.

  35. Paul
    January 23, 2013 at 18:15 | #54

    Well done Inazaruk!

    It works like a charm. Just made a new version for API-16 without any major problems. I have followed all 5 parts of this tutorial succesfuly. I have a few minor remarks at part 2 which I post at that part.

    @all: When you read carefull and follow instructions exactly, you will succeed as well.

  36. King Wu
    February 20, 2013 at 05:53 | #55

    Inazaruk! Awesome works! Thanks a lot.

  37. Plinio Santos
    February 28, 2013 at 17:01 | #56

    Hi Inazaruk,

    First of all, thanks for this amazing post!
    After follow your steps, I’m able to use hidden and internal APIs. Actually I’m able to use not only the APIs within framework.jar but also that ones present in android.policy.jar, servers.jar and so on.
    Unfortunately I use to compile my android apps using Ubuntu+Ant. In my opinion, as ant uses the same SDK than eclipse, it should see that hidden and internal APIs. But I can’t compile my app using ant though.
    Do you have any tips regarding it?
    The error output is:

    error: cannot find symbol

  38. Fred F.
    March 8, 2013 at 08:11 | #57

    In android-15 the permission error has changed

    03-08 00:11:00.622 3412 3412 W System.err: java.lang.SecurityException: WifiService: Neither user 10080 nor current process has android.permission.ACCESS_WIFI_STATE.

  39. June 28, 2013 at 21:41 | #58

    Thanks for this post… It has been very helpful.. However, I have the latest ADT and I cannot get the .extended to show in the Android Properties. I think they are there but I don’t see them. Also, I need the ClientCertRequestHandler, but it does not show up.

    • June 28, 2013 at 23:06 | #59

      Found problem… My metadata file in my workspace was looking in the wrong location. I had to update my adt and put it in another location… but the adt did not update the .metadata in the workspace.

  40. Hadongtung
    July 16, 2013 at 13:25 | #60

    Hi Admin, Thank alot for your post. But in my case, i must call to class android.net.ethernet.EthernetManager for manage ethernet connection (it’s not exist in defaut android SDK – android defaut only support wifi, not ethernet). So i must get framework.jar in my android device (Android TV box) to build my self custom android.jar . But when we found /system/framework/framework.jar, size of it is 15kb, and framework.odex is 10mB.
    When i extract framework.jar, i not found framework.dex. And i can’t explain why.
    Can you help me to resolve my problem . Thank you very much!

  41. August 18, 2013 at 01:21 | #61

    Excellent…I have not tried it though. I had similar stuff in Windows world long time back. On windows phone using hidden api to transfer bluetooth files. Great..Will certainly try to use it.

  1. March 6, 2013 at 13:30 | #1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 34 other followers