Inicio > Delphi > Información de batería (Android – XE5)

Información de batería (Android – XE5)

Share Button

images

En esta entrada vamos a tratar de cómo obtener infoemación del estado de la batería de un dispositivo Android.

En algunos casos se trata como un sensor más del sistema, aunque en Delphi XE5, no se tiene en cuenta en las clases específicas para acceder a los sensores.
Sea como sea, no es más que una forma de obtener información de un aspecto más, de nuestros dispositivos.

Para acceder a la información de la batería del dispositivo vamos a hacerlo utilizando “Intents”. En Delphi podemos acceder a ellos a través de la clase JIntent, definida en la unit Androidapi.JNI.GraphicsContentViewText.

Un ejemplo de utilización de la clase JIntent, para abrir una página en el navegador o para abrir un fichero, podéis verla en esta pregunta de stackoverflow y la respuesta por parte de Rodrigo Ruz.

Un “Intent” es una forma de solicitar/pedir a nuestro dispositivo Android que necesitamos invocar a un “componente”. Un componente puede ser parte de la interfaz gráfica, un servicio, un código que se ejecuta, un “broadcast receiver” o un proveedor de contenido, por citar algunos.
images (1)Simplificando, diremos que un “intent” es una forma de interactuar con otra aplicación, ya sea para añadir datos o para pedir información. Y podemos podemos dividirlos en 2 tipos:

  • Llamada a otra aplicación.
  • Llamada a otra aplicación y esperar respuestas desde ella.

En es link, podemos acceder a la información de la clase Intent en Android. En la parte inferior están definidas las ACTIONS que podemos utilizar según categorías.

Una vez creado un “intent” lo primero que debemos hacer es definirle una o más acciones que queremos asociarle.

0
1
2
3
4
5
// Creamos y Configuramos el Intent
filter := TJIntentFilter.Create;
// Asociamos la ACTION que queremos capturar
filter.addAction(TJIntent.JavaClass.ACTION_BATTERY_CHANGED);
// lo registramos
intentBatt := aContext.RegisterReceiver(nil, filter);

Por último, en este trozo de código aparece una llamada a RegisterReceiver.
Necesitamos utilizar este método, ya que la acción ACTION_BATTERY_CHANGED, que utilizaremos, necesita registrarse para recibir notificaciones (tal como explica en la documentación).

“Broadcast Action: This is a sticky broadcast containing the charging state, level, and other information about the battery. See BatteryManager for documentation on the contents of the Intent.”

Una vez registrado, ya podemos empezar a interrogarlo.

Si accedemos a la documentación de BatteryManager, podemos ver todos los valores por los que podemos preguntar y las constantes necesarias para hacerlo.  Para ello utilizaremos un código como el que se ve a continuación:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// health
i := intentBatt.getIntExtra(StringToJString('health'), -1);
Memo1.Lines.Add('Salut: ' + BateryHealthStr[i]);
// Icon
//  i := battery.getIntExtra(StringToJString('icon-smal'), -1);
//  Memo1.Lines.Add('icon-smal: ' + IntToStr(i));
// Nivel de batería
iLevel := intentBatt.getIntExtra(StringToJString('level'), -1);
Memo1.Lines.Add('Level: ' + IntToStr(iLevel));
// Plugged
i := intentBatt.getIntExtra(StringToJString('plugged'), -1);
Memo1.Lines.Add('Enchufado: ' + BateryPluggedStr[i]);
// battery present
b := intentBatt.getBooleanExtra(StringToJString('present'), False);
Memo1.Lines.Add('Presente: ' + BoolToStr(b, True));
// Escala para medir el nivel
iScale := intentBatt.getIntExtra(StringToJString('scale'), -1);
Memo1.Lines.Add('Escala: ' + IntToStr(iScale));
// status de la batería
i := intentBatt.getIntExtra(StringToJString('status'), -1);
Memo1.Lines.Add('Estado: ' + BateryStatusStr[i]);
// tecnología de la batería
Str := intentBatt.getStringExtra(StringToJString('technology'));
Memo1.Lines.Add('Tecnología: ' + JStringToString(Str));
// Temperatura (en décimas de grado)
i := intentBatt.getIntExtra(StringToJString('temperature'), -1);
Memo1.Lines.Add('Temperatura: ' + FloatToStr(i / 10) + '°');
// Voltage (en MILIVOLTIOS)
i := intentBatt.getIntExtra(StringToJString('voltage'), -1);
Memo1.Lines.Add('Voltaje: ' + FloatToStr(i/1000) + ' v.');

Antes de acabar, hacer referencia a la línea que obtiene el contexto de la aplicación, que utiliza la función SharedActivityContext, y que está definida en la unit FMX.Helpers.Android.

0
1
// Contexto
myContext := SharedActivityContext;

Imagen672He generado un formulario para poder visualizar los valores que se obtienen de cada una de las constantes.

En la documentación además podemos encontrar que para obtener el nivel de batería (Level) tenemos que tener en cuenta el valor de Scale.

El valor de la temperatura se expresa en grados celsius y viene en décimas de grado.

Y por último, el voltaje de la batería viene expresado en milivoltios.

Os dejo el código fuente del proyecto y el instalable para Android (apk).

<Código fuente>

<Instalable apk>

Un pequeño vídeo de la aplicación corriendo en mi teléfono.

Información de la batería. XE5 en Android.

 

Imagen674Finalmente, aunque no tenga que ver expresamente con este tema, al generar la aplicación para un dispositivo, he tenido que completar algunos pasos finales.

Desde las opciones del proyecto, podemos seleccionar, de forma similar a como se hace en las aplicaciones de escritorio, el icono (en las diferentes resoluciones) que va a tener nuestra aplicación.

También desde la configuración, las diferentes orientaciones que va a admitir nuestra aplicación cuando se ejecute en los dispositivos.

Imagen675

Imagen676

Un saludo y hasta la próxima.

Share Button
Categories: Delphi Tags: , ,
  1. martes, 19 de noviembre de 2013 a las 01:00 | #1

    Hola,

    He llegado a esta entrada buscando otra cosa pero mira tú por dónde no hay mala búsqueda que por bien no venga. :)

    ¡Gracias Germán!

  2. Neftalí
    martes, 19 de noviembre de 2013 a las 09:03 | #2

    Hola David.
    Ya he visto que has añadido a los componentes la clase para el acceso a la información de la batería.
    Fantástico. ;-)

    ________________
    Germán

  3. Enrique
    martes, 20 de enero de 2015 a las 16:55 | #3

    Hola Germán.

    Sé que tiene tiempo este post, pero ando revisando y no encuentro nada parecido.
    ¿Sería posible controlar cuando se dispara la cámara integrada del teléfono (ya sea delantera o trasera) y obtener la fotografía que acaba de realizar? No se si con Delphi XE5, XE6 o XE7 podría realizar algo así.

    Sé que podría hacerlo con la aplicación que estoy desarrollando pero lo que quiero es lo contrario que el usuario saque las fotos normalmente entrando directamente en la cámara y no en mi aplicación.

    Gracias por tu blog y por todo de ante mano.

    Saludos,
    Enrique.

  4. Neftalí
    martes, 20 de enero de 2015 a las 17:53 | #4

    @Enrique
    Tal vez revisando el directorio donde se almacenan. No se si puedes capturarlas directamente cuando se hacen.

  5. Enrique
    martes, 20 de enero de 2015 a las 18:02 | #5

    @Neftalí
    Estuve mirando y revisando y creo que he encontrado algo que me puede servir: ACTION_NEW_PICTURE lo probaré y te diré pero gracias de todos modos!

  1. Sin trackbacks aún.
What is 14 + 19 ?
Please leave these two fields as-is:
IMPORTANTE! Para continuar, debes contestar la pregunta anterior (para evitar SPAM) :-)