Python – Android
Manuel Aznar
manuel.aznar@neodoo.es
Noviembre de 2011
Indice
● Introducción a Android
● SL4A
● Ejemplos básicos
● Ejemplos avanzados
● Ejercicio
● Generación de un APK instalable en el móvil
Android
● Es un sistema operativo basado en GNU/Linux
● Para dispositivos móviles (teléfonos inteligentes
y tabletas)
● Desarrollado inicialmente por Android Inc.
Comprada por Google en 2005
● Lo componen el sistema operativo, librerías,
middleware y aplicaciones
Características
● Máquina Virtual optimizada para dispositivos móviles Dalvik
● Navegador integrado basado en webkit
● Base de datos SQLite
● Gráficos 3D basado en OpenGL
● Soporte para audio, video e imágenes
● Bluetooth, EDGE, 3G y wifi
● Camara, GPS y acelerometro
Versiones de Android
Crecimiento de Android
Arquitectura de Android
Market Android I
Market Android II
Market Android III
Market Android IV
Market Android V
Market Android VI
● Un único pago de 25$
● Si la aplicación es de pago el reparto de los
beneficios es de 30% Google, 70% Desarrollador
● Hay otros markets como el de Amazon,
Motorola, Vodafone, ... con distintas condiciones
Componentes de una aplicación
●Activities: Bloques básicos que constituyen una aplicación
●Services: Procesos que corren en segundo plano, no UI
●Broadcast y Intent Receivers: Reciben y reaccionan a anuncios,
no UI
●Content Providers: Proveen acceso a datos a otras aplicaciones
SL4A: Scripting Layer for Android
SL4A hace posibles crear rapidamente prototipos
de aplicaciones para Android en el mismo
dispositivo usando lenguajes de scripting de alto
nivel.
Esos scripts tienen acceso a muchas de las APIs
disponibles por la aplicaciones desarrolladas en
Java con un interface simplificado.
SL4A: ¿Por qué?
● ¿Es suficientemente fácil escribir programas
para Android? Sí. ¿Entonces?
● El entorno de desarrollo de Android te hace la
vida más fácil. Pero te obliga a tener un
ordenador para trabajar.
● SL4A es una nueva idea para poder trabajar en
una situación en la que necesites algo
rápidamente. Después de que se haya aprendido
se puede pasar a hacer una aplicación real.
SL4A: ¿Cómo?
● SL4A provee de una fachada que hace
llamadas al API via JSON RPC.
● ¿SL4A compila los programas a Dex bytecode
o hay una capa adicional de interpretación?
● Depende del lenguaje. Python es una versión de
C que arranca nativamente.
SL4A: ¿Rendimiento?
● Se centra sobre todo en el desarrollo rápido y
sencillo mas que en el rendimiento.
● Si importa mucho el rendimiento es mejor usar
el SDK o el NDK, donde se tiene más control
sobre el sistema.
SL4A: Características
● Manejar intents
● Iniciar activities
● Realizar llamadas
● Enviar SMS
● Enviar correos
● Escanear códigos de Barras
● Obtener localización y valores de sensores
● Usar comunicaciones como wifi o bluetooth
● Usar Text To spech (TTS)
● Obtener información de la bateria
● Grabar videos y audios
SL4A: API
● La API provista por SL4A es la misma para los lenguajes
soportados.
● Las llamadas del API devuelve un objeto con 3 campos:
● id:Valor numérico asociado con la llamada.
● result: valor que devuelve el API o null si no devuelve.
● error: Descripción del error, null si no hubo.
● URL:
http://code.google.com/p/android-scripting/wiki/ApiReference
SL4A: ¿API completa?
● BeanShell, JRuby, y Rhino tienen básicamente
un API completa ya que invocan a Java
directamente.
● Los lenguajes interpretados como Python son
más restrictivos. Ellos solo tienen acceso al API
expuesto a través de la capa RPC.
● Mirar la referencia al API para saber la lista de
las cosas que estan soportadas.
● La capa RPC se puede extender fácilmente.
http://code.google.com/p/android-scripting/wiki/ApiReference
SL4A: Lenguajes
soportados
● Shell
● PHP
● JRuby
● Perl
● Python
● Lua
● BeanShell
● Rhino
● Instalación en el Celular
● Instalación en el emulador de Android en Linux: Para este caso
se debe tener instalado el SDK de android
Instalación de SL4A
Instalación del interprete de Python
Al darle clip al icono de SL4A aparece la una información donde
nos pide que se agreguen scripts o interpretes presionando el
botón menú como lo muestra la siguiente figura.
Instalación del interprete de Python
Se lista los scripts en python de ejemplo para trabajar con
Android
Herramientas para el desarrollo
● Instalar JDK
http://www.oracle.com/technetwork/java/javase/downloads/index.html
● Instalar Android SDK
http://developer.android.com/sdk/index.html
● Instalar ANT
http://ant.apache.org
● Instalar Eclipse
http://www.eclipse.org
● Instalar plugin Eclipse-Android
http://developer.android.com/sdk/eclipse-adt.html
Crear APK
Para hacerlo con Ant:
● Descomprimir el script_for_android_template.zip
● Poner la variable de entorno "ANDROID_SDK"
● Poner el paquete del proyecto :
sh configure_package.sh <nombre del
paquete de la aplicacion>
● Cambiar el nombre del proyecto en el "build.xml"
● Ejecutar "ant release" para crear el APK
Ejemplos: Hola Mundo
import android
droid = android.Android()
droid.makeToast('Hello, Android!')
print 'Hello world!'
Ejemplos: Entrada de datos
import android
droid = android.Android()
texto = droid.dialogGetInput("Escriba su nombre","Nombre:")
droid.makeToast('Hola %s' %texto[1])
Ejemplos: Entrada de datos
Ejemplos: Entrada de datos
Ejemplos: Notificación
import android
droid = android.Android()
droid.notify('Prueba' , 'Hola Mundo 3!')
Ejemplos: Notificación
Ejemplos: Botones
#!/usr/bin/env python
import android
droid = android.Android()
title = 'Alerta'
message = ('Esta alerta tiene 3 botones y' 'se espera que presione
uno')
droid.dialogCreateAlert(title, message)
droid.dialogSetPositiveButtonText('Si')
droid.dialogSetNegativeButtonText('No')
droid.dialogSetNeutralButtonText('Cancelar')
droid.dialogShow()
response = droid.dialogGetResponse()
droid.makeToast('El resultado de la ejecucion del boton es: %s'
%response[1]['which'])
Ejemplos: Botones
Ejemplos: Botones
Ejemplos: Botones
Ejemplos: Botones
Ejemplos: Menús
import android
droid=android.Android()
droid.addOptionsMenuItem("Si","si",None,"star_on")
droid.addOptionsMenuItem("No","no","No","star_off")
droid.addOptionsMenuItem("Salir","off",None,"ic_menu_revert")
print "Presiona el menu para ver opciones extra.."
print "En 10 segundos se saldra si no hace nada"
while True: # Wait for events from the menu.
response=droid.eventWait(10000).result
if response==None:
break
print response
if response["name"]=="off":
break
print "Hecho."
Ejemplos: Enviar email
import android
droid = android.Android()
asunto = "Prueba de envio de correo desde Android con un script de python"
para = "xxxx@neodoo.es"
cuerpo_correo = "Esta es una prueba de envio de correon El tiempo en el reloj
es: %sn ------n Curso de Pythonn" %time.ctime()
#Se llama a la funcion sendEmail con los datos necesarios.
#Esto llama a la aplicacion de envio de correo de forma grafica con la
#informacion que se pasa en la funcion.
droid.sendEmail(para,asunto,cuerpo_correo)
#Se finaliza la instancia de la clase.
droid.exit()
Ejemplos: Enviar SMS
#Importando el módulo android y el módulo time
import android,time
#Creando la instancia droid del objeto Android
droid = android.Android()
#Asignando el número de teléfono y mensaje
telefono ="034777777777"
mensaje = "Esta es una prueba de envio de sms a la hora %s" %time.ctime()
#Enviar mensaje a la pantalla de android con la info del número y mensaje
droid.makeToast("enviando mensaje a %s, con el siguiente contenido: %s" %
(telefono,mensaje))
#Enviando el mensaje de texto
droid.smsSend(telefono,mensaje)
Ejemplos: Llamar
#Importando el módulo android y el módulo time
import android
#Creando la instancia droid del objeto Android
droid = android.Android()
#Asignando el número de teléfono
telefono ="034777777777"
#Llamando al numero de telefono dado
droid.phoneCallNumber(telefono)
Ejemplos: Propone llamar
#Importando el módulo android y el módulo time
import android
#Creando la instancia droid del objeto Android
droid = android.Android()
#Asignando el número de teléfono y mensaje
telefono ="034777777777"
#Propone llamar al numero de telefono dado
droid.phoneDialNumber(telefono)
Ejemplos: Geolocalización
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 segunfos
sleep(15)
#Se presenta en la consola la información de la localización
#Se maneja la información de un diccionario.
print "Altitud: ",droid.readLocation().result["network"]["altitude"]
print "Proveedor: ",droid.readLocation().result["network"]["provider"]
print "Latitud: ",droid.readLocation().result["network"]["latitude"]
print "Longitud: ",droid.readLocation().result["network"]["longitude"]
print "Tiempo: ",droid.readLocation().result["network"]["time"]
print "Velocidad: ",droid.readLocation().result["network"]["speed"]
print "Precisión: ",droid.readLocation().result["network"]["accuracy"]
#Se detiene la localización
droid.stopLocating()
Ejemplos: Chat por bluetooth I
import android
import time
droid = android.Android()
droid.toggleBluetoothState(True)
droid.dialogCreateAlert('¿Eres el servidoe?')
droid.dialogSetPositiveButtonText('Si')
droid.dialogSetNegativeButtonText('No')
droid.dialogShow()
result = droid.dialogGetResponse()
is_server = result.result['which'] == 'positive'
if is_server:
droid.bluetoothMakeDiscoverable()
droid.bluetoothAccept()
else:
droid.bluetoothConnect()
Ejemplos: Chat por bluetooth II
if is_server:
result = droid.getInput('Chat', 'Pon tu mensaje').result
if result is None:
droid.exit()
droid.bluetoothWrite(result + 'n')
while True:
message = droid.bluetoothReadLine().result
droid.dialogCreateAlert('Chat recibido', message)
droid.dialogSetPositiveButtonText('Ok')
droid.dialogShow()
droid.dialogGetResponse()
result = droid.getInput('Chat', 'Pon tu mensaje').result
if result is None:
break
droid.bluetoothWrite(result + 'n')
droid.exit()
Ejemplos: Hacer una foto
import android
droid = android.Android()
droid.cameraCapturePicture('/sdcard/foo.jpg')
Ejemplos: Text-To-Speech
import android
droid = android.Android()
message = droid.dialogGetInput('TTS', '¿Que quieres decir?').result
droid.ttsSpeak(message)
Ejemplos: Mensajería I
import android
import xmpp
_SERVER = 'talk.google.com', 5223
def log(droid, message):
print message
self.droid.ttsSpeak(message)
class SayChat(object):
def __init__(self):
self.droid = android.Android()
username = self.droid.dialogGetInput('Usuario').result
password = self.droid.dialogGetInput('Password').result
jid = xmpp.protocol.JID(username)
self.client = xmpp.Client(jid.getDomain(), debug=[])
self.client.connect(server=_SERVER)
self.client.RegisterHandler('message', self.message_cb)
Ejemplos: Mensajería II
if not self.client:
log('Ha fallado la conexion!')
return
auth = self.client.auth(jid.getNode(), password, 'botty')
if not auth:
log('Ha fallado la autentificacion!')
return
self.client.sendInitPresence()
def message_cb(self, session, message):
jid = xmpp.protocol.JID(message.getFrom())
username = jid.getNode()
text = message.getBody()
self.droid.ttsSpeak('%s dice %s' % (username, text))
def run(self):
try:
while True:
self.client.Process(1)
except KeyboardInterrupt:
pass
saychat = SayChat()
saychat.run()
Ejemplos: Batería I
#!/usr/bin/env python2.6
# -*- coding: utf-8 -*-
import android
droid = android.Android()
#Se monitoriza la bateria
droid.batteryStartMonitoring()
#Se captura la información de la bateria
bateriaHealth = droid.batteryGetHealth()[1]
if bateriaHealth == 2:
print "La bateria está bien"
elif bateriaHealth == 1:
print "Salud de la Bateria desconocido"
elif bateriaHealth == 3:
print "La bateria tiene sobrecarga"
elif bateriaHealth == 4:
print "La bateria está muerta"
elif bateriaHealth == 5:
print "La bateria tiene sobrevoltaje"
else:
print "falla desconocida"
Ejemplos: Batería II
#Se captura el tipo de conexión que usa el dispositivo
tipoConexion = droid.batteryGetPlugType()[1]
if tipoConexion == 0:
print "Cable desconectado"
elif tipoConexion == 1:
print "Fuente de alimentación: cargador AC"
elif tipoConexion == 2:
print "Fuente de alimentación: cable USB"
else:
print "Desconocido"
#Se captura lel estatus de la bateria
estatus = droid.batteryGetStatus()[1]
if estatus == 2:
print "Bateria cargandose"
elif estatus == 3:
print "Bateria descargandose"
elif estatus == 4:
print "Bateria no se está cargando"
elif estatus == 5:
print "Bateria full de carga"
Ejemplos: Batería III
print "Tipo de tecnología: ",droid.batteryGetTechnology()[1]
print "Temperatura: ",droid.batteryGetTemperature()[1]
print "voltaje: ",droid.batteryGetVoltage()[1]
#Se deja de monitorizar la bateria
droid.batteryStopMonitoring()
Ejemplos: SQLite
import sqlite3
# Connect to database file, create it if it does not exist
conn = sqlite3.connect('/sdcard/sqlitedemo.db')
# Get a cursor
cursor = conn.cursor()
# Create a table
cursor.execute("CREATE TABLE IF NOT EXISTS gente (texto)")
# Insert some data
cursor.execute("INSERT INTO gente VALUES ('Juan Ramirez Sanchez')")
cursor.execute("INSERT INTO gente VALUES ('Alejandro Garcia Garcia')")
conn.commit()
# Read the data back out
cursor.execute("SELECT * from gente")
for row in cursor:
print row
conn.close()
Más ejemplos
Más ejemplos en la página oficial
● http://code.google.com/p/android-scripting/wiki/Tutorials
Mandar la posición y hora por Email I
● Que escuche los SMS
● Si le llega un SMS con la palabra “GPS”
● Hacer que capture la posición GPS del móvil
● Que la envíe por email aun contacto
● Que la meta como evento en el Google
Calendar
Mandar la posición y hora por Email II
# -*- coding: utf-8 -*-
try:
from xml.etree import ElementTree # for Python 2.5 users
except ImportError:
from elementtree import ElementTree
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import atom
import android
import sys
import time
import urllib2
from string import split
from string import find
droid = android.Android()
Mandar la posición y hora por Email III
def servicio():
while True:
time.sleep(10)
# Escuchar los mensajes SMS
msg_solicitud = droid.smsGetMessages(True)
for i in msg_solicitud.result:
msg_sms = i["body"].strip().upper()
if msg_sms == "GPS":
droid.makeToast(u"Solicitud de localización recibida")
droid.smsMarkMessageRead([i["_id"]], True)
telefono = i["address"]
enviar_mensaje(telefono)
droid.makeToast(u"%s: %s" % (telefono,msg_sms))
if __name__ == "__main__":
servicio()
Mandar la posición y hora por Email IV
def enviar_mensaje(numero):
try:
mensaje, mapa = localizar()
msg = "%s %s" % (mensaje, mapa)
asunto = u"Respuesta a la peticion de localización GPS desde el numero
%s" % (numero)
para = "xxxx666@gmail.com"
droid.sendEmail(para, asunto, msg.encode('ascii', 'replace'))
droid.makeToast(u"Enviada respuesta")
anadirEvento(msg)
droid.makeToast(u"Evento añadido al calendario")
except:
droid.makeToast("Error: " + str(sys.exc_info()[0]))
Mandar la posición y hora por Email Vdef localizar():
droid.makeToast(u"Empezando a localizar la posicion")
droid.startLocating(3600,1)
time.sleep(10)
fin = True
segundos = 300
seg_trancurridos = 0
while fin:
time.sleep(1)
seg_trancurridos += 1
l = droid.readLocation()
ll = l.result
if "gps" in ll:
mensaje = u"Posición actual: "
pos = (str(ll["gps"]["latitude"]), str(ll["gps"]["longitude"]))
fin = False
droid.makeToast(u"Posición GPS encontrada")
Mandar la posición y hora por Email VIelse:
if seg_trancurridos == segundos:
fin = False
if "network" in ll:
pos = (str(ll["network"]["latitude"]), str(ll["network"]["longitude"]))
mensaje = u"Posición red celular: "
droid.makeToast(u"Posición Red Celular encontrada")
else:
ll = droid.getLastKnownLocation().result
pos = (str(ll["network"]["latitude"]), str(ll["network"]["longitude"]))
mensaje = u"Ultima posición red celular: "
droid.makeToast(u"No se pudo establecer conexión, se enviara la
ultima posición registrada")
droid.makeToast(u"Terminado de localizar la posicion")
pll = "%s,%s" % (str(pos[0]), str(pos[1]))
mapa = "http://maps.google.com/maps?ll=%s&q=%s" % (pll, pll)
droid.stopLocating()
return mensaje, mapa
Mandar la posición y hora por Email
VII
def anadirEvento(mensaje):
EMAIL_USER = 'xxxx@gmail.com'
EMAIL_PSWD = 'xxxxxxxx'
calendar_service = gdata.calendar.service.CalendarService()
calendar_service.email = EMAIL_USER
calendar_service.password = EMAIL_PSWD
calendar_service.source = 'Android'
calendar_service.ProgrammaticLogin()
event = gdata.calendar.CalendarEventEntry()
event.content = atom.Content(text=mensaje)
event.quick_add = gdata.calendar.QuickAdd(value='true')
Mandar la posición y hora por Email
VIII
# Send the request and receive the response:
while True:
# Sometime Google Calendar service returns an error. This keeps trying
until there's no error.
try:
new_event = calendar_service.InsertEvent(event,
'/calendar/feeds/default/private/full')
break
except gdata.service.RequestError as inst:
if inst[0]['status'] == 302:
time.sleep(1.0)
continue
raise
except:
raise
Referencias:
● Wikipedia
http://es.wikipedia.org/wiki/Android
● Sitio oficial de Android
http://developer.android.com/guide/basics/what-is-android.html
● Sitio Oficial de SL4A
http://code.google.com/p/android-scripting/