Як створити Android SDK із доступними прихованими та внутрішніми API?


86

Я хочу відновити Android SDK (вірніше, лише android.jar), щоб включити приховані та внутрішні API.

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

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

Що я хочу зробити, це внести зміни до програми, яка використовує прихований API, і для її відновлення я хотів би використовувати змінений SDK.


2
@Hidden просто приховує javadoc, усі ці методи все ще доступні
Blundell

12
@hide видаляє їх із файлів класу.
Thomas Hofmann


Я знаю, що я міг би використовувати рефлексію, але я хочу змінити існуючу програму, яка використовує прихований API без посилання, і я не хочу змінювати весь існуючий код для використання рефекції.
Thomas Hofmann,

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

Відповіді:


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

Це спрацювало і у мене! тепер я можу
приступити

ІМХО, це найпростіше і найшвидше.
Patrick Cho

Чи немає способу позначити це як правильну відповідь?
Chris Browet

2
чи працює цей метод з усіма пристроями, чи працює лише з цільовим пристроєм?
Hải Phong

Щоб визначити порядок бібліотеки в андроїд-студії, вам потрібно змінити .imlфайл модуля та перенести потрібні бібліотеки <orderEntry>перед Android SDK . На жаль, цей прийом не зберігається, оскільки файл буде перезаписаний після натискання кнопки градації-синхронізації.
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 , тобто доповнення, які ви можете знайти в менеджері SDK для Android від постачальників, наприклад, Samsung надає вам додатковий API для речей, специфічних для телефонів Samsung. mkstubsробить майже те саме, що процес генерації заглушок DroidDoc, однак він не використовує @hideанотації, він використовує .defsфайл, що описує, які пакети / класи / поля включати або виключати з вашого аддону SDK.

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


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

На жаль, я не в цьому, але теж мені здається, все залежить від змінної, яка називається hide. Я не знайшов, якщо він отримує набір, хоча. Якщо ви шукаєте $ (сховати) в інших файлах збірки, ви побачите, що багато залежить від цього значення. Здається, це також впливає на спосіб побудови C-ліб.
Томас Хофманн,

@ThomasHofmann: Я спочатку також заплутався в інструменті mkstubs. Я дізнався, що mkstubs звикає лише тоді, коли ви створюєте аддон (постачальника) sdk, а не коли ви просто створюєте звичайний sdk. Однак mkstubs робить майже те саме, що і DroidDoc, за винятком того, що він не використовує @hideанотації, він "просто" використовує .defsфайл, що описує, які пакети / класи / поля повинні бути включені в API аддона.
Bjarke Freund-Hansen

2
@ThomasHofmann: Про те $(hide), ти заплутаєш себе. $(hide)це просто префікс у make-файлах, щоб приховати фактичний командний рядок виконуваної програми, не більше того, і він використовується майже скрізь скрізь. Це не має нічого спільного з Android SDK або @hideанотацією у вихідному коді.
Bjarke Freund-Hansen

як я можу перевірити цей вище шлях out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

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.

Ми могли б перетворити ці форматовані у форматі DEX * .jars у справжні 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 7 Java. (Створений APK, наскільки я бачу, не містить жодного фактичного коду з JAR-файлів.)


Щиро дякую, я спробував безліч способів, щоб тільки ваші методи працювали для мене.
SalutonMondo

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

не вдалося знайти core.jar у зефірі
mehmet6parmak

чи маєте ви ідею про jar & framework jar в android p?
Прабхакаран,

як я можу перевірити цей вище шлях out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

17

Для льодяника потік мало відрізняється:

  1. Завантажте /system/framework/arm/boot.oat із пристрою льодяник

  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
див. розділ "випуски"
девіант

2
Отже, схоже, останні версії dex2jar змінили формат завантаження. Просто розпакуйте завантаження і замість 'java -jar ...' просто запустіть скрипт 'd2j-dex2jar.sh' або 'd2j-dex2jar.bat', залежно від вашої платформи, безпосередньо у файлі framework.dex
CalumMcCall

1
я скопіював обидва jar-файли в android.jar, тепер андроїд-студія повідомляє мені про помилку: Помилка виконання для завдання ': 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

16

Ви можете завантажити змінене android.jarдля використання як прихований API з цього сховища . Дотримуйтесь інструкцій там.


4
Цю відповідь слід голосувати більше, оскільки вона є найпростішим рішенням. Люди, якщо ви шукаєте рішення - знайте, що це вже робили інші люди і розміщували рішення для цього репозиторію github. Використовуйте його і насолоджуйтесь! ))
Mixaz

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 (Здається, посилання Hmm не працює).

Перейдіть на веб-сторінку 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) Видаліть контейнер Androidpathpath із шляху збірки. 3) Визначте бібліотеку користувача (також поставте прапорець біля системної бібліотеки), що включає файли JAR із збірки ASOP ROM, наприклад cm7). Які файли JAR ви використовуєте, залежить від того, на що вам потрібно посилатися. framework-neposredtes, ймовірно, буде його частиною.
Thomas Hofmann

4) Коли проект вже побудований, класи бібліотеки користувачів не будуть включені до створюваного файлу .apk. Прихований API видно, і все буде скомпільовано чудово.
Thomas Hofmann

@Blundell: Чи можете ви оновити посилання .. вони мертві!
зомбі

12

Спробуйте поглянути на це :

Кінцева мета цих статей - надати розробникам потужність внутрішніх та прихованих API без використання роздумів. Якщо ви виконаєте всі кроки, описані в наступних кількох частинах, ви зможете використовувати Внутрішній та Прихований API, як якщо б вони були загальнодоступними відкритими API. Не буде потреби в роздумах.

Але якщо ви використовуєте ці загальнодоступні API, ви повинні знати, що ваша програма піддається великому ризику. В основному немає гарантій, що API не буде порушено при наступному оновленні ОС Android. Навіть немає гарантій щодо послідовної поведінки різних пристроїв від різних постачальників. Ви повністю самі по собі.

Є три сценарії, якими ви можете дотримуватися:

  1. Увімкнути як внутрішні, так і приховані API (сценарій A)
  2. Увімкнути лише прихований API (сценарій B)
  3. Увімкнути лише внутрішній API (сценарій C)

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

Сценарій А : прочитати частини 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
Наведені посилання недоступні, потрібен дозвіл автора
SHAHS

як я можу перевірити цей вище шлях out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

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
Bunny

Я заархівував це репо, оскільки воно було востаннє оновлене для пряників . Вам доведеться знайти інший підхід на жаль.
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, щоб отримати фреймворк jar ... я справді застряг .. Я не можу знайти цей шлях або чогось не вистачає ... прошу поводити
Зайчик

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
Bunny
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.