Wie erstelle ich das Android SDK mit versteckten und internen APIs?

85

Ich möchte das Android SDK (oder besser nur die android.jar) neu erstellen, um versteckte und interne APIs einzuschließen.

Ich konnte keine Dokumentation oder Diskussion darüber finden, wie ich vorgehen sollte. Ich habe bereits eine Ubuntu CyanogenMod-Build-Umgebung eingerichtet, die cm7 erstellen kann.

Jetzt habe ich gelesen, dass make SDK das SDK erstellt, aber ich möchte ein SDK erstellen, das Methoden und Felder enthält, die mit @hide als ausgeblendet markiert sind. Ist das möglich?

Ich möchte Änderungen an einer Anwendung vornehmen, die eine versteckte API verwendet. Um sie neu zu erstellen, möchte ich das geänderte SDK verwenden.

Thomas Hofmann
quelle
2
@Hidden versteckt nur den Javadoc, alle diese Methoden sind noch verfügbar
Blundell
12
@hide entfernt sie aus den Klassendateien.
Thomas Hofmann
Ich weiß, dass ich Reflection verwenden könnte, aber ich möchte eine vorhandene Anwendung ändern, die eine versteckte API ohne Refelction verwendet, und ich möchte nicht den gesamten vorhandenen Code ändern, um Refelction zu verwenden.
Thomas Hofmann
4
Ich denke, Sie können die @HiddenBezeichnung der API entfernen, auf die Sie zugreifen möchten, dann ausführen make update-apiund make SDKIhr eigenes SDK erstellen.
Dreamtale

Antworten:

68

Dies ist, was ich immer tue, um versteckte API zu verwenden.

  1. Erstellen Sie das Repo oder laden Sie die Gläser von https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong herunter
  2. Kopieren Sie out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar (besser umbenennen in etwas wie framework_all.jar).
  3. Konfigurieren Sie Ihren Projekterstellungspfad -> Bibliotheken -> fügen Sie diese externen Jars hinzu. Verschieben Sie es in Order and Export nach oben und vor android.jar
Lange
quelle
Das hat auch bei mir funktioniert! Jetzt kann ich mit der eigentlichen Aufgabe
weitermachen
IMHO, das ist das einfachste und das schnellste.
Patrick Cho
Gibt es nicht eine Möglichkeit, dies als die richtige Antwort zu markieren?
Chris Browet
2
Funktioniert diese Methode mit allen Geräten oder nur mit dem Zielgerät?
Hải Phong
Um die Bibliotheksreihenfolge in Android Studio zu definieren, müssen Sie die .imlDatei des Moduls ändern und die gewünschten Bibliotheken <orderEntry>vor das Android SDK bringen . Leider ist diese Technik nicht dauerhaft, da die Datei überschrieben wird, sobald die Gradle-Sync-Taste gedrückt wird.
Waqaslam
42

Ich habe einige Nachforschungen angestellt, und meine Schlussfolgerung lautet einfach: Dies kann nicht ohne viel Arbeit geschehen. Lesen Sie den Rest dieser Antwort, um Einzelheiten zu dem zu erfahren, was ich gefunden habe.


android.jarbesteht eigentlich aus der "öffentlichen API" von framework.jarund core.jardie sich system/frameworks/auf dem Gerät befindet. android.jarist eine Art von dem, was ich als Java-Bibliotheksheader bezeichnen würde. Alle Implementierungen im eigentlichen Bytecode sind nur a throw new RuntimeException("stub");. Dies ermöglicht es Ihnen, dagegen zu bauen android.jar(z. B. in Eclipse), aber die Ausführung muss auf einem Gerät oder Emulator durchgeführt werden.

Die öffentliche API des Android SDK wird durch Klassen / Methoden / Felder definiert, denen die Javadoc-Annotation nicht vorangestellt ist @{hide}. Dh alles, was nicht kommentiert ist, ist im SDK enthalten.

android.jarwird aus den Quellen erstellt, in out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediatesdenen sich das Tool DroidDoc befindet build/tools/droiddoc.

DroidDoc ist das Tool (wahrscheinlich aus Javadoc angepasst oder mithilfe von Javadoc), das die eigentliche Android SDK-Dokumentation generiert. Als Nebeneffekt und wahrscheinlich, weil es bereits alle Javadoc analysiert, spuckt es auch die Android-Stubs aus, die dann in das kompiliert werdenandroid.jar im SDK verteilten .

Um das verborgene Material einzuschließen, können Sie, wenn Sie nur bestimmte Teile einschließen möchten, einfach das entfernen @hide Anmerkung und das SDK neu erstellen.

Wenn Sie jedoch alle versteckten Teile einbeziehen möchten, werden die Dinge viel komplizierter. Sie können DroidDoc ändern (die entsprechende Quelle befindet sich inbuild/tools/droiddoc/src/Stubs.java ) so dass nichts als versteckt erkannt wird. Dies ist ziemlich trivial und ich habe es versucht, aber die Stubs, die dann generiert werden, werden überhaupt nicht kompiliert.

Mein Fazit ist inzwischen, dass dies einfach nicht machbar ist. Die Stubs, die generiert werden, wenn Sie den Teil von DroidDoc entfernen, der versteckte Anmerkungen erkennt, sind einfach nicht kompilierbar und erfordern eine Menge Arbeit, um korrekt zu kompilieren.

Meine Antwort auf Ihre Fragen lautet also: Nein, dies kann nicht ohne viel Arbeit geschehen. Es tut uns leid.


Eine Randnotiz zum mkstubsTool. mkstubswerden verwendet, wenn Sie ein SDK-Addon erstellen , dh die Addons, die Sie im Android SDK-Manager von Anbietern finden, z. B. Samsung, das Ihnen eine zusätzliche API für Dinge bereitstellt, die für Samsung-Telefone spezifisch sind. mkstubsFunktioniert ähnlich wie beim Generieren von DroidDoc-Stubs, verwendet jedoch keine @hideAnmerkungen, sondern eine .defsDatei, die beschreibt, welche Pakete / Klassen / Felder in Ihr SDK-Addon aufgenommen oder aus diesem ausgeschlossen werden sollen.

Dies ist jedoch für die Frage irrelevant, da der Android SDK-Build das Tool nicht verwendet mkstubs. (Unglücklicherweise.)

Bjarke Freund-Hansen
quelle
Ich habe auch nachgesehen. Neben Droiddoc gibt es in / development / tools / mkstubs ein Tool namens mkstubs. Es wird während des Builds aufgerufen und wird, soweit ich gesehen habe, die Klassendateien ändern, die Inhalte aus ihnen entfernen. In build / core / task / sdk-addon.mk gibt es den folgenden Code: define stub-addon-jar $ (rufe stub-addon-jar-file auf, $ (1)): $ (1) | mkstubs $ (info Stubbing-Addon-Jar mit $ (PRODUCT_SDK_ADDON_STUB_DEFS)) $ (verstecken) java -jar $ (Modul-installierte-Dateien aufrufen, mkstubs) $ (wenn $ (verstecken) ,, - v) \ "$$ <" "$$ @" @ $ (PRODUCT_SDK_ADDON_STUB_DEFS) endef
Thomas Hofmann
Leider mag ich dieses Zeug nicht, aber auch ich, es sieht so aus, als ob alles von einer Variablen namens hide abhängt. Ich habe nicht gefunden, wo es eingestellt wird. Wenn Sie in den anderen Build-Dateien nach $ (hide) suchen, werden Sie feststellen, dass vieles von diesem Wert abhängt. Es scheint auch die Art und Weise zu beeinflussen, wie C-Bibliotheken erstellt werden.
Thomas Hofmann
@ThomasHofmann: Das mkstubs-Tool hat mich anfangs auch verwirrt. Was ich gelernt habe ist, dass mkstubs nur verwendet wird, wenn Sie ein (Hersteller-) SDK-Addon erstellen, nicht, wenn Sie nur das normale SDK erstellen. Mkstubs funktioniert jedoch ähnlich wie DroidDoc, verwendet jedoch keine @hideAnmerkungen, sondern "nur" eine .defsDatei, die beschreibt, welche Pakete / Klassen / Felder in die API des Addons aufgenommen werden sollen.
Bjarke Freund-Hansen
2
@ThomasHofmann: Über $(hide), Sie verwirren sich. $(hide)ist einfach ein Präfix in den Makefiles, um die eigentliche Befehlszeile des ausgeführten Programms zu verbergen, nichts weiter, und es wird fast überall überall verwendet. Es hat überhaupt nichts mit dem Android SDK oder der @hideAnmerkung im Quellcode zu tun .
Bjarke Freund-Hansen
Wie kann ich diesen obigen Pfad überprüfen? out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
30

Wir könnten die * .jar-Dateien von der Android-Plattform rekonstruieren.

Schließen Sie zuerst ADB an Ihr Gerät an. Dann renne:

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

Sie core.jarenthalten die Standard-Java-Bibliotheken ( java.*) und framework.jardie Android-Bibliotheken ( android.*). Dies ist noch nicht verwendbar, da die tatsächlichen Dateien im DEX-Format und nicht im JAR-Format vorliegen.

Wir könnten diese DEX-formatierten * .jars mit Tools wie dex2jar in echte JARs konvertieren :

dex2jar core.jar
dex2jar framework.jar

Ziehen Sie diese Gläser dann mit "Externe JARs hinzufügen ..." ein (vorausgesetzt, Sie verwenden Eclipse ADT).

  • Rechtsklick auf Project → Properties → Java Build Path → Libraries → Add External JARs... → (Wählen Sie das core-dex2jar.jarund framework-dex2jar.jarvon oben).

Auf diese Weise können Sie die internen und einige Java 7-APIs verwenden. (Die generierte APK enthält, soweit ich sehen kann, keinen tatsächlichen Code aus den JARs.)

kennytm
quelle
Vielen Dank, ich habe viele Möglichkeiten ausprobiert, nur Ihre Methoden funktionieren für mich.
SalutonMondo
7
Es ist wichtig zu beachten, dass diese Methode immer noch mit ICS und späteren Systemen funktioniert, jedoch etwas mehr Jonglieren erfordert. Die entsprechenden Dateien sind /system/framework/core.odex, /system/framework/framework.odexund wahrscheinlich mehr. Diese können deodexiert ( java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core) und reodexiert ( java -jar smali-2.0.3.jar -x -o core.dex core) werden, und erst danach dex2jar core.dexerledigt es seine Aufgabe.
Alex Cohn
Core.jar in Marshmallow konnte nicht gefunden werden
mehmet6parmak
Hast du eine Idee für Core & Framework JAR in Android P?
Prabhakaran
Wie kann ich diesen obigen Pfad überprüfen? out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
17

Für Lollipop ist der Fluss etwas anders:

  1. Holen Sie sich /system/framework/arm/boot.oat vom Lollipop-Gerät

  2. Verwenden Sie 'java -jar oat2dex.jar boot boot.oat'

  3. Sie erhalten zwei Ordner: dex und odex. Gehen Sie zu dex und machen Sie 'java -jar dex2jar.jar framework.dex'
  4. Benennen Sie die resultierende Framework.jar in .zip um, extrahieren Sie sie und suchen Sie die gewünschten Klassen
  5. Gehen Sie zu [sdk_path] / platform / [target_platform] und extrahieren Sie android.jar (benennen Sie es zuerst in zip um).
  6. Kopieren Sie Dateien aus dem extrahierten Framework in die extrahierte Datei android.jar. Dann auf zip komprimieren und in .jar umbenennen :)

ps: wahrscheinlich musst du die Schritte 4-6 für 'framework_classes2.dex' wiederholen

abweichend
quelle
In Schritt 3 kann ich die Datei dex2jar.jar unter diesem Link nicht finden. Ich habe viele Dinge ausprobiert und kann es nicht herausfinden. Gibt es irgendwo einen Link dazu? Befindet es sich in meinem Android SDK? Ich kann es nicht finden
Dwebtron
Ja, es geht um ein Github-Projekt, und vielleicht bin ich es, aber ich kann dort keine Datei finden, die auf ".jar" endet ...
Dwebtron
1
Siehe Abschnitt "Veröffentlichungen"
abweichend
2
Es sieht also so aus, als hätten die neuesten Versionen von dex2jar das Format des Downloads geändert. Entpacken Sie einfach den Download und führen Sie anstelle von 'java -jar ...' das Skript 'd2j-dex2jar.sh' oder 'd2j-dex2jar.bat' aus, je nach Plattform direkt in der Datei framework.dex
CalumMcCall
1
Ich habe beide JAR-Dateien in die android.jar kopiert, jetzt sagt mir Android Studio Fehler: Ausführung für Aufgabe ': app: processDebugResources' fehlgeschlagen. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Prozess 'Befehl' D: \ Programm \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe 'verarbeiten. 'beendet mit einem Exit-Wert ungleich Null 1
wutzebaer
15

DroidCon 2011

Hier erklärt Erik Hellman von Sony Ericson, wie man auf die versteckten Android-APIs zugreift:

http://vimeo.com/30180393 (Hmm-Link scheint nicht zu funktionieren).

Gehen Sie zur DroidCon-Webseite Tag 2 und scrollen Sie nach unten zu Using Hidden APIs 10:15 können Sie sie ansehen.

Links sterben!

Ich habe dieses gefunden: http://skillsmatter.com/podcast/os-mobile-server/hidden-api Keine Ahnung, wie lange es noch dauern wird

Die offiziellen APIs im Android SDK reichen normalerweise für die meisten normalen Anwendungen aus. Es gibt jedoch manchmal Situationen, in denen ein Entwickler Zugriff auf die internen Systemdienste, APIs und Ressourcen benötigt, die nicht in den offiziellen APIs veröffentlicht sind. Glücklicherweise sind diese APIs immer noch durch einige clevere Tricks verfügbar und können oft nützlich sein, wenn neue und innovative Lösungen auf Android entwickelt werden. In dieser Sitzung erfahren Sie, wie Sie auf diese versteckten und geschützten APIs zugreifen und sie verwenden, welche Einschränkungen sie verwenden und wie Sie sie auf Geräten und Android-Versionen mehrerer Anbieter sicher und kontrolliert verwenden können. Das Publikum wird mehrere erweiterte Demos sehen, die Sie normalerweise mit Android nicht machen können. Erwarten Sie eine ziemlich fortgeschrittene Sitzung mit vielen Einblicken in die Interna der Android-Plattform.

Blundell
quelle
1
Es ist interessant, aber leider beantwortet es meine Frage nicht. Ich habe nach einer Möglichkeit gefragt, das SDK tatsächlich mit versteckten Dingen neu zu erstellen.
Thomas Hofmann
Es sieht so aus, als hätte ich einen anderen Weg gefunden, um das zu erreichen, was ich will. Ich werde es morgen beschreiben.
Thomas Hofmann
Ich habe herausgefunden, dass Sie Folgendes tun können, wenn Sie die Quelle eines Projekts kompilieren möchten, das eine versteckte API in ADT verwendet: 1) Erstellen Sie ein Android-Projekt für die Quelle. 2) Entfernen Sie den Android-Klassenpfadcontainer aus dem Erstellungspfad. 3) Definieren Sie eine Benutzerbibliothek (aktivieren Sie auch das Kontrollkästchen Systembibliothek), die JAR-Dateien aus einem ASOP-ROM-Build enthält, z. B. cm7. Welche JAR-Dateien Sie verwenden, hängt davon ab, auf was Sie verweisen müssen. Framework-Instantiates werden wahrscheinlich ein Teil davon sein.
Thomas Hofmann
4) Wenn das Projekt jetzt erstellt wird, werden die Benutzerbibliotheksklassen nicht in die zu erstellende APK aufgenommen. Versteckte API ist sichtbar und alles wird gut kompiliert.
Thomas Hofmann
@Blundell: Kannst du bitte die Links aktualisieren .. sie sind tot!
Zombie
13

Sie können die geänderten android.jarAPIs als versteckte APIs aus diesem Repository herunterladen . Folgen Sie dort den Anweisungen.

Anggrayudi H.
quelle
3
Diese Antwort sollte mehr positiv bewertet werden, da dies die einfachste Lösung ist. Leute, wenn Sie nach einer Lösung suchen - wissen Sie, dass andere Leute das bereits getan haben und eine Lösung für dieses Github-Repo gefunden haben. Nutzen Sie es und genießen Sie! ))
Mixaz
1
Bei der Verwendung von android.jar für API 28 wird eine Fehlermeldung bei robolectric angezeigt. Ich habe ein Problem mit github.com/anggrayudi/android-hidden-api/issues/62 angesprochen und danke Ihnen für Ihr Glas @Anggrayudi
Prabhakaran
12

Versuchen Sie , betrachten dies :

Das ultimative Ziel dieser Artikel ist es, Entwicklern die Leistung interner und versteckter APIs ohne Reflexion zu bieten. Wenn Sie alle in den nächsten Abschnitten beschriebenen Schritte ausführen, können Sie interne und versteckte APIs so verwenden, als wären sie öffentliche offene APIs. Es besteht kein Grund zur Reflexion.

Wenn Sie jedoch diese nicht öffentlichen APIs verwenden, sollten Sie sich bewusst sein, dass Ihre Anwendung einem hohen Risiko ausgesetzt ist. Grundsätzlich gibt es keine Garantie dafür, dass APIs beim nächsten Update auf Android OS nicht beschädigt werden. Es gibt sogar keine Garantie für ein konsistentes Verhalten zwischen Geräten verschiedener Hersteller. Sie sind ganz alleine.

Es gibt drei Szenarien, denen Sie folgen möchten:

  1. Aktivieren Sie sowohl interne als auch versteckte APIs (Szenario A).
  2. Nur versteckte API aktivieren (Szenario B)
  3. Nur interne API aktivieren (Szenario C)

Szenario A ist eine Summe aus B und C. Szenario B ist das einfachste (erfordert keine Änderungen am Eclipse ADT-Plugin).

Szenario A : Lesen Sie die Teile 1 , 2 , 3 , 4 , 5

Szenario B : Lesen Sie die Teile 1 , 2 , 3 , 5

Szenario C : Lesen Sie die Teile 1 , 2 , 3 , 4 , 5

Zorb
quelle
3
Ich habe diesen Blogeintrag bereits gelesen. Es wird Folgendes erwähnt: "1) Android ist ein Open-Source-Projekt. Wir können den Quellcode herunterladen und das Build-System so anpassen, dass interne und versteckte Klassen nicht von android.jar ausgeschlossen werden. Dies ist ein schwieriger Weg." Leider geht es nicht ins Detail.
Thomas Hofmann
3
Im letzten Teil des Blogposts ( devmaze.wordpress.com/2011/01/19/… ) befindet sich ein Link ( github.com/inazaruk/android-sdk/tree/master/platforms ) zu vorgefertigtem Android APIs mit allen versteckten und internen APIs.
Bob
1
Die angegebenen Links sind nicht zugänglich, bedürfen der Erlaubnis des Autors
SHAHS
Wie kann ich diesen obigen Pfad überprüfen? out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
1

Ich habe einmal einige Groovy-Skripte geschrieben, um die Java-Dateien aus einem Repo-Checkout von http://source.android.com/ zu extrahieren und sie dann zu kompilieren, ohne dass eine vollständige Toolchain zum Kompilieren aller Android-Quellen erforderlich ist, einschließlich der erforderlichen anderen Schritte ( Verpackung, Erzeugung von Ressourcen usw.).

Sie finden sie hier:

https://github.com/thoutbeckers/CollectAndroid

Aber sicher muss dies für alles nach Gingerbread aktualisiert werden, hauptsächlich durch Festlegen der richtigen Verzeichnisse in "rootdirs" in der Konfigurationsdatei (CollectConfig.groovy).

Zu der Zeit habe ich dies regelmäßig für die Entwicklung verwendet, wobei alle versteckten APIs und Quellen (die zu dieser Zeit ebenfalls problematisch waren) verfügbar waren.

Wie an anderer Stelle erwähnt, wird com / android / internal / ** in neueren Versionen von ADT aufgrund der hinzugefügten Zugriffsregel weiterhin ausgeblendet.

thoutbeckers
quelle
Wie kann ich diesen obigen Pfad überprüfen? out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
Ich habe dieses Repo archiviert, seit es das letzte Mal aktualisiert wurde Gingerbread . Sie müssen leider einen anderen Ansatz finden.
thoutbeckers
1

Longs Antwort funktionierte für mich, aber mir fehlten noch einige Klassen, die ich brauchte, insbesondere android.provider.Telephony. Ich konnte es so hinzufügen:

  1. Extrahieren Sie die Datei framework.jar

    mkdir /tmp/framework
    cp framework.jar /tmp
    cd /tmp/framework
    jar xvf ../framework.jar
    mv android classes
  2. Erstellen Sie das Android-Repo, das das Verzeichnis out / target / common / obj / JAVA_LIBRARIES erstellt

  3. Finden Sie heraus, wo die fehlenden Klassen sind

    $ 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. Fügen Sie die neuen Klassen hinzu und erstellen Sie die Framework-JAR-Datei neu

    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 .

Oder Sie können einfach faul sein und alle Klassen in eine riesige JAR-Datei aufnehmen:

cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .
Bmaupin
quelle
out / target / common / obj / JAVA_LIBRARIES Wie finde ich diesen Pfad?
Bunny
@ Bunny Ich habe meine Antwort mit weiteren Details aktualisiert. Aber es scheint, dass die Antwort hier einfacher sein könnte: stackoverflow.com/a/32626155/399105
bmaupin
Vielen Dank für Ihre Antwort @bmaupin ..können Sie mir bitte helfen, wie ich diesen Pfad herausfinden kann / target / common / obj / JAVA_LIBRARIES, um das Framework jar zu erhalten ... ich steckte wirklich fest .. Ich kann diesen Pfad nicht finden oder etwas fehlt ... bitte führen
Bunny
0

Ich kann keinen Kommentar abgeben, aber dies ist im Grunde ein Kommentar zu @ KennyTMs ( https://stackoverflow.com/a/13550030/2923406 ) ausgezeichneter Antwort:

Wenn Sie den folgenden Fehler in Eclipse haben:

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

(das heißt, android.internal. * ist nicht verfügbar)

Eine mögliche Lösung besteht darin, dieselbe Methode für /system/framework/framework2.jar anzuwenden. Mit dem Android Emulator für SDK19 habe ich dieses zusätzliche Glas. Auf meinem HTC One gibt es sogar ein framework3.jar.

Rolf
quelle
Wie kann ich diesen obigen Pfad überprüfen? out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny