30 abr. 2011

Reproducir una canción en un Celular con Android desde python

Pensaba escribir primero como crear opciones a un  menú pero recordé que existe la posibilidad de reproducir una canción mp3 desde python con el API de SL4A.

Las opciones que tiene el API de SL4A para reproducir música son las siguientes:

  • mediaIsPlaying: Consulta si la canción se está reproduciendo en ese momento.
  • mediaPlayInfo: Retorna información de la canción.
  • mediaPlay: Se reproduce la canción.
  • mediaPlayList:
  • mediaPlayPause: Se pausa la canción.
  • mediaPlaySeek: Se reproduce la canción en un tiempo determinado.
  • mediaPlaySetLooping: Se define si se reproduce de nuevo la canción automáticamente.
  • mediaPlayStart: Inicia la reproducción del archivo 
  • mediaPlayClose: Se cierra el archivo de la canción.
Solamente se utilizaraá en este post las funciones mediaPlay y mediaPlayInfo.

 La idea es listar los archivos mp3 en el widget de selección simple y luego reproducir la canción seleccionada.

Antes de reproducir la canción, se toma información de la canción, principalmente la duración de la canción, ese tiempo es luego manejado por una barra de progreso que avanza  mientras se reproduce la canción.

El código del programa se muestra a continuación:

#Importar el modulo android,path, la funcion sleep,listdir y exit.
import android
from time import sleep
from os import listdir
from os import path
from sys import exit


#La ruta donde se encuentran los mp3s
ruta = "/sdcard/mp3z/"


#Se crea la instancia de android
droid = android.Android()
#Se muestra un mensaje si se desea reproducir una cancion.si es si, se reproduce si no se sale del programa.
droid.dialogCreateAlert("Reproducir una cancion", "Desea reproducir una cancion?")
droid.dialogSetPositiveButtonText('Si')
droid.dialogSetNegativeButtonText('No')
droid.dialogShow()


#Se captura la respuesta.
respuesta = droid.dialogGetResponse()


if respuesta[1]['which'] == "positive":
    #Se busca los archivos y directorios de la ruta definida.
    archivos = listdir(ruta)
    #Se crea una lista vacia donde se agregaran los nombres de archivos mp3s
    listado = []
    #Se agregan los archivos mp3 a la lista
    for i in archivos:
        #Si es un archivo se agrega a listado, se pasa la ruta y el archivo.
        if path.isfile("%s%s" %(ruta,i)):
            listado.append(i)
            
    #Se muestra un mensaje con la lista de canciones que se pueden reproducir.
    droid.dialogCreateAlert("Reproducir una cancion")
    droid.dialogSetSingleChoiceItems(listado)
    droid.dialogSetPositiveButtonText('Seleccione')
    droid.dialogSetNegativeButtonText('Salir')
    droid.dialogShow()
    #Se captura la respuesta y el item seleccionado
    respuesta  = droid.dialogGetResponse().result
    item = droid.dialogGetSelectedItems()
    #Si la respuesta es positiva se reproduce la cancion
    if  respuesta['which'] == "positive":
        droid.makeToast("La cancion selecionada es: %s " %listado[int(item[1][0])])
        sleep(2)
        droid.makeToast("Reproduciendo la cancion")
        #Se agrega a cancion la cancion seleccionada segun la variable item.
        cancion = listado[int(item[1][0])]
        #Se reproduce la cancion pasando la ruta donde esta el archivo y el archivo.
        droid.mediaPlay("%s%s" %(ruta,cancion))
        #Se captura la duracion de la cancion representado en milisegundos
        tiempo = int(droid.mediaPlayInfo()[1]["duration"])
        #Se pasa la duracion de la cancion de milisegundos a segundos
        duracion = int(tiempo /1000)
        #Se crea una barra de progreso con el titulo reproduciendo, mensaje el nombre de la cancion y la duracion.
        droid.dialogCreateHorizontalProgress("Reproduciendo",cancion,duracion)
        #Se muestra el widget.
        droid.dialogShow()
        #Se incrementa el valor de la barra de progreso cada 1 seg.
        for i in range(0,duracion):
            sleep(1)
            droid.dialogSetCurrentProgress(i)
        #Al finalizar la cancion se muestra un mensaje de fin de la cancion y se sale de la aplicacion.
        droid.makeToast("Fin de la reproduccion de la cancion")
        droid.dialogDismiss()
    else:
        #Si no se selecciono una cancion se sale del programa
        droid.makeToast("No se selecciono una cancion-Se sale de la aplicacion")
        sleep(1)


else:
    #Se selecciono que no se desea reproducir una cancion
    droid.makeToast("Fin del programa")
    exit()

La siguiente figura muestra la ventana donde se pregunta si se desea reproducir una canción:
La siguiente figura muestra la lista de canciones que se puede reproducir, se selecciona una y luego se le da al botón seleccione.

La última figura muestra el proceso de reproducción de la canción:

A continuación se muestra el código QR del programa:

23 abr. 2011

Tomar una foto desde android con un temporizador desde python

La idea es decirle a un programa el tiempo en que se tomará una foto, al cumplirse el tiempo se toma la foto y se guarda en un directorio donde luego se abre una página web en el celular que muestra la foto en el celular.

El artículo se basa en un programa hecho en  ruby donde crea se crea un script que toma fotos de manera remota con el celular;  el artículo del programa en ruby se encuentra   acá.

Se usará la función cameraCapturePicture pasandole el archivo donde se va a guardar la foto.

El código html se muestra en la siguiente figura:

El código python se muestra a continuación:
import android
#
#Se importa la función sleep
from time import sleep
#Importar el módulo os para usar os.path.isfile y os.remove.
import os 
 
#Mensaje del programa
title = 'Captura de una foto'
message = ('Desea capturar una foto?') 
#Se crea la instancia del objeto android 
droid = android.Android()
#Se crea el mensaje si se desea tomar la foto.
droid.dialogCreateAlert(title, message)
droid.dialogSetPositiveButtonText('Si')
droid.dialogSetNegativeButtonText('No')
droid.dialogShow()
 
#Se captura la respuesta si es positiva se pide el tiempo que se desea
#usar para tomar la foto.
#Si es negativa finaliza el programa.
respuesta = droid.dialogGetResponse()
if respuesta[1]['which'] == "positive":
    tiempo = droid.dialogGetInput("Escriba el tiempo para capturar la foto","tiempo:")
    #Se crea el mensaje del tiempo para ejecutar la toma de la foto.
    droid.makeToast("Tiempo para tomar la foto: %s " %tiempo[1])
    #Se espera el tiempo definido
    sleep(int(tiempo[1]))
    #Se toma la foto guardandola en el archivo latest.png.Si la imagen existe
    #se borra si no se toma la foto. 
    if os.path.isfile("/sdcard/sl4a/scripts/latest.png") == True:
        os.remove("/sdcard/sl4a/scripts/latest.png")
    droid.cameraCapturePicture("/sdcard/sl4a/scripts/latest.png")
    sleep(1)
    droid.makeToast("Presentando la foto tomada")
    sleep(2)
    #Se muestra una página web donde aparecerá la foto tomada.
    droid.webViewShow("file:///sdcard/sl4a/scripts/captura.html")
    sleep(120)
    droid.makeToast("Fin del programa")
else:
    droid.makeToast('Fin del programa')

La figura muestra la ejecución del programa preguntando si desea tomar la foto.
La siguiente figura muestra que se le pide al usuario el tiempo que quiere esperar hasta que tome la foto:

En la siguiente figura se muestra la página web donde está la foto que se tomó:

El código QR del script captura.py se muestra en la siguiente figura:
El código QR de captura.html se muestra en la siguiente figura:
Una mejora al programa es que se pueda visualizar remotamente la foto tomada por medio de un servidor web en el celular con Android, se intento con el módulo en python que permite iniciar un servidor web pero por los permisos que maneja SL4A no se pudo iniciar el servidor web.

Captura de información que maneja el sensor del celular Android con python

Se explicará como manejar la información del sensor del celular (orientación, acelerometro, magnetometro, precisión e iluminación).

La API tiene las siguientes funciones:


startSensingTimed(
    Entero SensorNum: 1=Todo, 2=Acelerometro, 3=Magnetometro, 4=Iluminación;
    Entero tiempo: Mínimo tiempo para realizar la lectura en milisegundos
    ): Inicia los eventos de lectura del sensor del celular.

stopSensing(): Detiene la lectura del sensor
 sensorsReadMagnetometer(): Devuelve una lista con la información del campo magnetico, una lista con los valores x, y, z.
 sensorsReadOrientation(): Devuelve una lista de valores sobre la orientación: azimut, pitch, roll.

 sensorsGetAccuracy():Retorna la precisión de la lectura.

sensorsGetLight(): Retorna la iluminación recibida en el equipo.

sensorsReadAccelerometer():Retorna una lista con los valores x,y,z del acelerometro.


Primero se activa la lectura del sensor por 30seg, se genera un mensaje que se inicia el proceso de lectura, lluego se muestra la lista de los valores capturados, se le pide al usuario que se salga de la aplicación y así termina la captura de la información del sensor del celular.

El código se muestra a continuación:
#Importar el módulo android import android
#Importar sleep from time import sleep
#Se crea la instancia del objeto android droid=android.Android()
#Se activa el sensor con un tiempo de activación de 30seg. droid.startSensingTimed(1,30000)
#Se crea el mensaje y la info a desplegar en el dialogo. titulo = "Inicio de captura de informacion de los sensores" mensaje = "Espere 10 seg"
#Se crea la barra spinner con un tiempo de 10 seg droid.dialogCreateSpinnerProgress(titulo, mensaje) droid.dialogShow() sleep(10)
droid.dialogDismiss()  
#Se captura la información de la precisión, iluminación, acelerometro, #magnetometro y orientación
precision = droid.sensorsGetAccuracy() luz = droid.sensorsGetLight() acelerometro = droid.sensorsReadAccelerometer() magnetometro = droid.sensorsReadMagnetometer() orientacion = droid.sensorsReadOrientation() #Se desactiva el sensor del celular
droid.stopSensing() #Se crea variables de texto con un formato para mostrar la información textAcelerometro = "" textMagnetometro = "" textOrientacion = "" for i in acelerometro[1]:     textAcelerometro = textAcelerometro + "%s," %i for i in orientacion[1]:     textOrientacion = textOrientacion + "%s," %i for i in magnetometro[1]:     textMagnetometro = textMagnetometro + "%s," %i infoPrecision = "Precision: %s " %precision[1] infoIluminacion = "Iluminacion: %s" %luz[1] infoAcelerometro = "Acelerometro: %s" %textAcelerometro infoMagnetometro = "Campo Magnetico: %s" %textMagnetometro infoOrientacion = "Orientacion: %s" %textOrientacion
#Se presenta la información en pantalla.
droid.dialogCreateAlert("Informacion del sensor del celular") datos = [infoPrecision,infoIluminacion,infoAcelerometro,infoMagnetometro,infoOrientacion] droid.dialogSetItems(datos) droid.dialogSetNegativeButtonText('Salir') droid.dialogShow() respuesta  = droid.dialogGetResponse().result if  respuesta['which'] == "negative":     droid.makeToast("Saliendo del programa")     time.sleep(2)

La figura muestra cuando se ejecuta la apliación, se muestra un mensaje de expera para la lectura del sensor y luego muestra  la información obtenida:




El código QR de la aplicación se muestra en la siguiente figura:

18 abr. 2011

Visualización de las coordenadas del gps del celular desde Android

En artículo anterior expliqué como capturar información de la posición del celular en Linux, en este artículo más sencillo que la versión anterior lo hace directamente en android.

En el artículo mencionado se captura la información de la posición del celular con la la función readLocation(), en esta versión se usará  función getLastKnownLocation() . Note diferencias entre una función y la otra, en la última si pude tomar la posición correcta que muestra googlemap, en cambio con la primera función marcaba la posición que donde el celular se encontraba hace unos días, es necesario investigar más de la API de SL4A  o de Android para ver la razón de esta característica.

Lo otro nuevo en el programa es que se visualiza directamente en el celular la posición, esto se logra usando la función webviewShow(), se mostró su uso en el artículo sobre webview. En ese artículo se abre una página web desde la memoria SD del celular, en este caso se abrirá la página de googlemaps pasandole la lontitud y latitud y el navegador mostrará la ubicación del celular en el mapa.

Adicional a la  información de latitud y longitud se puede capturar información de:

  • tiempo
  • altitud
  • velocidad
  • precisión 

El código se muestra a continuación:


#Importando el modulo android
import android
from time import sleep


    
#Se crea la instancia de la clase Android
droid = android.Android()
#Se inicia la localizacion
droid.startLocating()
#Se espera 15 segundos
sleep(15)
#Se presenta en la consola la informaci?n de la localizaci?n
#Se maneja la informacion de un diccionario.
resultado = droid.getLastKnownLocation()


latitud = resultado[1]["passive"]["latitude"]
longitud = resultado[1]["passive"]["longitude"]
altitud = resultado[1]["passive"]["altitude"]
#Se detiene la localizacion
droid.stopLocating()
#Se muestra googlemaps en el navegador en android
droid.webViewShow("http://maps.google.com/maps?q=%s,%s" %(latitud,longitud))


La siguiente figura muestra la ejecución del script.


El código QR del script se muestra en la siguiente figura:

8 abr. 2011

Festival Latinoamerica de Instalación de Software Libre 2011- Cabudare



Los invito a participar en las distintas ciudades donde se realizará en FLISOL en Venezuela y en los distintos países de Latinoamerica. El evento se realizará mañana Sábado 9 de Abril, más información referente el Flisol en Venezuela acá o de Latinoamerica acá.

En mi caso participare en el Flisol en la Ciudad de Cabudare en el Estado Lara, en la Universidad de Yacambu.



La charla que dictaré mañana a las 2pm es sobre Programar en Android con Python.
El enlace para bajar la presentación  esta en slideshare.


Manejar remotamente un equipo con Debian desde Android con gmote

Gmote es una aplicación hecha en java que permite controlar el ratón y el teclado.
El enlace de gmote es esta aquí .


Para instalarlo en android se busca en el market gmote y ahí se consigue como lo muestra la figura.

Al tenerlo instalado en el android sólo falta bajar la aplicación para Linux en el siguiente enlace

Al descomprimir el archivo se ejecuta GmoteServer.sh.

Se configura el acceso a wifi del Android.

En el equipo con Android se busca en las aplicaciones y se ejecuta gmote.

Aparece la  parte de control de reproductor de música se presione menú en el celular y aparece entre las opciones Touchpad.
Al presionar TouchPad ya se tiene control del ratón en el computador.
Al darle clip al símbolo del teclado nos permite escribir remotamente en el computador.
Esta opción de gmote es útil para manejar presentaciones de forma remota.

3 abr. 2011

Control remoto del reproductor de música en Debian desde Android

Buscando aplicaciones para control remoto de reproductores de música en Linux desde Android me encontre con tesla.
Para instalar tesla en el celular se pueden bajar  el archivo apk desde andAppStore.
En su equipo con Debian es necesario instalar openssh y libpam-ck-connector.
aptitude install libpam-ck-connector openssh-server openssh-client openssh-blacklist-extra openssh-blacklist

Es necesario reiniciar ssh.
/etc/init.d/ssh restart.

Se tiene que conectar el celular a una red wifi igual que su computador.
Al iniciar tesla en el celular le pedirá la dirección IP de su computador, el usuario con el cual se inicia sesión y su clave como lo muestra la figura.
Se puede seleccionar otros reproductores que funcionan en Linux antes de darle conectar a la aplicación.
La siguiente imagen muestra a tesla funcionando en el celular y luego el productor Rhythmbox.

2 abr. 2011

Introducción a webview en Android con python

La serie de widgets del SL4A que se ha explicado en el blog no son suficientes para realizar aplicaciones tal como las que se bajan del market de Android, pues existe una forma de aumentar las posibilidades en interfaz gráfica para Android y es usando webview.

Webview permite visualizar páginas html con contenidos en javascript.

En la página de SL4A tienen una introducción sobre webview .

Se tiene un archivo html llamado text_to_speech.html con código javascript, es un formulario html  donde se le pasa un texto a reproducir.

Luego se tiene el código python en un archivo llamado webview.py. Se crea la instancia de android, se abre el archivo text_to_speech2.html, se espera por el evento tomando el resultado y reproduciendolo con text to speech.
La siguiente imagen muestra la pantalla de la página web.

Y la figura donde se muestra que se escribió un texto en el formulario, al darle clip al botón el celular reproduce el texto que se le paso al formulario.

Widgets en Android con python. Parte 9 (selección multiple)

En este artículo explico como usar el widget de selección multiple con botones, es inicialmente el mismo código del artículo anterior lo que cambie es que se usa el método dialogSetMultiChoiceItems.

En este ejemplo luego de seleccionar algunas ciudades se abre una ventana de dialogo mostrando las ciudades seleccionadas.

El código se muestra a continuación:
#!/usr/bin/env python
#Se importan los módulos android y time.
import android, time
#Se crea la instancia de la clase android
droid = android.Android()
#Se crea el título de la ventana
titulo = "Seleccione las ciudades de su preferencia"
#Se crea una lista de ciudades
ciudades = ['Valencia','Barquisimeto','Merida','Caracas','Maracaibo','Maracay','Margarita']
#Se crea la ventana de alerta con el título asociado
droid.dialogCreateAlert(titulo)
#Se crea el widget de selección multiple
droid.dialogSetMultiChoiceItems(ciudades)
#Se crea el botón seleccionar
droid.dialogSetPositiveButtonText('Seleccionar')
#Se crea el botón salir
droid.dialogSetNegativeButtonText('Salir')
#Se muestra la ventana
droid.dialogShow()
#Se captura la respuesta de los botones
respuesta  = droid.dialogGetResponse().result
#Se captura los items seleccioandos
items = droid.dialogGetSelectedItems()
#Si se da clip al botón seleccionar se 
if  respuesta['which'] == "positive":
    #Se averigua si no se selecciono una ciudad y devuelve un mensaje
    if len(items[1]) == 0:
        droid.dialogCreateAlert("No se selecciono ciudad alguna")
    elif len(items[1]) > 0:
    #Si se selecciona una ciuad o más se agrega a una variable texto las ciudades separadas por coma
        lista = []
        texto = ""
        cantidad = len(items[1])
        c = 1
        for i in items[1]:
            lista.append(ciudades[int(i)])
            if c <> cantidad:
                #Si no es el último elemento se agrega al final la coma.
                texto = texto + ciudades[int(i)] + ","
            else:
                #Si es el último elemento se agrega sin colocar la coma al final.
                texto = texto + ciudades[int(i)]
            c = c+1
        #Se crea la ventana de dialogo con la info de las ciudades
        droid.dialogCreateAlert("Ciudades seleccionada: %s" %texto)
else:
     #Si se le dio clip al botón salir se muestra un mensaje y se sale de la aplicación
    droid.dialogCreateAlert("Saliendo de la aplicacion")
#Se crea el botón aceptar
droid.dialogSetPositiveButtonText('Aceptar')
#Se muestra la ventana
droid.dialogShow()
La 2 siguientes imágenes muestran la ventana de selección de ciudades y luego la ventana del resultado.


Se muestra ahora un vídeo donde se muestra el funcionamiento de la aplicación con las diferentes posibles opciones.
video
El código QR del ejemplo de selección multiple se muestra en la siguiente imagen:

El código QR del ejemplo de selección simple con botones.

Widgets en Android con python. Parte 8 (selección simple y botones)


Wikio – Top Blogs

Continuando con los artículos sobre los widgets de Android, ahora se agregará una mejora al de selección simple. Se le incluirá 2 botones, uno de seleccionar y otro para salir.

El ejemplo muestra una serie de ciudades, se selecciona una y luego se le da el botón seleccionar, al final se muestra la ciudad que se ha seleccionado.

El código se muestra a continuación:
#!/usr/bin/env python

#Se importa el módulo android y time
import android, time

#Se crea una instancia de la clase android
droid = android.Android()

#Se define el título de la ventana
titulo = "Seleccione una ciudad"

#Se define una lista con las ciudades a seleccionar
ciudades = ['Valencia','Barquisimeto','Merida','Caracas']

#Se crea la ventana con el título
droid.dialogCreateAlert(titulo)

#Se agrega las ciudades a la lista de selección
droid.dialogSetSingleChoiceItems(ciudades)

#Se agrega el botón seleccionar
droid.dialogSetPositiveButtonText('Seleccionar')

#Se agrega el botón salir
droid.dialogSetNegativeButtonText('Salir')

#Se muestra la ventana de dialogo
droid.dialogShow()

#Se captura la respuesta de los botones
respuesta  = droid.dialogGetResponse().result

#Se captura la ciudad seleccionada, se captura el número en la lista.
#Items es una lista de eventos, el valor 1 guarda el resultado de una lista y como se selecciono
#un solo elemento se solicita el valor cero de esa lista para tener el item seleccionado.
items = droid.dialogGetSelectedItems()

#Se el botón que se le da clip es seleccionar se busca que ciudad se selecciono.
if  respuesta['which'] == "positive":
     #Se muestra un mensaje de la ciudad seleccionada, 
    droid.makeToast("La ciudad seleccionada es: %s " %ciudades[int(items[1][0])])
    time.sleep(2)
else:
    #Si se seleciono el botón salir se muestra un mensaje al respecto.
    droid.makeToast("Saliendo del programa")
    time.sleep(2)

En la figura se muestra las ciudades a seleccionar con los botones seleccionar y salir.



Y un vídeo donde se muestra el widget funcionando.
video