Как мне собрать Android SDK с доступными скрытыми и внутренними API?


86

Я хочу перестроить Android SDK (или, скорее, только android.jar), чтобы включить скрытые и внутренние API.

Я не смог найти никакой документации или обсуждения того, как это сделать. У меня уже настроена среда сборки Ubuntu CyanogenMod, которая может создавать cm7.

Теперь я прочитал, что make SDK создаст SDK, но я хочу создать SDK, который включает методы и поля, которые помечены как скрытые с помощью @hide. Это возможно?

Я хочу внести изменения в приложение, использующее скрытый API, и для его перестройки я хотел бы использовать модифицированный SDK.


2
@Hidden просто скрывает javadoc, все эти методы по-прежнему доступны
Бланделл

12
@hide удаляет их из файлов классов.
Thomas Hofmann


Я знаю, что могу использовать отражение, но я хочу изменить существующее приложение, которое использует скрытый API без отражения, и я не хочу изменять весь существующий код для использования отражения.
Томас Хофманн

4
Я думаю, вы можете удалить @Hiddenярлык API, к которому хотите получить доступ, затем выполнить make update-apiи make SDKсоздать свой собственный SDK.
dreamtale

Ответы:


69

Я всегда делаю это, чтобы использовать скрытый API.

  1. Создайте репо или загрузите банки с https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
  2. скопируйте out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar (лучше переименовать его как-то вроде framework_all.jar)
  3. сконфигурируйте путь сборки вашего проекта -> библиотеки -> добавьте эти внешние банки. В разделе «Порядок и экспорт» переместите его вверх до android.jar.

У меня это тоже сработало! теперь я могу приступить к
делу

ИМХО, это самый простой и быстрый.
Патрик Чо

Разве нет способа отметить это как правильный ответ?
Chris Browet

2
работает ли этот метод со всеми устройствами или только с целевым устройством?
Hải Phong

Чтобы определить порядок библиотек в студии Android, вам необходимо изменить .imlфайл модуля и перенести желаемую библиотеку <orderEntry>до Android SDK . К сожалению, этот метод не является постоянным, так как файл будет перезаписан после нажатия кнопки gradle-sync.
waqaslam

44

Я провел некоторое расследование по этому поводу, и мой вывод простой: это невозможно сделать без небольшой работы. Прочтите оставшуюся часть этого ответа, чтобы узнать о том, что я нашел.


android.jarфактически состоит из «общедоступного API» framework.jarи core.jarнаходится system/frameworks/на устройстве. android.jar- это своего рода то, что я бы назвал заголовком библиотеки Java, вся реализация в фактическом байтовом коде - это просто a throw new RuntimeException("stub");, это позволяет вам строить android.jar(например, в Eclipse), но выполнение должно выполняться на устройстве или эмуляторе.

Общедоступный API Android SDK определяется классами / методами / полями, которые не имеют префикса @{hide}аннотации javadoc. Т.е. все, что не аннотировано, входит в SDK.

android.jarстроится из источников, в out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediatesкоторых сам генерируется инструментом DroidDoc, находящимся в build/tools/droiddoc.

DroidDoc - это инструмент (возможно, адаптированный из javadoc или использующий javadoc), который генерирует фактическую документацию Android SDK. В качестве побочного эффекта и, вероятно, из-за того, что он уже анализирует всю javadoc, он также извергает заглушки Android, которые затем компилируются вandroid.jar который распространяется в SDK.

Итак, чтобы включить то, что скрыто, вы можете, если вы хотите включить только определенные части, просто удалите @hideаннотацию и перестройте SDK.

Однако, если вы хотите включить все скрытые части, все становится намного сложнее. Вы можете изменить DroidDoc (соответствующий источник находится внутри build/tools/droiddoc/src/Stubs.java), чтобы ничего не обнаруживалось как скрытое. Это довольно тривиально, и я пробовал это, однако генерируемые затем заглушки вообще не компилируются.

На данный момент я пришел к выводу, что это просто невозможно. Заглушки, сгенерированные, если вы удалите часть DroidDoc, которая обнаруживает скрытые аннотации, просто не компилируются, и для правильной компиляции потребуется довольно много работы.

Итак, мой ответ на ваши вопросы: нет, это невозможно сделать, не проделав большой работы. Сожалею.


Замечание об mkstubsинструменте. mkstubsиспользуются при создании надстройки SDK , то есть надстройки, которые вы можете найти в диспетчере Android SDK от поставщиков, например, Samsung предоставляет вам дополнительный API для вещей, специфичных для телефонов Samsung. mkstubsвыполняет во многом то же самое, что и процесс создания заглушек DroidDoc, однако он не использует @hideаннотации, он использует .defsфайл, описывающий, какие пакеты / классы / поля включить или исключить из вашего аддона SDK.

Однако все это не имеет отношения к вопросу, поскольку сборка Android SDK не использует этот mkstubsинструмент. (К сожалению.)


Я тоже посмотрел. Помимо Droiddoc, в / development / tools / mkstubs есть инструмент mkstubs. Он вызывается во время сборки, и, насколько я видел, он изменяет файлы классов, заменяя их заглушками. В build / core / tasks / sdk-addon.mk есть следующий код: define stub-addon-jar $ (вызов stub-addon-jar-file, $ (1)): $ (1) | mkstubs $ (info Заглушка аддона jar с помощью $ (PRODUCT_SDK_ADDON_STUB_DEFS)) $ (hide) java -jar $ (вызов установленных-файлов модуля, mkstubs) $ (if $ (hide) ,, - v) \ "$$ <" "$$ @" @ $ (PRODUCT_SDK_ADDON_STUB_DEFS) endef
Томас Хофманн,

К сожалению, я не в этом разбираюсь, но мне тоже кажется, что все зависит от переменной hide. Я не нашел, хотя он был настроен. Если вы выполните поиск $ (hide) в других файлах сборки, вы увидите, что от этого значения многое зависит. Похоже, это также влияет на способ построения библиотек C.
Thomas Hofmann

@ThomasHofmann: Поначалу меня тоже смутил инструмент mkstubs. Я узнал, что mkstubs используется только при создании надстройки sdk (поставщика), а не когда вы просто создаете обычный sdk. Однако mkstubs делает то же самое, что и DroidDoc, за исключением того, что он не использует @hideаннотации, он «просто» использует .defsфайл, описывающий, какие пакеты / классы / поля должны быть включены в API аддона.
Бьярке Фройнд-Хансен,

2
@ThomasHofmann: О $(hide), ты сбиваешься с толку. $(hide)это просто префикс в make-файлах, чтобы скрыть фактическую командную строку выполняемой программы, не более того, и он используется практически везде. Это не имеет никакого отношения к Android SDK или @hideаннотации в исходном коде.
Бьярке Фройнд-Хансен,

как я могу проверить этот путь из / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Банни

31

Мы могли восстановить файлы * .jar с платформы Android.

Сначала подключите ADB к вашему устройству. Затем запустите:

adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .

Они core.jarсодержат стандартные библиотеки Java ( java.*) и framework.jarсодержат библиотеки Android ( android.*). Это пока не может быть использовано, поскольку фактические файлы находятся в формате DEX, а не в формате JAR.

Мы могли бы преобразовать эти * .jar-файлы в формате DEX в настоящие JAR-файлы с помощью таких инструментов, как dex2jar :

dex2jar core.jar
dex2jar framework.jar

Затем вставьте эти банки, используя «Добавить внешние JAR-файлы ...» (при условии, что вы используете Eclipse ADT).

  • щелкните правой кнопкой мыши на Project → Properties → Java Build Path → Libraries → Add External JARs... → (Выберите core-dex2jar.jarи framework-dex2jar.jarсверху).

Это позволит вам использовать внутренний API и некоторые API Java 7. (Сгенерированный APK, насколько я понимаю, не содержит фактического кода из JAR.)


Большое вам спасибо, я перепробовал много-много способов, которыми у меня работают только ваши методы.
SalutonMondo 08

7
Важно отметить, что этот метод по-прежнему работает с системами ICS и более поздними версиями, но требует дополнительных действий. Соответствующие файлы /system/framework/core.odex, /system/framework/framework.odexи , вероятно , больше. Их можно deodexed ( java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core) и reodexed ( java -jar smali-2.0.3.jar -x -o core.dex core), и только после этого dex2jar core.dexони выполнят свою работу.
Alex Cohn

невозможно найти core.jar в marshmallow
mehmet6parmak

у вас есть идеи для ядра и фреймворка в android p?
Прабхакаран

как я могу проверить этот путь из / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Банни

17

Для Lollipop поток немного отличается:

  1. Получите /system/framework/arm/boot.oat с устройства Lollipop

  2. Используйте 'java -jar oat2dex.jar boot boot.oat'

  3. Вы получите две папки: dex и odex. Перейдите в dex и сделайте java -jar dex2jar.jar framework.dex
  4. Переименуйте полученный framework.jar в .zip, извлеките и найдите нужные классы
  5. Перейдите в [sdk_path] / platform / [target_platform] и извлеките android.jar (сначала переименуйте его в zip).
  6. Скопируйте файлы из извлеченного фреймворка в извлеченный файл android.jar. Затем сожмите в zip и переименуйте в .jar :)

ps: возможно, вам нужно повторить шаги 4-6 для 'framework_classes2.dex'


Для шага 3 я не могу найти dex2jar.jar по этой ссылке .... Я много чего перепробовал и не могу понять. Есть где-нибудь ссылка на это? Он находится в моем Android SDK? Я не могу его найти.
Dwebtron

Да, это идет в проект на github, и, возможно, это я, но я не могу найти там ЛЮБОЙ файл, заканчивающийся на ".jar" ...
Dwebtron

1
см. раздел «релизы»
Deviant

2
Похоже, что последние версии dex2jar изменили формат загрузки. Просто разархивируйте загрузку и вместо java -jar ... просто запустите сценарий d2j-dex2jar.sh или d2j-dex2jar.bat, в зависимости от вашей платформы, непосредственно в файле framework.dex
CalumMcCall

1
Я скопировал оба jar-файла в android.jar, теперь студия Android сообщает мне об ошибке: сбой выполнения для задачи ': app: processDebugResources'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: команда процесса 'D: \ Program \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe' 'закончился с ненулевым значением выхода 1
wutzebaer 05

16

Вы можете загрузить измененные android.jarAPI для использования в качестве скрытых API из этого репозитория . Следуйте инструкциям там.


4
За этот ответ следует проголосовать больше, так как это самое простое решение. Люди, если вы ищете решение - знайте, что другие люди уже сделали это и разместили решение в этом репозитории github. Используйте и наслаждайтесь! ))
Mixaz 06

1
При использовании android.jar для API 28 я получаю сообщение об ошибке robolectric. Поднят вопрос github.com/anggrayudi/android-hidden-api/issues/62 и благодарим вас за банку @Anggrayudi
Прабхакаран

Я также сделал то же самое для Android 10, это не работает для меня, скорее я загрузил его у другого участника github.com/aeab13/android-jar-with-hidden-api . мне удалось получить доступ к классу hdmi-cec и построить его, но коды все еще сбивают с толку .code link android.googlesource.com/platform/frameworks/base/+/4e90fcd/…
babbin tandukar

15

DroidCon 2011

Здесь Эрик Хеллман из Sony Ericson объясняет, как получить доступ к скрытым API Android:

http://vimeo.com/30180393 (хм, ссылка не работает).

Перейти на веб-страницу DroidCon. День 2, прокрутите вниз до Использование скрытого API , 10:15 и вы можете посмотреть его там.

Ссылки умирают!

Я нашел вот это: http://skillsmatter.com/podcast/os-mobile-server/hidden-api не знаю, как долго он будет работать

Официальных API в Android SDK обычно достаточно для большинства обычных приложений. Однако иногда возникают ситуации, когда разработчику требуется доступ к внутренним системным службам, API и ресурсам, которые не опубликованы в официальных API. К счастью, эти API-интерфейсы по-прежнему доступны с помощью некоторых хитрых уловок и часто могут быть полезны при разработке новых и инновационных решений на базе Android. В этом сеансе вы узнаете, как получить доступ и использовать эти скрытые и защищенные API-интерфейсы, ограничения на их использование и некоторые советы по их безопасному и контролируемому использованию на устройствах разных производителей и в версиях Android. Зрители увидят несколько продвинутых демонстраций, которые обычно не подходят для Android. Ожидайте довольно продвинутого сеанса с большим количеством идей о внутреннем устройстве платформы Android.


1
Это интересно, но, к сожалению, не отвечает на мой вопрос. Я просил найти способ действительно перестроить SDK со скрытыми вещами.
Thomas Hofmann

Похоже, я нашел другой способ добиться того, чего хочу. Опишу завтра.
Thomas Hofmann

Я обнаружил, что если вы хотите скомпилировать исходный код проекта, который использует скрытый API в ADT, вы можете сделать следующее: 1) Создать проект Android для источника. 2) Удалите контейнер пути к классам Android из пути сборки. 3) Определите пользовательскую библиотеку (также отметьте флажок системной библиотеки), которая включает файлы JAR из сборки ASOP ROM, например cm7). Какие файлы JAR вы используете, зависит от того, на что вам нужно ссылаться. framework -mediates, вероятно, будет его частью.
Томас Хофманн

4) Когда проект будет построен, классы пользовательской библиотеки не будут включены в создаваемый APK. Скрытый API виден, и все будет хорошо скомпилировано.
Томас Хофманн

@Blundell: Не могли бы вы обновить ссылки .. они мертвы!
zombie

12

Попробуйте посмотреть на это :

Конечная цель этих статей - дать разработчикам возможность использовать внутренние и скрытые API без использования рефлексии. Если вы выполните все шаги, описанные в следующих нескольких частях, вы сможете использовать внутренние и скрытые API, как если бы они были общедоступными открытыми API. В размышлениях не будет необходимости.

Но если вы используете эти закрытые API, вы должны знать, что ваше приложение подвергается большому риску. По сути, нет никаких гарантий, что API не будут повреждены при следующем обновлении ОС Android. Нет даже никаких гарантий относительно единообразного поведения устройств от разных производителей. Вы полностью сами по себе.

Есть три сценария, по которым вы можете следовать:

  1. Включите как внутренние, так и скрытые API (сценарий A)
  2. Включить только скрытый API (сценарий B)
  3. Включить только внутренний API (сценарий C)

Сценарий A представляет собой сумму B и C. Сценарий B - самый простой (не требует модификаций плагина eclipse ADT).

Сценарий A : прочтите части 1 , 2 , 3 , 4 , 5

Сценарий B : прочтите части 1 , 2 , 3 , 5

Сценарий C : прочтите части 1 , 2 , 3 , 4 , 5


3
Я уже читал эту запись в блоге. В нем упоминается следующее: «1) Android - это проект с открытым исходным кодом. Мы можем загрузить исходный код и настроить систему сборки, чтобы она не исключала внутренние и скрытые классы из android.jar. Это трудный путь». К сожалению, подробностей здесь не приводится.
Thomas Hofmann

3
Перейдите к последней части сообщения в блоге ( devmaze.wordpress.com/2011/01/19/… ), там есть ссылка ( github.com/inazaruk/android-sdk/tree/master/platforms ) на предварительно созданный Android API со всеми скрытыми и внутренними API.
Боб

1
Данные ссылки недоступны, требуется разрешение автора
ШАХС

как я могу проверить этот путь из / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Банни

1

Однажды я написал несколько сценариев Groovy для извлечения файлов java из проверки репо с http://source.android.com/, а затем их компиляции без необходимости в полной цепочке инструментов для компиляции всех источников Android, включая необходимые другие шаги ( упаковка, создание ресурсов и т. д.).

Их можно найти здесь:

https://github.com/thoutbeckers/CollectAndroid

Но наверняка это потребует обновления для чего-либо после Gingerbread, в основном путем установки правильных каталогов в "rootdirs" в файле конфигурации (CollectConfig.groovy).

В то время я регулярно использовал это для разработки со всеми доступными скрытыми API и источниками (также проблемными в то время).

Как упоминалось в другом месте, com / android / internal / ** по-прежнему будет скрыт в последних версиях ADT из-за добавленного правила доступа.


как я могу проверить этот путь из / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Банни

Я заархивировал это репо с момента последнего обновления для Gingerbread . К сожалению, вам придется найти другой подход.
thoutbeckers

1

Длинный ответ сработал для меня, но мне все еще не хватало некоторых необходимых мне классов, в частности android.provider.Telephony. Я смог добавить это так:

  1. Распакуйте файл framework.jar

    mkdir /tmp/framework
    cp framework.jar /tmp
    cd /tmp/framework
    jar xvf ../framework.jar
    mv android classes
    
  2. Создайте репозиторий Android, который создаст каталог out / target / common / obj / JAVA_LIBRARIES.

  3. Найдите недостающие классы

    $ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
    $ find . | grep "/Telephony.class"
    ./telephony-common_intermediates/classes/android/provider/Telephony.class
    ./android_stubs_current_intermediates/classes/android/provider/Telephony.class
    
  4. Добавьте новые классы и перестройте JAR-файл фреймворка.

    cd /tmp/framework
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
    cd classes
    jar cvf ../framework.jar .
    

Или вы можете просто полениться и включить все классы в один гигантский файл jar:

cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .

out / target / common / obj / JAVA_LIBRARIES как найти этот путь?
Зайчик

@Bunny Я обновил свой ответ более подробной информацией. Но похоже, что ответ здесь может быть проще: stackoverflow.com/a/32626155/399105
bmaupin

спасибо за ответ @bmaupin .. не могли бы вы помочь мне, как я могу найти этот путь из / target / common / obj / JAVA_LIBRARIES, чтобы получить фреймворк ... я действительно застрял ... я не могу найти этот путь или что-то не хватает ... пожалуйста, гид
Банни,

0

Я не могу комментировать, но это в основном комментарий к отличному ответу @ KennyTM ( https://stackoverflow.com/a/13550030/2923406 ):

Если вы обнаружите в Eclipse следующую ошибку:

The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class   files

(то есть android.internal. * недоступен)

Тогда одно из возможных решений - применить тот же метод для /system/framework/framework2.jar. Используя эмулятор Android для SDK19, у меня есть дополнительная банка. На моем HTC One даже есть framework3.jar.


как я могу проверить этот путь из / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Банни
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.