¿Cómo construyo el SDK de Android con API internas y ocultas disponibles?

Quiero reconstruir el SDK de Android (o más bien solo el android.jar) para incluir las API internas y ocultas.

No pude encontrar ninguna documentación o discusión sobre cómo hacerlo. Tengo un entorno de comstackción Ubuntu CyanogenMod ya configurado que puede construir cm7.

Ahora, leí que SDK creará el SDK, pero quiero construir un SDK que incluya métodos y campos que estén marcados como ocultos usando @hide. es posible?

Lo que quiero hacer es realizar cambios en una aplicación que utiliza API oculta y para poder reconstruirla, me gustaría usar el SDK modificado.

Esto es lo que siempre hago para usar api oculto.

  1. Cree el repository o descargue flasks de https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
  2. copia hacia fuera / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar (mejor cambiarle el nombre por algo como framework_all.jar)
  3. configure su ruta de comstackción del proyecto -> bibliotecas -> agregue estos archivos jar externos. En Order and Export, muévelo hacia arriba y antes de android.jar

He investigado un poco sobre esto, y mi conclusión es simple: esto no puede hacerse sin bastante trabajo. Lea el rest de esta respuesta para obtener detalles sobre lo que he encontrado.


android.jar realidad está compuesto por la “API pública” de framework.jar y core.jar que se encuentra en system/frameworks/ en el dispositivo. android.jar es una especie de lo que yo llamaría encabezado de biblioteca Java, toda implementación en el código de bytes real es solo una throw new RuntimeException("stub"); , esto le permite comstackr contra android.jar (por ejemplo, en Eclipse), pero la ejecución debe realizarse en un dispositivo o emulador.

La API pública de Android SDK está definida por clases / métodos / campos que no están prefijados con la anotación @{hide} javadoc. Es decir, todo lo que no está anotado está incluido en el SDK.

android.jar se construye a partir de las fonts ubicadas en out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates que a su vez es generado por la herramienta DroidDoc ubicada en build/tools/droiddoc .

DroidDoc es la herramienta (probablemente adaptada de javadoc, o que utiliza javadoc) que genera la documentación real de Android SDK. Como efecto secundario, y probablemente porque ya está analizando todo el javadoc, también arroja los stains de Android que luego se comstackn en el android.jar que se distribuye en el SDK.

Entonces, para incluir las cosas que están ocultas, si solo quieres incluir partes específicas, simplemente elimina la anotación @hide y reconstruye el SDK.

Sin embargo, si quieres incluir todas las partes ocultas, las cosas se vuelven mucho más complicadas. Puede modificar DroidDoc (la fuente relevante está en build/tools/droiddoc/src/Stubs.java ) de manera que no se detecte nada como oculto. Esto es bastante trivial y lo he intentado, sin embargo, los apéndices que se generan no comstackn en absoluto.

Mi conclusión ahora es que esto simplemente no es factible. Los stubs generados si elimina la parte de DroidDoc que detecta anotaciones ocultas, simplemente no son comstackbles y requeriría bastante trabajo para comstackrse correctamente.

Entonces mi respuesta a sus preguntas es: No, esto no se puede hacer sin hacer mucho trabajo. Lo siento.


Una nota al mkstubs sobre la herramienta mkstubs . mkstubs se usan cuando construyes un complemento SDK , es decir, los complementos que puedes encontrar en el administrador de Android SDK de los proveedores, por ejemplo, Samsung, que te proporciona una API adicional para cosas específicas de los teléfonos Samsung. mkstubs hace lo mismo que el proceso de generación de stubs DroidDoc, sin embargo, no utiliza anotaciones @hide , sino que utiliza un archivo .defs que describe qué paquetes / clases / campos incluir o excluir de su complemento SDK.

Sin embargo, todo esto es irrelevante para la pregunta, ya que la versión de Android SDK no usa la herramienta mkstubs . (Desafortunadamente.)

Podríamos reconstruir los archivos * .jar de la plataforma Android.

Primero, conecta ADB a tu dispositivo. Entonces corre:

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

El core.jar contiene las bibliotecas estándar de Java ( java.* ) Y framework.jar contiene las bibliotecas de Android ( android.* ). Esto no se puede utilizar todavía, ya que los archivos reales están en formato DEX, no en formato JAR.

Podríamos convertir estos * .jars con formato DEX en archivos JAR reales utilizando herramientas como dex2jar :

 dex2jar core.jar dex2jar framework.jar 

Luego, ingrese estos archivos usando “Agregar archivos JAR externos …” (suponiendo que esté utilizando Eclipse ADT)

  • Haga clic derecho en Project → Properties → Java Build Path → Libraries → Add External JARs … → (Elija el core-dex2jar.jar y framework-dex2jar.jar desde arriba).

Esto le permitirá usar las API internas y algunas de Java 7. (La APK generada, hasta donde puedo ver, no contiene ningún código real de los JAR).

Para Lollipop, el flujo es un poco diferente:

  1. Obtenga /system/framework/arm/boot.oat del dispositivo lollipop

  2. Use ‘java -jar oat2dex.jar boot boot.oat’

  3. Obtendrá 2 carpetas: dex y odex. Ve a dex y crea ‘java -jar dex2jar.jar framework.dex’
  4. Cambie el nombre resultante framework.jar por .zip, extraiga y encuentre las clases que necesita
  5. Vaya a [ruta_sdk] / platforms / [plataforma_destino] y extraiga android.jar (primero cámbiele el nombre a zip).
  6. Copie los archivos del marco extraído a android.jar extraído. Luego comprime para comprimir y cambiar el nombre a .jar 🙂

ps: probablemente necesites repetir los pasos 4-6 para ‘framework_classes2.dex’

DroidCon 2011

Aquí Erik Hellman de Sony Ericson explica cómo acceder a las API de Android ocultas:

http://vimeo.com/30180393 (El enlace de Hmm no parece funcionar).

Ir a la página web de DroidCon El día 2 desplácese hacia abajo para usar las API ocultas 10:15 y puede verlo allí.

¡Los enlaces están muriendo!

Encontré este: http://skillsmatter.com/podcast/os-mobile-server/hidden-api no sé cuánto tiempo durará

Las API oficiales en Android SDK suelen ser suficientes para la mayoría de las aplicaciones normales. Sin embargo, a veces hay situaciones en las que un desarrollador necesita acceder a los servicios del sistema interno, las API y los recursos que no están publicados en las API oficiales. Afortunadamente, estas API todavía están disponibles a través de algunos trucos ingeniosos y, a menudo, pueden ser útiles cuando se desarrolla una solución nueva e innovadora sobre Android. En esta sesión, aprenderá cómo acceder y usar estas API ocultas y protegidas, las limitaciones de su uso y algunos consejos y sugerencias sobre cómo usarlas de forma segura y controlada en múltiples dispositivos de vendedores y versiones de Android. La audiencia verá varias demos avanzadas que normalmente no puedes hacer con Android. Espere una sesión bastante avanzada con muchas ideas en el interior de la plataforma Android.

Intenta ver esto :

El objective final de estos artículos es brindar a los desarrolladores el poder de las API internas y ocultas sin usar la reflexión. Si completa todos los pasos descritos en las siguientes partes, podrá usar las API internas y ocultas como si fueran API públicas abiertas. No habrá necesidad de reflexión.

Pero si usa estas API no públicas, debe tener en cuenta que su aplicación corre un gran riesgo. Básicamente, no hay garantías de que las API no se rompan con la próxima actualización del sistema operativo Android. Incluso no hay garantías sobre el comportamiento constante en dispositivos de diferentes proveedores. Estás completamente solo.

Hay tres escenarios que puede seguir:

  1. Habilitar API internas y ocultas (escenario A)
  2. Habilitar solo la API oculta (escenario B)
  3. Habilitar solo la API interna (escenario C)

El escenario A es una sum de B y C. El escenario B es el más fácil (no requiere modificaciones de complementos ADT de eclipse).

Escenario A : lea las partes 1 , 2 , 3 , 4 , 5

Escenario B : lea las partes 1 , 2 , 3 , 5

Escenario C : lea las partes 1 , 2 , 3 , 4 , 5

Puede descargar el android.jar modificado para utilizarlo como API ocultas de este repository . Sigue las instrucciones allí.

Una vez escribí algunas secuencias de comandos Groovy para extraer los archivos java de un repo checkout desde http://source.android.com/ y luego comstackrlos sin la necesidad de una cadena de herramientas completa para comstackr todas las fonts de Android, incluidos los otros pasos necesarios ( embalaje, generación de recursos, etc.).

Pueden ser encontrados aquí:

https://github.com/thoutbeckers/CollectAndroid

Pero seguro que necesitará una actualización para algo después de Gingerbread, principalmente estableciendo los directorios correctos en “rootdirs” en el archivo de configuración (CollectConfig.groovy).

En ese momento, usé esto regularmente para el desarrollo con todas las API y fonts ocultas (también problemáticas en ese momento) disponibles.

Como se mencionó en otra parte, com / android / internal / ** seguirá oculto en las versiones recientes de ADT debido a la regla de acceso aded.

Hay una publicación de blog en la página web de Sony Ericsson con la charla y el código de Erik Hellmans y algunas referencias que creo que serán útiles para usted.

Saludos cordiales
/ Johan

No puedo comentar, pero esto es básicamente un comentario a la excelente respuesta de @ KennyTM ( https://stackoverflow.com/a/13550030/2923406 ):

Si te encuentras con el siguiente error en Eclipse:

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

(es decir, android.internal. * no está disponible)

Entonces, una posible solución es aplicar el mismo método para /system/framework/framework2.jar. Usando el emulador de Android para SDK19 tengo este flask adicional. En mi HTC One incluso hay un framework3.jar.

La respuesta de Long funcionó para mí, pero todavía me faltaban algunas clases que necesitaba, en particular android.provider.Telephony. Pude agregarlo así:

  1. Encuentra dónde está la clase

     $ 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 
  2. Agregue las nuevas clases y reconstruya el archivo JAR de framework

     cd /path/to/temp/folder 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 . 

O simplemente puede ser flojo e incluir todas las clases en un archivo jar gigante:

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