jueves, 6 de septiembre de 2012

Android: Como DESACTIVAR y/o ACTIVAR un componente (BroadcastReceiver, Activity, etc) dinamicamente


Para desactivar o activar desde código según condiciones algún componente Android como son BroadcastReceivers, Activities, Services, etc. ya sean registrados en el manifest o también desde código  se utiliza un objeto de la clase component, esto es especialmente útil cuando por ejemplo solo necesitan activar la funcionalidad al  100% de su aplicación bajas condiciones de los usuarios o acciones que estos realizen(Por ejemplo registrar la app usando un web service)

Vean el código:

//Activar

PackageManager pm = context.getPackageManager();    
pm.setComponentEnabledSetting(new ComponentName(context, Discovery.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED , PackageManager.DONT_KILL_APP);

//Desactivar


PackageManager pm = context.getPackageManager();      
pm.setComponentEnabledSetting(new ComponentName(context, Discovery.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);


.Heberth
heberth2788@gmail.com

Android: Como modificar un APK

En alguna oportunidad quizá necesitemos modificar el contenido de un APK y que éste continue siendo instalable. Lo que se necesita es lo siguiente:

  • El APK(Ejm: com.micasa.client.apk)
  • El keystore con el que se firmo el APK(Aunque leí que éste ultimo no es necesario, tambien podrian generar un nuevo keystore distinto al original con el que se firmo el APK, queda que ustedes lo prueben)(Ejm: myalmacendeclaves.heystore)(Generar una nuevo keystore, Ejm: keytool -genkey -v -keystore almacen-android -alias Theliel -keyalg RSA -keysize 2048 -validity 3650 )

Y las herramientas(Poner las rutas de estos ejecutables en la PATH del sistema para poder acceder desde cualquier directorio en el que nos encontremos):

  • apktool(http://code.google.com/p/android-apktool/)
  • jarsigner(http://www.oracle.com/technetwork/java/javase/downloads/index.html)
  • zipalign(http://developer.android.com/sdk/index.html)-Viene en el JDK de Android
El procedimiento a seguir es el siguiente:
  • Decompilar el APK
  • Modificar el contenido descomprimido(Archivos en RAW, manifest, imagenes, etc)
  • Recontruir el apk
  • Firmar el APK
  • Alinear el APK(Que en palabras simples es optimizarlo, osea que use menos memoria)(Se puede obiar éste paso)
Quiza le parescan demasiados pasos, pero se pueden por ejemplo poner todos éstos en un .bat(Windows) o en un .sh(Linux)

Comencemos:

Decompilamos el APK en una carpeta usando la herramienta apktool:

                apktool d -f com.micasa.client.apk .\decompilado\client

La "d" indica descomprimir, el "-f" indica que si existe la carpeta destino, la chancará.

Luego de esto debemos tener en la carpeta .\decompilado\client (Usted puede poner la que quiera) el apk descomprimido.

Modificar el contenido de los archivos descomprimidos, aqui viene la parte interesante, podemos por ejemplo cambiar alguna IP que tenga por defecto el APK, la imagen por defecto, los arhivos que tenga, etc, miles de cosas(Pos favor no usarlo para cosas oscuras (mentira))

Yo solo necesitaba modificar el contenido de un archivo en la carpeta RAW del APK, por lo que lo hice con ésta linea(en un .bat porsupuesto):

                    echo iptexto="192.168.1.21">.\decompilado\client\res\raw\auxiliar.txt

Recontruir el APK de la siguiente forma:

                      apktool b .\decompilado\client\ apk_client_sinfirmar_sinalineal.apk 

La "b" indica al contrario de "d", generar el APK o 'comprimirlo'. Ésta linea nos debería crear el APK llamado pk_client_sinfirmar_sinalineal.apk en el directorio actual donde nos encontremos, éste APK esta sin firmar y sin optimizar.

Firmar el APK, aquí usaremos nuestro archivo de almacén de claves(.keystore):

Para Java 7:
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore ./myalmacendeclaves.keystore  -storepass   -keypass  ./apk_client_sinfirmar_sinalineal.apk  

Para Java 6:
jarsigner -verbose -keystore ./myalmacendeclaves.keystore -storepass  -keypass  ./apk_client_sinfirmar_sinalineal.apk

Ejm para Java6: 
jarsigner -verbose -keystore ./myalmacendeclaves.keystore -storepass androidsp -keypass androidkey ./apk_client_sinfirmar_sinalineal.apk platform

Jarsigner es una herramienta que sirve para firmar en éste caso APKs,  "-keystore" indica que usaremos un archivo keystore para firmar,  "-sigalg MD5withRSA -digestalg SHA1" indican el algoritmo a usar para firmar, se debe especificar obligatoriamente para Java 7, en caso contrario saldrá un error al firmar, para Java 6 no es necesario ya que Android conserva la compatibilidad con Java 6 y no con Java 7(Por el momento).

Nuestro APK apk_client_sinfirmar_sinalineal.apk ahora ya se encuentra firmado, es importante primero firmar el APK y luego optimizarlos, ya que si se hace de la manera contraria, la optimización sera nula. Renombramos el apk de  apk_client_sinfirmar_sinalineal.apk a  apk_client_sinalineal.apk

Optimizar el APK, también se le conoce como alinear:

             zipalign -v 4  apk_client_sinalineal.apk com. micasa .client.apk

El "-v 4"  indica que el comienzo de cada archivo del APK(Ejm: imágenes, archivos de texto, etc) comience con un bloque de 32 bits(4 bytes)

---------------------------------------------------------------------------------------------------------------------------------

¡ Y listo ya tenemos nuestro nuevo APK modificado e instalable, 100% funcional !


.Heberth
heberth2788@gmail.com

miércoles, 5 de septiembre de 2012

Android: Como saber si una aplicación está instalada o no


En Android para poder conocer si un paquete en particular(conociendo su nombre Ejm: com.heberth.client) está instalado en el dispositivo o no se debe usar un objeto de la clase PackageManager y con un pequeño truco podremos saberlo, el código es el siguiente:

//Consultar el método
if(isAppInstaled("com.heberth.client"))
{
      Log.d(getClass().getSimpleName(), "Instalado");
}
else
{
    Log.d(getClass().getSimpleName(), "No Instalado");
}

//Método
 private boolean isAppInstaled(String nomPackage)
    {
    PackageManager manejadorPaquetes = getPackageManager();
    boolean ret=Boolean.FALSE;
    try
    {
    manejadorPaquetes.getInstallerPackageName(nomPackage);
       ret=Boolean.TRUE;
    }
    catch(Exception ex)
    {
    ret=Boolean.FALSE;
    }  
    return ret;
    }

Lo que hace éste método es valerse de try y catch cuando se llama al método getInstallerPackageName(nomPackage), ya que éste metodo devuelve una exepción cuando no logra encontrar el paquete en la lista de todos los paquetes instalados en nuestro Android.

.Heberth
heberth2788@gmail.com