«

»

nov 27 2013

Usar códigos secretos en tu aplicación

androcode_secret_code

Estoy seguro de que todos habréis usado alguna vez un “código secreto” en vuestro móvil. Son los códigos que al introducirlos en el teclado del “teléfono” (el de llamar, que los smartphones también hacen eso, eh) permiten acceder a alguna función especial, como ver el IMEI (*#06#) o información del teléfono (*#*#4636#*#*). Pero no queda ahí la cosa, porque podemos crear nuestros propios códigos, y vamos a ver cómo.

¿De dónde viene esto?

protips_original_recorteBueno, de dónde viene realmente no lo sé, pero sí os diré cómo me enteré yo de su existencia. Hace unos (muchos) meses estaba preparando un teléfono viejo para dárselo a alguien, ya sabéis, configurar algunas cosas e instalar aplicaciones básicas. Como tenía versión 2.3, sin duda le puse en la pantalla principal el widget de bienvenida que traía Android por aquel entonces, ¿lo recordáis? Pero tuve una mejor idea: modificar el widget para poner consejos y mensajes más personales. Así de detallista soy :p. Así que me bajé el código fuente (gracias, Open Source), me creé un proyecto con él y empecé a cambiar cosas. Sorpresa la mía al ver en el AndroidManifest.xml un Intent-Filter que no había visto antes:

<receiver android:name=".ProtipWidget" android:label="@string/widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.android.protips.NEXT_TIP" />
                <action android:name="com.android.protips.HEE_HEE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.provider.Telephony.SECRET_CODE" />
                <data android:scheme="android_secret_code" android:host="8477" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_build" />
        </receiver>

Ese android.provider.Telephony.SECRET_CODE es bastante llamativo, ¿no? Con el número 8477 (que corresponde al Phoneword de “TIPS”) en los datos y la acción perteneciente al paquete Telephony, no hay que ser un genio para deducir que ese código se introduce en el marcador del teléfono. Lo hice y… Voilà! Los consejos del widget cambiaron por completo:

protips__secret

¡Toma huevo de pascua! Como veis, al introducir el código los consejos originales cambian por unos en tono más de humor. Y como de costumbre en Android, si el widget puede nosotros también.

¿Por qué os cuento esto? Pues para que sirva de moraleja: leyendo código fuente, tanto de Android como de otros proyectos, se aprende mucho.

Déjate de rollos, cómo se hace

El funcionamiento de los códigos secretos propios no tiene misterio. En el anterior extracto de manifiesto tenéis la mitad del trabajo hecho. Sólo hay que añadir un Intent-Filter a nuestro AndroidManifest.xml con la acción android.provider.Telephony.SECRET_CODE, y con la especificación de esquema “android_secret_code” y nuestro número secreto como host. Hay que tener en cuenta que estos códigos se introducen en el dialer en formato *#*#código#*#*, pero nosotros aquí sólo especificamos el número.

La segunda parte es añadir el elemento que recibe ese Intent. Podría ser cualquiera, por ejemplo una Activity o un Broadcast Receiver que active cierta función en la aplicación. Una implementación básica podría ser:

public class SecretCodeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.provider.Telephony.SECRET_CODE")) {
            String numero = intent.getData().getHost();
            if (numero.equals("732738")) {
                Toast.makeText(context, "¡Función chachipiruli altamente secreta desbloqueada!", Toast.LENGTH_SHORT).show();
            } else {
                // Podemos usar el mismo receiver para otros códigos distintos
            }
        }
    }
}

Y listo. Por supuesto las posibilidades no acaban aquí. Ya sabéis lo versátiles que son los Intents, así que posibilidades de explotar esta pequeña función hay infinitas. A mí se me ocurren varias aparte de los huevos de pascua y pantallas ocultas. ¿Y a vosotros? ¿Para qué usaríais los códigos secretos? ¿Los conocíais ya?

Acerca del autor

Rafa Vázquez

Estudio Ingeniería Informática del Software en Sevilla. Me considero geek sin dinero, amante y desarrollador novato de Android. He creado algunas aplicaciones como SeviBus, TicTacDroide, Kill Bieber y Traductor Hoygan, si es que se puede llamar aplicaciones a estas dos últimas ;) Ganas de aprender más y más no me faltan, e intentaré compartir mis experiencias con vosotros en la medida de lo posible.

  • hgramaje

    No tenía ni idea de que existía esta funcionalidad. A explotarla pero YA!!!

  • http://www.forgottenprojects.com/ Fernando F. Gallego

    Lo vi hace un tiempo y lancé una pregunta pero va a ser que es imposible recibir números arbitrarios si no están previamente definidos en el manifest, vamos que no puedes aceptar cualquier número, sólo los que definas. También es conveniente introducir algún símbolo, no sea que en algún país se use ese número e interfieras con el marcado convencional.

    También es útil para la típica pantalla de opciones para el developer pero recordad que los intent filters se pueden encontrar usando comandos de adb y el package manager así que secretos del todo no son.

    • http://about.me/sloy Sloy

      Correcto, sólo te llegan códigos que definas tú. Eso impone más limitaciones, aunque también evita muchas malas prácticas por parte de algunos.

      Por supuesto que no es un “secreto absoluto”, es útil para esconder cosas que no quieres que estén a la vista o que cualquiera encuentre fácilmente, como huevos de pascua u opciones de debug (eso hago yo en SeviBus).

  • Sergio

    Hola, he creado mi propio código y no he conseguido que se ejecute el Toast. lo he probado con Andorid 4.3 y 4.4.2.

    Puse las almohadillas y asteriscos, como dices en el post.

    Hace falta algún permiso o algo¿?

    Gracias de antemano.

  • Giordano

    Intentaré aprender desde vuestras experiencias Rafa Vázquez.