Obtener información de un APK

Necesitamos utilizar la herramienta aapt (Android Asset Packaging Tool).

  • Entrar en el directorio donde se encuentra el SDK de Android:

$ cd $ANDROID_SDK_HOME

  • Localizar el comando “aapt”:

$ find . -name 'aapt'
./build-tools/26.0.2/aapt
./build-tools/25.0.2/aapt
./build-tools/25.0.3/aapt
./build-tools/23.0.3/aapt
./build-tools/26.0.1/aapt
./build-tools/24.0.3/aapt
./build-tools/24.0.1/aapt
./build-tools/24.0.2/aapt

  • Obtener información del APK:

$ ./build-tools/26.0.2/aapt dump badging /path/to/some.apk

La salida de este comando nos da diferente información (nombre del package, versiones de Android, permisos requeridos, …).

package: name='com.example.android.contactmanager' versionCode='1' versionName='1.0' platformBuildVersionName=''
sdkVersion:'5'
targetSdkVersion:'5'
uses-permission: name='android.permission.GET_ACCOUNTS'
uses-permission: name='android.permission.READ_CONTACTS'
uses-permission: name='android.permission.WRITE_CONTACTS'
application-label:'Contact Manager'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Contact Manager' icon='res/drawable-mdpi/icon.png'
application-debuggable
launchable-activity: name='com.example.android.contactmanager.ContactManager' label='Contact Manager' icon=''
uses-permission: name='android.permission.READ_CALL_LOG'
uses-implied-permission: name='android.permission.READ_CALL_LOG' reason='targetSdkVersion < 16 and requested READ_CONTACTS' uses-permission: name='android.permission.WRITE_CALL_LOG' uses-implied-permission: name='android.permission.WRITE_CALL_LOG' reason='targetSdkVersion < 16 and requested WRITE_CONTACTS' feature-group: label='' uses-feature: name='android.hardware.faketouch' uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' main other-activities supports-screens: 'small' 'normal' 'large' supports-any-density: 'true' locales: '--_--' densities: '120' '160' '240'

Abrir ventana Terminator maximizada

Me gusta utilizar la combinación de teclas control+shift+t para abrir nuevas ventanas del terminal. Es la que suele venir configurada por defecto.

Para que la ventana se abra ocupando toda la pantalla, sólo hay que editar el fichero $HOME/.config/terminator/config y, en dentro del apartado global_config fijar la propiedad window_state.

[global_config]
  window_state = maximise

Recomendación SDKMAN

SDKMAN es una herramienta genial que nos permite gestionar diferentes instalaciones de herramientas relacionadas con el mundo Java (JDK, Maven, Gradle, SpringBoot, …) desde la línea de comandos. Lo que es muy práctico es que permite que convivan, de forma muy fácil, diferentes versiones de estas herramientas.

$ sdk current

Using:

gradle: 3.4.1
grails: 3.2.7
groovy: 2.4.10
kotlin: 1.1.1
maven: 3.3.9
sbt: 0.13.13
scala: 2.12.1
springboot: 1.5.2.RELEASE

Si no lo estáis usando ya, os recomiendo que le echéis un ojo.

Saludos

No funciona el login JHipster Oauth 2

Al crear una aplicación con JHipster, habilitando la autenticación con Oauth2, me he encontrado que no era capaz de entrar en la app generada con los usuarios por defecto (admin y user).

El “problema”, si no he entendido mal, es que jhipster está generando incorrectamente un fichero .csv, que posteriormente cargará en la BBDD.

src/main/resources/config/liquibase/oauth_client_details.csv

Este fichero tenía la siguiente pinta:

client_id;resource_ids;client_secret;scope;authorized_grant_types;web_server_redirect_uri;authorities;access_token_validity;refresh_token_validity;additional_information;autoapprove
<%= baseName %>app;res_<%= baseName %>;my-secret-token-to-change-in-production;read,write;password,refresh_token,authorization_code,implicit;;ROLE_ADMIN,ROLE_USER;1800;2000;{};true

Se trata de sustituir el tag: <%= baseName %> por el nombre de tu aplicación. Suponiendo que tu app se llame “example”, quedaría así:

client_id;resource_ids;client_secret;scope;authorized_grant_types;web_server_redirect_uri;authorities;access_token_validity;refresh_token_validity;additional_information;autoapprove
exampleapp;res_example;my-secret-token-to-change-in-production;read,write;password,refresh_token,authorization_code,implicit;;ROLE_ADMIN,ROLE_USER;1800;2000;{};true

Una vez hecho esto, rearrancamos la app y al volver a cargar los datos de la BD ya tiene las referencias correctas y ya es posible hacer login.

Realmente no tengo muy claro si esto es un bug de JHipster o símplemente es que no he seguido todos los pasos necesarios para configurar la instalación.

Bonus: Para visualizar el contenido de la BD h2 en memoria, es posible utilizar el cliente web al que podemos acceder en la siguiente dirección: http://localhost:8080/h2-console.

Saludos y espero que le sirva a alguien

Gradle, Sonar e Informes de cobertura (Jacoco)

Para un proyecto java simple.

El análisis estático de SonarQube se lanza desde Jenkins.

sonar-project.properties:

sonar.projectKey=com.sourcerebels:some_project
sonar.projectName=SomeProject
sonar.projectVersion=1.0
sonar.language=java
sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.java.binaries=build/classes/main
sonar.jacoco.reportPaths=build/jacoco/test.exec

build.gradle

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'jacoco'

mainClassName = "SomeProject"
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:2.7.16'
}

JitPack.io mola mucho

Hace ya un tiempo que vengo siguiendo este servicio (he visto que mucha gente lo va utilizando). No voy explicar nada del otro mundo, simplemente quiero recomendar su uso.

JitPack.io es un servicio que permite publicar un tag concreto de un repositorio de Github en su repositorio de Maven.

El esfuerzo necesario para publicar i/o utilizar una librería de Android es tan poco que parece mentira.

Este repositorio es compatible con los sistemas de construcción: Maven (Java), Gradle (Java, Android, Groovy), SBT (Scala) o Leiningen (Clojure).

Mola mucho. Buen trabajo 🙂

Centralizar las versiones de las librerías utilizadas por Gradle

Cuando tenemos un proyecto con varios módulos, a veces, nos interesa tener un lugar centralizado dónde definir las versiones de las librerías que utilizaremos.

De esta manera, si varios módulos del proyecto, utilizan la misma librería nos aseguraremos que todos estén usando la misma versión.

En el fichero build.gradle de la carpeta raíz, en el apartado “ext”, definiremos las versiones a utilizar:

ext {
    supportLibrary = '24.2.0'
    googlePlayServices = '9.4.0'
    junit = '4.12'
}

En el fichero build.gradle de cada uno de los módulos, en el apartado “dependencies”, haremos referencia a las versiones definidas de la siguiente manera:

dependencies {

    def versions = rootProject.ext

    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile "junit:junit:" + versions.junit
    androidTestCompile "junit:junit:" + versions.junit
    compile "com.android.support:appcompat-v7:" + versions.supportLibrary
    compile "com.android.support:design:" + versions.supportLibrary
    compile "com.google.android.gms:play-services-maps:" + versions.googlePlayServices
    compile "com.google.android.gms:play-services-location:" + versions.googlePlayServices
}