Lollipop y superior: ¿cómo instalo un APK como aplicación del sistema?

En el pasado, instalar una aplicación como aplicación del sistema era tan simple como mover el archivo APK a /system/appo /system/priv-app. Eliminarlos fue tan simple como borrar el APK.

Ahora, mientras personalizo la ROM estándar del teléfono, noté que todas y cada una de las aplicaciones en la partición del sistema estaban dentro de su propia carpeta. Intenté simplemente colocar el APK en /system/appo /system/priv-app, pero no funcionan.

¿Cómo instalo una aplicación como aplicación del sistema en Lollipop? Sospecho que pasa algo con SELinux y el contexto, pero no tengo acceso de root. Sin embargo, tengo acceso de lectura/escritura al sistema de archivos (montando la imagen en Linux).

ACTUALIZACIÓN: Probé la Death Mask Salesmansugerencia de y eché un vistazo a logcat. Las aplicaciones que quiero preinstalar (por ejemplo, Instagram) arrojan este error:

01-01 01:04:45.108 5538-5538/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: com.instagram.android, PID: 5538
                                                 java.lang.RuntimeException: Unable to instantiate application com.instagram.app.InstagramAppShell: java.lang.ClassNotFoundException: Didn't find class "com.instagram.app.InstagramAppShell" on path: DexPathList[[zip file "/system/framework/com.google.android.maps.jar"],nativeLibraryDirectories=[/custpack/app/removeable/withlibs/com.instagram.android-1/lib/arm, /vendor/lib, /system/lib]]
                                                     at android.app.LoadedApk.makeApplication(LoadedApk.java:572)
                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4818)
                                                     at android.app.ActivityThread.access$1500(ActivityThread.java:178)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
                                                     at android.os.Handler.dispatchMessage(Handler.java:111)
                                                     at android.os.Looper.loop(Looper.java:194)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5624)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
                                                  Caused by: java.lang.ClassNotFoundException: Didn't find class "com.instagram.app.InstagramAppShell" on path: DexPathList[[zip file "/system/framework/com.google.android.maps.jar"],nativeLibraryDirectories=[/custpack/app/removeable/withlibs/com.instagram.android-1/lib/arm, /vendor/lib, /system/lib]]
                                                     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                     at android.app.Instrumentation.newApplication(Instrumentation.java:985)
                                                     at android.app.LoadedApk.makeApplication(LoadedApk.java:567)
                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4818) 
                                                     at android.app.ActivityThread.access$1500(ActivityThread.java:178) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                     at android.os.Looper.loop(Looper.java:194) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:5624) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at java.lang.reflect.Method.invoke(Method.java:372) 
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754) 
                                                    Suppressed: java.lang.ClassNotFoundException: com.instagram.app.InstagramAppShell
                                                     at java.lang.Class.classForName(Native Method)
                                                     at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                                                     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                                                            ... 13 more
                                                  Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

Síntomas:

  • Todas las aplicaciones que he instalado cierran a la fuerza
  • Los nombres de sus paquetes y el logotipo genérico aparecen en el iniciador en lugar del nombre y el logotipo de la aplicación.
  • simplemente no funcionan

Para las personas que planean marcar esto como un duplicado, estas respuestas no funcionan/están desactualizadas/no aplican (no es un sistema en vivo/no tiene acceso a la raíz):

Desde 5.1.1 en adelante, las aplicaciones que se instalarán como aplicaciones del sistema deben ubicarse en una subcarpeta en /system/priv-app/ . Por ejemplo, si planea instalar Termux como una aplicación del sistema, debe colocar el APK de Termux en algo como /system/priv-app/com.termux/ . También tendría que cambiar los permisos y la propiedad apropiados, y establecer el contexto SELinux correcto.
@DeathMaskSalesman Acabo de mover un APK en /system/app (Stock Android 6.0.1 - Nexus 6), no me molesté en cambiar los permisos de rwx-rwx-rwx a rw-rr, no seguí la convención de nomenclatura y simplemente suave -reinició el sistema. Después del reinicio, encontré mi aplicación instalada como una aplicación del sistema. Así que la suya es una generalización radical, diría yo. :-)
@DeathMaskSalesman ¿Cómo configuro el contexto SELinux de una aplicación en un sistema fuera de línea ?
@Firelord Sí, la mía es principalmente una convención, pero simplemente colocar el APK deseado en / system / app no ​​funcionó en mi CM12.1: cualquier aplicación forzaba el cierre cada vez que la abría.
@DeathMaskSalesman MISMO, aunque los he colocado en sus carpetas individuales, pero aún nada. También intenté instalarlos como una aplicación de usuario y luego mover la carpeta de /data/appa /system/app.

Respuestas (1)

Está bien, lo tengo funcionando. Así es como lo hice:

  1. Copie el archivo APK en /system/app/some-folder/o /system/priv-app/xyz-folder/.
    • Mantenerlos en sus propias carpetas puede/prevendrá conflictos. Algunas aplicaciones quieren que se libsextraigan sus archivos y otros y se coloquen junto con el APK en carpetas específicas, aunque son bastante raros.
    • Intente revisar algunas carpetas de otras aplicaciones del sistema. Tenga en cuenta que algunos de ellos tienen una libu otra carpeta al lado del APK.
    • Es por eso que casi todas las aplicaciones en las carpetas mencionadas anteriormente tienen sus APK dentro de sus propias carpetas.
    • Seguir el paso 1 suele ser suficiente.
  2. Cambia el contexto del archivo APK usando el comando
    • chcon u:object_r:system_file:s0 /path/to/apk-file.apk
    • O, si lo copió en su propia carpeta, ejecute chcon -R u:object_r:system_file:s0 /folder/where/the/APK/is/saved.

Si no se cambia el contexto, Android no tratará su aplicación como una aplicación del sistema. Aparecerá en el iniciador como una aplicación con un icono genérico y zzz.package.namecomo nombre.

En los viejos tiempos (por ejemplo, Gingerbread), simplemente tenía que copiar el APK /system/app/y establecer los permisos adecuados. Los tiempos han cambiado.

Como complemento a su respuesta, algunas aplicaciones incluso requieren que extraiga y coloque sus libs en una carpeta específica también; si solo están los APK, sus íconos se muestran normalmente, pero se quejarán de que faltan libs en logcat una vez que los inicie.
@AndyYan Exactamente. Lo escribí mientras respondía, pero decidí que no era lo suficientemente importante como para mencionarlo :)
¿Cómo haría uno para hacer esa extracción @AndyYan?
@RubberDuck No he tenido la necesidad de realizar dicho procedimiento, pero si recuerdo lo que leí correctamente, si no coloca tales bibliotecas allí, la aplicación arrojará errores en logcat, diciéndole que necesita qué bibliotecas en qué localización. Las bibliotecas en sí deben ser independientes dentro del APK, extraerlas y colocarlas en las ubicaciones respectivas.
@AndyYan Creo que tiene algo que ver con SELinux, al menos en mi teléfono específico. Es bueno saber que los teléfonos fabricados en China (Alcatel, desafortunadamente) tienen cierto nivel de seguridad del sistema. Estaba personalizando el teléfono en el nivel NAND para alguien y me encontré con este problema.
pandalion98, ¿cuál es el significado de u:object_r:system_file:s0 en el comando chcon? Mi sistema emite un mensaje de error cuando trato de usar esta sintaxis. Gracias.