Come faccio a creare l'SDK Android con API nascoste e interne disponibili?


85

Voglio ricostruire Android SDK (o meglio solo android.jar) per includere API nascoste e interne.

Non sono riuscito a trovare alcuna documentazione o discussione su come procedere. Ho già configurato un ambiente di build Ubuntu CyanogenMod che è in grado di costruire cm7.

Ora, ho letto che make SDK creerà l'SDK ma desidero creare un SDK che includa metodi e campi contrassegnati come nascosti utilizzando @hide. È possibile?

Quello che voglio fare è apportare modifiche a un'applicazione che utilizza API nascoste e per ricostruirla vorrei utilizzare l'SDK modificato.


2
@Hidden nasconde solo il javadoc, tutti questi metodi sono ancora disponibili
Blundell

12
@hide li rimuove dai file di classe.
Thomas Hofmann


So che potrei usare la riflessione ma voglio cambiare un'applicazione esistente che utilizza API nascoste senza refelction e non voglio cambiare tutto il codice esistente per usare la refelction.
Thomas Hofmann

4
Penso che tu possa rimuovere l' @Hiddenetichetta dell'API a cui desideri accedere, quindi eseguire make update-apie make SDKcreare il tuo SDK.
dreamtale

Risposte:


68

Questo è quello che faccio sempre per usare l'API nascosta.

  1. Crea il repository o scarica i jar da https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
  2. copia / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar (meglio rinominarlo come qualcosa come framework_all.jar)
  3. configura il percorso di compilazione del tuo progetto -> librerie -> aggiungi questi jars esterni. In Order and Export, spostalo verso l'alto e prima di android.jar

Questo ha funzionato anche per me! ora posso andare avanti con il compito vero e proprio, grazie per questo
CurlyPaul

IMHO, questo è il più semplice e il più veloce.
Patrick Cho

Non c'è un modo per contrassegnare questo come la risposta corretta?
Chris Browet

2
questo metodo funziona con tutti i dispositivi o funziona solo con il dispositivo di destinazione?
Hải Phong

Per definire l'ordine della libreria in Android Studio, è necessario modificare il .imlfile del modulo e portare la libreria desiderata <orderEntry>prima di Android SDK . Sfortunatamente questa tecnica non è persistente in quanto il file verrà sovrascritto una volta premuto il pulsante gradle-sync.
Waqaslam

44

Ho svolto alcune indagini al riguardo e la mia conclusione è semplicemente: questo non può essere fatto senza un bel po 'di lavoro. Leggi il resto di questa risposta per i dettagli su ciò che ho trovato.


android.jarè in realtà costituito dall '"API pubblica" di framework.jare core.jarche si trova nel system/frameworks/dispositivo. android.jarè un tipo di ciò che chiamerei intestazione della libreria Java, tutte le implementazioni nel codice byte effettivo sono solo un throw new RuntimeException("stub");, questo ti permette di costruire contro android.jar(ad esempio in Eclipse), ma l'esecuzione deve essere eseguita su un dispositivo o un emulatore.

L'API pubblica di Android SDK è definita da classi / metodi / campi che non sono preceduti @{hide}dall'annotazione javadoc. Cioè tutto ciò che non è annotato è incluso nell'SDK.

android.jarè costruito dalle sorgenti situate in out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediatescui è generato dallo strumento DroidDoc situato in build/tools/droiddoc.

DroidDoc è lo strumento (probabilmente adattato da javadoc, o utilizzando javadoc) che genera la documentazione effettiva di Android SDK. Come effetto collaterale, e probabilmente perché sta già analizzando tutto il javadoc, sputa anche gli stub Android che vengono quindi compilati in android.jarcui è distribuito nell'SDK.

Quindi, per includere gli elementi nascosti, potresti, se desideri includere solo parti specifiche, rimuovere l' @hideannotazione e ricostruire l'SDK.

Tuttavia, se vuoi includere tutte le parti nascoste, le cose diventano molto più complicate. È possibile modificare DroidDoc (la fonte pertinente è in build/tools/droiddoc/src/Stubs.java) in modo che nulla venga rilevato come nascosto. Questo è abbastanza banale e l'ho provato, tuttavia gli stub che vengono generati non si compilano affatto.

La mia conclusione a questo punto è che questo semplicemente non è fattibile. Gli stub generati se rimuovi la parte di DroidDoc che rileva le annotazioni nascoste, semplicemente non sono compilabili e richiederebbero un bel po 'di lavoro per essere compilati correttamente.

Quindi la mia risposta alle tue domande è: No, questo non può essere fatto senza fare molto lavoro. Scusate.


Una nota a margine sullo mkstubsstrumento. mkstubsvengono utilizzati quando crei un componente aggiuntivo SDK , ovvero i componenti aggiuntivi che puoi trovare nel gestore SDK di Android dai fornitori, ad esempio Samsung che ti fornisce un'API aggiuntiva per cose specifiche dei telefoni Samsung. mkstubsfa più o meno lo stesso del processo di generazione di stub DroidDoc, tuttavia non utilizza @hideannotazioni, utilizza un .defsfile che descrive quali pacchetti / classi / campi includere o escludere dal tuo componente aggiuntivo SDK.

Tuttavia, questo è tutto irrilevante per la domanda, poiché la build di Android SDK non utilizza lo mkstubsstrumento. (Sfortunatamente.)


Anch'io ho dato un'occhiata. Oltre a Droiddoc c'è uno strumento chiamato mkstubs in / development / tools / mkstubs. Viene chiamato durante la compilazione e, per quanto ho visto, modificherà i file di classe eliminandoli. In build / core / tasks / sdk-addon.mk c'è il seguente codice: define stub-addon-jar $ (call stub-addon-jar-file, $ (1)): $ (1) | mkstubs $ (info Stubbing addon jar usando $ (PRODUCT_SDK_ADDON_STUB_DEFS)) $ (nascondi) java -jar $ (chiama module-installed-files, mkstubs) $ (if $ (hide) ,, - v) \ "$$ <" "$$ @" @ $ (PRODUCT_SDK_ADDON_STUB_DEFS) endef
Thomas Hofmann

Sfortunatamente, non mi piacciono queste cose ma anche a me sembra che tutto dipenda da una variabile chiamata hide. Non ho trovato dove viene impostato però. Se cerchi $ (hide) negli altri file di build vedrai che molto dipende da questo valore. Sembra influire anche sul modo in cui vengono create le librerie C.
Thomas Hofmann

@ThomasHofmann: inizialmente sono stato confuso anche dallo strumento mkstubs. Quello che ho imparato è che mkstubs viene utilizzato solo quando stai costruendo un addon sdk (fornitore), non quando costruisci solo il normale sdk. Tuttavia, mkstubs fa più o meno lo stesso di DroidDoc, tranne per il fatto che non utilizza @hideannotazioni, utilizza "solo" un .defsfile che descrive quali pacchetti / classi / campi devono essere inclusi nell'API dell'addon.
Bjarke Freund-Hansen

2
@ThomasHofmann: A proposito $(hide), ti stai confondendo. $(hide)è semplicemente un prefisso nei makefile per nascondere l'effettiva riga di comando del programma in esecuzione, niente di più, ed è usato praticamente ovunque ovunque. Non ha assolutamente nulla a che fare con l'SDK Android o l' @hideannotazione nel codice sorgente.
Bjarke Freund-Hansen

come posso controllare questo percorso sopra fuori / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

31

Potremmo ricostruire i file * .jar dalla piattaforma Android.

Innanzitutto, collega ADB al tuo dispositivo. Quindi esegui:

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

L' core.jarcontengono le librerie standard di Java ( java.*) e la framework.jarcontengono le librerie Android ( android.*). Non è ancora utilizzabile, poiché i file effettivi sono in formato DEX, non in formato JAR.

Potremmo convertire questi * .jar formattati in DEX in JAR reali utilizzando strumenti come dex2jar :

dex2jar core.jar
dex2jar framework.jar

Quindi inserisci questi barattoli usando "Aggiungi JAR esterni ..." (supponendo che tu stia utilizzando Eclipse ADT)

  • fare clic con il tasto destro del mouse su Project → Properties → Java Build Path → Libraries → Add External JARs... → (Scegli core-dex2jar.jare framework-dex2jar.jardall'alto).

Ciò ti consentirà di utilizzare le API interne e alcune API di Java 7. (L'APK generato, per quanto posso vedere, non contiene alcun codice effettivo dai JAR.)


Grazie mille, ho provato molti modi in cui solo i tuoi metodi funzionano per me.
SalutonMondo

7
È importante notare che questo metodo funziona ancora con ICS e sistemi successivi, ma richiede un po 'più di giocoleria. I file rilevanti sono /system/framework/core.odex, /system/framework/framework.odexe probabilmente più. Questi possono essere deodexed ( java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core) e reodexed ( java -jar smali-2.0.3.jar -x -o core.dex core), e solo dopo dex2jar core.dexfa il suo lavoro.
Alex Cohn

impossibile trovare core.jar in marshmallow
mehmet6parmak

avete qualche idea per core e framework jar in android p?
Prabhakaran

come posso controllare questo percorso sopra fuori / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

17

Per Lollipop il flusso è leggermente diverso:

  1. Ottieni /system/framework/arm/boot.oat dal dispositivo lollipop

  2. Usa "java -jar oat2dex.jar boot boot.oat"

  3. Otterrai due cartelle: dex e odex. Vai a dex e crea 'java -jar dex2jar.jar framework.dex'
  4. Rinomina framework.jar risultante in .zip, estrai e trova le classi di cui hai bisogno
  5. Vai a [sdk_path] / piattaforme / [target_platform] ed estrai android.jar (prima rinominalo in zip).
  6. Copia i file dal framework estratto in android.jar estratto. Quindi comprimi in zip e rinomina in .jar :)

ps: probabilmente dovrai ripetere i passaggi 4-6 per "framework_classes2.dex"


Per il passaggio 3, non riesco a trovare dex2jar.jar a quel link .... Ho provato molte cose e non riesco a capirlo. C'è un collegamento a quello da qualche parte? Si trova nel mio SDK Android? Non riesco a trovarlo.
Dwebtron

Sì, va a un progetto GitHub, e forse sono io, ma non riesco a trovare NESSUN file che termina con ".jar" lì ...
Dwebtron

1
vedere la sezione "rilasci"
deviante

2
Quindi sembra che le versioni recenti di dex2jar abbiano cambiato il formato del download. Basta decomprimere il download e invece di 'java -jar ...' basta eseguire lo script 'd2j-dex2jar.sh' o 'd2j-dex2jar.bat', a seconda della piattaforma, direttamente sul file framework.dex
CalumMcCall

1
Ho copiato entrambi i file jar in android.jar, ora Android Studio mi dice Errore: esecuzione non riuscita per l'attività ': app: processDebugResources'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Processo 'comando' D: \ Program \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe ' 'finito con valore di uscita 1 diverso da zero
wutzebaer

16

È possibile scaricare le modifiche android.jarda utilizzare come API nascoste da questo repository . Segui le istruzioni lì.


4
Questa risposta dovrebbe essere votata di più in quanto è la soluzione più semplice. Persone, se stai cercando una soluzione, sappi che altre persone l'hanno già fatto e hanno messo una soluzione a quel repository GitHub. Usalo e divertiti! ))
Mixaz

1
Durante l'utilizzo di android.jar per l'API 28 ricevo un errore con robolectric. Ha sollevato un problema github.com/anggrayudi/android-hidden-api/issues/62 e grazie per il tuo barattolo @Anggrayudi
Prabhakaran

Ho fatto lo stesso anche per Android 10, non funziona per me, piuttosto l'ho scaricato da un altro collaboratore github.com/aeab13/android-jar-with-hidden-api . Sono stato in grado di accedere alla classe hdmi-cec e crearla, ma i codici continuano a confondere .code link android.googlesource.com/platform/frameworks/base/+/4e90fcd/…
babbin tandukar

15

DroidCon 2011

Qui Erik Hellman di Sony Ericson spiega come accedere alle API Android nascoste:

http://vimeo.com/30180393 (il collegamento Hmm non sembra funzionare).

Vai alla pagina web DroidCon Giorno 2 scorri verso il basso fino a Utilizzo delle API nascoste 10:15 e puoi guardarlo lì.

I link stanno morendo!

Ho trovato questo: http://skillsmatter.com/podcast/os-mobile-server/hidden-api non so quanto durerà

Le API ufficiali nell'SDK Android sono generalmente sufficienti per la maggior parte delle normali applicazioni. Tuttavia, a volte ci sono situazioni in cui uno sviluppatore ha bisogno di accedere ai servizi di sistema interni, alle API e alle risorse che non sono pubblicate nelle API ufficiali. Fortunatamente, queste API sono ancora disponibili attraverso alcuni trucchi intelligenti e spesso possono essere utili quando si sviluppa una soluzione nuova e innovativa su Android. In questa sessione imparerai come accedere e utilizzare queste API nascoste e protette, i limiti del loro utilizzo e alcuni suggerimenti su come usarle in modo sicuro e controllato su dispositivi di più fornitori e versioni Android. Il pubblico vedrà diverse demo avanzate che normalmente non puoi fare con Android. Aspettatevi una sessione abbastanza avanzata con molti approfondimenti sugli interni della piattaforma Android.


1
È interessante ma sfortunatamente non risponde alla mia domanda. Stavo chiedendo un modo per ricostruire effettivamente l'SDK con materiale nascosto incluso.
Thomas Hofmann

Sembra che abbia trovato un altro modo per ottenere ciò che voglio. Lo descriverò domani.
Thomas Hofmann

Ho scoperto che se vuoi compilare il sorgente di un progetto che utilizza API nascoste in ADT puoi fare quanto segue: 1) Creare un progetto Android per il sorgente. 2) Rimuovere il contenitore del percorso di classe Android dal percorso di compilazione 3) Definire una libreria utente (selezionare anche la casella di controllo della libreria di sistema) che include file JAR da una build ASOP ROM, ad esempio cm7). I file JAR che usi dipendono da ciò che devi fare riferimento. framework-immediati ne faranno probabilmente parte.
Thomas Hofmann

4) Quando il progetto è ora costruito, le classi della libreria utente non saranno incluse nell'APK in fase di creazione. L'API nascosta è visibile e tutto verrà compilato correttamente.
Thomas Hofmann

@Blundell: Puoi aggiornare i link .. sono morti!
zombie

12

Prova a guardare questo :

L'obiettivo finale di questi articoli è fornire agli sviluppatori la potenza delle API interne e nascoste senza utilizzare la riflessione. Se completi tutti i passaggi descritti nelle diverse parti successive, sarai in grado di utilizzare API interne e nascoste come se fossero API pubbliche aperte. Non ci sarà bisogno di riflettere.

Ma se stai usando queste API non pubbliche, dovresti essere consapevole che la tua applicazione è a grande rischio. Fondamentalmente non ci sono garanzie che le API non verranno interrotte con il prossimo aggiornamento del sistema operativo Android. Non ci sono nemmeno garanzie sul comportamento coerente tra i dispositivi di diversi fornitori. Sei completamente da solo.

Ci sono tre scenari che potresti voler seguire:

  1. Abilita API interne e nascoste (scenario A)
  2. Abilita solo API nascoste (scenario B)
  3. Abilita solo API interna (scenario C)

Lo scenario A è una somma di B e C. Lo scenario B è il più semplice (non richiede modifiche al plugin ADT di eclipse).

Scenario A : leggi le parti 1 , 2 , 3 , 4 , 5

Scenario B : leggi le parti 1 , 2 , 3 , 5

Scenario C : leggi le parti 1 , 2 , 3 , 4 , 5


3
Ho già letto quel post sul blog. Lo menziona: "1) Android è un progetto open source. Possiamo scaricare il codice sorgente e personalizzare il sistema di compilazione in modo che non escluda classi interne e nascoste da android.jar. Questo è un modo difficile." Purtroppo non entra nei dettagli.
Thomas Hofmann

3
Vai all'ultima parte del post del blog ( devmaze.wordpress.com/2011/01/19/… ), c'è un collegamento ( github.com/inazaruk/android-sdk/tree/master/platforms ) per Android pre-costruito API con tutte le API nascoste e interne.
Bob

1
I link indicati non sono accessibili, richiedono l'autorizzazione dell'autore
SHAHS

come posso controllare questo percorso sopra fuori / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

1

Una volta ho scritto alcuni script Groovy per estrarre i file java da un repository checkout da http://source.android.com/ e quindi compilarli senza la necessità di una toolchain completa per la compilazione di tutte le fonti Android, inclusi gli altri passaggi necessari ( packaging, generazione di risorse, ecc.).

Possono essere trovati qui:

https://github.com/thoutbeckers/CollectAndroid

Ma sicuramente questo dovrà essere aggiornato per qualsiasi cosa dopo Gingerbread, principalmente impostando le directory corrette in "rootdirs" nel file di configurazione (CollectConfig.groovy).

All'epoca lo usavo regolarmente per lo sviluppo con tutte le API nascoste e le fonti (anche problematiche al momento) disponibili.

Come accennato altrove, com / android / internal / ** sarà ancora nascosto nelle versioni recenti di ADT a causa della regola di accesso aggiunta.


come posso controllare questo percorso sopra fuori / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

Ho archiviato quel repo dall'ultimo aggiornamento per Gingerbread . Sfortunatamente dovrai trovare un altro approccio.
thoutbeckers

1

La risposta di Long ha funzionato per me, ma mi mancavano ancora alcune classi di cui avevo bisogno, in particolare android.provider.Telephony. Sono stato in grado di aggiungerlo in questo modo:

  1. Estrai il file framework.jar

    mkdir /tmp/framework
    cp framework.jar /tmp
    cd /tmp/framework
    jar xvf ../framework.jar
    mv android classes
    
  2. Costruisci il repository Android, che creerà la directory out / target / common / obj / JAVA_LIBRARIES

  3. Trova dove sono le classi mancanti

    $ 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. Aggiungi le nuove classi e ricostruisci il file JAR del framework

    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 .
    

Oppure puoi semplicemente essere pigro e includere tutte le classi in un unico file jar gigante:

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 come trovare questo percorso?
Bunny

@Bunny ho aggiornato la mia risposta con maggiori dettagli. Ma sembra che la risposta qui potrebbe essere più facile: stackoverflow.com/a/32626155/399105
bmaupin

grazie per la tua risposta @bmaupin .. puoi per favore aiutarmi a trovare questo percorso fuori / target / common / obj / JAVA_LIBRARIES per ottenere framework jar ... sono rimasto davvero bloccato..non sono in grado di trovare questo percorso o manca qualcosa ... per favore guida
Bunny

0

Non posso commentare ma questo è fondamentalmente un commento alla risposta eccellente di @ KennyTM ( https://stackoverflow.com/a/13550030/2923406 ):

Se ti trovi con il seguente errore in Eclipse:

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

(ovvero, android.internal. * non è disponibile)

Quindi una possibile soluzione è applicare lo stesso metodo per /system/framework/framework2.jar. Usando l'emulatore Android per SDK19 ho questo jar extra. Sul mio HTC One c'è persino un framework3.jar.


come posso controllare questo percorso sopra fuori / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.