Resultados 1 al 3 de 3


[Tutorial] [GUÍA] - [MOD] Click y Click Largo sobre hora en cabecera de Cortina y/o barra de estado


Estás en el tema [Tutorial] [GUÍA] - [MOD] Click y Click Largo sobre hora en cabecera de Cortina y/o barra de estado dentro del subforo Tutoriales - Samsung Galaxy S III en Esp-Desarrolladores. En este tutorial os voy contar una de las formas de implementar este mod. Vamos a trabajar sobre SystemUI y presupongo que quien vaya a seguir este tutorial sabe compilar y descompilar. La idea es la siguiente. Cuando desplegamos la cortina (veremos también que nos vale sobre la hora en la barra de estado), si pulsamos sobre la hora de la cabecera de cortina, vamos a lanzar una aplicación. Si el click es largo, pues lanzamos otra, por ejemplo. Os voy a poner un código, que además de...



Este tema tuvo 1856 Visitas y 2 Respuestas

Actualmente hay 1 usuarios viendo este tema. (0 miembros y 1 visitantes)

  1. #1
    Fecha de ingreso
     Mar-2013
    Mensajes
     12,594
    Gracias Enviadas
    8,662
    Agradecido 22,992 Veces en 7,864 Posts


    En este tutorial os voy contar una de las formas de implementar este mod.

    Vamos a trabajar sobre SystemUI y presupongo que quien vaya a seguir este tutorial sabe compilar y descompilar.

    La idea es la siguiente. Cuando desplegamos la cortina (veremos también que nos vale sobre la hora en la barra de estado), si pulsamos sobre la hora de la cabecera de cortina, vamos a lanzar una aplicación. Si el click es largo, pues lanzamos otra, por ejemplo.

    Os voy a poner un código, que además de hacer esto, realiza una pequeña vibración al ejectuarse cada uno de los mods y además pone un mensaje de error si no puede ejecutarse la aplicación que hayáis puesto (por ejemplo, si se ha desinstalado).

    He simplificado el código para que sea más didáctico, pero se puede jugar con él. Por ejemplo, podemos hacer que si la aplicación no se puede lanzar no vibre. Por supuesto en mi mod, irá con opciones de configuración sobre la función a ejecutar, si vibra o no, etc. Pero eso será motivo de otro tuto más adelante.

    Este mod, de forma similar, se puede implementar sobre la fecha (dateview.smali)

    Vamos a ello.


    - Descompilamos systemui (o quien quiera directamente que desensamble el classes.dex del systemui).
    - Nos dirigimos a com/android/systemui/statusbar/policy/ y abrimos con notepad++ el smali Clock.smali.

    - Lo primero que tenemos que hacer es indicar que esta clase implementa los métodos de click y click largo.
    Para ello, debajo de
    Código:
    .class public Lcom/android/systemui/statusbar/policy/Clock;
    .super Landroid/widget/TextView;
    .source "Clock.java"
    pondremos lo siguiente
    Código:
    # interfaces
    .implements Landroid/view/View$OnClickListener;
    .implements Landroid/view/View$OnLongClickListener;
    - Lo segundo, es en el constructor establecer ambos eventos. Para ello, localizamos el método

    Código:
    .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    y justo antes del return-void ponemos lo siguiente

    Código:
    invoke-virtual {p0, p0}, Lcom/android/systemui/statusbar/policy/DateView;->setOnClickListener(Landroid/view/View$OnClickListener;)V
    
    invoke-virtual {p0, p0}, Lcom/android/systemui/statusbar/policy/DateView;->setOnLongClickListener(Landroid/view/View$OnLongClickListener;)V

    Pues nada, ya tenemos preparado el armazón. Si compiláramos ahora y metiéramos el systemui en el sistema, al pulsar os dará un fc por que lógicamente no hemos implementado los métodos que atienden ambos eventos. Vamos a ello.


    - Método para el Click. Lanza la apk del reloj. Se pone después de #virtual methods


    Código:
    .method public onClick(Landroid/view/View;)V
        .locals 3
        .parameter "v"
    
        iget-boolean v0, p0, Lcom/android/systemui/statusbar/policy/Clock;->mExpandedHeader:Z  #si quitamos esta línea (debemos quitar las dos siguientes en ese caso)
    																							#el click se ejecutará también sobre el reloj en la barra de estado
    
        move/from16 v1, v0 																		# mExpandedHeader=1 quiere decir que la cortina está desplegada, 
    																							#= 0 no desplegada, hemos pulsado sobre el reloj de la barra de estado
    
        if-eqz v1, :cond_a																		#esto sobraría también si queremos ejecutarlo sobre el reloj en barra de estado. 
    	
    	invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/Clock;->vibrar()V 			#llamamos a una función que realizará una pequeña vibración, luego lo vemos.		
    	
    	const-string v2, "com.sec.android.app.clockpackage" 									#nombre de la apk. Se obtiene descompilando la apk que queramos, en su manifiest el packagename
    
        invoke-direct {p0, v2}, Lcom/android/systemui/statusbar/policy/Clock;->lanzar_aplicacion(Ljava/lang/String;)V 	#método para lanzar la aplicación con seguridad y sin fcs.
    	
        invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/Clock;->cerrar_cortina()V 	#cerramos la cortina
    
     	:cond_a
    
        return-void
    .end method
    Luego vemos los métodos llamados desde el onclick, pero como véis es un código sencillito. Para el longClick el método es muy similar. En el ejemplo os pongo un nombre incorrecto para que podáis comprobar que salta el error y se pone el mensaje.

    Lo ideal sería poner la línea de código que hace la vibración, dentro del método de lanzar la aplicación, o mejor aún, que ésta devuelva un boolean o integer con un 1 si se lanzó bien o un 0 si no, y en caso positivo, vibrar.
    Pero para el objetivo del tuto y por claridad para que podáis aprovechar el código en vuestros trabajos, lo dejo así.

    Pues nada, el código para el longclick es muy parecido, sólo difiere en el ejemplo, en que necesitamos controlar el estado de la pulsación de forma muy simple, y devolver el estado al sistema, tal y como está definido este evento en android.
    Como véis, lo mismo prácticamente. Se pone también después de #virtual methods, al tratarse de un .method public

    Código:
    .method public onLongClick(Landroid/view/View;)Z
     	
        .locals 4
        .parameter "v"
    	
        const/4 v3, 0x0
    
        invoke-virtual {p1, v3}, Landroid/view/View;->setPressed(Z)V	
    
        iget-boolean v0, p0, Lcom/android/systemui/statusbar/policy/Clock;->mExpandedHeader:Z
    
        move/from16 v1, v0
    
        if-eqz v1, :cond_a
    
    	invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/Clock;->vibrar()V		
    	
    	const-string v2, "com.sec.android.app.clockpackagessssss"  #esto no existe, es para provocar un casque y que salte el mensaje, poned uno bueno.
    
        invoke-direct {p0, v2}, Lcom/android/systemui/statusbar/policy/Clock;->lanzar_aplicacion(Ljava/lang/String;)V
    	
        invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/Clock;->cerrar_cortina()V
    
     	:cond_a
    	
        const/4 v3, 0x1
    
        return v3
    	
    .end method
    Si compiláramos ahora y lo metiéramos en el teléfono os daría fc al pulsar, porque nos faltan los métodos cerrar_cortina, lanzar_aplicacion y vibrar. Vamos a ello.

    Si os fijáis los llamo con un invoke-direct a ellos. Esto significa que hay que definirlos como métodos privados de la clase. En este ejemplo os los pongo dentro del propio smali, si bien en otro tuto os explicaré cómo podemos hacer un smali con todas estas funcionalidades auxiliares de forma que se
    puedan invocar desde cualquier clase del systemui. Esto tiene sus pros y sus contras. A mi me gusta más repetir a veces el código (por ejemplo, cerrar_cortina, poner_mensaje, etc.) en las clases e invocarlo con invoke-direct pues como véis en ram es ridículo lo que ocupa el código, sin embargo, es más rápida la ejecución y consume menos recursos y batería. Depende del caso. :)

    Al tratarse de métodos privados los debemos escribir antes del

    Código:
    # virtual methods
    que encontraréis en prácticamente todos los smalis. También podéis localizar #direct methods y escribirlos justo después, para no liaros.

    Dicho esto vamos a ver los métodos.


    - Cerrar Cortina

    Código:
    .method private cerrar_cortina()V
        .locals 3
    
        const-string v2, "statusbar"
    
        invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/Clock;->getContext()Landroid/content/Context; #siempre necesitamos el contexto para estas cosas, depende de dónde andemos se consigue de una forma u otra, aquí es así.
    
        move-result-object v1	#el context
    	
    
        invoke-virtual {v1, v2}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object; #puntero a la clase del statusbar
    
        move-result-object v0
    
        check-cast v0, Landroid/app/StatusBarManager; 
    
        .local v0, sbm:Landroid/app/StatusBarManager;
        invoke-virtual {v0}, Landroid/app/StatusBarManager;->collapse()V #que se cierre
    
        return-void
    .end method
    La vibración...


    Código:
    .method private vibrar()V
        .locals 4
    
        .prologue
    	
        invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/Clock;->getContext()Landroid/content/Context;
    
        move-result-object v0	#aquí el context
    
        const-string v1, "vibrator"
    
        invoke-virtual {v0, v1}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object; #obtenemos el puntero al servicio de vibración del sistema
    
        move-result-object v2
    
        check-cast v2, Landroid/os/Vibrator;
    
        const-wide/16 v3, 0x3c #duración en milisegundos de la vibración, en hexadecimal
    
        invoke-virtual {v2, v3, v1}, Landroid/os/Vibrator;->vibrate(J)V #a vibrar, venga.
    
        return-void
    .end method
    Vamos a lanzar la aplicación, parecido al método que os puse en el tuto de los botones de accesos a apks, un poco diferente. Este lanza una aplicación, si queréis lanzar una actividad concreta de una aplicación, revisad los tutos que puse para hacer botones..


    Código:
    .method private lanzar_aplicacion(Ljava/lang/String;)V
        .locals 5
    
        invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/Clock;->getContext()Landroid/content/Context;
    
        move-result-object v0 #en v0 tenemos el context
    
        invoke-virtual {v0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;
    
        move-result-object v2 #instancia del packagemanager del android
    
        invoke-virtual {v2, p1}, Landroid/content/pm/PackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent; # p1 es el string con el nombre de la apk con que invocamos este método
     
        move-result-object v3 		#el intent para lanzar la aplicación, ya podemos intentarlo, je je..
    
        :try_start_0   #iniciamos la captura de excepciones, así evitamos un fc de campeonato en caso de error al llamara a la apk
    	
        invoke-virtual {v0, v3}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V  #iniciamos la aplicación
    	
        :try_end_0  #fin de capturas de casques 
        .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0   #si tenemos un casque nos vamos a posición (label) :catch_0
    
        :goto_0
        return-void  #salimos
    
        :catch_0    #si hay casque al lanzar la aplicación, el código continúa aquí
    	
        move-exception v1  #en v1 tenemos la excepción, podríamos escribirlo al log por ejemplo o tratarla, aquí pasamos de hacer nada con la excepción
    
        const-string v4, "Error lanzando la aplicación. Revisa tu configuraci\u00f3n"  #mensaje que va a salir con el casque
    	
    	invoke-direct {p0, v4}, Lcom/android/systemui/statusbar/policy/Clock;->pon_mensaje_error(Ljava/lang/String;)V  #llamamos a la función de poner mensaje y le pasamos el texto que hemos definido
    
        goto :goto_0
    .end method


    Y este ya le conocéis de otros tutos, se trata de poner un mensaje..., pone "Atención: "+ mensaje pasado

    Código:
    .method private pon_mensaje_error(Ljava/lang/String;)V
        .locals 5
    
    
        invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/Clock;->getContext()Landroid/content/Context;
    
        move-result-object v1	
    	
    
        new-instance v2, Ljava/lang/StringBuilder;
    
        invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
    
        const-string v3, "Atenci\u00f3n: "
    
        invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    
        move-result-object v2
    
        invoke-virtual {v2, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
    
        move-result-object v2
    
        invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    
        move-result-object v2
    
        const/4 v0, 0x1
    
        invoke-static {v1, v2, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
    
        move-result-object v4
    
        invoke-virtual {v4}, Landroid/widget/Toast;->show()V
    
        return-void
    .end method

    Pues nada, espero que os sea de utilidad, como véis no es tan complicado y resulta útil. Esta técnica se puede usar en otros sitios, es cuestión de que investiguéis un poquito....

    Última edición por Grouxho; 14-10-13 a las 22:05


  2. Los siguientes 5 Usuarios dieron las gracias a Grouxho Por su Mensaje :

    axl33 (15-10-13),Dav88 (13-12-13),luiso51 (15-10-13),mrbojangle69 (29-10-13),victorgordis (15-10-13)




  3. #2
    Fecha de ingreso
     May-2013
    Mensajes
     211
    Versión de ROM
     FancierROM NewMAX
    Modelo de smartphone
     Samsung Galaxy Note 3
    Tu operador
     Vodafone
    Gracias Enviadas
    127
    Agradecido 151 Veces en 86 Posts


    No es tan complicado,no...para ti. Ya sólo ver tanto código junto me empieza a dar vueltas la cabeza. Ainsss que tendría que haber estudiado un poco más...

  4. #3
    Fecha de ingreso
     Aug-2013
    Ubicación
     Las Palmas de Gran Canaria
    Mensajes
     1,332
    Versión de ROM
     YtseJam v1 by mrbojangle69 + Modem I9300BUUGMK1
    Versión de Kernel
     Boeffla-Kernel-5.2-beta1
    Modelo de smartphone
     Samsung GSIII GT-I9300 Android 4.3 Jelly Bean JSS15J.XXUGNA7
    Tu operador
     Movistar
    Gracias Enviadas
    646
    Agradecido 572 Veces en 378 Posts


    Muy buen tuto, sobre todo lo más importante de él es que es práctico, haces una cosa concreta para que él que quiera hacerlo tenga un ejemplo. Bajo mi punto de vista, estos tutos tienen el objetivo de motivar al aprendiz de programador Android a investigar en el código y sacar conclusiones que le servirán para más adelante.

    Enhorabuena señor Marx.

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •  


ESP-Desarrolladores

    ESP-Desarrolladores, es una comunidad de desarrollo Android en habla hispana, Aquí encontrarás lo último en Android, ROMs, Kernel, APPs, etc... Pasa y Ponte Cómodo!!! estás en tu casa ;)

Síguenos en

Twitter Facebook Google+ espdesarrolladores - Andyou Youtube RSS Feed