Python for Series 60
Elvis Pfützenreuter – [email protected]
Original de Osvaldo Santana Neto ([email protected])
O que são celulares “Série 60”ou Symbian
Smartphones com capacidade de processamento respeitável
Sistema operacional Symbian Plataforma Série 60: Symbian +
interface de usuário + recursos adicionais
Restou apenas a Nokia no consórcio Symbian
Desenvolvimento C++ para S60
SDK completo gratuito em http://forum.nokia.com SDK inclui emulador Alguns recursos mais avançados são pagos (JTAG) API C++ do Symbian é sui generis e canhestra
Progressiva adoção de APIs open-source (Qt, OpenC)
_LIT(KFileName, "C:\\file1");RFile fd;RFs fs;fs.Connect();CleanupClosePushL(fs);User::LeaveIfError(fd.Open(fs, KFileName,
EFileShareExclusive | EFileWrite));CleanupClosePushL(fd);TBuf8<8> buf;myFile.Read(0, buf);myFile.Close();fs.Close();CleanupStack::PopAndDestroy(2);
char buf[8];fd = open(“C:\\file1”, O_RDWR);int len = read(fd, buf, 8);close(fd);
Por que desenvolver para S60
Mais de 150-200 milhões de celulares vendidos Distribuição do aplicativo: uma vez assinado,
não sofre qualquer restrição Previsões ainda apontam como plataforma
dominante para os próximos anos Várias opções de linguagem: J2ME, C++,
Qt, Python Plataforma fechada aberta e SDK gratuito Existe mercado e comunidade de
desenvolvedores
Por que usar Python para S60
Desenvolvimento C++ é difícilDesenvolver para mobile é ainda mais difícilAs APIs e ferramentas dos fabricantes não ajudam
O Python “resolve” muitos destes problemas por introduzir uma camada de abstração
Desvantagens do PyS60
Desempenho pode ser um problema solução: módulos Python escritos em C/C++
Nem toda a API C++ do Symbian está coberta solução: idem
Salada de versões dos softwares
Python PyS60 Série 60 Symbian
2.2 <= 1.4.6 2nd Edition
3rd Edition
6.x até 8.x6600, 6681, N70
9.xN85, N95, N82, N96
2.5 1.9.7,2.0
3rd Edition
5th Edition
9.xN85, N95, N82, N96
N97, XPressMusic
Este curso é baseado no PyS60 1.9.7 para dispositivos 3rd Edition
Obter e instalar o PyS60
Distribuiçãopara Windows
Distribuiçãogenérica
PyS60 para SDKVersão 3.2
https://garage.maemo.org/projects/pys60/
Obter e instalar o PyS60 (cont.)
Instalar via Bluetooth ou PC Suite; prefira instalar no cartão de memória (D:)
Interpretador(inclui OpenC PIPS)
Shell interativoAssinado Nokia
“alta capacidade”
Shell interativoAuto-assinadopara S60 3.2
Shell interativo PyS60
Terminal Bluetooth via Windows
Terminal Bluetooth via Mac OS X
Celularconecta
Terminal Bluetooth via Linux
Celularconecta
Terminal via Bluetooth - PyS60
Aviso: O perfil “Serial Port” do Bluetooth é temperamental
Tentar conectar algumas vezes É interessante parear e liberar antes Se nada mais der certo, tente desligar
celular, computador, ou ambos Console/terminal via cabo USB
Rodando PyS60 no emulador
Python versus modelo de segurança
Pacote SISoriginalnão instalável
Crypto
CertificadoX.509 dodesenvolvedor
Pacote SISassinado einstalável
Capacidadesrequisitadaspelo aplicativo
Escopo dedistribuiçãorequisitado
Homologação $$$$$$$$$
Auto--assinado
Assinado CASymbian $$$
VideSymbian SignedOpen Signed !$
Python versus modelo de segurança
Pacote SIS de aplicativo Python
- é um “executável”- pode ter menos capacidades que o runtime- suas capacidades determinam o que os scripts podem fazer- contém scripts e módulos Python- PyScriptShell = um simples aplicativo escrito em Python- FAQ como utilizar o PyScriptShell assinado pela Nokia?
Runtime PyS60
- Python_1.9.7.sis- é uma biblioteca- assinada pela Nokia- muitas capacidades
Módulo em C/C++(opcional)
- tem de possuir nomínimo as mesmascapacidades do aplicativo
Scripts Python
- arquivos-texto- elementospassivos
Python versus modelo de segurança
Shell high-capas assinado pela Nokia Instalar script no cartão de memória via USB; ou criar um pacote SIS (veremos mais adiante)
Instalar scripts via Bluetooth ou SMS não funciona Truque: ZIPar e mandar
IMPORTANTE: instalar PyS60 no cartão de memória (D:) D:\data\python\ D:\private\20022ee9\
Python versus modelo de segurança
Comprando um celular Série 60para fins de desenvolvimento Modelos que já utilizei com PyS60:
N-Gage QD, 6600, 6681, N93, N95, N85 Prefira modelos recentes, 3rd Edition FP1 ou
superior (N95, N85, N82, N96) Verifique a lista de compatibilidade do PyS60 para
evitar surpresas Celulares 2nd Edition: última versão do PyS60 que
suporta é a 1.4.6
Módulos Python específicos para Symbian
http://pys60.garage.maemo.org/doc/s60/
http://wiki.opensource.nokia.com/projects/PyS60_documentation
Módulos Python para Symbian
Relativamente fáceis de usar Poucos tipos novos
Strings “mágicas” Protocolos “informais” via listas/tuplas/dicts
Mesmo método pode ser sync & async Diferença = passar callback como parâmetro
Não esquecer dos módulos padrão Python
Módulo e32 “Caixa de ferramentas” do Symbian Não serve para muita coisa, isoladamente Active Objects = análogo a main loop, glib
No futuro, o Qt deve preencher esta função
from e32 import *
get_capabilities()drive_list()ao_sleep(1)ao_yield()is_ui_thread()
s60_version_info
x = Ao_lock()x.wait()
# em outro lugarx.signal()
x = Ao_timer()x.after(1, funcao)x.cancel()
Módulo e32 (continuação)
import appuifw
import e32
trava = e32.Ao_lock()
def callback_sair():
print “Apertou botao”
e32.ao_sleep(1)
trava.signal() # acorda
def main():
global trava
appuifw.app.exit_key_handler = callback_sair
trava.wait() # dorme
main()
Módulo sysinfo
Informações diversas sobre o dispositivo: sysinfo.battery() sysinfo.imei() sysinfo.signal_dbm() sysinfo.signal_bars() sysinfo.display_pixels()
Módulo appuifw
Acesso à UI, o mais complexo dos módulos S60 Quem já usou PyGTK+, vai achar familiar appuifw.app: classe Application appuifw.app.body: Canvas, ListBox ou Text appuifw.app.menu Dialogs modais
Form (widget “composto”) Ligação de eventos/teclas a ações
No futuro, o Qt deve tomar o lugar deste módulo
Layout de uma aplicação S60
Módulo appuifw
>>> import appuifw>>> appuifw.app.title = u"BLA"
>> def tab_cb(n):... print "Mudou para tab", n... >>> appuifw.app.set_tabs([u"Um", u"Dois"], tab_cb)Mudou para tab 1Mudou para tab 0
>>> appuifw.app.orientation = 'landscape'>>> appuifw.app.screen = 'large'
Módulo appuifw
>>> def menu_cb(*algo):... print algo... >>> appuifw.app.menu = \ [(u"Item um", menu_cb), (u"Item dois", menu_cb)]>>> ()
>>> appuifw.selection_list([u"AAA", u"BBB"])1
>>> appuifw.query(u"Digite texto", u"text")u'Inconstitucional'
Módulo appuifw
>>> appuifw.note(u"Fora Sarney", u"error")
>>> def cb(*algo):... print algo... >>> f = appuifw.Form( [(u'Nome', 'text'), (u'Idade', 'number')])
>>> f.save_hook = cb
>>> f.execute()([(u'Nome', 'text', u'Boa'), (u'Idade', 'number', 18L)],)
Módulo graphics
Classe Image e função screenshot() Câmera gera imagens da classe Image Image implementa API drawable
appuifw.Canvas idem
>>> i = graphics.Image.open("E:\\teste.jpg")>>> i.ellipse((0, 0, 100, 100), fill=0xff0000)>>> i.save("E:\\teste2.jpg")
Módulo camera
Permite manipular a(s) câmera(s) Não funciona no emulador Symbian, mas há
extensões para suprir esta função
camera.cameras_available()
i = camera.take_photo() # Imagei.save(u“E:\\imagem.jpg”)
canvas = appuifw.Canvas()appuifw.app.body = canvascanvas.blit(i)
import e32, camera, appuifw, key_codes
def finder_cb(im): # pode manipular a imagem antes canvas.blit(im)
camera.start_finder(finder_cb)...camera.stop_finder()
i = camera.take_photo(size=(640,480))
Tirar foto usando a 2a câmeracamera.take_photo(position=1)
Não há viewfinder para 2a câmeraImprovisar com take_photo()+blit() periódicoou tentar com camera.device[1].start_finder()
# Copyright Jurgen Scheible
import e32, camera, appuifw, key_codes
def finder_cb(im): canvas.blit(im)
def take_picture(): camera.stop_finder() pic = camera.take_photo(size = (640,480)) w,h = canvas.size canvas.blit(pic,target=(0, 0, w, 0.75 * w), scale = 1) pic.save('e:\\teste.jpg')
def quit(): app_lock.signal()
canvas = appuifw.Canvas()appuifw.app.body = canvas
camera.start_finder(finder_cb)canvas.bind(key_codes.EKeySelect, take_picture)
appuifw.app.title = u"Camera"appuifw.app.exit_key_handler = quitapp_lock = e32.Ao_lock()app_lock.wait()
import e32, camera, appuifw
def finder_cb(im): canvas.blit(im)
def status_cb(*algo): print algo
canvas = appuifw.Canvas()appuifw.app.body = canvas
camera.start_finder(finder_cb)camera.start_record(“e:\\video.mpeg”, status_cb)
e32.ao_sleep(10)
camera.stop_record()camera.stop_finder()camera.release()
Módulos gles/glcanvas
Módulo de acesso ao OpenGL/ES OpenGL/ES é acelerado por hardware nos
celulares Nokia N93, N95 e N82 (N97?) Não será abordado aqui Exemplo: script gles.py
Módulo audio
Funciona no emulador audio.say(u”Bla”)
Classe audio.Sound s = Sound.open(u”e:\\arquivo.wav”) s.record()
Cumulativo, não trunca Se durante ligação, grava ligação
s.stop() s.play()
Módulo telephone
telephone.dial(“5551234567”) telephone.hang_up() Fazer e atender ligações Gravação de áudio: vide módulo audio
Módulo sensor
API diferente em FP1 e >= FP2 3rd Edition FP1: Sensor (N95, N93)
from sensor import *
sensor_type = sensors()['RotSensor']N95_sensor = Sensor(sensor_type['id'], sensor_type['category'])N95_sensor.set_event_filter(RotEventFilter())
def get_sensor_data(status): print status
N95_sensor.connect(get_sensor_data)
Módulo sensor
>= 3rd Edition FP2 (N85, N96, N97...)
import sensorfrom sensor import *accel = RotationData() # AccelerometerXYZAxisData()
>>> accel.start_listening()True>>> accel.x-2
>>> import e32>>> x = 1000>>> while x > 0: ... x -= 1... print accel.x, accel.y, accel.z ... e32.ao_sleep(1)
Módulo messaging
messaging.sms_send(”99845555”, u”Oi”) messaging.mms_send(...) Repare na string Unicode! Permite passar um callback para receber o
status do envio
Módulo positioning
>>> import positioning>>> positioning.modules()[{'available': 1, 'id': 270526860, 'name': u'Assisted GPS'}, {'available': 1, 'id': 270526858, 'name': u'Integrated GPS'}, {'available': 1, 'id': 270559509, 'name': u'Network based'}]
>>> positioning.select_module(270526860)
>>> positioning.set_requestors( [{"type":"service", "format": "application", "data": "test_app"}])
>>> positioning.last_position()>>> positioning.position()>>> # positioning.position(callback=cb)
Módulo inbox
Acesso a mensagens SMS incoming Callback para ser notificado de novas msgs.
>>> import inbox>>> i = inbox.Inbox()>>> m = i.sms_messages()>>> i.content(m[0])U'Meet me by 7pm at motel'>>> i.time(m[0])1130267365.03125>>> i.address(m[0])U'Vulnavia Phibes'>>> i.delete(m[0]) # SIGWIFE
Módulos contacts/e32calendar
Módulos razoavelmente complexos Explorar com base na documentação
>>> import e32calendar>>> db = e32calendar.open()>>> db.find_instances(time.time(), \ time.time() + 30*86400)[{'id': 2, 'datetime': 1251226800.0}]
>>> >>> db[2]<e32calendar.AppointmentEntry>>>> db[2].contentu'Pendrive'>>> db[2].get_repeat(){'end': 4133905200.0, 'interval': 1, }
>>> import contacts>>> db = contacts.open()>>> db.find("Ana")[<Contact #33: "Ana Bolena">]>>> db[33].as_vcard()'BEGIN:VCARD\r\n...END:VCARD\r\n'
Módulo btsocket
Soquetes Bluetooth btsocket.socket(AF_BT || AF_INET, ...) Testar BT no console BT pode falhar Bug em bt_discover() (3rd Edition FP2)
Controle de access points à Internet AP escolhido pelo usuário ou pelo aplicativo Sockets podem ligados a diferentes Aps
Módulo padrão socket também disponível socket.set_default_access_point(u”Nome”)
Módulo btsocket
>>> bt_discover() # invoca UI('00:23:12:3c:ba:a3', {u'Bluetooth-PDA-Sync': 3})
>>> bt_obex_discover()Traceback (most recent call last): File "<console>", line 1, in <module>error: (13, 'Permission denied')
>>> bt_obex_discover('00:23:12:3c:ba:a3')('00:23:12:3c:ba:a3', {u'OBEX Object Push': 10})
>>> bt_obex_send_file('00:23:12:3c:ba:a3', \ 10, u"e:\\teste.jpg")
>>> s.connect(("00:23:12:3c:ba:a3", 10))
# bt_advertise_service# bt_rfcomm_get_available_server_channel
Módulo btsocket>>> from btsocket import *>>> access_points()[{'iapid': 10, 'name': u'ASP'}, {'iapid': 2, 'name': u'bandalarga.claro.com.br'},{'iapid': 9, 'name': u'EPX'}]>>> ap = access_point(9)>>> set_default_access_point(ap)>>> ap.start()>>> ap.ip()'192.168.141.9'
>>> s = socket(AF_INET, SOCK_STREAM)>>> s.connect(("www.folha.com.br", 80))>>> s.send("GET /\r\n\r\n")9>>> print s.recv(100)<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">...>>> s.close()>>> ap.stop()
btsocket X socket
btsocket = “soquetes” Symbian, limitados Não são aceitos por select()
Limitação inclui soquetes BT Não ingressam em grupos multicast etc.
socket = soquetes do OpenC Mais poderosos (multicast funciona) Única desvantagem: relação com access points
Módulo select não “repete” notificações não funciona para write (Symbian)
Módulo scriptext
Platform Services API: acesso neutro a recursos do sistema (via strings) >= 3rd FP2, abordaremos “por cima” Application Manager, Sys Info Calendário, Contatos Location, Landmarks Messaging Sensors Media Management
import scriptext
m = scriptext.load('Service.Messaging', 'Imessaging')msgs = m.call("GetList", {"Type": u"Inbox"})
for msg in msgs: print msg['Sender']
Módulos e32db/e32dbm
e32db: mini-banco de dados do Symbian Mesma idéia do SQLite
e32dbm: Interface DBM para e32db anydbm é apelido de e32dbm em PyS60
>>> import anydbm>>> db = anydbm.open("E:\\teste.dbm", "c")>>> db["a"] = "b" >>> db.close()
>>> db = anydbm.open("E:\\teste.dbm")>>> db{'a': 'b'}
Outros módulos
logs (registro de ligações e SMS) keycapture (captura eventos teclado) topwindow (Janela modal top-level)
Ciclo de desenvolvimento
Ediçãono PC
Teste nocelular
Teste no PC(emuladoresde API)
Teste noemuladorSymbian
Impl. APIs(pys60-compat)
Windows
EmuladorimperfeitoMoroso
Testando scripts PyS60 no PC
Use módulos emuladores criadas por terceiros PyS60-compat (UI e gráficos) Lightblue (Bluetooth)
Muita atenção com o Unicode Saiba quais APIs demandam ou retornam strings Unicode
Tire proveito da orientação a objetos Python Crie módulos ”emuladores” para o PC
PyS60 no emulador Symbian
Instalar Carbide, Perl e SDK 3rd Edition FP1 ou FP2
Instalar PyS60 para SDK, casando a versão (FP1 ou FP2)
Cygwin é muito utilizado por desenvolvedores Symbian profissionais
EPOC32=C:\s60\devices\S60_3rd_FP2_SDK_v1.1\epoc32$EPOC32\winscw\c\Data\python # scripts$EPOC32\winscw\c\resource\python25 # módulos
PyS60-compat
Distribuindo um aplicativo PyS60
Aplicativo = um script ou uma pasta Ensymble
Vem na distribuição PyS60 Depende do Python 2.5 (não serve 2.4 ou 2.6) Gera e assina pacote SIS Determina módulos Python a embarcar Não elide necessidade de certificado $$$ Permite embutir outros SIS
...por exemplo, o runtime PyS60 facilita a distribuição de app. Python ao usuário final
Criando um pacote SIS no Windows
Criando um pacote SIS no Linux
Criando um pacote SIS no MacOSX
Instalando pacote SIS do PyS60
Criando extensões em C/C++ Implica em usar Windows e o SDK do S60 src\extras\elemlist ou elemlist.zip (curso) Capacidades >= aplicativo que vai importá-la
(e.g. nosso “aplicativo” é o PyScriptShell) Opção 1: usar o PyScriptShell auto-assinado Opção 2: adquirir um certificado $$$
Links sobre PyS60
http://www.mobilenin.com/pys60/menu.htm http://sourceforge.net/projects/pys60-compat/ https://garage.maemo.org/projects/pys60 http://pys60.garage.maemo.org/doc/s60/ http://wiki.opensource.nokia.com/projects/PyS60_applications http://www.hiit.fi/files/fi/da/sdk2unix/ http://www.hiit.fi/files/fi/da/miso/utils/web/