do PDF da Ajuda

Propaganda
Desenvolvimento de aplicativos
do ADOBE AIR 1.5 com o
ADOBE FLASH CS4 PROFESSIONAL
®
®
™
®
© 2008 Adobe Systems Incorporated. Todos os direitos reservados.
Copyright
Desenvolvimento de aplicativos Adobe® AIR™ 1.5 com o Adobe® Flash® CS4
Se distribuído com o software que inclui um acordo de usuário final, este guia, juntamente com o software nele descrito, ficará sujeito à licença, podendo ser
usado ou copiado apenas de acordo com os termos dessa licença. Exceto conforme permitido por esta licença, nenhuma parte deste guia pode ser reproduzida,
armazenada em um sistema de recuperação ou transmitida, em nenhuma forma ou meio eletrônico, mecânico, de gravação, ou semelhante, sem a permissão
prévia por escrito da Adobe Systems Incorporated. Observe que o conteúdo deste guia está protegido por leis de direitos autorais, mesmo não sendo distribuído
com o software que inclui um contrato de licença de usuário final.
O conteúdo deste guia foi desenvolvido apenas para fins informativos, está sujeito a alterações sem aviso prévio e não deve ser considerado um compromisso
firmado pela Adobe Systems Incorporated. A Adobe Systems Incorporated não se responsabiliza por erros ou imprecisões que possam aparecer no conteúdo
informativo deste guia.
Lembre-se de que os desenhos ou imagens existentes e cogitados para inclusão em projetos podem estar protegidos por leis de direitos autorais.. A incorporação
não autorizada desse material em um novo trabalho pode ser considerada uma violação dos direitos autorais do respectivo detentor. Certifique-se de obter a
permissão necessária do detentor em questão.
Todas as referências a nomes de empresas ou pessoas em modelos de amostra são apenas para fins demonstrativos e não têm o objetivo de fazer alusões a
nenhuma pessoa ou organização real.
Adobe, the Adobe logo, Acrobat, ActionScript, Adobe AIR, ColdFusion, Dreamweaver, Flash, Flex, Flex Builder, and Reader are either registered trademarks or
trademarks of Adobe Systems Incorporated in the United States and/or other countries.
Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Apple, Macintosh,
and Mac OS are trademarks of Apple Inc., registered in the United States and other countries. Java is a trademarks or registered trademark of Sun Microsystems,
Inc. in the United States and other countries. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. All other trademarks are the
property of their respective owners.
This work is licensed under the Creative Commons Attribution Non-Commercial 3.0 License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc/3.0/us/
This product includes software developed by the Apache Software Foundation (http://www.apache.org/)
MPEG Layer-3 audio compression technology licensed by Fraunhofer IIS and Thomson Multimedia (http://www.mp3licensing.com).
Speech compression and decompression technology licensed from Nellymoser, Inc. (www.nellymoser.com)
Video compression and decompression is powered by On2 TrueMotion video technology. © 1992-2005 On2 Technologies, Inc. All Rights Reserved.
http://www.on2.com.
This product includes software developed by the OpenSymphony Group (http://www.opensymphony.com/)
This product contains either BSAFE and/or TIPEM software by RSA Security, Inc.
Sorenson Spark™ video compression and decompression technology licensed from Sorenson Media, Inc.
This product includes software developed by the IronSmith Project (http://www.ironsmith.org/).
Adobe Systems Incorporated, 345 Park Avenue, San Jose, California 95110, USA.
Notice to U.S. Government End Users. The Software and Documentation are “Commercial Items,” as that term is defined at 48 C.F.R. §2.101, consisting of
“Commercial Computer Software” and “Commercial Computer Software Documentation,” as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202,
as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §§227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and
Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights
as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States.
Adobe Systems Incorporated, 345 Park Avenue, San Jose, CA 95110-2704, USA. For U.S. Government End Users, Adobe agrees to comply with all applicable
equal opportunity laws including, if appropriate, the provisions of Executive Order 11246, as amended, Section 402 of the Vietnam Era Veterans Readjustment
Assistance Act of 1974 (38 USC 4212), and Section 503 of the Rehabilitation Act of 1973, as amended, and the regulations at 41 CFR Parts 60-1 through 60-60,
60-250, and 60-741. The affirmative action clause and regulations contained in the preceding sentence shall be incorporated by reference.
iii
Conteúdo
Capítulo 1: Instalação do Adobe AIR
Instalação do Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Remoção do Adobe AIR
............................................................................................... 2
Instalação e execução de aplicativos de amostra do AIR
................................................................ 2
Capítulo 2: Configuração do Flash CS3 para Adobe AIR
Requisitos de sistema para atualização do Adobe AIR para Flash CS3
.................................................... 3
Instalação da atualização do Adobe AIR para Flash CS3
................................................................. 3
Remoção da atualização do Adobe AIR para Flash CS3
.................................................................. 4
Adições do AIR para o Flash CS3
....................................................................................... 5
Capítulo 3: Introdução ao Adobe AIR
Novidades do AIR 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Novidades do AIR 1.5
.................................................................................................. 8
Capítulo 4: Localização de recursos do AIR
Capítulo 5: Criação do seu primeiro aplicativo AIR usando o Flash CS3 ou CS4
Criar aplicativo Hello World no Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Testar o aplicativo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Converter um arquivo FLA em um aplicativo Adobe AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Capítulo 6: Atualização do Adobe AIR para Flash CS3 Professional
Criar um arquivo Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Definição das configurações de publicação do Adobe AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Visualizar um aplicativo Adobe AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Depurar um aplicativo Adobe AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Criação de arquivos do aplicativo AIR e do instalador
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Criação de um arquivo personalizado de descrição do aplicativo
Assinatura do aplicativo
Capítulo 7: Segurança do AIR
Noções básicas de segurança do AIR
Instalação e atualizações
Caixas de proteção
segurança HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Script entre conteúdos em domínios distintos
Gravação em disco
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Trabalho seguro com conteúdo não confiável
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Práticas recomendadas de segurança para desenvolvedores
Assinatura de código
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Capítulo 8: Configuração de propriedades do aplicativo do AIR
A estrutura do arquivo do descritor do aplicativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Definição de propriedades no arquivo do descritor do aplicativo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL iv
Conteúdo
Capítulo 9: Adobe AIR - funcionalidade específica
Classes específicas do AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Classes de tempo de execução com funcionalidade específica do AIR
Classes de estrutura de monitoramento de serviço
Capítulo 10: Trabalhar com janelas nativas
Mais informações on-line sobre janelas nativas
Noções básicas sobre janelas do AIR
Criação de janelas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Gerenciamento de janelas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Monitorando eventos de janela
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Exibição de janelas em tela cheia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Capítulo 11: Telas
Informações on-line adicionais sobre telas
Noções básicas de tela
Enumeração de telas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Capítulo 12: Trabalho com menus nativos
Informações online adicionais sobre menus nativos
Noções básicas do menu AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Criação de menus nativos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Sobre menus de contexto
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Sobre menus de contexto em HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Definição de forma clara de menus nativos
Exibição de menus pop-up
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Tratamento de itens de menu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Exemplo: Menu de janela e aplicativo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Capítulo 13: Ícones na barra de tarefas
Informações on-line adicionais sobre ícones da barra de tarefas
Sobre ícones na barra de tarefas
Ícones de encaixe
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Ícones da bandeja do sistema
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Ícones e botões da barra de tarefas do Windows
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Capítulo 14: Trabalho com o sistema de arquivos
Informações adicionais on-line sobre a API de Arquivo AIR
Noções básicas do arquivo AIR
Trabalho com objetos File
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Obtenção de informações sobre o sistema de arquivos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Trabalho com diretórios
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Trabalho com arquivos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Leitura e gravação de arquivos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Capítulo 15: Arrastar e soltar
Informações online adicionais sobre arrastar e soltar
Conceitos básicos de arrastar e soltar
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL v
Conteúdo
Suporte ao gesto de arrastar para fora
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Suporte ao gesto de arrastar para dentro
HTML arrastar e soltar
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Capítulo 16: Copiar e colar
Informações online adicionais sobre copiar e colar
Copiar e colar HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Comandos de menu e pressionamentos de tecla para copiar e colar
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Capítulo 17: Trabalhar com matrizes de bytes
Ler e escrever um ByteArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Exemplo de ByteArray: leitura de um arquivo .zip
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Capítulo 18: Trabalhar com bancos de dados SQL locais
Mais informações on-line sobre bancos de dados SQL locais
Sobre bancos de dados SQL locais
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Criação e modificação de um banco de dados
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Manipulação de dados de um banco de dados SQL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Uso de operações de banco de dados síncronas e assíncronas
Uso da criptografia com bancos de dados SQL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Estratégias para trabalhar com bancos de dados SQL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Capítulo 19: Armazenamento de dados criptografados
Capítulo 20: Sobre o ambiente HTML
Visão geral do ambiente HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Extensões do AIR e Webkit
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Capítulo 21: Programação em HTML e JavaScript
Sobre a classe HTMLLoader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Como evitar erros JavaScript relacionados à segurança
Acesso às classes API do AIR no JavaScript
Sobre URLs no AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Como tornar objetos ActionScript disponíveis para JavaScript
Acesso a objetos HTML DOM e JavaScript do ActionScript
Incorporação de conteúdo SWF em HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Uso de bibliotecas do ActionScript em uma página HTML
Conversão de objetos Date e RegExp
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Manipulação de folha de estilos HTML do ActionScript
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Conteúdo entre scripts em caixas de proteção de segurança distintas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Capítulo 22: Tratamento de eventos relacionados a HTML
eventos HTMLLoader
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Tratamento de eventos DOM com o ActionScript
Resposta a exceções JavaScript não capturadas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Tratamento de eventos de tempo de execução com JavaScript
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL vi
Conteúdo
Capítulo 23: Gravação de script de contêiner HTML
Exibição de propriedades de objetos HTMLLoader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Rolagem de conteúdo HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Acesso à lista de histórico de HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Definição do agente do usuário usado ao carregar conteúdo HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Configuração de codificação de caractere para uso de conteúdo HTML.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Definição de interfaces do usuário como navegadores para conteúdo HTML
Criação de subclasses da classe HTMLLoader
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Capítulo 24: Adição de conteúdo em PDF
Detecção de recurso de PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Carregamento de conteúdo em PDF
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Gravando em script o conteúdo em PDF
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Limitações conhecidas do conteúdo em PDF no AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Capítulo 25: Utilização de gerenciamento de direitos digitais
Informações online adicionais sobre o gerenciamento de direitos digitais
Compreensão do fluxo de trabalho FLV criptografado
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Membros e eventos relacionados a DRM da classe NetStream
Uso da classe DRMStatusEvent
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Uso da classe DRMAuthenticateEvent
Uso da classe DRMErrorEvent
Uso da classe DRMManager
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Uso da classe DRMContentData
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Capítulo 26: Inicialização do aplicativo e opções de saída
Invocação do aplicativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Captura de argumentos de linha de comando
Inicialização no login
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
Invocação do navegador
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
Encerramento do aplicativo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Capítulo 27: Leitura de configurações do aplicativo
Leitura do arquivo do descritor do aplicativo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Como obter os identificadores de aplicativo e editor
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Capítulo 28: Trabalho com tempo de execução e informações do sistema operacional
Gerenciamento de associações de arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Obtenção da versão do tempo de execução e do nível de patch
Detecção de recursos do AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Rastreamento de presença do usuário
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Capítulo 29: Monitoramento de conectividade de rede
Detecção de alterações na conectividade de rede . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Noções básicas de monitoramento de serviço
Detecção de conectividade HTTP
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Detecção de conectividade de soquete
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL vii
Conteúdo
Capítulo 30: Solicitações de URL e rede
Uso da classe URLRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Alterações feitas na classe URLStream
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Abertura de uma URL no navegador da Web padrão do sistema
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Capítulo 31: Comunicação entre aplicativos
Capítulo 32: Distribuição, instalação e execução de aplicativos do AIR
Instalação e execução de um aplicativo do AIR da área de trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Instalação e execução de aplicativos do AIR de uma página da Web
Implantação empresarial
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Assinatura digital de um arquivo do AIR
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Capítulo 33: Atualização de aplicativos do AIR
Sobre atualização de aplicativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Apresentação de uma interface de usuário de atualização do aplicativo personalizado
Download de um arquivo do AIR no computador do usuário
Verificar se um aplicativo está sendo executado pela primeira vez
Uso da estrutura de atualização
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Capítulo 34: Localização de aplicativos AIR
Introdução à localização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Localização do nome e da descrição do aplicativo no instalador do aplicativo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Seleção de código de idiomas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Localização de conteúdo Flash
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Localização de conteúdo HTML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Localização de datas, horas e moedas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Capítulo 35: Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Uso do ADL (AIR Debug Launcher) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Empacotamento de um arquivo de instalação do AIR usando o ADT (ferramenta para desenvolvedores do AIR)
Assinatura de um arquivo do AIR para alterar o certificado do aplicativo
Criação de um certificado auto-assinado com o ADT
Uso do Apache Ant com as ferramentas do SDK
Índice
. . . . . . . . 357
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
1
Capítulo 1: Instalação do Adobe AIR
O Adobe® AIR™ permite executar aplicativos AIR na área de trabalho. É possível instalar o tempo de execução das
seguintes formas:
• Instalando o tempo de execução separadamente (sem instalar também um aplicativo AIR)
• Instalando o aplicativo AIR pela primeira vez (você é solicitado a também instalar o tempo de execução)
• Configurando um ambiente de desenvolvimento AIR como o AIR SDK, Adobe® Flex™ Builder™ 3, ou Adobe Flex™
3 SDK(que inclui as ferramentas de desenvolvimento de linha de comando do AIR)
Só é necessário instalar o tempo de execução uma vez por computador.
Os requisitos do sistema para instalar o AIR e executar aplicativos do AIR são detalhados aqui: Adobe AIR: Requisitos
do sistema (http://www.adobe.com/products/air/systemreqs/).
Instalação do Adobe AIR
Use as seguintes instruções para fazer download e instalar as versões do AIR para Windows®, Mac OS X e Linux.
Para atualizar o tempo de execução, o usuário deve ter privilégios administrativos no computador.
Instalação do tempo de execução em um computador com Windows
1 Faça download do arquivo de instalação do tempo de execução.
2 Clique duas vezes no arquivo de instalação do tempo de execução.
3 Na janela de instalação, siga os avisos para concluir a instalação.
Instalação do tempo de execução em um computador com Mac
1 Faça download do arquivo de instalação do tempo de execução.
2 Clique duas vezes no arquivo de instalação do tempo de execução.
3 Na janela de instalação, siga os avisos para concluir a instalação.
4 Se o instalador exibir a janela Autenticação, insira seu nome de usuário e sua senha do Mac OS.
Instalação do tempo de execução em um computador com Linux
1 Baixe o arquivo de instalação do tempo de execução.
2 Defina as permissões de arquivo para que seja possível executar o aplicativo instalador.
De uma linha de comando, você pode definir as permissões de arquivo com o comando chmod +x installer.bin.
Algumas versões do Linux permitem definir as permissões de arquivo na caixa de diálogo Propriedades aberta por
meio de um menu de contexto.
3 Execute o instalador da linha de comando ou clicando duas vezes no arquivo de instalação do tempo de execução.
4 Na janela de instalação, siga os avisos para concluir a instalação.
O AIR é instalado como pacotes rpm ou dpkg, com nomes de pacote: adobeairv.n e adobecerts. A instalação requer
um servidor X em execução. O AIR registra o tipo mime: application/vnd.adobe.air-application-installerpackage+zip.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 2
Instalação do Adobe AIR
Remoção do Adobe AIR
Após instalar o tempo de execução, você poderá removê-lo usando os seguintes procedimentos.
Remoção do tempo de execução em um computador com Windows
1 No menu Iniciar do Windows, selecione Configurações > Painel de controle.
2 Selecione o painel de controle Adicionar ou remover programas
3 Selecione “Adobe AIR” para remover o tempo de execução.
4 Clique no botão Alterar/remover.
Remoção do tempo de execução em um computador com Mac
• Clique duas vezes em “Desinstalador do Adobe AIR”, localizado na pasta /Aplicativos/Utilitários.
Remoção do tempo de execução em um computador com Linux
Execute um dos seguintes procedimentos:
• Selecione o comando “Adobe AIR Uninstaller” no menu Aplicativos.
• Execute o binário instalador do AIR com a opção -uninstall.
• Remova os pacotes do AIR (adobeairv.n e adobecerts) com o gerenciador de pacotes.
Instalação e execução de aplicativos de amostra do AIR
Alguns aplicativos de amostra estão disponíveis para demonstrar recursos do AIR Você pode acessá-los e desinstalálos usando as seguintes instruções:
1 Faça download e execute os aplicativos de amostra do AIR. Os aplicativos compilados, bem como o código fonte,
estão disponíveis.
2 Para fazer download e executar o aplicativo de amostra, clique no botão Instalar agora do aplicativo de amostra.
Você é solicitado a instalar e executar o aplicativo.
3 Se você optar por fazer download de aplicativos de amostra e executá-los mais tarde, selecione os links de download.
Você pode executar aplicativos AIR a qualquer momento:
• No Windows, clicando duas vezes no ícone do aplicativo na área de trabalho, ou selecionando-o no menu Iniciar
do Windows.
• No Mac OS, clicando duas vezes no ícone do aplicativo, que está instalado na pasta Aplicativos do diretório do
usuário (por exemplo, no Macintosh, HD/Users/JoeUser/Applications/), por padrão.
• No Linux, clicando duas vezes no ícone do aplicativo na área de trabalho, ou selecionando-o no menu
Aplicativos. Os aplicativos do AIR são instalados em sua própria pasta no diretório /opt.
Nota: Verifique as notas de versão do AIR para atualizações dessas instruções, que estão localizadas aqui:
http://www.adobe.com/go/learn_air_relnotes_br.
3
Capítulo 2: Configuração do Flash CS3
para Adobe AIR
A atualização do Adobe® AIR™ para o Adobe® Flash® CS3 Professional aumenta o ambiente de desenvolvimento do
Flash com elementos que permitem criar aplicativos do AIR com o Flash. Isso permite criar, testar e depurar arquivos
de aplicativos do AIR no Flash.
O Adobe® Flash® CS4 Professional tem suporte incorporado para criação de aplicativos AIR. Para obter mais
informações, consulte Publicação para o Adobe AIR em Como usar o Flash.
A Atualização do Adobe AIR para Flash CS3 dá suporte ao AIR 1.0 e 1.1 e ao Flash Player 9.x. O Flash CS4 é necessário
para desenvolver aplicativos com o AIR 1.5 e o Flash Player 10.
Requisitos de sistema para atualização do Adobe AIR
para Flash CS3
Para usar o Flash CS3 para desenvolver e executar aplicativos do AIR, você deve ter o seguinte software instalado:
• Flash CS3 Professional
Se você não tiver uma cópia do Flash CS3 Professional, poderá adquiri-la no site da Adobe:
http://www.adobe.com/products/flash/
• Adobe AIR
Para obter informações sobre a instalação do Adobe AIR, consulte “Instalação do Adobe AIR” na página 1.
• Atualização do Adobe AIR para o Flash CS3
Se você tiver instalado anteriormente uma versão da atualização do Adobe AIR para Flash CS3, primeiro remova-a
seguindo as etapas em Desinstalação da atualização do Adobe AIR para Flash CS3. Se você não tiver instalado
anteriormente a atualização do Adobe AIR para Flash CS3, continue na seção “Instalação da atualização do Adobe AIR
para Flash CS3” na página 3.
Instalação da atualização do Adobe AIR para Flash CS3
Antes de instalar a atualização do Adobe AIR para Flash CS3, saia do Flash e também de qualquer navegador que
estiver aberto.
• Faça download da atualização do Adobe AIR para Flash CS3.
• Depois de fazer download da atualização, clique duas vezes no arquivo patch de atualização para instalá-la.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 4
Configuração do Flash CS3 para Adobe AIR
Remoção da atualização do Adobe AIR para Flash CS3
Se você tiver instalado anteriormente a atualização do Adobe AIR para Flash CS3, siga estas etapas para removê-la
antes de instalar uma nova atualização do Adobe AIR para Flash CS3.
1 Excluir a seguinte pasta:
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\AIK
(Mac) HD:/Aplicativos/Adobe Flash CS3/AIK
2 Vá para o local a seguir:
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\<lang>\First Run\Commands\
(Mac) HD:/Aplicativos/Adobe Flash CS3/First Run/Commands
e exclua os seguintes arquivos/pastas:
• pasta AIR
• AIR - Application and Installer Settings.jsfl
• AIR - Create AIR File.jsfl
3 Exclua o seguinte arquivo:
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\<lang>\Configuration\External
Libraries\FLAir.dll
(Mac) HD:/Aplicativos/Adobe Flash CS3/Configuration/External Libraries/FLAir.bundle.
4 Exclua o seguinte arquivo:
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash
CS3\<lang>\Configuration\Players\AdobeAIR1_0.xml
(Mac) HD:/Aplicativos/Adobe Flash CS3/Configuration/Players/ AdobeAIR1_0.xml
5 Vá para o local a seguir:
(Windows) HD:\Document and Settings\<username>\Configurações locais\Application Data\Adobe\Flash
CS3\<lang>\Configuration\Commands\
(Mac) HD:/Users/<username>/Library/Application Support/Adobe/Flash
CS3/<lang>/Configuration/Commands/
e exclua os seguintes arquivos/pastas:
• pasta AIR
• AIR - Application and Installer Settings.jsfl
• AIR - Create AIR File.jsfl
Nota: Se você não vir o local especificado no Windows, ative a opção "Mostrar pastas e arquivos ocultos" nas opções
de pasta.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 5
Configuração do Flash CS3 para Adobe AIR
Adições do AIR para o Flash CS3
Depois de instalar a atualização do Adobe AIR, você poderá ver as seguintes alterações no Flash:
• Na caixa de diálogo Configurações de publicação (Arquivo > Configurações de publicação), na aba Flash, uma nova
entrada no menu Versão para Adobe AIR 1.0.
• Uma tela atualizada de boas-vindas que contém uma entrada para a criação de arquivo Flash (Adobe AIR).
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\FirstRun\StartPage
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\FirstRun\StartPage\resources
Observação: em um computador MacIntosh, se Arquivo Flash (Adobe AIR) não for exibido na tela de boas-vindas,
exclua a pasta a seguir e reinicie o Flash:
HD:/Users/<username>/Libraries/Application Support/Adobe/Flash CS3/<language>/Configuration/StartPage
• Um novo arquivo playerglobal.swc que inclui todas as APIs do ActionScript 3.0 e do Adobe AIR na pasta
ActionScript 3.0/Classes
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\Configuration\ActionScript 3.0 Classes
(Mac) HD:/Aplicativos/Adobe Flash CS3/Configuration/ActionScript 3.0/Classes/
• Novos arquivos jsfl (AIR - Application and Installer Settings.jsfl, AIR - Publish AIR File.jsfl)
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\FirstRun\Commands
(Mac) HD:/Aplicativos/Adobe Flash CS3/First Run/Commands/
• Adobe AIR Software Development Kit (AIK)
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\AIK
• Biblioteca externa
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\Configuration\External Libraries
(Mac) HD:/Aplicativos/Adobe Flash CS3/Configuration/External Libraries/
• Arquivo de configurações de destino
(Windows) HD:\Arquivos de programas\Adobe\Adobe Flash CS3\en\Configuration\Players\
(Mac) HD:/Aplicativos/Adobe Flash CS3/Configuration/Players
6
Capítulo 3: Introdução ao Adobe AIR
O Adobe® AIR™ é um tempo de execução entre vários sistemas operacionais que permite potencializar suas habilidades
existentes de desenvolvimento para Web (Adobe® Flash® CS3 Professional, Adobe® Flash® CS4 Professional, Adobe®
Flex™, Adobe® ActionScript® 3.0, HTML, JavaScript®, Ajax) para criar e implantar RIAS (Aplicações ricas para internet)
na área de trabalho.
Você pode encontrar mais informações sobre introdução e uso do Adobe AIR na Conexão de desenvolvedores do
Adobe AIR em (http://www.adobe.com/devnet/air/).
O AIR permite trabalhar em ambientes familiares, potencializar as ferramentas e abordagens que você considera mais
confortáveis e, oferecendo suporte a Flash, Flex, HTML, JavaScript e Ajax, criar a melhor experiência possível que
atenda a suas necessidades.
Por exemplo, os aplicativos podem ser desenvolvidos usando uma das seguintes tecnologias ou uma combinação delas:
• Flash / Flex / ActionScript
• HTML / JavaScript / CSS / Ajax
• O PDF pode ser potencializado com qualquer aplicativo
Como resultado, os aplicativos AIR podem ser:
• Baseados em Flash ou Flex: Aplicativos cujo conteúdo de raiz é Flash/Flex (SWF)
• Baseados em Flash ou Flex com HTML ou PDF. Aplicativos cujo conteúdo de raiz seja Flash/Flex (SWF) com
conteúdo HTML (HTML, JS, CSS) ou PDF incluído
• Baseado em HTML. Aplicativo cujo conteúdo de raiz seja HTML, JS e CSS
• Baseado em HTML com Flash/Flex ou PDF. Aplicativos cujo conteúdo de raiz seja HTML com conteúdo
Flash/Flex (SWF) ou PDF incluído
Usuários interagem com aplicativos AIR da mesma forma que interagem com aplicativos nativos da área de trabalho.
O tempo de execução é instalado uma vez no computador do usuário e, em seguida, os aplicativos AIR são instalados
e executados exatamente como qualquer outro aplicativo da área de trabalho.
O tempo de execução oferece uma plataforma cruzada de sistema operacional e estrutura para implantação de
aplicativos e, portanto, elimina os testes entre navegadores, assegurando funcionalidade e interações consistentes entre
áreas de trabalho. Em vez de desenvolver para um sistema operacional específico, você direciona o tempo de execução,
o que oferece seguintes benefícios:
• Aplicativos desenvolvidos para execução do AIR através de vários sistemas operacionais sem nenhum trabalho
adicional feito por você. O tempo de execução assegura apresentações e interações previsíveis e consistentes entre
todos os sistemas operacionais com suporte do AIR.
• Os aplicativos podem ser criados mais rapidamente, permitindo potencializar as tecnologias da Web existentes e o
padrão de projetos, além de estender seus aplicativos baseados na Web para a área de trabalho sem ter que aprender
as tecnologias tradicionais de desenvolvimento da área de trabalho ou a complexidade do código nativo.
• O desenvolvimento de aplicativo é mais fácil do que usar linguagens de níveis inferiores, como C e C++. Você não
precisa gerenciar APIs complexas de nível inferior, específicas de cada sistema operacional.
Ao desenvolver aplicativos para o AIR, você pode potencializar um enorme conjunto de estruturas e APIs:
• APIs específicas do AIR fornecidas pelo tempo de execução e pela estrutura AIR
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 7
Introdução ao Adobe AIR
• APIs do ActionScript usadas em arquivos SWF e na estrutura Flex (bem como outras bibliotecas e estruturas
baseadas no ActionScript)
• HTML, CSS e JavaScript
• Maioria das estruturas Ajax
O AIR altera significativamente o modo como os aplicativos podem ser criados, implantados e experimentados. Você
obtém mais controle criativo e pode estender os aplicativos baseados em Flash, Flex, HTML e Ajax para a área de
trabalho, sem ter que aprender as tecnologias tradicionais de desenvolvimento para área de trabalho.
Novidades do AIR 1.1
O Adobe AIR 1.1 apresentou os novos recursos a seguir:
• Instalação e outras caixas de diálogo de tempo de execução foram traduzidos para os idiomas:
• Português (Brasil)
• Chinês (Tradicional e simplificado)
• Francês
• Alemão
• Italiano
• Japonês
• Coreano
• Russo
• Francês
• Espanhol
• Suporte para criação de aplicativos internacionalizados, incluindo entrada de teclado para idiomas de bytes duplos.
Consulte “Localização de aplicativos AIR” na página 343.
• Suporte para localização de nome e atributos de descrição no arquivo de descrição do aplicativo.
• Suporte para localização de mensagens de erro, como SQLError.detailID e SQLError.detailArguments, no
banco de dados SQLite.
• Adição da propriedade Capabilities.languages para obter uma matriz de idiomas preferidos de interface do
usuário, como definidos pelo sistema operacional.
• Rótulos de botão e menus padrão HTML, como menus de contexto e a barra de menu Mac, foram localizados
em todos os idiomas suportados.
• Suporte para migração de certificado de um aplicativo auto-assinado para um que se vincule a uma CA (Autoridade
de certificação).
• Suporte para Microsoft Windows XP Tablet PC Edition e suporte para edições de 64 bits do Windows Vista® Home
Premium, Business, Ultimate ou Enterprise.
• Adição da API File.spaceAvailable, para obter a quantidade de espaço disponível em um disco.
• Adição da propriedade NativeWindow.supportsTransparency para determinar se uma janela pode ser desenhada
como transparente pelo sistema operacional atual.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 8
Introdução ao Adobe AIR
Para obter mais informações sobre a versão AIR 1.1, consulte as Notas de versão do Adobe AIR 1.1
(http://www.adobe.com/go/learn_air_relnotes_en).
Novidades do AIR 1.5
O Adobe AIR 1.5 apresentou os novos recursos a seguir:
• Suporte para os seguintes recursos do Flash Player 10.
• Filtros e efeitos personalizados
• API de desenho aprimorada
• Geração dinâmica de sons
• Tipo de dados vetoriais
• APIs aprimoradas para carregar e baixar arquivos
• Protocolo RTMFP (Real Time Media Flow Protocol)
• Efeitos 3D
• Suporte avançado de texto
• Gerenciamento de cores
• Mecanismo de texto
• Fluxo dinâmico
• Codec de áudio Speex
Para obter mais informações, consultehttp://www.adobe.com/products/flashplayer/features/ para obter detalhes
sobre esses recursos.
• Idiomas adicionais com suporte no instalador do AIR 1.5 e em outras caixas de diálogo de tempo de execução:
tcheco, holandês, sueco, turco e polonês.
• Criptografia de banco de dados.
Arquivos de banco de dados podem ser criptografados no AIR 1.5. Todo o conteúdo do banco de dados, incluindo
os metadados, podem ser criptografados para que os dados não possam ser lidos fora do aplicativo do AIR que os
criptografou. Esse recurso permitirá ao desenvolvedor criptografar, descriptografar e criptografar novamente os
arquivos do banco de dados. Consulte “Armazenamento de dados criptografados” na página 215.
• A versão de WebKit usada pelo Adobe AIR foi atualizada e agora inclui suporte para o intérprete SquirrelFish do
JavaScript.
• Novas APIs de validação de assinatura XML que podem ser usadas para verificar a integridade e a identidade de
quem assina dados ou informações. Consulte Validação da assinatura XML.
Para obter mais informações sobre a versão AIR 1,5, consulte as Notas de versão do Adobe AIR 1.5
(http://www.adobe.com/go/learn_air_relnotes_en).
9
Capítulo 4: Localização de recursos do AIR
Para obter mais informações sobre o desenvolvimento de aplicativos Adobe® AIR™, consulte os seguintes recursos:
Origem
Localização
Programação do ActionScript 3.0
http://www.adobe.com/go/learn_fl_cs4_programmingAS3_en
Referência dos componentes e da linguagem do
ActionScript 3.0 (inclui o AIR)
http://www.adobe.com/go/learn_flashcs4_langref_en
Início rápido do Adobe AIR para Flash
http://www.adobe.com/go/learn_air_flash_qs_en
Uso do Flash
http://www.adobe.com/go/learn_fl_cs4_using_en
Uso de componentes do ActionScript 3.0
http://www.adobe.com/go/learn_fl_cs4_as3components_en
Você pode encontrar artigos, amostras e apresentações da Adobe e de especialistas da comunidade na Conexão de
desenvolvedores do Adobe AIR em http://www.adobe.com/devnet/air/. Você também pode baixar o Adobe AIR e
software relacionado nesse endereço.
Você pode encontrar uma seção específica para desenvolvedores Flash em http://www.adobe.com/devnet/air/flash/.
Visite o site de suporte da Adobe, em http://www.adobe.com/support/, para encontrar informações para solução de
problemas do seu produto e saber sobre as opções de suporte técnico paga e gratuita. Siga o link Treinamento para
acessar os livros da Adobe Press, uma variedade de recursos de treinamento, programas de certificação de software da
Adobe e mais.
10
Capítulo 5: Criação do seu primeiro
aplicativo AIR usando o Flash CS3 ou CS4
Para ver uma demonstração rápida e prática de como funciona o Adobe® AIR™, siga as instruções deste tópico para
criar e compactar um aplicativo AIR “Hello World” simples utilizando o Adobe® Flash® CS3 Professional.
Faça download e instale as atualizações do Adobe AIR para Flash CS3, se ainda não tiver feito isso. Para obter mais
informações sobre a instalação do Adobe AIR para Flash CS3, consulte “Configuração do Flash CS3 para Adobe AIR”
na página 3.
Se você estiver usando o Adobe ®Flash® CS4 Professional, o suporte para o Adobe AIR está incorporado; não é
necessário instalar nada para começar.
Criar aplicativo Hello World no Flash
A criação de um aplicativo Adobe AIR no Flash é semelhante à criação de qualquer outro arquivo FLA. A diferença é
que você começará criando um Arquivo Flash (Adobe AIR) na tela de boas-vindas e terminará criando as
configurações do aplicativo e do instalador e instalando seu aplicativo AIR. O procedimento a seguir orienta no
processo de criação de um aplicativo Hello World simples utilizando o Flash CS3 ou o Flash CS4.
Para criar o aplicativo Hello World
1 Inicie o Flash.
2 Na tela de boas-vindas, clique em Arquivo Flash (Adobe AIR) para criar um arquivo FLA vazio com as
configurações de publicação do Adobe AIR.
3 Clique em OK para responder o diálogo de resumo, Autoria para Adobe AIR com Flash CS3. Esse diálogo demora
alguns segundos para ser exibido pela primeira vez. (Esse diálogo não é exibido no Flash CS4.)
4 Selecione a ferramenta Texto no painel Ferramentas e crie um campo de texto estático (o padrão) no centro do
Palco. Faça-o grande o suficiente para conter de 15 a 20 caracteres.
5 Digite o texto "Hello World" no campo de texto.
6 Salve o arquivo, nomeando-o (por exemplo, helloAIR).
Testar o aplicativo
1 Pressione Ctrl + Enter ou selecione Controlar -> Testar filme para testar o aplicativo no Adobe AIR.
2 Para utilizar o recurso Depurar filme, primeiro adicione o código ActionScript ao aplicativo. Você pode fazer isso
rapidamente adicionando uma instrução trace como esta:
trace("Running AIR application using Debug Movie");
3 Pressione Ctrl + Shift + Enter ou selecione Controlar -> Depurar filme para executar o aplicativo com Depurar
filme.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 11
Criação do seu primeiro aplicativo AIR usando o Flash CS3 ou CS4
4 Selecione Comandos > AIR > Configurações do aplicativo e do instalador para abrir a caixa de diálogo AIR -
Configurações do aplicativo e do instalador. No Flash CS4, você pode abrir essa caixa de diálogo selecionando
Arquivo > AIR - Configurações.
5 Assine o pacote do Adobe AIR com um certificado digital auto-assinado:
a Clique no botão Definir... no prompt Assinatura digital para abrir a caixa de diálogo Assinatura digital.
b Clique no botão Criar... para abrir a caixa de diálogo Criar certificado digital auto-assinado.
c Preencha as entradas para Nome do editor, Unidade organizacional, Nome da organização, E-mail, País, Senha
e Confirmar senha.
d Especifique o tipo de certificado. A opção Tipo de certificado refere-se ao nível de segurança: 1024-RSA usa uma
chave de 1024 bits (menos segura) e 2048-RSA usa uma chave de 2048 bits (mais segura).
e Salve as informações em um arquivo de certificado preenchendo a entrada Salvar como ou clicando no botão
Procurar... para procurar o local da pasta. (Por exemplo, C:/Temp/mycert.pfx). Quando terminar, clique em OK.
f
O Flash retorna para o diálogo Assinatura digital. O caminho e o nome de arquivo do certificado auto-assinado
que você criou são exibidos na caixa de texto Certificado. Se isso não ocorrer, digite o caminho e o nome de
arquivo ou clique no botão Procurar para localizá-lo e selecioná-lo.
g Digite a mesma senha no campo de texto Senha da caixa de diálogo Assinatura digital que você atribuiu na Etapa
C e clique em OK. Para obter mais informações sobre assinatura de aplicativos Adobe AIR, consulte “Assinatura
do aplicativo” na página 21.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 12
Criação do seu primeiro aplicativo AIR usando o Flash CS3 ou CS4
6 Para criar o arquivo do aplicativo e do instalador, clique no botão Publicar arquivo AIR. Execute Testar filme ou
Depurar filme para criar os arquivos SWF e application.xml antes de criar o arquivo AIR.
7 Para instalar o aplicativo, clique duas vezes no arquivo AIR (application.air) na mesma pasta em que salvou seu
aplicativo.
8 Clique no botão Instalar no diálogo Instalação do aplicativo.
9 Revise as Preferências da instalação e as Configurações locais e verifique se a caixa de seleção 'Iniciar aplicativo após
a instalação' está marcada. Em seguida, clique em Continuar.
10 Clique em Concluir quando a mensagem Instalação concluída for exibida.
O aplicativo Hello World é semelhante a esta ilustração:
Converter um arquivo FLA em um aplicativo Adobe AIR
Você também pode converter um arquivo FLA existente para um aplicativo AIR. Para obter mais informações,
consulte “Definição das configurações de publicação do Adobe AIR” na página 13. Se você estiver usando o Flash CS4,
consulte Publicação para o Adobe AIR em Como usar o Flash.
13
Capítulo 6: Atualização do Adobe AIR
para Flash CS3 Professional
A atualização do Adobe® AIR™ para o Adobe® Flash® CS3 Professional aumenta o ambiente de autoria para permitir
que você crie, depure e compacte aplicativos Adobe AIR com o Flash. O processo de criação de um aplicativo Adobe
AIR consiste na criação de um arquivo FLA do Adobe AIR, na definição das configurações de publicação apropriadas,
no desenvolvimento do aplicativo e na criação de arquivos do instalador e do aplicativo que permitirão implantar o
aplicativo.
Se você estiver usando o Adobe® Flash® CS4 Professional, consulte Publicação no Adobe AIR, em Como usar o Flash,
para obter mais informações sobre como criar aplicativos AIR.
Para obter mais informações sobre as APIs do Adobe AIR ActionScript®3.0 que podem ser utilizadas no aplicativo,
consulte a Referência dos componentes e da linguagem do ActionScript 3.0.
Para obter uma lista das APIs do Adobe AIR ActionScript, consulte “Adobe AIR - funcionalidade específica” na
página 54.
Nota: Para usar classes no pacote air.net, arraste primeiro o componente ServiceMonitorShim do painel Componentes
para o painel Biblioteca e, em seguida, adicione a seguinte instrução import ao código ActionScript 3.0:
import air.net.*;
Criar um arquivo Adobe AIR
Você pode criar documentos de Arquivo Flash (Adobe AIR) utilizando a tela de boas-vindas do Flash ou criar um
Arquivo Flash (ActionScript 3.0) e convertê-lo em um arquivo Adobe AIR usando a caixa de diálogo Configurações
de publicação. No entanto, não é possível criar um arquivo Adobe AIR utilizando a caixa de diálogo Novo documento
(Arquivo > Novo). Para obter mais informações sobre a conversão de arquivos FLA em arquivos Adobe AIR, consulte
“Definição das configurações de publicação do Adobe AIR” na página 13.
1 Inicie o Flash ou, se já tiver iniciado o Flash, feche quaisquer documentos abertos e volte para a tela de boas-vindas.
Nota: Se você desabilitou a tela de boas-vindas do Flash, poderá exibi-la novamente selecionando Editar >
Preferências e marcando Tela de boas-vindas na categoria Geral do menu pop-up Ao iniciar.
2 Na tela de boas-vindas, clique em Arquivo Flash (Adobe AIR).
Uma mensagem de alerta é exibida para orientá-lo sobre como acessar as configurações do aplicativo Adobe AIR e
a documentação da Ajuda. Você pode ignorar essa mensagem de alerta no futuro selecionando Não mostrar
novamente, mas não será possível exibi-la posteriormente.
Definição das configurações de publicação do Adobe
AIR
Use as configurações de publicação do Flash para analisar ou alterar as configurações de um arquivo AIR e converter
um documento Arquivo Flash (ActionScript 3.0) para um documento Arquivo Flash (Adobe AIR).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 14
Atualização do Adobe AIR para Flash CS3 Professional
Exibir configurações de publicação do Adobe AIR
1 Na tela de boas-vindas do Flash, abra um documento Arquivo Flash (Adobe AIR).
2 Selecione Arquivo > Configurações de publicação e clique na aba Flash para ver as configurações de publicação do
Adobe Air.
O Adobe AIR 1.0 é selecionado automaticamente no menu Versão quando você abre um documento do Adobe
AIR. A versão do ActionScript é automaticamente definida para ActionScript 3.0. A configuração Segurança de
reprodução local é desativada porque é irrelevante para um arquivo AIR SWF.
Se você abrir um arquivo FLA do Flash, poderá convertê-lo para um arquivo AIR do Flash alterando as configurações
de publicação.
Converter um arquivo FLA do Flash para um arquivo AIR do Flash utilizando a caixa de diálogo Configurações
de publicação
1 Execute um dos seguintes procedimentos:
• Abra um arquivo FLA existente.
• Use a tela de boas-vindas ou selecione Arquivo > Novo para criar um arquivo FLA.
2 Selecione Arquivo > Configurações de publicação.
3 Na aba Flash, selecione Adobe AIR 1.0 no menu pop-up Versão.
A entrada de versão do ActionScript fica desabilitada porque ActionScript 3.0 é a única opção para um arquivo AIR.
As opções padrão restantes são as mesmas para um arquivo FLA e um arquivo Adobe AIR.
4 Clique no botão Publicar e, em seguida, em OK para fechar a caixa de diálogo Configurações de publicação. O
Inspetor de propriedade agora indica que o player de destino é o Adobe AIR 1, quando a ferramenta Seleção é
marcada.
Nota: Quando você escolher o perfil Adobe AIR 1.0, o Flash adicionará automaticamente o local do arquivo
playerglobal.swc do AIR na variável de ambiente Classpath. O arquivo playerglobal.swc do AIR permite que você use
as APIs do ActionScript AIR. Contudo, se você alternar do Adobe AIR 1 para o Adobe® Flash® Player 9, o Flash não
reverterá automaticamente para o perfil padrão nem irá alterar a configuração de Classpath para usar o arquivo
playerglobal.swc para o Flash Player 9. Se você alterar a configuração de publicação do Adobe AIR 1 para o Flash
Player 9, deverá alterar o perfil de configuração para Padrão.
Para obter informações adicionais sobre a caixa de diálogo Configurações de publicação, consulte Uso do Flash em
www.adobe.com/go/learn_fl_using_br.
Converter um arquivo FLA do Flash para um aplicativo AIR do Flash utilizando o menu Comandos
1 Abra o arquivo FLA do Flash.
2 Se você estiver abrindo um novo Arquivo Flash (ActionScript 3.0), salve-o. Caso contrário, um aviso será exibido
quando iniciar a próxima etapa.
3 Selecione Comandos > AIR - Configurações do aplicativo e do instalador.
Uma mensagem de alerta é exibida, perguntando se você deseja converter o arquivo em configurações de
publicação do Adobe AIR.
4 Clique em OK para converter o arquivo FLA para as configurações de publicação do Adobe AIR. A caixa de diálogo
AIR - Configurações do aplicativo e do instalador é exibida.
Para obter informações sobre a caixa de diálogo AIR - Configurações do aplicativo e do instalador, consulte
“Criação de arquivos do aplicativo AIR e do instalador” na página 15.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 15
Atualização do Adobe AIR para Flash CS3 Professional
Você pode usar os comandos Test Movie, Debug Movie e Create AIR File no arquivo FLA do AIR convertido.
Visualizar um aplicativo Adobe AIR
Você pode visualizar um arquivo AIR SWF do Flash quando ele for exibido na janela do aplicativo AIR. A visualização
é útil quando você quiser ver quais são os aspectos visíveis da aparência do aplicativo sem compactá-lo e instalá-lo.
1 Certifique-se de que você definiu as configurações de publicação no aplicativo Adobe AIR. Para obter mais
informações, consulte “Definição das configurações de publicação do Adobe AIR” na página 13.
2 Selecione Controlar > Testar filme ou pressione Ctrl + Enter.
Se você ainda não definiu as configurações do aplicativo na caixa de diálogo AIR - Configurações do aplicativo e do
instalador, o Flash gera um arquivo de descrição do aplicativo padrão (swfname-app.xml) para você na mesma
pasta em que o arquivo SWF está gravado. Se você definir as configurações de aplicativo utilizando a caixa de
diálogo AIR - Configurações do aplicativo e do instalador, o arquivo de descrição do aplicativo irá refleti-las.
Depurar um aplicativo Adobe AIR
O arquivo SWF do Adobe AIR pode ser depurado como um arquivo ActionScript 3.0 SWF do Flash Player 9, exceto
para depuração remota.
1 Verifique se você definiu as configurações de publicação do Adobe AIR.
2 Adicione o código ActionScript ao painel Ações (Janela > Ações). Para o teste, você pode simplesmente adicionar
uma instrução trace() como a seguinte ao painel Ações, no primeiro quadro da Linha de tempo:
trace("My application is running");
3 Selecione Depurar > Depurar filme ou pressione Ctrl+Shift+Enter.
O Flash inicia o depurador do ActionScript e exporta o arquivo SWF com as informações de depuração.
Se você ainda não definiu as configurações do aplicativo na caixa de diálogo AIR - Configurações do aplicativo e do
instalador, o Flash gera um arquivo de descrição do aplicativo padrão (swfname-app.xml) para você na mesma
pasta em que o arquivo SWF está gravado. Se você definir as configurações de aplicativo utilizando a caixa de
diálogo AIR - Configurações do aplicativo e do instalador, o arquivo de descrição do aplicativo irá refleti-las.
Quando você seleciona Depurar > Depurar filme ou pressiona Ctrl+Shift+Enter para depurar o aplicativo, o Flash
exibe um alerta se o seu aplicativo não incluir nenhum código ActionScript.
Criação de arquivos do aplicativo AIR e do instalador
Depois de concluir seu aplicativo, crie os arquivos do aplicativo AIR e do instalador para implantá-lo. O Adobe AIR
adiciona dois itens de menu novos ao menu Comandos de Flash: AIR - Configurações do aplicativo e do instalador e
AIR - Criar arquivo AIR. Depois de criar as configurações do aplicativo AIR e do instalador, você pode usar o item
AIR-Criar arquivo AIR para recriar o arquivo AIR (.air) com as configurações existentes.
Criar arquivos do aplicativo Adobe AIR e do instalador
1 No Flash, abra a página ou o conjunto de páginas que compõe seu aplicativo Adobe AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 16
Atualização do Adobe AIR para Flash CS3 Professional
2 Salve o arquivo FLA do Adobe AIR antes de abrir a caixa de diálogo AIR - Configurações do aplicativo e do
instalador.
3 Selecione Comandos > AIR - Configurações do aplicativo e do instalador.
4 Conclua a caixa de diálogo AIR - Configurações do aplicativo e do instalador e clique em Publicar arquivo AIR.
Quando você clica no botão Publicar arquivo AIR, os seguintes arquivos são compactados: o arquivo FLA, o
arquivo SWF, o arquivo de descrição do aplicativo, os arquivos de ícone do aplicativo e os arquivos listados na caixa
de texto Arquivos incluídos. Se você ainda não criou um certificado digital, o Flash exibe a caixa de diálogo
Assinatura digital quando você clica no botão Publicar arquivo AIR.
A caixa de diálogo AIR - Configurações do aplicativo e do instalador é dividida em duas seções: Configurações do
aplicativo e Configurações do instalador. Para obter mais informações sobre as configurações, consulte as seções a
seguir.
Configurações do aplicativo
A seção Configurações do aplicativo da caixa de diálogo AIR - Configurações do aplicativo e do instalador tem as
seguintes opções:
Nome do arquivo O nome do arquivo principal do aplicativo. O padrão é o nome do arquivo SWF.
Nome O nome usado pelo instalador para gerar o nome de arquivo e a pasta do aplicativo. O nome deve conter apenas
caracteres válidos para nomes de arquivos ou de pastas. O padrão é o nome do arquivo SWF.
Versão Opcional. Especifica o número da versão do aplicativo. O padrão é em branco.
ID Identifica o aplicativo com uma ID exclusiva. Você pode alterar a ID padrão se preferir. Não use espaços nem
caracteres especiais na ID. Os únicos caracteres válidos são 0-9, a-z, A-Z, . (ponto) e - (traço), os caracteres de 1 a 212
de comprimento. O padrão é com.adobe.example.application_name.
Descrição Opcional. Permite digitar uma descrição do aplicativo para ser exibida quando o usuário o instala. O padrão
é em branco.
Copyright Opcional. Permite digitar um aviso de copyright para ser exibido quando o usuário instala o aplicativo.
Estilo da janela Especifica o estilo da janela (ou cromo) que será utilizado na interface de usuário quando o usuário
executa o aplicativo no computador. Você pode especificar Cromo do sistema, que se refere ao estilo visual que o
sistema operacional usa. Também é possível especificar Cromo personalizado (opaco) ou Cromo personalizado
(transparente). Para exibir seu aplicativo sem o cromo do sistema, selecione Nenhum. O Cromo do sistema rodeia o
aplicativo com o controle de janelas padrão do sistema operacional. O Cromo personalizado (opaco) elimina o cromo
padrão do sistema e permite a você criar um cromo do seu próprio aplicativo. (Você cria o cromo personalizado
diretamente no arquivo FLA.) O Cromo personalizado (transparente) é igual ao Cromo personalizado (opaco), mas
ele adiciona recursos transparentes às margens da página. Esses recursos servem para janelas de aplicativos que não
são quadradas ou retangulares.
Ícone Opcional. Permite que você especifique um ícone para o aplicativo. O ícone é mostrado depois que você instala
o aplicativo e o executa no Adobe AIR. Você pode especificar quatro tamanhos diferentes de ícones (128, 48, 32 e 16
pixels) para permitir diferentes exibições nas quais os ícones são exibidos. Por exemplo, o ícone pode ser exibido no
navegador do arquivo nas exibições em miniatura, detalhes e lado a lado. Ele também pode ser exibido como um ícone
de desktop e no título da janela do aplicativo AIR, bem como em outros lugares.
O padrão da imagem do ícone é o ícone de aplicativo AIR de amostra, se nenhum outro arquivo de ícone for
especificado.
Para especificar um ícone, clique no botão Selecionar imagens de ícones na caixa de diálogo AIR - Configurações do
aplicativo e do instalador. Na caixa de diálogo Imagens de ícone que é exibida, clique na pasta para cada tamanho de
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 17
Atualização do Adobe AIR para Flash CS3 Professional
ícone e selecione o arquivo de ícone que utilizará. Os arquivos devem estar no formato PNG (Portable Network
Graphics).
A ilustração a seguir mostra a caixa de diálogo Imagens de ícone com os ícones padrão do aplicativo Adobe AIR.
Especificação de diferentes tamanhos das imagens de ícone do aplicativo
Se você especificar uma imagem, ela deve estar no tamanho exato (128x128, 48x48, 32x32 ou 16x16). Se você não
fornecer uma imagem para um tamanho de ícone específico, o Adobe AIR escala one das imagens fornecidas para criar
a imagem do ícone que está faltando.
Configurações avançadas
O botão Configurações na caixa de diálogo AIR - Configurações do aplicativo e do instalador permite especificar
configurações avançadas para o arquivo de descrição do aplicativo. Quando você clique no botão Configurações, a
caixa de diálogo Configurações avançadas é exibida.
A caixa de diálogo Configurações avançadas permite especificar qualquer tipo de arquivo associado que o aplicativo
deve suportar. Por exemplo, se você definiu seu aplicativo para ser o aplicativo principal para suportar arquivos
HTML, você deverá especificar isso na caixa de texto Tipos de arquivos associados.
Também é possível especificar configurações para os seguintes aspectos do aplicativo:
• O tamanho e a posição da janela inicial.
• A pasta na qual o aplicativo está instalado.
• A Pasta de menu do programa na qual o aplicativo ficará.
A caixa de diálogo tem as seguintes opções:
Tipos de arquivos associados Permite especificar os tipos de arquivos associados aos quais o aplicativo AIR oferece
suporte. Clique no botão de adição (+) para adicionar um novo tipo de arquivo à caixa de texto. Clicar no botão de
adição (+) exibe a caixa de diálogo Configurações de tipo de arquivo. Clicar no botão de subtração (-) remove um item
que está selecionado na caixa de texto. Clicar no botão Lápis exibe a caixa de diálogo Configurações de tipo de arquivo
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 18
Atualização do Adobe AIR para Flash CS3 Professional
e permite editar um item selecionado na caixa de texto. Por padrão, os botões de subtração (-) e Lápis estão
desativados. A seleção de um item na caixa de texto ativa os botões de subtração (-) e Lápis, permitindo remover ou
editar o item. O valor padrão na caixa de texto é Nenhum.
Para obter mais informações sobre as configurações de tipo de arquivo para tipos de arquivos associados, consulte
“Configurações de tipo de arquivo” na página 18.
Configurações da janela inicial Permite especificar as configurações de tamanho e posição para a janela inicial do
aplicativo.
• Largura: Especifica a largura inicial da janela em pixels. O valor padrão é em branco.
• Altura: Especifica a altura inicial da janela em pixels. O valor padrão é em branco.
• X: Especifica a posição inicial horizontal da janela em pixels. O valor padrão é em branco.
• Y: Especifica a posição inicial vertical da janela em pixels. O valor padrão é em branco.
• Largura máxima e altura máxima: Especifica o tamanho máximo da janela em pixels. Os valores padrão são em
branco.
• Largura mínima e altura mínima: Especifica o tamanho mínimo da janela em pixels. Os valores padrão são em
branco.
• Maximizável: Permite especificar se o usuário poderá maximizar a janela. Essa opção é selecionada (ou true) por
padrão.
• Minimizável: Permite especificar se o usuário poderá minimizar a janela. Essa opção é selecionada (ou true) por
padrão.
• Redimensionável: Permite especificar se o usuário poderá redimensionar a janela. Se essa opção não estiver
selecionada, Largura máxima, Altura máxima, Largura mínima e Altura mínima serão desativadas. Essa opção é
selecionada (ou true) por padrão.
• Visível: Permite especificar se a janela do aplicativo será visível inicialmente. A opção é selecionada (ou true) por
padrão.
Outras configurações Permite especificar as seguintes informações adicionais sobre a instalação:
• Pasta de instalação: especifica a pasta na qual o aplicativo está instalado.
• Pasta de menu do programa: especifica o nome da pasta de menu do programa para o aplicativo.
• UI atualizada personalizada: especifica o que acontece quando um usuário abre um arquivo AIR para um aplicativo
que já está instalado. Por padrão, o AIR exibe uma caixa de diálogo que permite ao usuário atualizar a versão
instalada com a versão no arquivo AIR. Se você não quiser que o usuário tome essa decisão e que o aplicativo tenha
o controle sobre as atualizações, selecione esta opção. A seleção desta opção substitui o comportamento padrão e
fornece ao aplicativo o controle sobre suas atualizações.
Para obter informações sobre atualização de um aplicativo AIR programaticamente, consulte “Atualização de
aplicativos do AIR” na página 328.
Configurações de tipo de arquivo
O Flash exibirá a caixa de diálogo Configurações de tipo de arquivo se você clicar no botão de adição (+) ou Lápis na
caixa de diálogo Configurações avançadas para adicionar ou editar tipos de arquivo associados para o aplicativo.
Os únicos dois campos obrigatórios nessa caixa de diálogo são Nome e Extensão. Se você clicar em OK e esses campos
estiverem em branco, o Flash exibirá uma caixa de diálogo de erro.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 19
Atualização do Adobe AIR para Flash CS3 Professional
Você pode especificar as seguintes configurações para um tipo de arquivo associado:
Nome O nome do tipo de arquivo (por exemplo, linguagem de markup de hipertexto, arquivo de texto ou de
exemplo).
Extensão A extensão do nome do arquivo (por exemplo, html, txt ou xmpl), até 39 caracteres alfanuméricos básicos
(A-Za-z0-9) e sem ponto à esquerda.
Descrição Opcional. A descrição de um tipo de arquivo (por exemplo, Arquivo de vídeo da Adobe).
Tipo de conteúdo Opcional. Especifica o tipo MIME do arquivo.
Configurações do ícone de tipo de arquivo Opcional. Permite especificar um ícone associado ao tipo de arquivo. Você
pode especificar quatro tamanhos diferentes de ícone (128x128, 48x48, 32x32 e 16x16 pixels) para permitir diferentes
exibições nas quais os ícones são exibidos. Por exemplo, o ícone pode ser exibido no navegador do arquivo nas
exibições em miniatura, detalhes e lado a lado.
Se você especificar uma imagem, ela deverá ser do tamanho especificado. Se você não especificar um arquivo para um
determinado tamanho, o AIR usará a imagem de um tamanho aproximado e a dimensionará para que se ajuste àquela
ocorrência.
Para especificar um ícone, clique na pasta para o tamanho de ícone e selecione um arquivo de ícone para ser utilizado
ou digite o caminho e o nome do arquivo para o arquivo de ícone na caixa de texto próxima ao prompt. O arquivo de
ícone deve estar no formato PNG.
Após a criação de um novo tipo de arquivo, ele é mostrado na caixa de listagem Tipo de arquivo na caixa de diálogo
Configurações avançadas.
Configurações do arquivo de descrição do aplicativo
As configurações do aplicativo especificadas são salvas no arquivo application_name-app.xml. Contudo, você tem a
opção de indicar ao Flash que deseja usar um arquivo personalizado de descrição do aplicativo.
Usar arquivo personalizado de descrição do aplicativo Permite navegar até um arquivo personalizado de descrição do
aplicativo. Se você selecionar Usar arquivo personalizado de descrição do aplicativo, a seção Configurações do
aplicativo da caixa de diálogo ficará desativada. Para especificar o local do arquivo personalizado de descrição do
aplicativo, digite-o no campo de texto abaixo de Usar arquivo personalizado de descrição do aplicativo ou clique no
ícone de pasta e navegue até o local. Para obter mais informações sobre o arquivo de descrição do aplicativo, consulte
“Criação de um arquivo personalizado de descrição do aplicativo” na página 20.
Configurações do instalador
A segunda seção da caixa de diálogo AIR - Configurações do aplicativo e do instalador contém as configurações de
instalação do aplicativo:
Assinatura digital Todos os aplicativo Adobe AIR devem estar assinados para serem instalados em outro sistema. Para
obter informações sobre atribuição de uma assinatura digital para o aplicativo Adobe AIR do Flash, consulte
“Assinatura do aplicativo” na página 21.
Destino Especifica onde salvar o arquivo AIR. O local padrão é o diretório em que salvou o arquivo FLA. Clique no
ícone de pasta para selecionar um local diferente. O nome do pacote padrão é o nome do aplicativo com a extensão de
nome de arquivo .air.
Arquivos/Pastas incluídos Especifica os arquivos e as pastas adicionais que estão inclusos no seu aplicativo. Clique no
botão de adição (+) para adicionar arquivos e no botão de pasta para adicionar pastas. Para excluir um arquivo ou pasta
da lista, selecione o arquivo ou a pasta e clique no botão de subtração (-).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 20
Atualização do Adobe AIR para Flash CS3 Professional
Por padrão, o arquivo de descrição do aplicativo e o arquivo SWF principal são adicionados automaticamente à lista
de pacotes. A lista de pacotes mostra esses arquivos mesmo se você ainda não tiver publicado o arquivo FLA do Adobe
AIR. A lista de pacotes exibe os arquivos e pastas em uma estrutura simples. Os arquivos em uma pasta não são listados,
e o caminho completo para os arquivos é mostrado, mas truncado se necessário.
Os arquivos de ícone não são incluídos na lista. Quando o Flash compacta os arquivos, ele copie os arquivos de ícone
para uma pasta temporária que é relativa ao local do arquivo SWF. O Flash exclui a pasta depois que a compactação
estiver concluída.
Falha na criação de arquivos do aplicativo e do instalador
Falha na criação dos arquivos do aplicativo e do instalador nas seguintes ocorrências:
• A string de ID do aplicativo tem um tamanho incorreto ou contém caracteres inválidos. A string de ID do aplicativo
pode conter de 1 a 212 caracteres e incluir os seguintes caracteres: 0-9, a-z, A-Z, . (ponto), - (hífen).
• Os arquivos não existem na lista do instalador.
• Os tamanhos dos arquivos personalizados de ícone estão incorretos.
• A pasta de destino do AIR não tem acesso de gravação.
• Você não assinou o aplicativo ou não especificou que ele é um aplicativo Adobe AIRI que pode ser assinado
posteriormente.
Criação de um arquivo personalizado de descrição do
aplicativo
O arquivo de descrição do aplicativo é um arquivo XML que pode ser editado com um editor de texto. Para criar um
arquivo personalizado de descrição do aplicativo, edite os valores para especificar os valores desejados. Os valores
padrão são mostrados aqui:
• id = com.adobe.example.swfname
• fileName = swfname
• name = swfname
• version = 1.0
• description = blank
• copyright = blank
• initialWindow
• title = name
• content = swfname.swf
• systemChrome = standard, type = normal
• transparent = false
• visible = true
• icon
• image128x128 = icons/AIRApp_128.png
• image48x48 = icons/AIRApp_48.png
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 21
Atualização do Adobe AIR para Flash CS3 Professional
• image32x32 = icons/AIRApp_32.png
• image16x16 = icons/AIRApp_16.png
• customUpdateUI = false
• allowBrowserInvocation = false
Para obter mais informações sobre o arquivo de descrição do aplicativo, consulte “Configuração de propriedades
do aplicativo do AIR” na página 44.
Assinatura do aplicativo
Todos os aplicativo Adobe AIR devem estar assinados para serem instalados em outro sistema. No entanto, o Flash
permite que você crie arquivos do instalador do Adobe AIR não assinados; dessa forma o aplicativo pode ser assinado
posteriormente. Esses arquivos do instalador do Adobe AIR não assinados são chamados de pacote AIRI. Esse recurso
é útil para os casos em que o certificado está em uma máquina diferente ou a assinatura é tratada separadamente do
desenvolvimento do aplicativo.
Assinar um aplicativo Adobe AIR com um certificado digital pré-adquirido de uma autoridade de certificação
raiz
1 Clique no botão Definição da assinatura digital na caixa de diálogo AIR - Configurações do aplicativo e do
instalador. A caixa de diálogo Assinatura digital é aberta.
Essa caixa de diálogo tem dois botões de opção que permitem assinar seu aplicativo Adobe AIR com um certificado
digital ou preparar um pacote AIRI. Se você assinar seu aplicativo AIR, poderá utilizar um certificado digital
concedido por uma autoridade de certificação raiz ou criar um certificado auto-assinado. Um certificado autoassinado é fácil de criar, mas não é tão confiável quanto um certificado concedido por uma autoridade de
certificação raiz.
Caixa de diálogo Assinatura digital para assinar um aplicativo AIR
2 Selecione um arquivo de certificado no menu pop-up ou clique no botão Procurar para localizar um arquivo de
certificado.
3 Selecione o certificado.
4 Digite a senha.
5 Clique em OK.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 22
Atualização do Adobe AIR para Flash CS3 Professional
Para obter mais informações sobre o assinatura do aplicativo AIR, consulte “Assinatura digital de um arquivo do AIR”
na página 321.
Criar um certificado digital auto-assinado
1 Clique no botão Criar. A caixa de diálogo Certificado digital auto-assinado é aberta.
2 Preencha as entradas para Nome do editor, Unidade organizacional, Nome da organização, País, Senha e
Confirmar senha.
3 Especifique o tipo de certificado.
A opção Tipo refere-se ao nível de segurança que o certificado carrega: 1024-RSA usa uma chave de 1024 bits
(menos segura) e 2048-RSA usa uma chave de 2048 bits (mais segura).
4 Salve as informações em um arquivo de certificado preenchendo a entrada Salvar como ou clicando no botão
Procurar.para procurar o local da pasta.
5 Clique em OK.
6 Na caixa de diálogo Assinatura digital, digite a senha atribuída na segunda etapa deste procedimento e clique em OK.
Depois de definir um certificado digital, o botão Definir muda para um botão Alterar.
Para que o Flash lembre da senha usada nesta sessão, clique em Lembrar senha dessa sessão.
Se a opção Carimbo de data e hora não estiver marcada quando clicar em OK, uma caixa de diálogo avisará que a
instalação do aplicativo falhará quando o certificado digital expirar. Se você clicar em Sim na resposta deste aviso, o
carimbo de data e hora será desabilitado. Se você clicar em Não, a opção Carimbo de data e hora será automaticamente
selecionada e habilitada.
Para obter mais informações sobre a assinatura do aplicativo AIR, consulte “Assinatura digital de um arquivo do AIR”
na página 321.
Você também pode criar um aplicativo AIRI (AIR Intermediate) sem uma assinatura digital. Entretanto, um usuário
não pode instalar o aplicativo em um desktop até que você adicione uma assinatura digital.
Preparar um pacote AIRI que será assinado posteriormente
❖ Na caixa de diálogo Assinatura digital, selecione Preparar um pacote AIRI que será assinado posteriormente e
clique em OK.
O status da assinatura digital é alterado para indicar que você optou por preparar um pacote AIRI que será assinado
posteriormente. O botão Definir muda para um botão Alterar.
23
Capítulo 7: Segurança do AIR
Esse tópico discute os problemas de segurança que você deve considerar ao desenvolver aplicativos do AIR.
Noções básicas de segurança do AIR
Os aplicativos do AIR são executados com os mesmos privilégios de usuário dos aplicativos nativos. Em geral, esses
privilégios permitem amplo acesso aos recursos do sistema operacional, como leitura e gravação de arquivos, inicialização
de aplicativos, desenho na tela e comunicação com a rede. As restrições do sistema operacional aplicadas aos aplicativos
nativos, tais como privilégios específicos do usuário, são aplicadas da mesma forma aos aplicativos do AIR.
Embora o modelo de segurança do Adobe® AIR™ seja uma evolução do modelo de segurança do Adobe® Flash® Player,
o contrato de segurança é diferente daquele aplicado ao conteúdo em um navegador. Esse contrato oferece aos
desenvolvedores um meio seguro de funcionalidade mais ampla para experiências enriquecedoras com uma liberdade
que seria inadequada para um aplicativo baseado em navegador.
Os Aplicativos do AIR são gravados usando o código de bytes compilado (conteúdo SWF) ou o script interpretado
(JavaScript, HTML) para que o tempo de execução forneça gerenciamento de memória. Isso minimiza as chances do
aplicativo AIR ser afetado pelas vulnerabilidades relacionadas a gerenciamento de memória, como estouro de buffer e
corrupção de memória. Essas são algumas das vulnerabilidades mais comuns que afetam os aplicativos de área de
trabalho gravados em código nativo.
Instalação e atualizações
Os aplicativos do AIR são distribuídos por meio de arquivos do instalador do AIR, que usa a extensão air. Quando o
Adobe AIR é instalado e um arquivo do instalador do AIR é aberto, o tempo de execução administra o processo de
instalação.
Nota: Os desenvolvedores podem especificar um nome de versão e de aplicativo e a origem de editor, mas o próprio fluxo
de trabalho inicial de instalação do aplicativo não pode ser modificado. Essa restrição é vantajosa para os usuários, pois
todos os aplicativos do AIR compartilham um procedimento de instalação consistente, otimizado e seguro, administrado
pelo tempo de execução. Se for necessária a personalização do aplicativo, ela poderá ser feita quando o aplicativo for
executado pela primeira vez.
Local de instalação do tempo de execução
Os aplicativos do AIR exigem que, primeiramente, o tempo de execução esteja instalado no computador do usuário,
assim como os arquivos SWF exigem que, primeiramente, o plug-in do navegador do Flash Player esteja instalado.
O tempo de execução é instalado no seguinte local no computador do usuário:
• Mac OS: /Library/Frameworks/
• Windows: C:\Program
• Linux: /opt/Adobe
Files\Common Files\Adobe AIR
AIR/
No Mac OS, para instalar uma versão atualizada de um aplicativo, o usuário deve ter privilégios adequados do sistema
para instalar no diretório do aplicativo. No Windows e no Linux, um usuário precisa de privilégios administrativos.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 24
Segurança do AIR
O tempo de execução pode ser instalado de duas maneiras: usando o recurso de instalação direta (instalando
diretamente do navegador da Web) ou através de instalação manual. Para obter mais informações, consulte
“Distribuição, instalação e execução de aplicativos do AIR” na página 312.
Instalação direta (tempo de execução e aplicativo)
O recurso de instalação direta fornece aos desenvolvedores uma experiência de instalação aprimorada para os usuários
que ainda não têm o Adobe AIR instalado. No método de instalação direta, o desenvolvedor cria um arquivo SWF que
apresenta o aplicativo de instalação. Quando o usuário clica no arquivo SWF para instalar o aplicativo, ele tenta
detectar o tempo de execução. Se o tempo de execução não puder ser detectado, ele será instalado e o tempo de
execução será ativado imediatamente com o processo de instalação do aplicativo do desenvolvedor.
Instalação manual
Se desejar, o usuário pode fazer o download e a instalação manual do tempo de execução antes de abrir o arquivo AIR.
Em seguida, o desenvolvedor pode distribuir o arquivo AIR por meios diversos (por exemplo, por e-mail ou link
HTML em um site da Web). Quando o arquivo AIR é aberto, o tempo de execução inicia o processo de instalação do
aplicativo.
Para obter mais informações sobre esse processo, consulte “Distribuição, instalação e execução de aplicativos do AIR”
na página 312
Fluxo de instalação do aplicativo
O modelo de segurança do AIR permite que os usuários decidam se devem instalar o aplicativo AIR . A experiência de
instalação do AIR oferece diversas melhorias sobre as tecnologias de instalação de aplicativo nativo, que tornam essa
decisão de confiança mais fácil para usuários:
• O tempo de execução fornece uma experiência de instalação consistente em todos os sistemas operacionais, mesmo
quando o aplicativo AIR é instalado de um link em um navegador da Web. A maioria das experiências de instalação
de aplicativo nativo dependem do navegador ou de outro aplicativo para fornecer informações de segurança, se de
fato elas são fornecidas.
• A experiência de instalação do aplicativo AIR identifica a fonte do aplicativo e as informações sobre que privilégios
estão disponíveis para o aplicativo (se o usuário permitir que a instalação continue).
• O tempo de execução administra o processo de instalação de um aplicativo AIR . O aplicativo AIR não pode
manipular o processo de instalação que o tempo de execução usa.
Em geral, os usuários não devem instalar nenhum aplicativo de área de trabalho vindo de uma fonte não confiável ou
que não possa ser verificada. O ônus da prova de segurança de aplicativos nativos é, da mesma forma, verdadeiro para
aplicativos do AIR, assim como é para outros aplicativos instaláveis.
Destino do aplicativo
O diretório de instalação pode ser definido usando uma das duas opções a seguir:
1 O usuário personaliza o destino durante a instalação. O aplicativo é instalado onde o usuário especificar.
2 Se o usuário não alterar o destino da instalação, o aplicativo será instalado no caminho padrão, conforme
determinado pelo tempo de execução:
• Mac OS: ~/Applications/
• Windows XP e anterior: C:\Program
Files\
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 25
Segurança do AIR
• Windows Vista: ~/Apps/
• Linux: /opt/
Se o desenvolvedor especificar a configuração installFolder no arquivo descritor do aplicativo, o aplicativo será
instalado em um subcaminho desse diretório.
O sistema de arquivos AIR
O processo de instalação de aplicativos do AIR copia todos os arquivos que o desenvolvedor incluiu no arquivo do
instalador do AIR para o computador local do usuário. O aplicativo instalado é composto de:
• Windows: Um diretório contendo todos os arquivos incluídos no arquivo do instalador AIR. O tempo de execução
também cria um arquivo exe durante a instalação do aplicativo AIR.
• Linux: Um diretório contendo todos os arquivos incluídos no arquivo do instalador do AIR. O tempo de execução
também cria um arquivo bin durante a instalação do aplicativo do AIR.
• Mac OS: Um arquivo app que contém todo o conteúdo do arquivo do instalador AIR. Ele pode ser inspecionado
usando a opção "Mostrar conteúdo do pacote" do Localizador. O tempo de execução cria esse arquivo app como
parte da instalação do aplicativo AIR.
O aplicativo AIR é executado por:
• Windows: Execução do arquivo .exe na pasta de instalação ou um atalho que corresponda a esse arquivo (como um
atalho do menu Iniciar ou área de trabalho).
• Linux: Iniciar o arquivo .bin na pasta de instalação, selecionar o aplicativo no menu Aplicativos ou executar um
alias ou atalho da área de trabalho.
• Mac OS: Execução do arquivo .app ou um alias que aponte para ele.
O sistema de arquivos do aplicativo também inclui subdiretórios relacionados à função do aplicativo. Por exemplo, as
informações gravadas no depósito local criptografado são salvas em um subdiretório do diretório nomeado depois do
identificador de aplicativo do aplicativo.
Armazenamento de aplicativo AIR
Os aplicativos do AIR têm privilégios de gravação em qualquer local do disco rígido do usuário, contudo, os
desenvolvedores são incentivados a usar o caminho app-storage:/ para armazenamento local relacionado aos
respectivos aplicativos. Os arquivos gravados em app-storage:/ de um aplicativo ficam localizados em um local
padrão, dependendo do sistema operacional do usuário:
• No Mac OS: o diretório de armazenamento do aplicativo é <appData>/<appId>/Local
Store/ onde <appData>
é a pasta "preferências do usuário", geralmente: /Users/<user>/Library/Preferences
• No Windows: o diretório de armazenamento do aplicativo é <appData>\<appId>\Local
Store\ onde
<appData> é a "pasta especial" CSIDL_APPDATA do usuário, geralmente: C:\Documents and
Settings\<user>\Application Data
• No Linux: <appData>/<appID>/Local
Store/ onde <appData> é /home/<user>/.appdata
Você pode acessar o diretório de armazenamento do aplicativo através da propriedade
air.File.applicationStorageDirectory. Você pode acessar o respectivo conteúdo usando o método
resolvePath() da classe File. Para obter detalhes, consulte“Trabalho com o sistema de arquivos” na página 106.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 26
Segurança do AIR
Atualização do Adobe AIR
Quando o usuário instala um aplicativo AIR que requer uma versão atualizada do tempo de execução, ele instala
automaticamente o tempo de execução atualizado desejado.
Para atualizar o tempo de execução, o usuário deve ter privilégios administrativos no computador.
Atualização de aplicativos do AIR
O desenvolvimento e a implantação de atualizações de software são alguns dos maiores desafios de segurança que os
aplicativos de código nativo enfrentam. A API do AIR oferece um mecanismo para melhorar isso: o método
Updater.update() pode ser chamado na inicialização para verificar o local remoto de um arquivo AIR. Se a
atualização for adequada, o arquivo AIR é baixado, instalado e o aplicativo reiniciado. Os desenvolvedores podem usar
essa classe não apenas para oferecer novas funcionalidades, mas também para responder a vulnerabilidades potenciais
de segurança.
Nota: Os desenvolvedores podem especificar a versão do aplicativo configurando a propriedade version do arquivo
descritor do aplicativo. O AIR não interpreta de maneira nenhuma a string de versão. Portanto, não se presume que a
versão "3.0" seja mais atual que a versão "2.0". Depende do desenvolvedor manter versões significativas. Para obter
detalhes, consulte “Definição de propriedades no arquivo do descritor do aplicativo” na página 45.
Desinstalação de aplicativo AIR
O usuário pode desinstalar o aplicativo AIR:
• No Windows: Usando o painel Adicionar/Remover programas para remover o aplicativo.
• No Mac OS: Excluindo o arquivo app do local de instalação.
Remover o aplicativo AIR remove também todos os arquivos no diretório do aplicativo. No entanto, não remove os
arquivos que o aplicativo possa ter gravado fora do diretório do aplicativo. Remover aplicativos do AIR não reverte as
alterações que o aplicativo AIR fez nos arquivos fora do diretório do aplicativo.
Desinstalação do Adobe AIR
O AIR pode ser desinstalado:
• No Windows: executando Adicionar/Remover programas no Painel de controle, selecionando Adobe AIR e, em
seguida, "Remover".
• No Mac OS: executando o aplicativo Desinstalador do Adobe AIR no diretório Aplicativos.
Configurações de Registro do Windows para administradores
No Windows, os administradores podem configurar o computador para impedir (ou permitir) a instalação de
aplicativo AIR e atualizações do tempo de execução. Essas configurações estão contidas no Registro do Windows na
seguinte chave: HKLM\Software\Policies\Adobe\AIR. Elas incluem o seguinte:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 27
Segurança do AIR
Configuração do Registro
Descrição
AppInstallDisabled
Especifica se a instalação e a desinstalação do aplicativo AIR é permitida. Defina como 0 para
“permitido,” defina como 1 para “não permitido.”
UntrustedAppInstallDisabled
Especifica se a instalação de aplicativos do AIR não confiáveis (aplicativos que não incluem certificado
confiável) é permitida (consulte “Assinatura digital de um arquivo do AIR” na página 321). Defina como
0 para “permitido,” defina como 1 para “não permitido.”
UpdateDisabled
Especifica se a atualização do tempo de execução é permitida como uma tarefa de plano de fundo ou
como parte de uma instalação explícita. Defina como 0 para “permitido,” defina como 1 para “não
permitido.”
Caixas de proteção
O AIR oferece uma arquitetura de segurança abrangente que define permissões de acordo com cada arquivo em um
aplicativo AIR, tanto internos quanto externos. As permissões são concedidas a arquivos de acordo com a respectiva
origem, e são atribuídas em agrupamentos lógicos de segurança chamados de caixas de proteção.
Sobre as caixas de proteção do aplicativo AIR
O modelo de segurança do tempo de execução de caixas de proteção composto pelo modelo de segurança do Flash
Player com o acréscimo da caixa de proteção do aplicativo. Os arquivos que não estão na caixa de proteção do
aplicativo têm restrições de segurança semelhantes às especificadas pelo modelo de segurança do Flash Player.
O tempo de execução usa essas caixas de proteção de segurança para definir o intervalo de dados que o código pode
acessar e as operações que ele pode executar. Para manter a segurança local, os arquivos de cada caixa de proteção
ficam isolados dos arquivos de outras caixas de proteção. Por exemplo, um arquivo SWF carregado em um aplicativo
AIR de uma URL de Internet externa é colocado em uma caixa de proteção remota e, por padrão, não tem permissão
para fazer script em arquivos que residem no diretório do aplicativo, que são atribuídos à caixa de proteção do
aplicativo.
A tabela a seguir descreve os tipos de caixa de proteção:
Caixa de proteção
Descrição
aplicativo
O arquivo reside no diretório do aplicativo e opera com o conjunto completo de privilégios do AIR.
remoto
O arquivo é de uma URL de Internet e opera sob as regras de caixa de proteção baseadas em domínio
análogas às regras aplicadas a arquivos remotos do Flash Player. (Há caixas de proteção remotas distintas
para cada domínio de rede, como http://www.example.com e https://foo.example.org.)
local confiável
O arquivo é um arquivo local e o usuário o designou como confiável, usando o Gerenciador de
configurações ou um arquivo de configuração confiável do Flash Player. O arquivo pode fazer a leitura
de fontes de dados locais e se comunicar com a Internet, mas não tem o conjunto completo de privilégios
do AIR.
local com rede
O arquivo é um arquivo SWF local publicado com uma designação de rede, mas não foi explicitamente
confiado pelo usuário. O arquivo pode se comunicar com a Internet mas não pode ler de fontes de dados
locais. Essa caixa de proteção só está disponível para conteúdo SWF.
local com sistema de arquivos
O arquivo é um arquivo de script local que não foi publicado com uma designação de rede e não foi
explicitamente confiado pelo usuário. Isso inclui arquivos JavaScript que não foram confiados. O arquivo
pode ler de fontes de dados locais, mas não pode se comunicar com a Internet.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 28
Segurança do AIR
Este tópico se concentra principalmente na caixa de proteção do aplicativo e no seu relacionamento com as outras
caixas de proteção de aplicativo AIR. Os desenvolvedores que usam conteúdo atribuído a outras caixas de proteção
devem ler a documentação adicional do modelo de segurança do Flash Player. Consulte o capítulo “Segurança do Flash
Player” na documentação Programação do ActionScript 3.0
(http://www.adobe.com/go/flashcs4_prog_as3_security_en) e o Documento Segurança do Flash Player 9
(http://www.adobe.com/go/fp9_0_security_br) ou o Documento Segurança do Flash Player 10
(http://www.adobe.com/go/fp10_0_security_en).
A caixa de proteção do aplicativo
Quando um aplicativo é instalado, todos os arquivos incluídos no arquivo do instalador do AIR são instalados em um
diretório do aplicativo no computador do usuário. Os desenvolvedores podem fazer referência a esse diretório no
código por meio do esquema de URL app:/ (consulte “Uso de esquemas de URL do AIR em URLs” na página 306).
Todos os arquivos na árvore de diretório do aplicativo são atribuídos à caixa de proteção do aplicativo quando o
aplicativo é executado. O conteúdo na caixa de proteção do aplicativo é agraciado com os privilégios completos
disponíveis para o aplicativo AIR , incluindo interação com o sistema de arquivos local.
Muitos dos aplicativos do AIR só usam esses arquivos instalados localmente para executar o aplicativo. No entanto, os
aplicativos do AIR não estão restritos apenas aos arquivos no diretório do aplicativo - eles podem carregar qualquer
tipo de arquivo de qualquer fonte. Isso inclui arquivos locais do computador do usuário, bem como arquivos de fontes
externas disponíveis, como aqueles em uma rede local ou na Internet. O tipo de arquivo não tem nenhum impacto nas
restrições de segurança, os arquivos HTML carregados têm os mesmos privilégios de segurança dos arquivos SWF
carregados da mesma fonte.
O conteúdo na caixa de proteção de segurança do aplicativo tem acesso as APIs do AIR que o conteúdo de outras caixas
de proteção não pode usar. Por exemplo, a propriedade
air.NativeApplication.nativeApplication.applicationDescriptor, que retorna o conteúdo do arquivo
descritor do aplicativo para o aplicativo, está restrita ao conteúdo na caixa de proteção de segurança do aplicativo.
Outro exemplo de API restrita é a classe FileStream, que contém métodos de leitura e gravação no sistema de arquivos
local.
As APIs do ActionScript disponíveis apenas para o conteúdo na caixa de proteção de segurança do aplicativo são
indicadas com o logotipo do AIR na Referência de Linguagem do ActionScript 3.0 para o Adobe AIR. Usar essas APIs
em outras caixas de proteção faz com que o tempo de execução lance uma exceção SecurityError.
No conteúdo HTML (em um objeto HTMLLoader), todas as APIs JavaScript do AIR (aquelas que estão disponíveis
através da propriedade window.runtime ou através do objeto air durante o uso do arquivo AIRAliases.js) estão
disponíveis para o conteúdo na caixa de proteção de segurança do aplicativo. O conteúdo HTML de outra caixa de
proteção não tem acesso à propriedade window.runtime, portanto, esse conteúdo não pode acessar as APIs do AIR.
Restrições de JavaScript e HTML
Para conteúdo HTML na caixa de proteção de segurança do aplicativo, há limitações de uso de APIs que possam
transformar dinamicamente as strings em código executável, após o código ser carregado. Isso é para evitar que o
aplicativo injete inadvertidamente (e execute) código de fontes "não-aplicativo" (como domínios de rede
potencialmente inseguros). Um exemplo é o uso da função eval(). Para obter detalhes, consulte “Restrições de código
de conteúdo em caixas de proteção distintas” na página 32.
Restrições sobre tags img no conteúdo de campo de texto do ActionScript
Para evitar possíveis ataques de phishing, as tags img de conteúdo HTML nos objetos TextField do ActionScript são
ignoradas no conteúdo SWF na caixa de proteção de segurança do aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 29
Segurança do AIR
Restrições em asfunction
O conteúdo na caixa de proteção do aplicativo não pode usar o protocolo asfunction do conteúdo HTML nos
campos de texto do ActionScript 2.0.
Nenhum acesso ao cache persistente entre domínios
O conteúdo SWF na caixa de proteção do aplicativo não pode usar o cache entre domínios, um recurso que foi
adicionado à Atualização 3 do Flash Player 9. Esse recurso permite que o Flash Player persista em colocar em cache o
conteúdo de componente da plataforma Adobe e reutilize-o no conteúdo SWF carregado sob demanda (eliminando a
necessidade de recarregar o conteúdo várias vezes).
Privilégios de conteúdo em caixas de proteção "não-aplicativo"
Os arquivos carregados de um local de rede ou da Internet são atribuídos à caixa de proteção remota. Os arquivos
carregados de fora do diretório do aplicativo são atribuídos à caixa de proteção local com sistema de arquivos,
local com rede ou local confiável, isso depende de como o arquivo foi criado e se o usuário confiou
explicitamente no arquivo por meio do Gerenciador de configurações globais do Flash Player. Para obter detalhes,
consulte http://www.macromedia.com/support/documentation/br/flashplayer/help/settings_manager.html.
Restrições de JavaScript e HTML
Ao contrário do conteúdo na caixa de proteção de segurança do aplicativo, o conteúdo JavaScript em uma caixa de
proteção de segurança "não-aplicativo" pode chamar a função eval() para executar código gerado dinamicamente a
qualquer momento. No entanto, há restrições para JavaScript em uma caixa de proteção de segurança "não-aplicativo".
Isso inclui:
• O código JavaScript em uma caixa de proteção "não-aplicativo" não tem acesso ao objeto window.runtime e,
portanto, esse código não pode executar APIs do AIR.
• Por padrão, o conteúdo em uma caixa de proteção de segurança "não-aplicativo" não pode usar chamadas
XMLHttpRequest para carregar dados de outros domínios diferentes do domínio que chama a solicitação.
Entretanto, o código do aplicativo pode conceder permissão para que o conteúdo "não-aplicativo" faça isso,
definindo um atributo allowCrossdomainXHR no frame ou iframe que o contém. Para obter mais informações,
consulte “Script entre conteúdos em domínios distintos” na página 35.
• Há restrições na chamada do método window.open() de JavaScript. Para obter detalhes, consulte “Restrições na
chamada do método window.open() de JavaScript” na página 35.
Para obter detalhes, consulte “Restrições de código de conteúdo em caixas de proteção distintas” na página 32.
Restrições no carregamento de elementos CSS, frame, iframe e img
O conteúdo HTML nas caixas de proteção de segurança remota (rede) pode carregar apenas conteúdo CSS, frame,
iframe e img de domínios remotos (de URLs de rede).
O conteúdo HTML nas caixas de proteção local com sistema de arquivos, local com rede ou local confiável só podem
carregar conteúdo CSS, frame, iframe e img de caixas de proteção locais (e não de URLs de aplicativo ou de rede).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 30
Segurança do AIR
segurança HTML
O tempo de execução aplica regras e oferece mecanismos para dominar possíveis vulnerabilidades de segurança em
HTML e JavaScript. As mesmas regras são aplicadas se o aplicativo for gravado principalmente em JavaScript ou se
você carregar conteúdo HTML e JavaScript em um aplicativo baseado em SWF. Conteúdo na caixa de proteção do
aplicativo e a caixa de proteção de segurança "não-aplicativo" (consulte “Caixas de proteção” na página 27) têm
privilégios distintos. Ao carregar o conteúdo em um iframe ou frame, o tempo de execução fornece um mecanismo de
ponte de caixa de proteção seguro, que permite que o conteúdo frame ou iframe se comunique de maneira segura com
o conteúdo na caixa de proteção de segurança do aplicativo.
Este tópico descreve a arquitetura de segurança HTML do AIR e como usar os iframes, os frames e a ponte de caixa de
proteção para configurar o aplicativo.
Para obter mais informações, consulte “Como evitar erros JavaScript relacionados à segurança” na página 235.
Visão geral sobre a configuração de aplicativo baseado em HTML
Os Frames e iframes oferecem uma estrutura conveniente para organizar conteúdo HTML no AIR. Os frames
oferecem um meio de manter a persistência de dados e trabalhar de maneira segura com conteúdo remoto.
Como o HTML no AIR retém sua organização normal baseada em página, o ambiente HTML será totalmente
atualizado, caso o frame superior do conteúdo HTML "navegue" para uma página diferente. Você pode usar frames e
iframes para manter a persistência de dados no AIR, da mesma maneira que em um aplicativo da Web em execução
em um navegador. Defina os objetos principais do aplicativo no frame superior e eles persistirão, desde que você não
permita que o frame navegue para uma nova página. Use frames ou iframes filhos para carregar e exibir as partes
transitórias do aplicativo. (Há diversas maneiras de manter a persistência de dados, que podem ser usadas além de ou
em vez de frames. Isso inclui cookies, objetos locais compartilhados, armazenamento local de arquivos, depósito de
arquivo criptografado e armazenamento de banco de dados local).
Como o HTML no AIR retém sua linha desfocada normal entre o código executável e os dados, o AIR coloca o
conteúdo no quadro superior do ambiente HTML, na caixa de proteção do aplicativo. Depois do evento load da
página, o AIR restringe quaisquer operações, como eval(), que possam converter uma seqüência de caracteres de
texto em um objeto executável. Essa restrição é aplicada mesmo quando o aplicativo não carrega conteúdo remoto.
Para permitir que o conteúdo em HTML execute essas operações restritas, você deve usar frames ou iframes para
colocar o conteúdo em uma caixa de proteção não-aplicativo. (Executar conteúdo em um quadro filho de uma caixa
de proteção pode ser necessário ao usar algumas estruturas do aplicativo JavaScript que dependem da função eval().)
Para obter uma lista completa das restrições JavaScript na caixa de proteção do aplicativo, consulte “Restrições de
código de conteúdo em caixas de proteção distintas” na página 32.
Como o HTML no AIR mantém a capacidade de carregar conteúdo remoto possivelmente inseguro, o AIR aplica a
política de mesma origem que impede que o conteúdo de um domínio interaja com o conteúdo de outro domínio. Para
permitir a interação entre o conteúdo do aplicativo e o conteúdo de outro domínio, você pode configurar uma ponte
para servir como interface entre um frame pai e filho.
Configuração de relacionamento pai-filho de caixa de proteção
O AIR adiciona os atributos sandboxRoot e documentRoot aos elementos frame e iframe de HTML. Esses atributos
permitem tratar o conteúdo do aplicativo como se ele tivesse vindo de outro domínio:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 31
Segurança do AIR
Atributo
Descrição
sandboxRoot
A URL que deve ser usada para determinar a caixa de proteção e o domínio em
que o conteúdo do frame deve ser colocado. Os esquemas de URL file:,
http: ou https: devem ser usados.
documentRoot
A URL da qual o conteúdo do frame deve ser carregado. Os esquemas de URL
file:, app: ou app-storage: devem ser usados.
O exemplo a seguir mapeia o conteúdo instalado no subdiretório da caixa de proteção do aplicativo a ser executado na
caixa de proteção remota e o domínio www.exemplo.com:
<iframe
src="ui.html"
sandboxRoot="http://www.example.com/local/"
documentRoot="app:/sandbox/">
</iframe>
Configuração de ponte entre frames pai e filho em caixas de proteção ou domínios distintos
O AIR adiciona as propriedades childSandboxBridge e parentSandboxBridge ao objeto window de qualquer frame
filho. Essas propriedades permitem definir pontes para servir como interfaces entre um quadro pai e filho. Cada ponte
segue em uma direção:
childSandboxBridge A propriedade childSandboxBridge permite que o frame filho exponha uma interface para
o conteúdo do frame pai. Para expor uma interface, você define a propriedade childSandbox como função ou objeto
no frame filho. Em seguida, você pode acessar o objeto ou a função do conteúdo no frame pai. O exemplo a seguir
mostra como um script que está sendo executado em um frame filho pode expor um objeto contendo uma função e
uma propriedade para o respectivo pai:
var interface = {};
interface.calculatePrice = function(){
return .45 + 1.20;
}
interface.storeID = "abc"
window.childSandboxBridge = interface;
Se esse conteúdo filho estiver em um iframe com id de "child" atribuída, você poderá acessar a interface do conteúdo
pai, lendo a propriedade childSandboxBridge do frame:
var childInterface = document.getElementById("child").childSandboxBridge;
air.trace(childInterface.calculatePrice()); //traces "1.65"
air.trace(childInterface.storeID)); //traces "abc"
parentSandboxBridge A propriedade parentSandboxBridge permite que o frame pai exponha uma interface para
o conteúdo do frame filho. Para expor uma interface, você define a propriedade parentSandbox do frame filho como
função ou objeto no frame pai. Em seguida, você pode acessar o objeto ou a função do conteúdo no frame filho. O
exemplo a seguir mostra como um script em execução no frame pai pode expor um objeto contendo uma função save
para o filho:
var interface = {};
interface.save = function(text){
var saveFile = air.File("app-storage:/save.txt");
//write text to file
}
document.getElementById("child").parentSandboxBridge = interface;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 32
Segurança do AIR
Ao usar essa interface, o conteúdo no frame filho poderá salvar texto em um arquivo chamado save.txt. No entanto,
ele não terá nenhum outro acesso ao sistema de arquivos. Em geral, o conteúdo do aplicativo deve expor a interface
mais estreita possível para as outras caixas de proteção. O conteúdo filho poderá chamar a função save da seguinte
maneira:
var textToSave = "A string.";
window.parentSandboxBridge.save(textToSave);
Se o conteúdo filho tentar definir uma propriedade do objeto parentSandboxBridge, o tempo de execução lançará
uma exceção SecurityError. Se o conteúdo pai tentar definir uma propriedade do objeto childSandboxBridge, o
tempo de execução lançará uma exceção SecurityError.
Restrições de código de conteúdo em caixas de proteção distintas
Como discutido na introdução deste tópico, “segurança HTML” na página 30, o tempo de execução aplica regras e
fornece mecanismos para dominar possíveis vulnerabilidades de segurança em HTML e JavaScript. Este tópico lista
essas restrições. Se o código tentar chamar essas APIs restritas, o tempo de execução lançará um erro com a mensagem
"Violação de segurança de tempo de execução do Adobe AIR para código JavaScript na caixa de proteção de segurança
do aplicativo".
Para obter mais informações, consulte “Como evitar erros JavaScript relacionados à segurança” na página 235.
Restrições sobre o uso da função eval() de JavaScript e técnicas semelhantes
Para conteúdo HTML na caixa de proteção de segurança do aplicativo há limitações no uso das APIs que podem
transformar dinamicamente as strings em código executável após o carregamento do código (após o evento onload
do elemento body ter sido despachado e o término de execução da função do manipulador onload). Isso é para evitar
que o aplicativo injete inadvertidamente (e execute) código de fontes "não-aplicativo" (como domínios de rede
potencialmente inseguros).
Por exemplo, se o aplicativo usa strings de dados de uma fonte remota para gravar na propriedade innerHTML de um
elemento DOM, a string pode incluir o código (JavaScript) executável que pode executar operações inseguras. No
entanto, enquanto o conteúdo estiver carregando, não há risco de inserir strings remotas no DOM.
Uma restrição está no uso da função eval() de JavaScript. Após o código na caixa de proteção do aplicativo tiver sido
carregado e após o processamento do manipulador de eventos onload, você só poderá usar a função eval() de forma
limitada. As seguintes regras se aplicam ao uso da função eval()após o código ter sido carregado da caixa de proteção
de segurança do aplicativo:
• São permitidas expressões que envolvem literais. Por exemplo:
eval("null");
eval("3 + .14");
eval("'foo'");
• As literais de objeto são permitidos da seguinte maneira:
{ prop1: val1, prop2: val2 }
• As opções setter/getters de literal de objeto são proibidas, conforme segue:
{ get prop1() { ... }, set prop1(v) { ... } }
• As literais de matriz são permitidas da seguinte maneira:
[ val1, val2, val3 ]
• Expressões que envolvem leituras de propriedades são proibidas, conforme segue:
a.b.c
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 33
Segurança do AIR
• A chamada de função é proibida.
• Definições de função são proibidas.
• A configuração de qualquer propriedade é proibida.
• As literais de função são proibidas.
No entanto, enquanto o código estiver sendo carregado, antes do evento onload e durante a execução da função do
manipulador de eventos onload, essas restrições não serão aplicadas ao conteúdo na caixa de proteção de segurança
do aplicativo.
Por exemplo, após o código ser carregado, o código a seguir resultará no lançamento de uma exceção pelo tempo de
execução.
eval("alert(44)");
eval("myFunction(44)");
eval("NativeApplication.applicationID");
O código gerado dinamicamente, como o que é feito durante a chamada da função eval(), representaria um risco à
segurança se permitido na caixa de proteção do aplicativo. Por exemplo, um aplicativo pode executar
inadvertidamente uma string carregada de um domínio de rede e essa string pode conter código mal-intencionado.
Por exemplo, esse pode ser um código de exclusão ou alteração de arquivos no computador do usuário. Ou pode ser
um código que informa o conteúdo de um arquivo local para um domínio de rede não confiável.
As formas de gerar código dinâmico são as seguintes:
• Chamando a função eval().
• Uso de propriedades innerHTML ou funções DOM para inserir tags de script que carregam um script de fora do
diretório do aplicativo.
• Uso de propriedades innerHTML ou funções DOM para inserir tags de scripts com código inline (em vez de carregar
um script através do atributo src).
• Configuração do atributo src para que a tag de script carregue um arquivo JavaScript que está fora do diretório
do aplicativo.
• Uso de esquema de URL javascript (como em href="javascript:alert('Test')").
• Uso da função setInterval() ou setTimout() em que o primeiro parâmetro (que define a função para ser
executada de forma assíncrona) é uma string (a ser avaliada) em vez de um nome de função (como em
setTimeout('x = 4', 1000)).
• Chamada de document.write() ou document.writeln().
O código na caixa de proteção de segurança do aplicativo só pode usar esses métodos enquanto o conteúdo estiver
sendo carregado.
Essas restrições não impedem o uso de eval() com literais do objeto JSON. Isso permite que o conteúdo do aplicativo
trabalhe com a biblioteca JavaScript JSON. No entanto, você não poderá usar código JSON sobrecarregado (com
manipuladores de eventos)
Em outras estruturas Ajax e bibliotecas de código JavaScript, certifique-se de que o código na estrutura ou biblioteca
funciona dentro dessas restrições em código gerado dinamicamente. Se não funcionarem, inclua algum conteúdo que
use a estrutura ou biblioteca em uma caixa de proteção de segurança "não-aplicativo". Para obter detalhes, consulte
“Privilégios de conteúdo em caixas de proteção "não-aplicativo"” na página 29 e “Script entre conteúdo de aplicativo e
"não-aplicativo"” na página 40. O Adobe mantém uma lista das estruturas Ajax conhecidas por oferecer suporte à caixa
de proteção de segurança do aplicativo, em http://www.adobe.com/products/air/develop/ajax/features/.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 34
Segurança do AIR
Ao contrário do conteúdo na caixa de proteção de segurança do aplicativo, o conteúdo JavaScript em uma caixa de
proteção de segurança "não-aplicativo" pode chamar a função eval() para executar código gerado dinamicamente a
qualquer momento.
Restrições de acesso às APIs do AIR (para caixas de proteção "não-aplicativo")
O código JavaScript em uma caixa de proteção "não-aplicativo" não tem acesso ao objeto window.runtime e, portanto,
esse código não pode executar APIs do AIR. Se o conteúdo em uma caixa de proteção de segurança "não-aplicativo"
chamar o código a seguir, o aplicativo lançará uma exceção TypeError:
try {
window.runtime.flash.system.NativeApplication.nativeApplication.exit();
}
catch (e)
{
alert(e);
}
O tipo de exceção é TypeError (valor indefinido), porque o conteúdo na caixa de proteção "não-aplicativo" não
reconhece o objeto window.runtime, portanto, ele é considerado como valor indefinido.
Você pode expor a funcionalidade de tempo de execução ao conteúdo em uma caixa de proteção "não-aplicativo"
usando uma ponte de script. Para obter detalhes, consulte “Script entre conteúdo de aplicativo e "não-aplicativo"” na
página 40.
Restrições no uso de chamadas XMLHttpRequest
O conteúdo HTML na caixa de proteção de segurança do aplicativo não pode usar os métodos XMLHttpRequest
síncronos para carregar dados de fora da caixa de proteção do aplicativo enquanto o conteúdo HTML estiver sendo
carregado e durante o evento onLoad.
Por padrão, o conteúdo HTML nas caixas de proteção de segurança "não-aplicativo" não têm permissão para usar o
objeto XMLHttpRequest de JavaScript para carregar dados de outros domínios que não o domínio que está chamando
a solicitação. A tag frame ou iframe pode incluir um atributo allowcrosscomainxhr. Configurar esse atributo como
qualquer valor diferente de "null" permite que o conteúdo no frame ou iframe use o objetoXMLHttpRequest de
Javascript para carregar dados de outros domínios que não sejam o domínio do código que está chamando a
solicitação:
<iframe id="UI"
src="http://example.com/ui.html"
sandboxRoot="http://example.com/"
allowcrossDomainxhr="true"
documentRoot="app:/">
</iframe>
Para obter mais informações, consulte “Script entre conteúdos em domínios distintos” na página 35.
Restrições no carregamento de elementos CSS, frame, iframe e img (para conteúdo em
caixas de proteção "não-aplicativo")
O conteúdo HTML nas caixas de proteção de segurança remota (rede) pode carregar apenas conteúdo CSS, frame,
iframe e img de caixas de proteção remotas (de URLs de rede).
O conteúdo HTML nas caixas de proteção local com sistema de arquivos, local com rede ou local confiável só podem
carregar conteúdo CSS, frame, iframe e img de caixas de proteção locais (e não de caixas de proteção de aplicativo ou
remotas).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 35
Segurança do AIR
Restrições na chamada do método window.open() de JavaScript
Se a janela criada através de uma chamada para o método window.open() de JavaScript exibir conteúdo de uma caixa
de proteção de segurança "não-aplicativo", o título da janela iniciará com o título da janela principal (inicializada),
seguido pelo caractere dois pontos. Você não pode usar código para remover da tela essa parte do título da janela.
O conteúdo nas caixas de proteção de segurança "não-aplicativo" só consegue chamar com êxito o método
window.open() de JavaScript em resposta a um evento acionado pelo mouse do usuário ou pela interação do teclado.
Isso evita que o conteúdo "não-aplicativo" crie janelas que possam ser usadas de maneira enganosa (por exemplo, em
ataques de phishing). Além disso, o manipulador de eventos do evento de mouse ou teclado não pode configurar o
método window.open() para ser executado após um atraso (por exemplo, chamando a função setTimeout()).
O conteúdo nas caixas de proteção remotas (rede) só podem usar o método window.open() para abrir o conteúdo nas
caixas de proteção de rede remota. Ele não pode usar o método window.open() para abrir o conteúdo das caixas de
proteção locais ou do aplicativo.
O conteúdo nas caixas de proteção local com sistema de arquivos, local com rede ou local confiável (consulte “Caixas
de proteção” na página 27 ) só pode usar o método window.open() para abrir o conteúdo nas caixas de proteção
locais. Ele não pode usar o método window.open() para abrir o conteúdo das caixas de proteção remotas ou do
aplicativo.
Erros na chamada de código restrito
Se você chamar um código com uso restrito em uma caixa de proteção, devido a essas restrições de segurança, o tempo
de execução despachará um erro de JavaScript: "Violação de segurança de tempo de execução do Adobe AIR para
código JavaScript na caixa de proteção de segurança do aplicativo."
Para obter mais informações, consulte “Como evitar erros JavaScript relacionados à segurança” na página 235.
Proteção da caixa de proteção ao carregar conteúdo HTML de uma seqüência
de caracteres
O método loadString() da classe HTMLLoader permite criar conteúdo HTML no tempo de execução. No entanto,
os dados usados como conteúdo HTML podem ser corrompidos se forem carregados de uma fonte de Internet
insegura. Por esse motivo, por padrão, o HTML criado com o método loadString() não é colocado na caixa de
proteção do aplicativo e não tem acesso às APIs do AIR. Entretanto, você pode definir a propriedade
placeLoadStringContentInApplicationSandbox de um objeto HTMLLoader como true para inserir o HTML
criado usando o método loadString() na caixa de proteção do aplicativo. Para obter mais informações, consulte
“Carregamento de conteúdo HTML de uma string” na página 233.
Script entre conteúdos em domínios distintos
Aplicativos do AIR recebem privilégios especiais quando são instalados. É fundamental que os mesmos privilégios não
vazem para outro conteúdo, incluindo arquivos remotos e arquivos locais que não fazem parte do aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 36
Segurança do AIR
Sobre a ponte de caixa de proteção do AIR
Normalmente, o conteúdo de outros domínios não pode chamar scripts de outros domínios. Para proteger os
aplicativos do AIR de vazamentos acidentais de informações privilegiadas ou de controle, as restrições a seguir são
colocadas no conteúdo na caixa de proteção de segurança do aplicativo (conteúdo instalado com o aplicativo):
• O código na caixa de proteção de segurança do aplicativo não pode permitir que outras caixas de proteção chamem
o método Security.allowDomain(). Chamar esse método de uma caixa de proteção de segurança do aplicativo
gerará um erro.
• Evita-se importar conteúdo "não-aplicativo" da caixa de proteção do aplicativo, definindo a propriedade
LoaderContext.securityDomain ou LoaderContext.applicationDomain.
Ainda há casos em que o aplicativo principal do AIR requer que o conteúdo de um domínio remoto tenha acesso
controlado a scripts no aplicativo principal do AIR ou vice-versa. Para fazer isso, o tempo de execução oferece o
mecanismo ponte de caixa de proteção, que serve como gateway entre as duas caixas de proteção. A ponte de caixa de
proteção pode oferecer interação explícita entre as caixas de proteção de segurança do aplicativo e remota.
A ponte de caixa de proteção expõe dois objetos que os scripts, carregados e em carregamento, podem acessar:
• O objeto parentSandboxBridge permite carregar propriedades e funções de exposição de conteúdo para scripts
no conteúdo carregado.
• O objeto childSandboxBridge permite que o conteúdo carregado exponha propriedades e funções para scripts no
conteúdo que está em carregamento.
Os objetos expostos através da ponte de caixa de proteção são passadas por valor e não por referência. Todos os dados
são serializados. Isso significa que os objetos expostos de um lado da ponte não podem ser definidos pelo outro lado
da ponte e que os objetos expostos são todos sem categoria. Além disso, você pode expor objetos e funções simples,
você não pode expor objetos complexos.
Se o conteúdo filho tentar definir uma propriedade do objeto parentSandboxBridge, o tempo de execução lançará uma
exceção SecurityError. Da mesma forma, se o conteúdo pai tentar definir uma propriedade do objeto
childSandboxBridge, o tempo de execução lançará uma exceção SecurityError.
Exemplo de ponte de caixa de proteção (SWF)
Suponhamos que um aplicativo de armazenamento de música do AIR deseja permitir que arquivos remotos SWF
transmitam preços de álbuns, mas não deseja que o arquivo remoto SWF divulgue se é preço de venda. Para fazer isso,
a classe StoreAPI oferece um método para adquirir o preço, mas ocultar o preço de venda. Em seguida, é atribuída uma
ocorrência dessa classe StoreAPI à propriedade parentSandboxBridge do objeto LoaderInfo do objeto Loader que
carrega o SWF remoto.
A seguir está o código para armazenamento de música do AIR:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 37
Segurança do AIR
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
title="Music Store" creationComplete="initApp()">
<mx:Script>
import flash.display.Loader;
import flash.net.URLRequest;
private var child:Loader;
private var isSale:Boolean = false;
private function initApp():void {
var request:URLRequest =
new URLRequest("http://[www.yourdomain.com]/PriceQuoter.swf")
child = new Loader();
child.contentLoaderInfo.parentSandboxBridge = new StoreAPI(this);
child.load(request);
container.addChild(child);
}
public function getRegularAlbumPrice():String {
return "$11.99";
}
public function getSaleAlbumPrice():String {
return "$9.99";
}
public function getAlbumPrice():String {
if(isSale) {
return getSaleAlbumPrice();
}
else {
return getRegularAlbumPrice();
}
}
</mx:Script>
<mx:UIComponent id="container" />
</mx:WindowedApplication>
O objeto StoreAPI chama o aplicativo principal para recuperar o preço regular do álbum, mas retorna "Não disponível"
quando o método getSaleAlbumPrice() é chamado. O código a seguir define a classe StoreAPI:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 38
Segurança do AIR
public class StoreAPI
{
private static var musicStore:Object;
public function StoreAPI(musicStore:Object)
{
this.musicStore = musicStore;
}
public function getRegularAlbumPrice():String {
return musicStore.getRegularAlbumPrice();
}
public function getSaleAlbumPrice():String {
return "Not available";
}
public function getAlbumPrice():String {
return musicStore.getRegularAlbumPrice();
}
}
O seguinte código representa um exemplo de um arquivo PriceQuoter SWF que informa o preço da loja, mas não pode
informar o preço de venda:
package
{
import flash.display.Sprite;
import flash.system.Security;
import flash.text.*;
public class PriceQuoter extends Sprite
{
private var storeRequester:Object;
public function PriceQuoter() {
trace("Initializing child SWF");
trace("Child sandbox: " + Security.sandboxType);
storeRequester = loaderInfo.parentSandboxBridge;
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
tf.appendText("Store price of album is: " + storeRequester.getAlbumPrice());
tf.appendText("\n");
tf.appendText("Sale price of album is: " + storeRequester.getSaleAlbumPrice());
}
}
}
Exemplo de ponte de caixa de proteção (HTML)
No conteúdo HTML, as propriedades parentSandboxBridge e childSandboxBridge são adicionados ao objeto de
janela de JavaScript de um documento filho. Para obter um exemplo sobre como definir funções de ponte em conteúdo
HTML, consulte “Configuração de interface de ponte de caixa de proteção” na página 249.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 39
Segurança do AIR
Limitação de exposição de API
Ao expor pontes de caixa de proteção, é importante expor APIs de alto nível que limitem o grau em que podem ser
abusadas. Lembre-se de que o conteúdo que chama a implementação da ponte pode estar comprometido (por
exemplo, através de uma injeção de código). Portanto, por exemplo, expor um método readFile(path:String) (que
lê o conteúdo de um arquivo arbitrário) através de uma ponte, estará vulnerável a abusos. Talvez seja melhor expor
uma API readApplicationSetting() que não siga um caminho e leia um arquivo específico. A abordagem mais
semântica limita o dano que o aplicativo pode causar, já que parte dele está comprometida.
Consulte também
“Conteúdo entre scripts em caixas de proteção de segurança distintas” na página 248
“A caixa de proteção do aplicativo” na página 28
“Privilégios de conteúdo em caixas de proteção "não-aplicativo"” na página 29
Gravação em disco
Os aplicativos em execução em um navegador da Web só têm interação limitada com o sistema de arquivos local do
usuário. Os navegadores da Web implementam políticas de segurança que garantem que o computador do usuário não
pode ser comprometido como resultado do carregamento de conteúdo da Web. Por exemplo, os arquivos SWF
executados por meio do Flash Player em um navegador não podem interagir diretamente com os arquivos existentes
no computador do usuário. Os objetos compartilhados e os cookies podem ser gravados no computador do usuário
com a finalidade de manter as preferências do usuário e outros dados, mas esse é o limite de interação do sistema de
arquivos. Como os aplicativos do AIR são instalados de forma nativa, eles têm contratos de segurança diferentes, um
dos quais inclui a capacidade de leitura e gravação no sistema de arquivos local.
Essa liberdade resulta em bastante responsabilidade para os desenvolvedores A falta de segurança acidental do
aplicativo coloca em risco não apenas a funcionalidade do aplicativo, mas também a integridade do computador do
usuário. Por esse motivo, os desenvolvedores devem ler as “Práticas recomendadas de segurança para
desenvolvedores” na página 41.
Os desenvolvedores do AIR podem acessar e gravar arquivos no sistema de arquivos local usando diversas convenções
de esquema de URL:
esquema de URL
Descrição
app:/
Um alias para o diretório do aplicativo. Aos arquivos acessados desse caminho são atribuídas caixas de proteção
do aplicativo e eles têm todos os privilégios concedidos pelo tempo de execução.
app-storage:/
Um alias para o diretório de armazenamento local, padronizado pelo tempo de execução. Aos arquivos acessados
desse caminho é atribuída uma caixa de proteção "não-aplicativo".
file:///
Um alias que representa a raiz do disco rígido do usuário. Ao arquivo acessado desse caminho é atribuída uma
caixa de proteção do aplicativo, se o arquivo estiver no diretório do aplicativo e, caso contrário, uma caixa de
proteção "não-aplicativo".
Nota: Os aplicativos do AIR não podem modificar o conteúdo que usa o app: esquema de URL. Além disso, o diretório
do aplicativo pode ser lido somente devido às configurações do administrador.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 40
Segurança do AIR
A menos que haja restrições do administrador para o computador do usuário, os aplicativos do AIR têm privilégio de
gravação em qualquer local no disco rígido do usuário, Recomenda-se que os desenvolvedores usem o caminho appstorage:/ para armazenamento local em relação ao aplicativo. Os arquivos gravados em app-storage:/ de um
aplicativo são colocados em um local padrão:
• No Mac OS: o diretório de armazenamento do aplicativo é <appData>/<appId>/Local
Store/ onde <appData>
é a pasta Preferências do usuário, que é normalmente /Users/<user>/Library/Preferences
• No Windows: o diretório de armazenamento do aplicativo é <appData>\<appId>\Local
Store\ onde
<appData> é a pasta especial CSIDL_APPDATA do usuário, que é normalmente C:\Documents and
Settings\<userName>\Application Data
• No Linux: <appData>/<appID>/Local
Store/ onde <appData> é /home/<user>/.appdata
Se o aplicativo for desenvolvido para interagir com os arquivos existentes no sistema de arquivos do usuário,
certifique-se de ler as “Práticas recomendadas de segurança para desenvolvedores” na página 41.
Trabalho seguro com conteúdo não confiável
O conteúdo não atribuído à caixa de proteção do aplicativo pode oferecer funcionalidade adicional de script ao
aplicativo, mas somente se ele atender aos critérios de segurança do tempo de execução. Este tópico explica o contrato
de segurança do AIR com conteúdo "não-aplicativo".
Security.allowDomain()
Os aplicativos do AIR restringem o acesso de script de conteúdo "não-aplicativo" com mais rigor do que o plug-in de
navegador do Flash Player restringe o acesso de script de conteúdo não confiável. Por exemplo, no Flash Player, no
navegador, quando um arquivo SWF atribuído à caixa de proteção local-trusted chama o método
System.allowDomain(), todos os SWF carregados do domínio especificado receberão acesso de script. Não é
permitida a abordagem análoga do conteúdo do aplicativo nos aplicativos do AIR, já que ela concederia acesso
excesso não razoável ao arquivo "não-aplicativo" no sistema de arquivos do usuário. Os arquivos remotos não podem
acessar diretamente a caixa de proteção do aplicativo, independentemente das chamadas para o
métodoSecurity.allowDomain().
Script entre conteúdo de aplicativo e "não-aplicativo"
Os aplicativos do AIR que fazem script entre conteúdo aplicativo e "não-aplicativo" têm organizações de segurança
mais complexas. Os arquivos que não estão na caixa de proteção do aplicativo só têm permissão para acessar
propriedades e métodos de aplicativos na caixa de proteção do aplicativo por meio do uso de uma ponte de caixa de
proteção. A ponte da caixa de proteção atua como gateway entre o conteúdo do aplicativo e "não-aplicativo",
oferecendo interação explícita entre os dois arquivos. Quando usadas corretamente, as pontes de caixa de proteção
oferecem uma camada extra de segurança, impedindo o conteúdo "não-aplicativo" de acessar as referências de objeto
que fazem parte do conteúdo do aplicativo.
O benefício das pontes de caixa de proteção é ilustrado melhor através do exemplo. Suponhamos que um aplicativo de
armazenamento de música do AIR deseja fornecer uma API para anunciantes que desejam criar seus próprios arquivos
SWF, com o qual o aplicativo de armazenamento poderá se comunicar em seguida. A loja deseja fornecer aos
anunciantes métodos de pesquisa de artistas e CDs, mas também deseja isolar alguns métodos e propriedades do
arquivo SWF terceirizado, por motivos de segurança.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 41
Segurança do AIR
A ponte de caixa de proteção pode propiciar essa funcionalidade. Por padrão, o conteúdo carregado externamente em
um aplicativo AIR em tempo de execução não tem acesso a nenhum método ou propriedade no aplicativo principal.
Com a implementação da ponte de caixa de proteção personalizada, o desenvolvedor pode fornecer serviços ao
conteúdo remoto sem expor esses métodos ou propriedades. Considere a ponte de caixa de proteção como um
caminho entre o conteúdo confiável e o não confiável, oferecendo comunicação entre o conteúdo carregado e o do
carregador sem expor as referências do objeto.
Para obter mais informações sobre como usar pontes de caixa de proteção de forma segura, consulte “Script entre
conteúdos em domínios distintos” na página 35.
Proteção contra conteúdo SWF inseguro gerado dinamicamente.
O método Loader.loadBytes() oferece uma maneira de o aplicativo gerar conteúdo SWF de uma matriz de bytes.
No entanto, ataques de injeção em dados carregados de fontes remotas podem causar dano grave ao carregar o
conteúdo. Isso é particularmente verdadeiro ao carregar dados na caixa de proteção do aplicativo, onde o conteúdo
SWF gerado pode acessar o conjunto completo de APIs do AIR.
Há usos válidos para a utilização do método loadBytes() sem gerar um código SWF executável. Você pode usar o
método loadBytes() para gerar dados de imagem para controlar o tempo de exibição de imagem, por exemplo. Há
também usos válidos que dependem do código de execução, como a criação dinâmica de conteúdo SWF para
reprodução de áudio. No AIR, por padrão, o método loadBytes()não permite carregar conteúdo SWF, ele só permite
carregar conteúdo de imagem. No AIR, a propriedade loaderContext do método loadBytes() tem uma
propriedade allowLoadBytesCodeExecution, que você pode definir como true para permitir explicitamente que o
aplicativo use loadBytes() para carregar o conteúdo SWF executável. O código a seguir mostra como usar esse
recurso:
var loader:Loader = new Loader();
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
loader.loadBytes(bytes, loaderContext);
Se você chamar loadBytes() para carregar conteúdo SWF e a propriedade allowLoadBytesCodeExecution do
objeto LoaderContext estiver definida como false (o padrão), o objeto Loader lançará uma exceção SecurityError.
Nota: Em um lançamento futuro do Adobe AIR, essa API pode ser alterada. Quando isso ocorre, talvez seja necessário
recompilar o conteúdo que usa a propriedade allowLoadBytesCodeExecution da classe LoaderContext.
Práticas recomendadas de segurança para
desenvolvedores
Embora os aplicativos do AIR sejam criados usando tecnologias da Web, é importante para os desenvolvedores
observar que eles não trabalham na caixa de proteção de segurança do navegador. Isso significa que é possível criar
aplicativos do AIR que podem danificar o sistema local de maneira intencional ou não intencional. O AIR tenta
minimizar esse risco, mais ainda há formas em que as vulnerabilidades podem ser introduzidas. Este tópico cobre faltas
de segurança potenciais importantes.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 42
Segurança do AIR
Risco de importar arquivos para a caixa de proteção de segurança do
aplicativo
Os arquivos existentes no diretório do aplicativo estão atribuídos à caixa de proteção do aplicativo e têm privilégios
completos de tempo de execução. Recomenda-se aos aplicativos que gravam no sistema de arquivos local gravar no
app-storage:/. Esse diretório está separado dos arquivos do aplicativo no computador do usuário, por isso os
arquivos não estão atribuídos na caixa de proteção do aplicativo e representam risco reduzido de segurança.
Recomenda-se aos desenvolvedores que considerem o seguinte:
• Somente incluir um arquivo em um arquivo do AIR (no aplicativo instalado) se for necessário.
• Somente incluir um arquivo em um arquivo do AIR (no aplicativo instalado) se o respectivo comportamento for
completamente compreensível e confiável.
• Não grave nem modifique conteúdo no diretório do aplicativo. O tempo de execução impede que aplicativos
gravem ou modifiquem arquivos e diretórios que usam o esquema de URL app:/, lançando uma exceção
SecurityError.
• Não use dados de uma fonte de rede como parâmetros de métodos da API do AIR que possam conduzir a execução
de código. Isso inclui o uso do método Loader.loadBytes() e a função eval() de JavaScript.
Risco de uso de fonte externa para determinar caminhos
O aplicativo AIR pode estar com o uso de dados ou conteúdo externo comprometido. Por esse motivo, tenha cuidado
especial ao usar dados da rede ou do sistema de arquivos. O ônus da confiança, depende em última análise do
desenvolvedor e das conexões de rede que eles fazem, mas carregar dados externos é inerentemente arriscado e não
deve ser usado em inserções de operações confidenciais. Recomenda-se aos desenvolvedores o seguinte:
• Usar dados de uma fonte de rede para determinar o nome de arquivo
• Usar dados de uma fonte de rede para construir uma URL que o aplicativo use para enviar informações particulares
O risco de usar, armazenar ou transmitir credenciais não seguras
Armazenar credenciais do usuário no sistema de arquivos local do usuário introduz inerentemente o risco de que essas
credenciais possam estar comprometidas. Recomenda-se aos desenvolvedores considerar o seguinte:
• Se credenciais devem ser armazenadas localmente, criptografe as credenciais ao gravá-las no sistema de arquivos
local. O tempo de execução oferece um armazenamento criptografado exclusivo para cada aplicativo instalado,
através da classe EncryptedLocalStore. Para obter detalhes, consulte “Armazenamento de dados criptografados” na
página 215.
• Não transmita credenciais do usuário não criptografadas em uma fonte de rede, a menos que essa fonte seja
confiável.
• Nunca especifique uma senha padrão na criação de credencial: deixe que os usuários criem suas próprias senhas.
Usuários que mantêm o padrão inalterado expõem as respectivas credenciais ao invasor que já conhece a senha
padrão.
Risco de um ataque de downgrade
Durante a instalação do aplicativo, o tempo de execução certifica-se de que não haja uma versão do aplicativo instalada
atualmente. Se o aplicativo já estiver instalado, o tempo de execução compara a string da versão em relação à versão
que está sendo instalada. Se essa string for diferente, o usuário poderá optar por atualizar a instalação. O tempo de
execução não garante que a versão instalada recentemente seja mais recente que a versão anterior, apenas que seja
diferente. O invasor pode distribuir uma versão anterior para o usuário, para contornar uma falha de segurança. Por
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 43
Segurança do AIR
esse motivo, recomenda-se que o desenvolvedor verifique as versões quando o aplicativo for executado. É uma boa
idéia fazer com que os aplicativos verifiquem a rede em busca de atualizações necessárias. Dessa maneira, mesmo se
um invasor fizer com que o usuário execute uma versão anterior, essa versão anterior irá reconhecer que é necessário
atualizar. Além disso, usar um esquema de versão bem-definido no aplicativo torna mais difícil enganar os usuários
para que instalem uma versão desatualizada. Para obter detalhes sobre como fornecer versões de aplicativo, consulte
“Definição de propriedades no arquivo do descritor do aplicativo” na página 45.
Assinatura de código
Todos os arquivos do instalador do AIR são obrigatórios para assinatura de código. A assinatura de código é um
processo criptográfico para confirmar que a origem especificada do software é precisa. Os aplicativos do AIR podem
ser assinados vinculando um certificado de uma autoridade de certificado externa (CA) ou criando o seu próprio
certificado Recomenda-se fortemente um certificado comercial de uma CA bem conhecida que ofereça segurança a
seus usuários de que estão instalando o aplicativo original e não uma falsificação. No entanto, os certificados autoassinados podem ser criados usando adt do SDK ou usando Flash, Flex Builder ou outro aplicativo que use adt para
geração de certificados. Certificados auto-assinados não oferecem nenhuma segurança de que o aplicativo que está
sendo instalado seja genuíno.
Para obter mais informações sobre como assinar digitalmente aplicativos do AIR , consulte “Assinatura digital de um
arquivo do AIR” na página 321 e “Criação de um aplicativo do AIR usando as ferramentas de linha de comando” na
página 355.
44
Capítulo 8: Configuração de propriedades
do aplicativo do AIR
Com exceção de todos os arquivos e outros ativos que formam um aplicativo do AIR, cada aplicativo do AIR requer
um arquivo do descritor do aplicativo. O arquivo do descritor do aplicativo é um arquivo XML que define as
propriedades básicas do aplicativo.
Ao desenvolver aplicativos do AIR usando a atualização do Adobe® AIR™ para Adobe® Flash® CS3 Professional ou
Adobe® Flash® CS4 Professional, o arquivo de descrição do aplicativo é gerado automaticamente quando você cria um
projeto do AIR. Você pode acessar um painel para alterar as configurações do descritor do aplicativo do menu
Comandos > AIR - Configurações do instalador e do aplicativo. Você também pode editar o arquivo do descritor do
aplicativo manualmente.
A estrutura do arquivo do descritor do aplicativo
O arquivo do descritor do aplicativo contém propriedades que afetam todo o aplicativo, como seu nome, versão, direitos
autorais e assim por diante. Qualquer nome de arquivo pode ser usado pelo arquivo do descritor do aplicativo. Quando
você cria um arquivo do AIR usando as configurações padrão do Flash CS3 ou Flash CS4, o arquivo de descrição do
aplicativo é renomeado para application.xml e colocado dentro de um diretório especial no pacote do AIR.
Veja um exemplo do arquivo do descritor do aplicativo:
<?xml version="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/1.5">
<id>com.example.HelloWorld</id>
<version>2.0</version>
<filename>Hello World</filename>
<name>Example Co. AIR Hello World</name>
<description>
<text xml:lang="en">This is a example.</text>
<text xml:lang="fr">C'est un exemple.</text>
<text xml:lang="es">Esto es un ejemplo.</text>
</description>
<copyright>Copyright (c) 2006 Example Co.</copyright>
<initialWindow>
<title>Hello World</title>
<content>
HelloWorld-debug.swf
</content>
<systemChrome>none</systemChrome>
<transparent>true</transparent>
<visible>true</visible>
<minimizable>true</minimizable>
<maximizable>false</maximizable>
<resizable>false</resizable>
<width>640</width>
<height>480</height>
<minSize>320 240</minSize>
<maxSize>1280 960</maxSize>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 45
Configuração de propriedades do aplicativo do AIR
</initialWindow>
<installFolder>Example Co/Hello World</installFolder>
<programMenuFolder>Example Co</programMenuFolder>
<icon>
<image16x16>icons/smallIcon.png</image16x16>
<image32x32>icons/mediumIcon.png</image32x32>
<image48x48>icons/bigIcon.png</image48x48>
<image128x128>icons/biggestIcon.png</image128x128>
</icon>
<customUpdateUI>true</customUpdateUI>
<allowBrowserInvocation>false</allowBrowserInvocation>
<fileTypes>
<fileType>
<name>adobe.VideoFile</name>
<extension>avf</extension>
<description>Adobe Video File</description>
<contentType>application/vnd.adobe.video-file</contentType>
<icon>
<image16x16>icons/avfIcon_16.png</image16x16>
<image32x32>icons/avfIcon_32.png</image32x32>
<image48x48>icons/avfIcon_48.png</image48x48>
<image128x128>icons/avfIcon_128.png</image128x128>
</icon>
</fileType>
</fileTypes>
</application>
Definição de propriedades no arquivo do descritor do
aplicativo
Use os elementos e atributos XML de descrição do aplicativo para definir os seguintes tipos de propriedades do seu
aplicativo do AIR:
• Versão de tempo de execução exigida pelo AIR
• Identidade do aplicativo
• Pastas de instalação e de menu de programas
• Conteúdo inicial e propriedades de janela
• Arquivos de ícone do aplicativo
• Se o aplicativo oferece uma interface do usuário atualizada e personalizada.
• Se o aplicativo pode ser chamado pelo conteúdo SWF em execução no navegador do usuário.
• Associações de tipo de arquivo
Especificação da versão exigida pelo AIR
Os atributos do elemento raiz de um arquivo de descrição do aplicativo, application, especifica a versão de tempo
de execução exigida pelo AIR:
<application xmlns="http://ns.adobe.com/air/application/1.5">
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 46
Configuração de propriedades do aplicativo do AIR
xmlns O namespace do AIR, que você deve definir como o namespace XML padrão. O namespace é alterado com cada
versão principal do AIR (mas não com patches secundários). O último segmento do espaço para nomes, como “1.5”
indica a versão do tempo de execução exigida pelo aplicativo. Assegure-se de definir o espaço para nomes como AIR
1.5 ("http://ns.adobe.com/air/application/1.5"), caso seu aplicativo use qualquer recurso novo do AIR 1.5.
Nos aplicativos baseados em SWF, a versão do tempo de execução do AIR especificada na descrição do aplicativo
determina a versão máxima do SWF que pode ser carregada como o conteúdo inicial do aplicativo. Aplicativos que
especificam AIR 1.0 ou AIR 1.1 só podem usar arquivos SWF9 (Flash Player 9) como conteúdo inicial, mesmo quando
executados usando o tempo de execução do AIR 1.5. Aplicativos que especificam AIR 1.5 podem usar arquivos SWF9
ou SWF10 (Flash Player 10) como conteúdo inicial. A versão do SWF determina que versão do AIR e APIs do Flash
Player estão disponíveis. Se um arquivo SWF9 for usado como conteúdo inicial de um aplicativo do AIR 1.5, esse
aplicativo só terá acesso ao AIR 1.1 e às APIs do Flash Player 9. Além disso, alterações de comportamento feitas em
APIs existentes no AIR 1.5 ou no Flash Player 10 não serão eficazes. (Alterações importantes relacionadas à segurança,
feitas em APIs, são uma exceção a esse princípio e podem ser aplicadas de forma retroativa em patches atuais ou
futuros do tempo de execução).
Em aplicativos baseados em HTML, a versão do tempo de execução especificada na descrição do aplicativo determina
sozinha que versão do AIR e de APIs do Flash Player estão disponíveis para o aplicativo. Os comportamentos de
HTML, CSS e JavaScript são sempre determinados pela versão do Webkit usada no tempo de execução do AIR
instalado, não pela descrição do aplicativo.
Quando um aplicativo do AIR carrega conteúdo SWF, a versão do AIR e das APIs do Flash Player disponíveis para
esse conteúdo depende de como o conteúdo é carregado. A tabela a seguir mostra como a versão da API é determinada
com base no método de carregamento:
Como o conteúdo é carregado
Como a versão da API é determinada
Conteúdo inicial, aplicativo baseado em SWF
Versão SWF do arquivo carregado
Conteúdo inicial, aplicativo baseado em HTML
Espaço para nomes da descrição do aplicativo
SWF carregado pelo conteúdo SWF
Versão do conteúdo carregado
Biblioteca SWF carregada pelo conteúdo HTML
usando a tag <script>
Espaço para nomes da descrição do aplicativo
SWF carregado pelo conteúdo HTML usando o
AIR ou as APIs do Flash Player (como
flash.display.Loader)
Espaço para nomes da descrição do aplicativo
SWF carregado pelo conteúdo HTML usando as
tags <object> ou <embed> (ou as APIs de
JavaScript equivalentes)
Versão SWF do arquivo carregado
Ao carregar um arquivo SWF de uma versão diferente do conteúdo carregado, você pode se deparar com dois
problemas:
• Carregamento do conteúdo do SWF10 pelo SWF9 (ou anterior) — Referências ao AIR 1.5 e a APIs do Flash Player
10 no conteúdo carregado não serão resolvidas
• Carregamento de conteúdo do SWF9 (ou anterior) pelo SWF10 — APIs alteradas no AIR 1.5 e Flash Player 10
podem se comportar de forma inesperada pelo conteúdo carregado.
minimumPatchLevel Opcional. Use o atributo minimumPatchLevel para especificar o nível de patch mínimo do
Adobe AIR exigido pelo aplicativo. Os aplicativos do AIR normalmente especificam que versão do AIR eles exigem,
definindo simplesmente o namespace no arquivo do descritor do aplicativo. O espaço para nomes é alterado para cada
versão principal do AIR (como 1.0 ou 1.5). O espaço para nomes não é alterado para versões de patch.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 47
Configuração de propriedades do aplicativo do AIR
As versões de patch contêm apenas um conjunto limitado de correções e nenhuma alteração de API. Normalmente,
os aplicativos não especificam que versão de patch exigem. No entanto, uma correção em uma versão de patch pode
corrigir um problema em um aplicativo. Nesta situação, um aplicativo pode especificar um valor para o atributo
minimumPatchLevel para garantir que o patch seja aplicado antes que o aplicativo seja instalado. O instalador do
aplicativo do AIR solicita que o usuário baixe e instale a versão exigida ou patch, se necessário. O exemplo a seguir
mostra um elemento de aplicativo que especifica um valor para o atributo minimumPatchLevel:
<application xmlns="http://ns.adobe.com/air/application/1.1"
minimumPatchLevel="5331">
Definição de identidade do aplicativo
Os seguintes elementos definem ID do aplicativo, versão, nome, nome do arquivo, descrição e informações de
copyright:
<id>com.example.samples.TestApp</id>
<version>2.0</version>
<filename>TestApp</filename>
<name>
<text xml:lang="en">Hello AIR</text>
<text xml:lang="fr">Bonjour AIR</text>
<text xml:lang="es">Hola AIR</text>
</name>
<description>An MP3 player.</description>
<copyright>Copyright (c) 2008 YourCompany, Inc.</copyright>
id Uma seqüência de caracteres de identificador única ao aplicativo, conhecida como a ID do aplicativo. O valor de
atributo é restrito aos seguintes caracteres:
• 0–9
• a–z
• A–Z
• . (ponto)
• - (hífen)
O valor deve conter de 1 a 212 caracteres. Esse elemento é necessário.
A seqüência de caracteres id normalmente usa uma hierarquia separada por ponto, em alinhamento com um endereço
de domínio DNS revertido, um pacote Java™ ou nome de classe ou um identificador de tipo universal X do Mac OS®.
A forma parecida com DNS não é aplicada e o AIR não cria nenhuma associação entre o nome e os domínios de DNS
reais.
version Especifica as informações de versão para o aplicativo. (Não tem relação com a versão do tempo de execução).
A seqüência de caracteres da versão é um designador definido pelo aplicativo. O AIR não interpreta de maneira
nenhuma a string de versão. Portanto, não se supõe que a versão “3.0” é mais atual que a versão “2.0.” Exemplos: "1.0",
"0.4", "0.5", "4.9", "1.3.4a". Esse elemento é necessário.
filename A seqüência de caracteres a usar como um filename do aplicativo (sem extensão) quando o aplicativo é
instalado. O arquivo do aplicativo inicia o aplicativo do AIR no tempo de execução. Se nenhum valor name for
fornecido, filename também será usado como o nome da pasta de instalação. Esse elemento é necessário.
A propriedade filename pode conter qualquer caractere Unicode (UTF-8), exceto o seguinte, que tem o uso proibido
como filenames em vários sistemas de arquivos:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 48
Configuração de propriedades do aplicativo do AIR
Caractere
Código hexadecimal
vários
0x00 – x1F
*
x2A
"
x22
:
x3A
>
x3C
<
x3E
?
x3F
\
x5C
|
x7C
O valor filename não pode terminar em um ponto.
name (Opcional, mas recomendado) O título exibido pelo instalador do aplicativo do AIR.
Se você especificar um único nó de texto (em vez de vários elementos text), o instalador do aplicativo do AIR usa esse
nome, independentemente do idioma do sistema:
<name>Test Application</name>
O esquema do descritor do aplicativo do AIR 1.0 permite apenas um simples nó de texto a ser definido para o nome
(e não vários elementos text).
No AIR 1.1 (ou acima), você pode especificar vários idiomas no elemento name. Por exemplo, o seguinte especifica o
nome em três idiomas (inglês, francês e espanhol):
<name>
<text xml:lang="en">Hello AIR</text>
<text xml:lang="fr">Bonjour AIR</text>
<text xml:lang="es">Hola AIR</text>
</name>
O atributo xml:lang para cada elemento de texto especifica um código de idioma, como definido em RFC4646
(http://www.ietf.org/rfc/rfc4646.txt).
O instalador do aplicativo do AIR usa o nome que mais se aproxima do idioma da interface do usuário do sistema
operacional do usuário. Por exemplo, considere uma instalação na qual o elemento name do arquivo do descritor do
aplicativo inclui um valor para o local en (inglês). O instalador do aplicativo do AIR usa o nome en se o sistema
operacional identifica en (inglês) como o idioma da interface do usuário. Ele também usa o nome en se o idioma da
interface do usuário do sistema for en-US (inglês norte-americano). No entanto, se o idioma da interface do usuário é
en-US e o arquivo do descritor do aplicativo define os nomes en-US e en-GB, o instalador do aplicativo do AIR usa o
valor en-US. Se o aplicativo não define nenhum nome que corresponda aos idiomas da interface do usuário do sistema,
o instalador do aplicativo do AIR usa o primeiro valor name definido no arquivo do descritor do aplicativo.
Se nenhum elemento name for especificado, o instalador do aplicativo do AIR exibirá filename como o nome do
aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 49
Configuração de propriedades do aplicativo do AIR
O elemento name define apenas o título do aplicativo usado no instalador do aplicativo do AIR. O instalador do
aplicativo do AIR suporta vários idiomas: chinês tradicional, chinês simplificado, tcheco, holandês, inglês, francês,
alemão, italiano, japonês, coreano, português do Brasil, russo, espanhol, sueco e turco. O instalador do aplicativo do
AIR seleciona seu idioma exibido (para texto que não seja o título do aplicativo e a descrição) com base no idioma da
interface do usuário do sistema. Essa seleção de idioma é independente das configurações no arquivo do descritor do
aplicativo.
O elemento namenão define as localidades disponíveis para o aplicativo instalado em execução. Para obter detalhes
sobre o desenvolvimento de aplicativos com vários idiomas, consulte “Localização de aplicativos AIR” na página 343.
description (Opcional) A descrição do aplicativo, exibida no instalador do aplicativo do AIR.
Se você especificar um único nó de texto (e não vários elementos text), o instalador do aplicativo do AIR usará essa
descrição, independentemente do idioma do sistema:
<description>This is a sample AIR application.</description>
O esquema do descritor do aplicativo do AIR 1.0 permite apenas um simples nó de texto a ser definido para o nome
(e não vários elementos text).
No AIR 1.1 (ou acima), você pode especificar vários idiomas no elemento description. Por exemplo, o seguinte
especifica uma descrição em três idiomas (inglês, francês e espanhol):
<description>
<text xml:lang="en">This is a example.</text>
<text xml:lang="fr">C'est un exemple.</text>
<text xml:lang="es">Esto es un ejemplo.</text>
</description>
O atributo xml:lang para cada elemento de texto especifica um código de idioma, como definido em RFC4646
(http://www.ietf.org/rfc/rfc4646.txt).
O instalador do aplicativo do AIR usa a descrição que mais se aproxima do idioma da interface do usuário do sistema
operacional do usuário. Por exemplo, considere uma instalação na qual o elemento description do arquivo do
descritor do aplicativo inclui um valor para o local en (inglês). O instalador do aplicativo do AIR usa o nome en se o
sistema do usuário identifica en (inglês) como o idioma da interface do usuário. Ele também usa o nome en se o idioma
da interface do usuário do sistema for en-US (inglês norte-americano). No entanto, se o idioma da interface do usuário
do sistema é en-US e o arquivo do descritor do aplicativo define os nomes en-US e en-GB, o instalador do aplicativo
do AIR usa o valor en-US. Se o aplicativo não define nenhum nome que corresponda ao idioma da interface do usuário
do sistema, o instalador do aplicativo do AIR usa o primeiro valor description definido no arquivo do descritor do
aplicativo.
Para obter mais informações sobre o desenvolvimento de aplicativos com vários idiomas, consulte “Localização de
aplicativos AIR” na página 343.
copyright (Opcional) As informações de copyright para o aplicativo do AIR. No Mac OS, o texto de copyright é
exibido caixa de diálogo Sobre para o aplicativo instalado. No Mac OS, as informações de copyright também são usadas
no campo NSHumanReadableCopyright no arquivo Info.plist para o aplicativo.
Definição das pastas de instalação e menu de programas
As pastas de instalação e menu de programas são definidas com as seguintes configurações de propriedade:
<installFolder>Acme</installFolder>
<programMenuFolder>Acme/Applications</programMenuFolder>
installFolder (Opcional) Identifica o subdiretório do diretório de instalação padrão.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 50
Configuração de propriedades do aplicativo do AIR
No Windows, o subdiretório de instalação padrão é Arquivos de Programas. No Mac OS, é o diretório /Applications.
No Linux, é /opt/. Por exemplo, se a propriedade installFolder é definida como "Acme" e um aplicativo é chamado
de "ExampleApp", o aplicativo é instalado em C:\Arquivos de Programas\Acme\ExampleApp no Windows, em
/Applications/Acme/Example.app no Mac OS e em /opt/Acme/ExampleApp no Linux.
Use o caractere de barra (/) como o caractere separador de diretório se desejar especificar um subdiretório aninhado,
como a seguir:
<installFolder>Acme/Power Tools</installFolder>
A propriedade installFolder pode conter qualquer caractere Unicode (UTF-8), exceto aqueles cujo uso é proibido
como nomes de pastas em vários sistemas de arquivos (consulte a propriedade filename acima para obter a lista de
exceções).
A propriedade installFolder é opcional. Se você não especificar nenhuma propriedade installFolder, o
aplicativo será instalado em um subdiretório do diretório de instalação padrão, com base na propriedade name.
programMenuFolder (Opcional) Identifica o local no qual colocar atalhos para o aplicativo no menu Todos os
Programas do sistema operacional Windows ou no menu Aplicativos do Linux. (Essa configuração é atualmente
ignorada em outros sistemas operacionais.) As restrições sobre os caracteres permitidos no valor da propriedade são
iguais às da propriedade installFolder. Não use um caractere de barra (/) como o último caractere desse valor.
Definição das propriedades da janela inicial do aplicativo
Quando um aplicativo do AIR é carregado, o tempo de execução usa os valores no elemento initialWindow para criar
a janela inicial do aplicativo. O tempo de execução carrega o arquivo SWF ou HTML especificado no elemento
content na janela.
Veja um exemplo do elemento initialWindow:
<initialWindow>
<content>AIRTunes.swf</content>
<title>AIR Tunes</title>
<systemChrome>none</systemChrome>
<transparent>true</transparent>
<visible>true</visible>
<minimizable>true</minimizable>
<maximizable>true</maximizable>
<resizable>true</resizable>
<width>400</width>
<height>600</height>
<x>150</x>
<y>150</y>
<minSize>300 300</minSize>
<maxSize>800 800</maxSize>
</initialWindow>
Os elementos filho do elemento initialWindow definem as propriedades da janela na qual o arquivo do conteúdo raiz
é carregado.
content O valor especificado para o elemento content é a URL para o arquivo principal de conteúdo do aplicativo.
Isso pode ser um arquivo SWF ou HTML. A URL é especificada em relação à raiz da pasta de instalação do aplicativo.
(Ao executar um aplicativo do AIR com o ADL, a URL é relativa à pasta que contém o arquivo do descritor do
aplicativo. Você pode usar o parâmetro root-dir do ADL para especificar um diretório de raiz diferente.)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 51
Configuração de propriedades do aplicativo do AIR
Nota: Como o valor do elemento content é tratado como uma URL, os caracteres no nome do arquivo de conteúdo devem
ser codificados por URL de acordo com as regras definidas em RFC 1738. Caracteres de espaço, por exemplo, devem ser
codificados como %20.
title (Opcional) O título da janela.
systemChrome (Opcional) Se você definiu esse atributo como standard, o cromo do sistema padrão fornecido pelo
sistema operacional será exibido. Se você o definiu como none, nenhum cromo do sistema será exibido. A
configuração do cromo do sistema não pode ser alterada em tempo de execução.
transparent (Opcional) Definido como "true" se você deseja que a janela do aplicativo suporte mesclagem alfa. Uma
janela com transparência pode ser desenhada mais lentamente e exigir mais memória. A configuração de transparente
não pode ser alterada em tempo de execução.
Importante: Você pode definir apenas transparent como true quando systemChrome for none.
visible (Opcional) Definido como true se você desejar que a janela principal seja visível assim que ela for criada. O
valor padrão é false.
Você pode querer deixar a janela principal oculta inicialmente, para que alterações na posição da janela, no tamanho
da janela e o layout de seu conteúdo não sejam exibidos. Você pode então exibir a janela chamando o método
activate() da janela ou definindo a propriedade visible como true. Para obter detalhes, consulte “Trabalhar com
janelas nativas” na página 59.
x, y, width, height (Opcional) Os limites iniciais da janela principal do aplicativo. Se você não definir esses valores, o
tamanho da janela será determinado pelas configurações no arquivo SWF raiz ou, no caso de HTML, pelo sistema
operacional.
minSize, maxSize (Opcional) Os tamanhos mínimo e máximo da janela. Se você não definir esses valores, eles serão
determinados pelo sistema operacional.
minimizable, maximizable, resizable (Opcional) Especifica se a janela pode ser minimizada, maximizada e
redimensionada. Por padrão, essas configuração são true.
Nota: Em sistemas operacionais como o Mac OS X, em que maximizar janelas é uma operação de redimensionamento,
tanto maximizable quanto resizable devem ser definidos como false para impedir que a janela seja ampliada ou
redimensionada.
Especificar arquivos de ícone
A propriedade icon especifica um ou mais arquivos de ícone a serem usados pelo aplicativo. Incluir um ícone é
opcional. Se você não especificar uma propriedade icon, o sistema operacional exibirá um ícone padrão.
O caminho especificado é relativo ao diretório raiz do aplicativo. Os arquivos de ícone devem estar no formato PNG.
Você pode especificar todos os tamanhos de ícones a seguir:
<icon>
<image16x16>icons/smallIcon.png</image16x16>
<image32x32>icons/mediumIcon.png</image32x32>
<image48x48>icons/bigIcon.png</image48x48>
<image128x128>icons/biggestIcon.png</image128x128>
</icon>
Se um elemento para um determinado tamanho estiver presente, a imagem no arquivo deverá ser exatamente do
tamanho especificado. Se todos os tamanhos não forem fornecidos, o tamanho mais próximo será dimensionado para
se ajustar para um determinado uso do ícone pelo sistema operacional.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 52
Configuração de propriedades do aplicativo do AIR
Nota: Os ícones especificados não são automaticamente adicionados ao pacote do AIR. Os arquivos de ícone devem ser
incluídos em seus locais corretos relativos quando o aplicativo for empacotado.
Para melhores resultados, forneça uma imagem para cada um dos tamanhos disponíveis. Além disso, verifique se os
ícones estão apresentáveis nos modos de cores de 16 e 32 bits.
Fornecer uma interface de usuário personalizada para atualizações de
aplicativos
O AIR instala e atualiza aplicativos usando as caixas de diálogo de instalação padrão. No entanto, você pode fornecer
sua própria interface de usuário para atualizar um aplicativo. Para indicar que seu aplicativo deve manipular o
processo de atualização sozinho, defina o elemento customUpdateUI como true:
<customUpdateUI>true</customUpdateUI>
Quando a versão instalada do seu aplicativo tiver o elemento customUpdateUI definido como true e o usuário clicar
duas vezes no arquivo do AIR para uma nova versão ou instalar uma atualização do aplicativo usando o recurso de
instalação direta, o tempo de execução abre a versão instalada do aplicativo, em vez do instalador do aplicativo do AIR
padrão. A lógica do seu aplicativo pode então determinar como proceder com a operação de atualização. (As IDs do
aplicativo e do editor no arquivo do AIR devem corresponder àquelas do aplicativo instalado para uma atualização
poder continuar.)
Nota: O mecanismo customUpdateUI apenas começa a funcionar quando o aplicativo já está instalado e o usuário clica
duas vezes no arquivo de instalação do AIR que contém uma atualização ou instala uma atualização do aplicativo
usando o recurso de instalação direta. Você pode baixar e iniciar uma atualização pela lógica do seu aplicativo, exibindo
sua interface de usuário personalizada conforme necessário, seja customUpdateUItrue ou não.
Para obter mais informações, consulte “Atualização de aplicativos do AIR” na página 328.
Permitir invocação do navegador do aplicativo
Se você especificar a seguinte definição, o aplicativo do AIR instalado poderá ser iniciado pelo recurso de invocação
do navegador (o usuário deve clicar em um link de uma página no navegador da Web):
<allowBrowserInvocation>true</allowBrowserInvocation>
O valor padrão é false.
Se você definiu esse valor como true, certifique-se de considerar implicações de segurança, descritas em “Invocação
do navegador” na página 294.
Para obter mais informações, consulte “Instalação e execução de aplicativos do AIR de uma página da Web” na
página 313.
Declaração de associações de tipo de arquivo
O elemento fileTypes permite que você declare os tipos de arquivos com os quais um aplicativo do AIR pode ser
associado. Quando um aplicativo do AIR é instalado, qualquer tipo de arquivo declarado é registrado com o sistema
operacional e, se esses tipos de arquivos ainda não estão associados a outro aplicativo, são associados ao aplicativo do
AIR. Para substituir uma associação existente entre um tipo de arquivo e outro aplicativo, use o método
NativeApplication.setAsDefaultApplication() em tempo de execução (preferencialmente com a permissão do
usuário).
Nota: Os métodos runtime podem apenas gerenciar associações para os tipos de arquivos declarados no descritor do
aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 53
Configuração de propriedades do aplicativo do AIR
<fileTypes>
<fileType>
<name>adobe.VideoFile</name>
<extension>avf</extension>
<description>Adobe Video File</description>
<contentType>application/vnd.adobe.video-file</contentType>
<icon>
<image16x16>icons/AIRApp_16.png</image16x16>
<image32x32>icons/AIRApp_32.png</image32x32>
<image48x48>icons/AIRApp_48.png</image48x48>
<image128x128>icons/AIRApp_128.png</image128x128>
</icon>
</fileType>
</fileTypes>
O elemento fileTypes é opcional. Ele pode conter qualquer número de elementos fileType.
Os elementos name e extension são necessários para cada declaração fileType que você inclui. O mesmo nome pode
ser usado para várias extensões. A extensão identifica unicamente o tipo de arquivo. (Observe que a extensão é
especificada sem o ponto anterior.) O elemento description é opcional e é exibido ao usuário pela interface de
usuário do sistema operacional. O contentType é exigido no AIR 1.5 (ele era opcional no AIR 1.0 e 1.1). A
propriedade ajuda o sistema operacional a localizar o melhor aplicativo para abrir um arquivo em algumas
circunstâncias. O valor deve ser o tipo MIME do conteúdo do arquivo. Observe que o valor será ignorado no Linux
se o tipo de arquivo já estiver registrado e tiver um tipo MIME atribuído.
Os ícones podem ser especificados para a extensão do arquivo, usando o mesmo formato do elemento do ícone do
aplicativo. Os arquivos do ícone deve também ser incluídos no arquivo de instalação do AIR (eles não são empacotados
automaticamente).
Quando um tipo de arquivo é associado a um aplicativo do AIR, o aplicativo será invocado sempre que um usuário
abre um arquivo desse tipo. Se o aplicativo já estiver em execução, o AIR irá despachar o objeto InvokeEvent para a
instância em execução. Caso contrário, o AIR lançará o aplicativo primeiro. Nos dois casos, o caminho para o arquivo
pode ser recuperado do objeto InvokeEvent despachado pelo objeto NativeApplication. Você pode usar esse caminho
para abrir o arquivo.
Para obter mais informações, consulte “Gerenciamento de associações de arquivos” na página 299 e “Captura de
argumentos de linha de comando” na página 292.
54
Capítulo 9: Adobe AIR - funcionalidade
específica
Esse tópico fornece uma visão geral da funcionalidade do Adobe® AIR™ que não está disponível para conteúdo do SWF
executado no Adobe® Flash® Player.
Classes específicas do AIR
As classes de tempos de execução a seguir são específicas do Adobe AIR. Elas não estão disponíveis para conteúdo do
SWF em execução no navegador:
Classe
Pacote
ApplicationUpdater
air.update
ApplicationUpdaterUI
air.update
BrowserInvokeEvent
flash.events
Clipboard
flash.desktop
ClipboardFormats
flash.desktop
ClipboardTransferMode
flash.desktop
CompressionAlgorithm
flash.utils
DockIcon
flash.desktop
DownloadErrorEvent
air.update.events
DRMAuthenticateEvent
flash.events
DRMErrorEvent
flash.events
DRMStatusEvent
flash.events
EncryptedLocalStore
flash.data
File
flash.filesystem
FileListEvent
flash.events
FileMode
flash.filesystem
FileStream
flash.filesystem
FocusDirection
flash.display
HTMLHistoryItem
flash.html
HTMLHost
flash.html
HTMLLoader
flash.html
HTMLPDFCapability
flash.html
HTMLUncaughtScriptExceptionEvent
flash.events
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 55
Adobe AIR - funcionalidade específica
Classe
Pacote
HTMLWindowCreateOptions
flash.html
Icon
flash.desktop
InteractiveIcon
flash.desktop
InvokeEvent
flash.events
NativeApplication
flash.desktop
NativeDragActions
flash.desktop
NativeDragEvent
flash.events
NativeDragManager
flash.desktop
NativeDragOptions
flash.desktop
NativeMenu
flash.display
NativeMenuItem
flash.display
NativeWindow
flash.display
NativeWindowBoundsEvent
flash.events
NativeWindowDisplayState
flash.display
NativeWindowDisplayStateEvent
flash.events
NativeWindowInitOptions
flash.display
NativeWindowResize
flash.display
NativeWindowSystemChrome
flash.display
NativeWindowType
flash.display
NotificationType
flash.desktop
OutputProgressEvent
flash.events
RevocationCheckSettings
flash.security
Screen
flash.display
ScreenMouseEvent
flash.events
SignatureStatus
flash.security
SignerTrustSettings
flash.security
SQLCollationType
flash.data
SQLColumnNameStyle
flash.data
SQLColumnSchema
flash.data
SQLConnection
flash.data
SQLError
flash.errors
SQLErrorEvent
flash.events
SQLErrorOperation
flash.errors
SQLEvent
flash.events
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 56
Adobe AIR - funcionalidade específica
Classe
Pacote
SQLIndexSchema
flash.data
SQLResult
flash.data
SQLSchema
flash.data
SQLSchemaResult
flash.data
SQLStatement
flash.data
SQLTableSchema
flash.data
SQLTransactionLockType
flash.data
SQLTriggerSchema
flash.data
SQLUpdateEvent
flash.events
SQLViewSchema
flash.data
StatusFileUpdateErrorEvent
air.update.events
StatusFileUpdateEvent
air.update.events
StatusUpdateErrorEvent
air.update.events
StatusUpdateEvent
air.update.events
SystemTrayIcon
flash.desktop
UpdateEvent
air.update.events
Updater
flash.desktop
URLRequestDefaults
flash.net
XMLSignatureValidator
flash.utils
Além disso, o pacote flash.security inclui a interface do IURIDereferencer, específica do AIR.
Classes de tempo de execução com funcionalidade
específica do AIR
As classes a seguir estão disponíveis para conteúdo do SWF em execução no navegador, mas o AIR fornece métodos
ou propriedades adicionais:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 57
Adobe AIR - funcionalidade específica
Classe
Propriedade ou método
Capabilities
idiomas
Event
DISPLAYING
EXITING
HTML_BOUNDS_CHANGE
HTML_DOM_INITIALIZE
HTML_RENDER
LOCATION_CHANGE
NETWORK_CHANGE
USER_IDLE
USER_PRESENT
FileReference
uploadUnencoded()
HTTPStatusEvent
HTTP_RESPONSE_STATUS
responseURL
responseHeaders
KeyboardEvent
commandKey
controlKey
LoaderContext
allowLoadBytesCodeExecution
LoaderInfo
parentSandboxBridge
childSandboxBridge
NetStream
resetDRMVouchers()
setDRMAuthenticationCredentials()
URLRequest
followRedirects
manageCookies
shouldAuthenticate
shouldCacheResponse
userAgent
userCache
setLoginCredentials()
URLStream
httpResponseStatus event
Stage
nativeWindow
Security
APPLICATION
A maioria dessas novas propriedades e métodos estão disponíveis apenas para conteúdo na caixa de proteção de
segurança de aplicativos do AIR. No entanto, os novos membros nas classes URLRequest também estão disponíveis
para conteúdo em execução em outras caixas de proteção.
Os métodos ByteArray.compress() e ByteArray.uncompress() incluem, cada um, um novo parâmetro
algorithm, permitindo que você escolha entre a compactação deflate e zlib. Esse parâmetro só está disponível para
conteúdo em execução no AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 58
Adobe AIR - funcionalidade específica
Classes de estrutura de monitoramento de serviço
O pacote air.net contém classes para detecção de rede. Este pacote só está disponível para conteúdo em execução no
Adobe AIR. Ele está incluído no arquivo ServiceMonitor.swc.
O pacote inclui as seguintes classes:
• ServiceMonitor
• SocketMonitor
• URLMonitor
59
Capítulo 10: Trabalhar com janelas nativas
Use as classes fornecidas pela API de janela nativa do Adobe® AIR® para criar e gerenciar janelas da área de trabalho.
Mais informações on-line sobre janelas nativas
Você encontra mais informações sobre a API de janela nativa e como trabalhar com janelas nativas nestas fontes:
Início rápido (Adobe AIR Developer Connection)
• Interação com uma janela
• Personalização da aparência de uma janela nativa
• Criação de janelas no estilo pop-up
• Controle da ordem de exibição das janelas
• Criação de janelas não retangulares redimensionáveis
Referência de linguagem
• NativeWindow
• NativeWindowInitOptions
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (procure 'Janelas do AIR')
Noções básicas sobre janelas do AIR
O AIR oferece uma API de janelas fácil de usar e compatível com várias plataformas, que permite criar janelas de
sistema operacional nativas usando técnicas de programação em Flash®, Flex™ e HTML.
Com o AIR, você tem grande liberdade para desenvolver a aparência do seu aplicativo. As janelas que você cria
parecem um aplicativo padrão de área de trabalho, correspondendo ao estilo Apple quando em execução no Mac, em
conformidade com convenções Microsoft quando executadas no Windows e em harmonia com o gerenciador de
janelas do Linux, tudo sem incluir um código específico de linha de plataforma. Se preferir, você pode usar o cromo
extensível e que pode ter a capa trocada, fornecido pela estrutura do Flex, para estabelecer o seu próprio estilo,
independentemente do local onde o aplicativo é executado. Você pode até mesmo desenhar seus próprios cromos de
janelas usando arte final vetorial e de bitmap com suporte completo para transparência e mesclagem alfa na área de
trabalho. Cansado de janelas retangulares? Desenhe uma redonda.
Janelas no AIR
O AIR suporta três APIs diferentes para se trabalhar com janelas:
• A classe NativeWindow orientada para ActionScript fornece o nível mais baixo de API de janela. Use o
NativeWindows em aplicativos de autoria Flash CS e ActionScript. Considere estender a classe NativeWindow para
especializar as janelas usadas em seu aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 60
Trabalhar com janelas nativas
• As classes mx:WindowedApplication e mx:Window da estrutura do Flex fornecem um "invólucro" para a classe
NativeWindow. O componente WindowedApplication substitui o componente Application quando você cria um
aplicativo do AIR com Flex e deve ser sempre usado como janela inicial no aplicativo Flex.
• No ambiente HTML, você pode usar a classe JavaScript Window, assim como faria em um aplicativo da Web
baseado em navegador. As chamadas para os métodos JavaScript Window são encaminhadas para o objeto janela
nativo subjacente.
Janelas ActionScript
Quando criar janelas com a classe NativeWindow, use a lista de exibição no palco do Flash Player diretamente. Para
adicionar um objeto visual a uma NativeWindow, adicione o objeto à lista de exibição do palco da janela ou a outro
contêiner do objeto de exibição no palco.
Janelas da estrutura do Flex
A estrutura do Flex define seus próprios componentes de janela que abrangem a API NativeWindow. Esses
componentes (mx:WindowedApplication e mx:Window) não podem ser usados fora da estrutura e, portanto, não
podem ser usados em aplicativos do AIR desenvolvidos com Flash CS.
Janelas HTML
Quando cria janelas HTML, você usa HTML, CSS e JavaScript para exibir o conteúdo. Para adicionar um objeto visual
a uma janela HTML, você adiciona esse conteúdo ao HTML DOM. As janelas HTML são uma categoria especial de
NativeWindow. O host do AIR define uma propriedade nativeWindow em janelas HTML que dá acesso à ocorrência
subjacente de NativeWindow. Você pode usar essa propriedade para acessar as propriedades, os métodos e os eventos
de NativeWindow descritos aqui.
Nota: O objeto JavaScript Window também tem métodos para gerar scripts da janela que o contém, como moveTo() e
close(). Se houver métodos de sobreposição disponíveis, você poderá usar o método mais conveniente.
A janela inicial do aplicativo.
A primeira janela do seu aplicativo é criada automaticamente para você pelo AIR. O AIR define as propriedades e o
conteúdo da janela usando os parâmetros especificados no elemento initialWindow do arquivo de descrição do
aplicativo.
Se o conteúdo raiz é um arquivo SWF, o AIR cria uma ocorrência de NativeWindow, carrega o arquivo SWF e o
adiciona ao palco da janela. Se o conteúdo raiz é um arquivo HTML, o AIR cria uma janela HTML e carrega o código
HTML.
Para obter mais informações sobre as propriedades de janela especificadas no descritor do aplicativo, consulte “A
estrutura do arquivo do descritor do aplicativo” na página 44.
Classes de janela nativa
A API de janela nativa contém as seguintes classes:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 61
Trabalhar com janelas nativas
Pacote
Classes
flash.display
•
NativeWindow
•
NativeWindowInitOptions
•
NativeWindowDisplayState
•
NativeWindowResize
•
NativeWindowSystemChrome
•
NativeWindowType
Constantes de string de janela são definidas nas seguintes classes:
flash.events
•
NativeWindowDisplayState
•
NativeWindowResize
•
NativeWindowSystemChrome
•
NativeWindowType
•
NativeWindowBoundsEvent
•
NativeWindowDisplayStateEvent
Fluxo de eventos de janelas nativas
As janelas nativas despacham eventos para notificar os componentes interessados de que uma alteração importante
está prestes a ocorrer ou já ocorreu. Muitos eventos relacionados a janelas são despachados em pares. O primeiro
evento avisa que uma alteração está prestes a ocorrer. O segundo comunica que a alteração foi feita. É possível cancelar
um evento de aviso, mas não um evento de notificação. Esta seqüência ilustra o fluxo de eventos que ocorre quando
um usuário clica no botão Maximizar de uma janela:
1 O objeto NativeWindow despacha um evento displayStateChanging.
2 Se nenhum ouvinte registrado cancelar o evento, a janela será maximizada.
3 O objeto NativeWindow despacha um evento displayStateChange.
Além disso, o objeto NativeWindow despacha eventos de alterações relacionadas feitas no tamanho e na posição de
uma janela. A janela não despacha eventos de aviso referentes a essas alterações relacionadas. Os eventos
relacionados são:
a Um evento move é despachado se o canto superior esquerdo da janela foi movido por causa da operação de
maximização.
b Um evento resize é despachado se o tamanho da janela mudou devido à operação de maximização.
Um objeto NativeWindow despacha uma seqüência semelhante de eventos quando maximiza, restaura, fecha,
movimenta e redimensiona uma janela.
Os eventos de aviso são despachados somente quando uma alteração é iniciada através do cromo da janela ou de
outro mecanismo controlado pelo sistema operacional. Quando você chama um método de janela para alterar o
tamanho, a posição ou o estado de exibição de uma janela, a janela só despacha um evento para comunicar a
alteração. Se desejar, você pode despachar um evento de aviso usando o método de janela dispatchEvent() e,
depois, verificar se o seu evento de aviso foi cancelado antes de prosseguir com a alteração.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 62
Trabalhar com janelas nativas
Para obter informações detalhadas sobre as classes, os métodos, as propriedades e os eventos da API de janela,
consulte a Referência dos componentes e da linguagem do de linguagem do ActionScript 3.0
(http://www.adobe.com/go/learn_flash_aslr_br).
Para obter informações gerais sobre como usar a lista de exibição do Flash, consulte a seção “Programação da
exibição” na referência Programação do Adobe ActionScript 3.0
(http://www.adobe.com/go/learn_fl_cs4_programmingAS3_en).
Propriedades que controlam o estilo e o comportamento de janelas nativas
As seguintes propriedades controlam a aparência e o comportamento básicos de uma janela:
•
type
•
systemChrome
•
transparent
Quando cria uma janela, você define essas propriedades no objeto NativeWindowInitOptions passado para o
construtor da janela. O AIR lê as propriedades da janela inicial do aplicativo no descritor do aplicativo. (Com exceção
da propriedade type, que não pode ser definida no descritor do aplicativo e é sempre definida como normal.) Não é
possível alterar as propriedades após a criação da janela.
Algumas configurações dessas propriedades são mutuamente incompatíveis: systemChrome não pode ser definida
como standard quando transparent é true ou quando type é lightweight.
Tipos de janela
Os tipos de janela do AIR combinam atributos de cromo e visibilidade do sistema operacional nativo para criar três
tipos funcionais de janela. Use as constantes definidas na classe NativeWindowType para fazer referência aos nomes
de tipo no código. O AIR oferece os seguintes tipos de janela:
Tipo
Descrição
Normal
Uma janela típica. As janelas normais usam o cromo de estilo em tamanho máximo e são exibidas na barra de
tarefas do Windows e no menu de janela do Mac OS X.
Utilitário
Uma paleta de ferramentas. As janelas de utilitário usam uma versão reduzida do cromo do sistema e não são
exibidas na barra de tarefas do Windows nem no menu de janela do Mac OS X.
Leve
As janelas leves não têm cromo e não são exibidas na barra de tarefas do Windows nem no menu de janela do
Mac OS X. Além disso, as janelas leves não têm o menu Sistema (Alt+espaço) no Windows. As janelas leves são
adequadas para as bolhas de notificação e controles como caixas de combinação que abrem uma área de
exibição de curta duração. Quando se usa o tipo leve, a propriedade systemChrome deve ser definida como
none.
Cromo de janela
O cromo de janela é o conjunto de controles que permitem aos usuários manipular uma janela no ambiente da área de
trabalho. Os elementos do cromo incluem a barra de título e seus botões, borda e alças de redimensionamento.
Cromo do sistema
É possível definir a propriedade systemChrome como standard ou none. Escolha o cromo do sistema standard para
dar à sua janela o conjunto de controles padrão criados e estilizados pelo sistema operacional do usuário. Escolha none
para fornecer o seu próprio cromo para a janela. Use as constantes definidas na classe NativeWindowSystemChrome
para fazer referência às configurações de cromo do sistema no código.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 63
Trabalhar com janelas nativas
O cromo do sistema é gerenciado pelo sistema. Seu aplicativo não tem acesso direto aos controles propriamente ditos,
mas pode reagir a eventos despachados quando eles são usados. Quando você usa o cromo padrão para uma janela, a
propriedade transparent deve ser definida como false e a propriedade type deve ser normal ou utility.
Cromo personalizado
Se você criar uma janela sem um cromo do sistema, deverá adicionar seus próprios controles de cromo para
administrar as interações entre um usuário e a janela. Você também tem liberdade para criar janelas não retangulares
transparentes.
Transparência de janelas
Para permitir a mesclagem alfa de uma janela com a área de trabalho ou outras janelas, defina a propriedade
transparent da janela como true. A propriedade transparent deve ser definida antes de a janela ser criada e não é
possível alterá-la.
Uma janela transparente não tem um plano de fundo padrão. Qualquer área da janela que não contém um objeto
desenhado pelo aplicativo fica invisível. Se um objeto exibido tiver uma configuração alfa de menos de 1, qualquer
coisa abaixo do objeto ficará transparente, inclusive outros objetos de exibição na mesma janela, em outras janelas e
na área de trabalho. O processamento de grandes áreas com mesclagem alfa pode ser lento, por isso o efeito deve ser
usado com cautela.
As janelas transparentes são úteis quando você deseja criar aplicativos com bordas irregulares ou que “desaparecem”
ou mesmo parecem ser invisíveis.
Importante: No Linux, eventos de mouse não passam por pixels totalmente transparentes. Você deve evitar criar janelas
com áreas grandes totalmente transparentes, já que isso pode bloquear invisivelmente o acesso do usuário a outras janelas
ou itens na área de trabalho. No Mac OS X e no Windows, eventos de mouse passam por pixels totalmente transparentes.
A transparência não pode ser usada com janelas que têm um cromo do sistema. Além disso, os conteúdos SWF e PDF
em HTML não são exibidos em janelas transparentes. Para obter mais informações, consulte “Considerações ao
carregar conteúdo SWF ou PDF em uma página HTML” na página 259.
Em alguns sistemas operacionais, pode não haver suporte para transparência devido à configuração de hardware ou
software ou às opções de exibição definidas pelo usuário. Quando não há suporte para transparência, o aplicativo é
composto com um plano de fundo preto. Nesses casos, qualquer área transparente do aplicativo é exibida como uma
área preta opaca.
A propriedade estática NativeWindow.supportsTransparency informa se a transparência de janela pode ser usada.
Se o teste dessa propriedade retornar false, por exemplo, você poderá exibir uma caixa de diálogo de aviso para o
usuário ou exibir uma interface de usuário de fallback retangular não transparente . Vale observar que sempre há
suporte para transparência nos sistemas operacionais Mac e Windows. O suporte em sistemas operacionais Linux
requer um gerenciador de composição de janela, mas mesmo quando um gerenciador de composição de janela está
ativo, a transparência pode estar indisponível devido às opções de exibição do usuário ou configuração de hardware.
Transparência em uma janela de aplicativo HTML
Por padrão, o plano de fundo do conteúdo HTML exibido em janelas HTML e objetos HTMLLoader é opaco, mesmo
quando a janela que o contém é transparente. Para desativar o plano de fundo padrão exibido com conteúdo HTML,
defina a propriedade paintsDefaultBackground como false. O exemplo abaixo cria um objeto HTMLLoader e
desativa o plano de fundo padrão:
var html:HTMLLoader = new HTMLLoader();
html.paintsDefaultBackground = false;
Este exemplo usa JavaScript para desativar o plano de fundo padrão de uma janela HTML:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 64
Trabalhar com janelas nativas
window.htmlLoader.paintsDefaultBackground = false;
Se um elemento do documento HTML define uma cor de plano de fundo, o plano de fundo desse elemento não fica
transparente. Não há suporte para definir um valor de transparência parcial (ou opacidade). No entanto, você pode
usar um elemento gráfico no formato PNG transparente para uma página ou um elemento de página a fim de obter
um efeito visual semelhante.
Um catálogo de janelas visuais
A seguinte tabela ilustra os efeitos visuais de diferentes combinações de configurações de propriedades de janela nos
sistemas operacionais Mac OS X, Windows e Linux:
Configurações de janela
Tipo: normal
SystemChrome: standard
Transparente: false
Tipo: utilitário
SystemChrome: standard
Transparente: false
Mac OS X
Microsoft Windows
Linux*
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 65
Trabalhar com janelas nativas
Configurações de janela
Mac OS X
Microsoft Windows
Linux*
Tipo: Qualquer um
SystemChrome: none
Transparente: false
Tipo: Qualquer um
SystemChrome: none
Transparente: true
mxWindowedApplication ou
mx:Window
Tipo: Qualquer um
SystemChrome: none
Transparente: true
Gerenciador de janela *Ubuntu with Compiz
Nota: Os seguintes elementos de cromo do sistema não têm suporte no AIR: a barra de ferramentas do OS X, o ícone
Proxy do Mac OS X, os ícones na barra de título do Windows e o cromo do sistema alternativo.
Criação de janelas
O AIR cria automaticamente a primeira janela de um aplicativo, mas você pode criar qualquer outra janela de que
precise. Para criar uma janela nativa, use o método de construtor NativeWindow. Para criar uma janela HTML, use o
método createRootWindow() de HTMLLoader ou, em um documento HTML, chame o método JavaScript
window.open().
Especificação das propriedades de inicialização de uma janela
As propriedades de inicialização de uma janela não podem ser alteradas após a criação da janela da área de trabalho.
Entre as propriedades imutáveis e seus valores padrão estão os seguintes:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 66
Trabalhar com janelas nativas
Propriedade
Valor padrão
systemChrome
standard
type
normal
transparent
false
maximizable
true
minimizable
true
resizable
true
Defina as propriedades da janela inicial criada pelo AIR no arquivo de descrição do aplicativo. A janela principal de
um aplicativo do AIR sempre é do tipo normal. (É possível especificar outras propriedades de janela no arquivo de
descrição, tais como visible, width e height, mas elas podem ser alteradas a qualquer momento.)
Defina as propriedades de outras janelas nativas e HTML criadas pelo seu aplicativo usando a classe
NativeWindowInitOptions. Quando você cria uma janela, deve passar um objeto NativeWindowInitOptions que
especifique as propriedades da janela para a função de construtor NativeWindow ou o método createRootWindow()
de HTMLLoader.
O seguinte código cria um objeto NativeWindowInitOptions para uma janela de utilitário:
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.systemChrome = NativeWindowSystemChrome.STANDARD;
options.type = NativeWindowType.UTILITY
options.transparent = false;
options.resizable = false;
options.maximizable = false;
Não é permitido definir systemChrome como standard quando transparent é true ou quando type é lightweight.
Nota: Não é possível definir as propriedades de inicialização de uma janela criada com a função JavaScript
window.open(). No entanto, você pode ignorar como elas são criadas implementando sua própria classe HTMLHost.
Para obter mais informações, consulte “Tratamento de chamadas JavaScript de window.open()” na página 268.
Criação da janela inicial do aplicativo
O AIR cria a janela inicial do aplicativo com base nas propriedades especificadas no descritor do aplicativo e carrega
o arquivo mencionado no elemento de conteúdo. O elemento de conteúdo deve referenciar um arquivo SWF ou um
arquivo HTML.
A janela inicial pode ser a janela principal do seu aplicativo ou pode simplesmente servir para iniciar uma ou mais
janelas. Não é necessário torná-la visível.
A ferramenta Flash Authoring automaticamente cria o arquivo SWF e adiciona a referência apropriada ao descritor
do aplicativo quando você testa ou publica um projeto no AIR. A linha do tempo principal funciona como o ponto de
entrada do seu aplicativo.
Quando seu aplicativo é iniciado, o AIR cria uma janela e carrega o arquivo SWF do aplicativo. Para controlar a janela
de área de trabalho com o ActionScript, use a propriedade nativeWindow do objeto Stage para obter uma referência
ao objeto NativeWindow. Dessa maneira, você poderá definir as propriedades da janela e chamar métodos de janela.
O exemplo abaixo ativa a janela principal no estado maximizado (a partir do primeiro quadro de um arquivo FLA do
Flash):
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 67
Trabalhar com janelas nativas
import flash.display.NativeWindow;
var mainWindow:NativeWindow = this.stage.nativeWindow;
mainWindow.maximize();
mainWindow.activate();
Criação de um objeto NativeWindow
Para criar um NativeWindow, passe um objeto NativeWindowInitOptions para o construtor NativeWindow:
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.systemChrome = NativeWindowSystemChrome.STANDARD;
options.transparent = false;
var newWindow:NativeWindow = new NativeWindow(options);
A janela não é exibida até você definir a propriedade visible como true ou chamar o método activate().
Uma vez criada a janela, você pode inicializar suas propriedades e carregar conteúdo nela usando as técnicas de
propriedade de palco e lista de exibição do Flash.
Em quase todos os casos, você deve definir a propriedade de palco scaleMode de uma nova janela nativa como
noScale (use a constante StageScaleMode.NO_SCALE). Os modos de dimensionamento do Flash foram
desenvolvidos para situações em que o autor do aplicativo não sabe de antemão a proporção do espaço de exibição do
aplicativo. Os modos de dimensionamento permitem que o autor escolha o melhor ajuste: recorte o conteúdo,
aumente ou compacte o conteúdo ou preencha-o com espaço vazio. Desde que você controle o espaço de exibição no
AIR (o quadro da janela), pode dimensionar a janela conforme o conteúdo ou vice-versa, sem comprometer o
resultado final.
Nota: Para determinar os tamanhos máximo e mínimo de uma janela permitidos no sistema operacional atual, use as
seguintes propriedades estáticas da classe NativeWindow:
var maxOSSize:Point = NativeWindow.systemMaxSize;
var minOSSize:Point = NativeWindow.systemMinSize;
Criação de uma janela HTML
Para criar uma janela HTML, você pode chamar o método JavaScript Window.open() ou o método
createRootWindow() da classe HTMLLoader do AIR.
O conteúdo HTML em qualquer caixa de proteção de segurança pode usar o método JavaScript Window.open()
padrão. Se o conteúdo estiver sendo executado fora da caixa de proteção do aplicativo, o método open() só poderá ser
chamado em resposta a interações do usuário, como cliques do mouse ou pressionamentos de tecla. Quando open()
é chamado, é criada uma janela com o cromo do sistema para exibir o conteúdo na URL especificada. Por exemplo:
newWindow = window.open("xmpl.html", "logWindow", "height=600, width=400, top=10, left=10");
Nota: Você pode estender a classe HTMLHost no ActionScript para personalizar a janela criada com a função JavaScript
window.open(). Consulte “Sobre estender a classe HTMLHost” na página 263.
O conteúdo na caixa de proteção de segurança do aplicativo tem acesso ao método de criação de janelas mais eficiente,
HTMLLoader.createRootWindow(). Com ele, você pode especificar todas as opções de criação de uma nova janela.
Por exemplo, o seguinte código JavaScript cria uma janela do tipo leve sem cromo do sistema e com tamanho de
300x400 pixels:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 68
Trabalhar com janelas nativas
var options = new air.NativeWindowInitOptions();
options.systemChrome = "none";
options.type = "lightweight";
var windowBounds = new air.Rectangle(200,250,300,400);
newHTMLLoader = air.HTMLLoader.createRootWindow(true, options, true, windowBounds);
newHTMLLoader.load(new air.URLRequest("xmpl.html"));
Nota: Se o conteúdo carregado por uma nova janela estiver fora da caixa de proteção de segurança do aplicativo, o objeto
Window não terá as propriedades do AIR: runtime, nativeWindow ou htmlLoader.
As janelas criadas com o método createRootWindow() permanecem independentes da janela de abertura. As
propriedades parent e opener do objeto JavaScript Window são null. A janela de abertura pode acessar o objeto
Window da nova janela usando a referência a HTMLLoader retornada pela função createRootWindow(). No
contexto do exemplo anterior, a instrução newHTMLLoader.window faria referência ao objeto JavaScript Window da
janela criada.
Nota: A função createRootWindow() pode ser chamada no JavaScript e no ActionScript.
Adicionar conteúdo a uma janela
O tipo de uma janela do AIR determina a maneira como você adiciona conteúdo a ela. É possível criar um clipe de
filme e usar a linha do tempo para controlar o estado do aplicativo. Com HTML, você define o conteúdo básico da
janela declarativamente. É possível incorporar recursos no arquivo SWF do aplicativo ou carregá-los a partir de
arquivos de aplicativo separados. O conteúdo Flash e HTML pode ser criado rapidamente e adicionado a uma janela
de forma dinâmica.
Quando você carrega conteúdo SWF, ou HTML com JavaScript, deve levar em consideração o modelo de segurança
do AIR. Qualquer conteúdo existente na caixa de proteção de segurança do aplicativo, ou seja, conteúdo instalado com
seu aplicativo e carregável com o esquema de URL app:, tem privilégios totais para acessar todas as APIs do AIR.
Qualquer conteúdo carregado de fora dessa caixa de proteção não pode acessar as APIs do AIR. O conteúdo JavaScript
fora da caixa de proteção do aplicativo não pode usar as propriedades runtime, nativeWindow ou htmlLoader do
objeto JavaScript Window.
Para permitir código entre scripts seguro, você pode usar uma ponte de caixa de proteção para disponibilizar uma
interface limitada entre conteúdo de aplicativo e conteúdo que não é de aplicativo. No conteúdo HTML, também é
possível mapear páginas do seu aplicativo para uma caixa de proteção que não seja de aplicativo, de maneira que essa
página possa cruzar scripts de conteúdo externo. Consulte “Segurança do AIR” na página 23.
Carregamento de arquivo ou imagem SWF
Você pode carregar arquivos ou imagens SWF do Flash na lista de exibição de uma janela nativa usando a classe
flash.display.Loader:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 69
Trabalhar com janelas nativas
package {
import
import
import
import
flash.display.Sprite;
flash.events.Event;
flash.net.URLRequest;
flash.display.Loader;
public class LoadedSWF extends Sprite
{
public function LoadedSWF(){
var loader:Loader = new Loader();
loader.load(new URLRequest("visual.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadFlash);
}
private function loadFlash(event:Event):void{
addChild(event.target.loader);
}
}
}
É possível carregar um arquivo SWF que contém código de biblioteca para uso em um aplicativo baseado em HTML.
A maneira mais simples de carregar um arquivo SWF em uma janela HTML é usar a tag script, mas você também
pode usar a API Loader diretamente.
Nota: Arquivos SWF mais antigos criados com o ActionScript 1 ou 2 compartilham estados globais, como definições de
classe, singletons e variáveis globais, se carregados na mesma janela. Se tal arquivo SWF depender de estados globais
intocados para funcionar corretamente, não será possível carregá-lo mais de uma vez na mesma janela nem carregá-lo
na mesma janela como outro arquivo SWF usando variáveis e definições de classe de sobreposição. Este conteúdo pode
ser carregado em janelas separadas.
Carregamento de conteúdo HTML em um objeto NativeWindow
Para carregar conteúdo HTML em um NativeWindow, você pode adicionar um objeto HTMLLoader ao palco da
janela e carregar o conteúdo HTML no HTMLLoader ou criar uma janela que já contenha um objeto HTMLLoader
usando o método HTMLLoader.createRootWindow(). O seguinte exemplo mostra conteúdo HTML em uma área de
exibição de 300 por 500 pixels no palco de uma janela nativa:
//newWindow is a NativeWindow instance
var htmlView:HTMLLoader = new HTMLLoader();
html.width = 300;
html.height = 500;
//set the stage so display objects are added to the top-left and not scaled
newWindow.stage.align = "TL";
newWindow.stage.scaleMode = "noScale";
newWindow.stage.addChild( htmlView );
//urlString is the URL of the HTML page to load
htmlView.load( new URLRequest(urlString) );
Nota: O conteúdo SWF ou PDF de um arquivo em HTML não é exibido se a janela utiliza transparência (ou seja, se a
propriedade transparent da janela for true) ou se o controle HTMLLoader estiver dimensionado.
Adicionar conteúdo SWF como sobreposição em uma janela HTML
Como as janelas HTML são contidas em uma ocorrência de NativeWindow, é possível adicionar objetos de exibição
do Flash tanto acima quanto abaixo da camada HTML na lista de exibição.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 70
Trabalhar com janelas nativas
Para adicionar um objeto de exibição acima da camada HTML, use o método addChild() da propriedade
window.nativeWindow.stage. O método addChild() adiciona conteúdo em camada acima de qualquer conteúdo
existente na janela.
Para adicionar um objeto de exibição abaixo da camada HTML, use o método addChildAt() da propriedade
window.nativeWindow.stage, passando um valor de zero para o parâmetro index. Colocar um objeto no índice zero
movimenta o conteúdo existente, inclusive a exibição HTML, uma camada acima e insere o novo conteúdo na parte
inferior. Para que o conteúdo disposto abaixo da página HTML fique visível, defina a propriedade
paintsDefaultBackground do objeto HTMLlLoader como false. Além disso, quaisquer elementos da página que
têm uma cor de plano de fundo definida não ficarão transparentes. Por exemplo, se você definir uma cor de plano de
fundo para o elemento body da página, nenhuma parte dela ficará transparente.
O exemplo a seguir ilustra como adicionar objetos de exibição do Flash na forma de sobreposições e bases a uma página
HTML. O exemplo cria dois objetos de forma simples, adiciona um abaixo do conteúdo HTML e um acima. O
exemplo também atualiza a posição da forma com base no evento enterFrame.
<html>
<head>
<title>Bouncers</title>
<script src="AIRAliases.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
air.Shape = window.runtime.flash.display.Shape;
function Bouncer(radius, color){
this.radius = radius;
this.color = color;
//velocity
this.vX = -1.3;
this.vY = -1;
//Create a Shape object and draw a circle with its graphics property
this.shape = new air.Shape();
this.shape.graphics.lineStyle(1,0);
this.shape.graphics.beginFill(this.color,.9);
this.shape.graphics.drawCircle(0,0,this.radius);
this.shape.graphics.endFill();
//Set the starting position
this.shape.x = 100;
this.shape.y = 100;
//Moves the sprite by adding (vX,vY) to the current position
this.update = function(){
this.shape.x += this.vX;
this.shape.y += this.vY;
//Keep the sprite within the window
if( this.shape.x - this.radius < 0){
this.vX = -this.vX;
}
if( this.shape.y - this.radius < 0){
this.vY = -this.vY;
}
if( this.shape.x + this.radius > window.nativeWindow.stage.stageWidth){
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 71
Trabalhar com janelas nativas
this.vX = -this.vX;
}
if( this.shape.y + this.radius > window.nativeWindow.stage.stageHeight){
this.vY = -this.vY;
}
};
}
function init(){
//turn off the default HTML background
window.htmlLoader.paintsDefaultBackground = false;
var bottom = new Bouncer(60,0xff2233);
var top = new Bouncer(30,0x2441ff);
//listen for the enterFrame event
window.htmlLoader.addEventListener("enterFrame",function(evt){
bottom.update();
top.update();
});
//add the bouncing shapes to the window stage
window.nativeWindow.stage.addChildAt(bottom.shape,0);
window.nativeWindow.stage.addChild(top.shape);
}
</script>
<body onload="init();">
<h1>de Finibus Bonorum et Malorum</h1>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis
et quasi architecto beatae vitae dicta sunt explicabo.</p>
<p style="background-color:#FFFF00; color:#660000;">This paragraph has a background color.</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis
praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias
excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui
officia deserunt mollitia animi, id est laborum et dolorum fuga.</p>
</body>
</html>
Este exemplo faz uma introdução rudimentar a algumas técnicas avançadas que cruzam os limites entre o JavaScript e
o ActionScript no AIR. Se não estiver familiarizado com o uso de objetos de exibição do ActionScript, consulte a seção
Programação da exibição, do guiaProgramação do Adobe ActionScript 3.0 para obter mais informações.
Exemplo: Criação de uma janela nativa
O exemplo abaixo mostra como criar uma janela nativa:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 72
Trabalhar com janelas nativas
public function createNativeWindow():void {
//create the init options
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.transparent = false;
options.systemChrome = NativeWindowSystemChrome.STANDARD;
options.type = NativeWindowType.NORMAL;
//create the window
var newWindow:NativeWindow = new NativeWindow(options);
newWindow.title = "A title";
newWindow.width = 600;
newWindow.height = 400;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
//activate and show the new window
newWindow.activate();
}
Gerenciamento de janelas
Use as propriedades e os métodos da classe NativeWindow para gerenciar a aparência, o comportamento e o ciclo de
vida das janelas de área de trabalho.
Obter uma ocorrência de NativeWindow
Para manipular uma janela, primeiro você deve obter a ocorrência dela. A ocorrência da janela pode ser obtida em um
dos seguintes lugares:
• O construtor nativo de janela usado para criar a janela:
var win:NativeWindow = new NativeWindow(initOptions);
• A propriedade nativeWindow do estágio da janela:
var win:NativeWindow = stage.nativeWindow;
• A propriedade stage de um objeto de exibição na janela:
var win:NativeWindow = displayObject.stage.nativeWindow;
• A propriedade target de um evento de janela nativa despachada pela janela:
private function onNativeWindowEvent(event:NativeWindowBoundsEvent):void
{
var win:NativeWindow = event.target as NativeWindow;
}
• A propriedade nativeWindow de uma página HTML exibida na janela:
var win:NativeWindow = htmlLoader.window.nativeWindow;
• As propriedades activeWindow e openedWindows do objeto NativeApplication:
var nativeWin:NativeWindow = NativeApplication.nativeApplication.activeWindow;
var firstWindow:NativeWindow = NativeApplication.nativeApplication.openedWindows[0];
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 73
Trabalhar com janelas nativas
NativeApplication.nativeApplication.activeWindow faz referência à janela ativa de um aplicativo (mas
retorna null se a janela ativa não é uma janela deste aplicativo do AIR). A matriz
NativeApplication.nativeApplication.openedWindows contém todas as janelas de um aplicativo do AIR
que não foram fechadas.
Ativar, mostrar e ocultar janelas
Para ativar uma janela, chame o método activate() de NativeWindow. A ativação de uma janela a traz para frente,
dá a ela foco do teclado e do mouse e, se necessário, a torna visível mediante a restauração da janela ou a definição da
propriedade visible como true. A ativação de uma janela não altera a ordem de outras janelas do aplicativo. A
chamada do método activate() faz com que a janela despache um evento activate.
Para mostrar uma janela oculta sem ativá-la, defina a propriedade visible como true. Isso traz a janela para frente,
mas não atribui o foco para ela.
Para ocultar uma janela de forma que não seja exibida, defina sua propriedade visible como false. Ocultar uma
janela suprime a exibição tanto da janela quanto de qualquer ícone relacionado na barra de tarefas e, no Mac OS X, a
entrada no menu Janelas.
Nota: No Mac OS X, não é possível ocultar totalmente uma janela minimizada que tenha um ícone na parte de janela
do encaixe. Se a propriedade visible está definida como false em uma janela minimizada, o ícone de encaixe da
janela continua sendo exibido. Se o usuário clica no ícone, a janela é restaurada para um estado visível e exibida.
Alteração da ordem de exibição de janelas
O AIR oferece diversos métodos para alterar diretamente a ordem de exibição das janelas. É possível mover uma janela
para o começo ou o final da ordem de exibição, bem como colocar uma janela em cima de outra ou atrás dela. Ao
mesmo tempo, o usuário pode reordenar as janelas ativando-as.
Você pode manter uma janela em frente de outras definindo sua propriedade alwaysInFront como true. Se mais de
uma janela tiver essa configuração, a ordem de exibição dessas janelas será definida entre elas, mas sempre serão
organizadas acima das janelas cuja propriedade alwaysInFront está definida como false. As janelas que estão no
primeiro grupo também são exibidas acima das janelas de outros aplicativos, mesmo quando o aplicativo do AIR não
está ativo. Como esse comportamento pode interromper o trabalho do usuário, definir alwaysInFront como true é
algo que só deve ser feito quando necessário e apropriado. Os exemplos de usos justificados incluem:
• Janelas pop-up temporárias de controles, como dicas de ferramentas, listas pop-up, menus personalizados e caixas
de combinação. Como essas janelas devem ser fechadas quando perdem o foco, pode-se evitar a dor de cabeça de
impedir um usuário de ver outra janela.
• Mensagens de erro e alertas extremamente urgentes. Quando pode ocorrer uma alteração irrevogável se o usuário
não responde de imediato, pode ser justificável trazer uma janela de alerta para frente. No entanto, a maioria dos
erros e alertas pode ser tratada na ordem de exibição normal das janelas.
• Janelas pop-up de curta duração.
Nota: O AIR não impõe o uso apropriado da propriedade alwaysInFront. Entretanto, se o seu aplicativo interrompe o
fluxo de trabalho de um usuário, possivelmente será enviado para a lixeira desse mesmo usuário.
A classe NativeWindow oferece estas propriedades e métodos para definir a ordem de exibição de uma janela em
relação a outras janelas:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 74
Trabalhar com janelas nativas
Membro
Descrição
propriedade alwaysInFront
Especifica se a janela é exibida no primeiro grupo de janelas.
Em quase todos os casos, false é a melhor configuração. Alterar o valor de false para true traz a janela
para frente de todas as janelas (mas não a ativa). Alterar o valor de true para false coloca a janela atrás
das demais janelas do primeiro grupo, mas ainda na frente de outras. Definir a propriedade de uma janela
com seu valor atual não altera a ordem de exibição.
orderToFront()
Traz a janela para frente.
orderInFrontOf()
Coloca a janela diretamente à frente de uma determinada janela.
orderToBack()
Envia a janela para trás de outras janelas.
orderBehind()
Coloca a janela diretamente atrás de uma determinada janela.
activate()
Traz a janela para frente (além de torná-la visível e de lhe atribuir foco).
Nota: Se uma janela está oculta (visible é false) ou minimizada, chamar os métodos de ordem de exibição não surte
nenhum efeito.
No sistema operacional Linux, diferentes gerenciadores de janela forçam regras diferentes, dependendo da ordem de
exibição da janela:
• Em alguns gerenciadores de janela, as janelas do utilitário são sempre exibidas em frente às janelas normais.
• Em alguns gerenciadores de janela, uma janela de tela cheia com alwaysInFront definida como true é sempre
exibida na frente de outras janelas que também tenham alwaysInFront definida como true.
Fechamento de janelas
Para fechar uma janela, use o método NativeWindow.close().
Fechar uma janela descarrega o conteúdo dela; porém, se outros objeto tiverem referências a esse conteúdo, os objetos
de conteúdo não serão destruídos. O método NativeWindow.close() é executado de forma assíncrona, e o aplicativo
que está contido na janela continua a executar durante o processo de fechamento. O método close despacha um evento
close quando a operação de fechamento é concluída. O objeto NativeWindow ainda é tecnicamente válido, mas o
acesso à maioria das propriedades e dos métodos em uma janela fechada gera IllegalOperationError. Não é possível
reabrir uma janela fechada. Verifique a propriedade closed de uma janela para testar se a janela foi fechada. Para
simplesmente ocultar a exibição de uma janela, defina a propriedade NativeWindow.visible como false.
Se a propriedade Nativeapplication.autoExit é true, o padrão, o aplicativo é encerrado ao ser fechada sua última
janela.
Permitir o cancelamento de operações de janela
Quando uma janela usa o cromo do sistema, a interação do usuário com ela pode ser cancelada monitorando ou
cancelando o comportamento padrão dos eventos apropriados. Por exemplo, quando um usuário clica no botão
Fechar do cromo do sistema, o evento closing é despachado. Se algum ouvinte registrado chamar o método
preventDefault() do evento, a janela não será fechada.
Quando uma janela não usa o cromo do sistema, os eventos de notificação referentes às alterações pretendidas não são
despachados automaticamente antes de a alteração ser feita. Por isso, se você chamar os métodos para fechar uma
janela ou se alterar o estado dela ou definir qualquer uma das propriedades de limites de janela, a alteração não poderá
ser cancelada. Para notificar os componentes do seu aplicativo antes que seja feita uma alteração de janela, a lógica do
aplicativo poderá despachar o evento de notificação relevante usando o método dispatchEvent() da janela.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 75
Trabalhar com janelas nativas
Por exemplo, a seguinte lógica implementa um manipulador de eventos cancelável para o botão Fechar de uma janela:
public function onCloseCommand(event:MouseEvent):void{
var closingEvent:Event = new Event(Event.CLOSING,true,true);
dispatchEvent(closing);
if(!closingEvent.isDefaultPrevented()){
win.close();
}
}
O método dispatchEvent() retorna false se o método preventDefault() do evento é chamado por um ouvinte.
No entanto, ele também pode retornar false por outros motivos, portanto é melhor usar o método
isDefaultPrevented() explicitamente para testar se a alteração deve ser cancelada.
Maximização, minimização e restauração de uma janela
Para maximizar a janela, use o método maximize() da classe NativeWindow.
myWindow.maximize();
Para minimizar a janela, use o método minimize() de NativeWindow.
myWindow.minimize();
Para restaurar a janela (isto é, colocá-la novamente no tamanho em que estava antes de ser minimizada ou
maximizada), use o método restore() de NativeWindow.
myWindow.restore();
Nota: O comportamento resultante da maximização de uma janela do AIR é diferente do comportamento padrão do
Mac OS X. Em vez de alternar entre um tamanho “padrão” definido pelo aplicativo e o último tamanho definido pelo
usuário, as janelas do AIR alternam entre o último tamanho definido pelo aplicativo ou pelo usuário e a área útil total
da tela.
No sistema operacional Linux, diferentes gerenciadores de janela forçam regras diferentes com relação a configuração
do estado de exibição da janela:
• Em alguns gerenciadores de janela, não é possível maximizar as janelas dos utilitários.
• Se um tamanho máximo for definido para a janela, algumas janelas não permitirão a maximização. Alguns outros
gerenciadores de janela definem o estado de exibição como maximizado, mas não redimensionam a janela. Em
qualquer um dos casos, não é despachado nenhum evento de alteração do estado de exibição.
• Alguns gerenciadores de janela não cumprem as configurações maximizable ou minimizable de janela.
Exemplo: Minimização, maximização, restauração e fechamento de uma
janela
O seguinte exemplo do ActionScript para Flash cria quatro campos de texto clicáveis que acionam os métodos
minimize(), maximize(), restore() e close() de NativeWindow:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 76
Trabalhar com janelas nativas
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
public class MinimizeExample extends Sprite
{
public function MinimizeExample():void
{
var minTextBtn:TextField = new TextField();
minTextBtn.x = 10;
minTextBtn.y = 10;
minTextBtn.text = "Minimize";
minTextBtn.background = true;
minTextBtn.border = true;
minTextBtn.selectable = false;
addChild(minTextBtn);
minTextBtn.addEventListener(MouseEvent.CLICK, onMinimize);
var maxTextBtn:TextField = new TextField();
maxTextBtn.x = 120;
maxTextBtn.y = 10;
maxTextBtn.text = "Maximize";
maxTextBtn.background = true;
maxTextBtn.border = true;
maxTextBtn.selectable = false;
addChild(maxTextBtn);
maxTextBtn.addEventListener(MouseEvent.CLICK, onMaximize);
var restoreTextBtn:TextField = new TextField();
restoreTextBtn.x = 230;
restoreTextBtn.y = 10;
restoreTextBtn.text = "Restore";
restoreTextBtn.background = true;
restoreTextBtn.border = true;
restoreTextBtn.selectable = false;
addChild(restoreTextBtn);
restoreTextBtn.addEventListener(MouseEvent.CLICK, onRestore);
var closeTextBtn:TextField = new TextField();
closeTextBtn.x = 340;
closeTextBtn.y = 10;
closeTextBtn.text = "Close Window";
closeTextBtn.background = true;
closeTextBtn.border = true;
closeTextBtn.selectable = false;
addChild(closeTextBtn);
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 77
Trabalhar com janelas nativas
closeTextBtn.addEventListener(MouseEvent.CLICK, onCloseWindow);
}
function onMinimize(event:MouseEvent):void
{
this.stage.nativeWindow.minimize();
}
function onMaximize(event:MouseEvent):void
{
this.stage.nativeWindow.maximize();
}
function onRestore(event:MouseEvent):void
{
this.stage.nativeWindow.restore();
}
function onCloseWindow(event:MouseEvent):void
{
this.stage.nativeWindow.close();
}
}
}
Redimensionamento e movimentação de uma janela
Quando uma janela usa o cromo do sistema, o cromo oferece controles de arrastar que permitem redimensionar a
janela e movimentá-la na área de trabalho. Se uma janela não usa o cromo do sistema, adicione seus próprios controles
para que o usuário possa redimensionar e movimentar a janela.
Nota: Para redimensionar ou movimentar uma janela, primeiro você deve obter uma referência à ocorrência de
NativeWindow. Para mais informações sobre como obter uma referência à janela, consulte “Obter uma ocorrência de
NativeWindow” na página 72.
Redimensionamento de uma janela
Para permitir que um usuário redimensione uma janela de forma interativa, use o método
NativeWindowstartResize(). Quando esse método é chamado a partir de um evento mouseDown, a operação de
redimensionamento é orientada pelo mouse e executada quando o sistema operacional recebe um evento mouseUp.
Quando chama startResize(), você passa um argumento que especifica a borda ou o canto a partir do qual a janela
deve ser redimensionada.
Para definir o tamanho das janelas de forma programática, defina as propriedades width, height ou bounds da janela
nas dimensões desejadas. Quando você define os limites, o tamanho da janela e a posição podem ser alterados ao
mesmo tempo., No entanto, não há garantias da ordem de exibição das alterações. Alguns gerenciadores de janela do
Linux não permitem que janelas se estendam além dos limites da tela da área de trabalho. Nesses casos, o tamanho final
da janela pode ser limitado devido à ordem em que as propriedades são definidas, apesar de as alterações resultarem
em uma janela legal. Por exemplo, se você alterar a altura e a posição y de uma janela perto da parte inferior da tela, a
alteração na altura total pode não ocorrer quando for aplicada antes da alteração na posição y.
Nota: No Linux, as propriedades da janela são alteradas de forma assíncrona. Se você definir uma propriedade em uma
linha do programa e ler os valores na linha seguinte, o valor lido ainda refletirá a configuração antiga. Você pode usar os
eventos gerados pela janela para detectar quando a alteração é aplicada.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 78
Trabalhar com janelas nativas
O modo de dimensionamento do palco determina o comportamento do palco da janela e de seu conteúdo quando uma
janela é redimensionada. Lembre-se de que os modos de dimensionamento de palco devem ser usados em situações
em que o aplicativo não tem controle sobre o tamanho ou a proporção de seu espaço de exibição, como é o caso de um
navegador da Web. Em geral, os melhores resultados são obtidos quando você define a propriedade scaleMode do
palco como StageScaleMode.NO_SCALE. Para que o conteúdo da janela seja dimensionado, também é possível definir
os parâmetros do conteúdo scaleX e scaleY em resposta às alterações nos limites da janela.
Movimentação de uma janela
Para movimentar uma janela sem redimensioná-la, use o método startMove() de NativeWindow. Da mesma forma
que ocorre com o método startResize(), quando você chama o método startMove() a partir de um evento
mouseDown, o processo de movimentação é orientado pelo mouse e executado quando o sistema operacional recebe
um evento mouseUp.
Para obter mais informações sobre os métodos startResize() e startMove(), consulte a Referência dos
componentes e da linguagem do ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_br).
Exemplo: Redimensionamento e movimentação de janelas
O exemplo abaixo mostra como iniciar operações de redimensionamento e movimentação em uma janela:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.NativeWindowResize;
public class NativeWindowResizeExample extends Sprite
{
public function NativeWindowResizeExample():void
{
// Fills a background area.
this.graphics.beginFill(0xFFFFFF);
this.graphics.drawRect(0, 0, 400, 300);
this.graphics.endFill();
// Creates a square area where a mouse down will start the resize.
var resizeHandle:Sprite =
createSprite(0xCCCCCC, 20, this.width - 20, this.height - 20);
resizeHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartResize);
// Creates a square area where a mouse down will start the move.
var moveHandle:Sprite = createSprite(0xCCCCCC, 20, this.width - 20, 0);
moveHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartMove);
}
public function createSprite(color:int, size:int, x:int, y:int):Sprite
{
var s:Sprite = new Sprite();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 79
Trabalhar com janelas nativas
s.graphics.beginFill(color);
s.graphics.drawRect(0, 0, size, size);
s.graphics.endFill();
s.x = x;
s.y = y;
this.addChild(s);
return s;
}
public function onStartResize(event:MouseEvent):void
{
this.stage.nativeWindow.startResize(NativeWindowResize.BOTTOM_RIGHT);
}
public function onStartMove(event:MouseEvent):void
{
this.stage.nativeWindow.startMove();
}
}
}
Monitorando eventos de janela
Para monitorar os eventos despachados por uma janela, registre um ouvinte na ocorrência da janela. Por exemplo, para
monitorar o evento closing, registre um ouvinte na janela, da seguinte maneira:
myWindow.addEventListener(Event.CLOSING, onClosingEvent);
Quando um evento é despachado, a propriedade target faz referência à janela que o está enviando.
A maioria dos eventos de janela tem duas mensagens relacionadas. A primeira mensagem sinaliza que uma alteração
de janela é iminente (e pode ser cancelada), enquanto a segunda indica que a alteração foi executada. Por exemplo,
quando um usuário clica no botão Fechar de uma janela, a mensagem do evento closing é despachada. Se nenhum
ouvinte cancelar o evento, a janela será fechada e o evento close será despachado para qualquer ouvinte.
Normalmente, os eventos de aviso, como closing, só são despachados quando o cromo do sistema foi usado para
acionar um evento. Se você chamar o método de janela close(), por exemplo, o evento closing não será despachado
automaticamente (será despachado apenas o evento close). No entanto, você pode construir um objeto de evento
closing e despachá-lo usando o método de janela dispatchEvent().
Os eventos de janela que despacham um objeto Event são:
Evento
Descrição
activate
Despachado quando a janela recebe foco.
deactivate
Despachado quando a janela perde foco.
closing
Despachado quando a janela está prestes a fechar. Este evento só ocorre automaticamente quando o botão
Fechar do cromo do sistema é pressionado ou, no Mac OS X, quando é chamado o comando Quit.
close
Despachado quando a janela foi fechada.
Os eventos de janela que despacham um objeto NativeWindowBoundsEvent são:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 80
Trabalhar com janelas nativas
Evento
Descrição
moving
Despachado imediatamente depois que o canto superior esquerdo da janela muda de posição, seja como
resultado da movimentação, do redimensionamento ou da alteração do estado de exibição da janela.
move
Despachado depois que a posição do canto superior esquerdo é alterada.
resizing
Despachado imediatamente antes de a largura ou a altura da janela ser alterada, seja como resultado do
redimensionamento ou de uma alteração no estado de exibição.
resize
Despachado após uma alteração no tamanho da janela.
Para eventos NativeWindowBoundsEvent, você pode usar as propriedades beforeBounds e afterBounds para
determinar os limites da janela antes e depois da alteração iminente ou concluída.
Os eventos de janela que despacham um objeto NativeWindowDisplayStateEvent são:
Evento
Descrição
displayStateChanging
Despachado imediatamente antes de uma alteração no estado de exibição da janela.
displayStateChange
Despachado depois que o estado de exibição da janela foi alterado.
Para eventos NativeWindowDisplayStateEvent , você pode usar as propriedades beforeDisplayState e
afterDisplayState para determinar o estado de exibição da janela antes e depois da alteração iminente ou
concluída.
Em alguns gerenciadores de janela do Linux, um evento de alteração do estado de exibição não é despachado quando
uma janela com uma configuração de tamanho máximo é maximizada. (A janela é definida como estado de exibição
máximo, mas não é redimensionada).
Exibição de janelas em tela cheia
Definir a propriedade displayState da classe Stage como StageDisplayState.FULL_SCREEN_INTERACTIVE
coloca a janela em modo de tela cheia, que permite entrada pelo teclado. (No conteúdo SWF em execução em um
navegador, a entrada pelo teclado não é permitida). Para sair do modo de tela cheia, o usuário deve pressionar a tecla
Escape.
Nota: Alguns gerenciadores de janela do Linux não alterarão as dimensões de janela para encher a tela, caso um
tamanho máximo seja definido para a janela (mas removerão o cromo do sistema da janela).
O seguinte exemplo do ActionScript para Flash simula um terminal de texto simples em tela cheia:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 81
Trabalhar com janelas nativas
import
import
import
import
flash.display.Sprite;
flash.display.StageDisplayState;
flash.text.TextField;
flash.text.TextFormat;
public class FullScreenTerminalExample extends Sprite
{
public function FullScreenTerminalExample():void
{
var terminal:TextField = new TextField();
terminal.multiline = true;
terminal.wordWrap = true;
terminal.selectable = true;
terminal.background = true;
terminal.backgroundColor = 0x00333333;
this.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
addChild(terminal);
terminal.width = 550;
terminal.height = 400;
terminal.text = "Welcome to the dumb terminal application. Press the ESC key to
exit.\n_";
var tf:TextFormat = new TextFormat();
tf.font = "Courier New";
tf.color = 0x00CCFF00;
tf.size = 12;
terminal.setTextFormat(tf);
terminal.setSelection(terminal.text.length - 1, terminal.text.length);
}
}
82
Capítulo 11: Telas
Use a classe Screen do Adobe® AIR® para acessar informações sobre as telas de exibição da área de trabalho anexadas
a um computador.
Informações on-line adicionais sobre telas
Você pode encontrar mais informações sobre a classe Screen e sobre o trabalho com telas nestas fontes:
Início rápido (Adobe AIR Developer Connection)
• Medida da área de trabalho virtual
Referência de linguagem
• Screen
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (pesquisar por 'AIR screens')
Noções básicas de tela
A API de tela contém uma classe única, Screen, que oferece membros estáticos para obter informações de tela do
sistema e membros de ocorrência para descrever uma tela específica.
Um sistema de computador pode ter vários monitores ou exibições anexadas, que podem corresponder a diversas telas
da área de trabalho organizadas em um espaço virtual. A classe Screen do AIR fornece informações sobre as telas, sua
organização relativa e seu espaço utilizável. Se mais de um monitor for mapeado para a mesma tela, haverá somente
uma tela. Se o tamanho da tela é maior que a área de exibição do monitor, não há como determinar que parte da tela
está visível atualmente
A tela representa uma área de exibição independente da área de trabalho. As telas são descritas como retângulos na
área de trabalho virtual. O canto superior esquerdo da tela designado como exibição principal é a origem do sistema
de coordenadas da área de trabalho virtual. Todos os valores usados para descrever a tela são fornecidos em pixels.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 83
Telas
Limites da tela
Tela virtual
Limites utilizáveis
Nessa organização de telas, há duas telas na área de trabalho virtual. As coordenadas do canto superior esquerdo da tela principal (nº1) são
sempre (0,0). Se a organização da tela for alterada para designar a tela nº 2 como tela principal, as coordenadas da tela nº 1 se tornarão
negativas. Barras de menu, barras de tarefa e encaixes são excluídos ao reportar limites utilizáveis de uma tela.
Para obter informações detalhadas sobre classe, métodos, propriedades e eventos da API da tela, consulte a Referência
dos componentes e da linguagem do ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_br).
Enumeração de telas
Você pode enumerar as telas da área de trabalho virtual com os seguintes métodos e propriedades de tela:
Método ou Propriedade
Descrição
Screen.screens
Oferece uma matriz de objetos Screen que descreve as telas disponíveis. Observe que a ordem da matriz
não é significativa.
Screen.mainScreen
Oferece o objeto Screen da tela principal. No Mac OS X, a tela principal é a tela que exibe a barra de
menu. No Windows, a tela principal é a tela primária designada pelo sistema.
Screen.getScreensForRectangle() Oferece uma matriz de objetos Screen que descreve as telas intersectadas pelo retângulo determinado.
O retângulo passado para este método está em coordenadas de pixel na área de trabalho virtual. Se
nenhuma tela intersectar o retângulo, a matriz ficará vazia. Você pode usar esse método para descobrir
em que telas a janela é exibida.
Você não deve salvar os valores retornados pelos métodos e propriedades da classe Screen. O usuário ou sistema
operacional pode alterar as telas disponíveis e a respectiva disposição a qualquer momento.
O exemplo a seguir usa a API da tela para mover uma janela entre várias telas em resposta ao pressionamento das teclas
de seta. Para mover a janela para a próxima tela, o exemplo obtém a matriz screens e a classifica verticalmente ou
horizontalmente (dependendo da tecla de seta pressionada). Em seguida, o código passa pela matriz classificada,
comparando cada tela com as coordenadas da tela atual. Para identificar a tela atual da janela, o exemplo chama
Screen.getScreensForRectangle(), passando nos limites da janela.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 84
Telas
package {
import
import
import
import
import
import
flash.display.Sprite;
flash.display.Screen;
flash.events.KeyboardEvent;
flash.ui.Keyboard;
flash.display.StageAlign;
flash.display.StageScaleMode;
public class ScreenExample extends Sprite
{
public function ScreenExample()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKey);
}
private function onKey(event:KeyboardEvent):void{
if(Screen.screens.length > 1){
switch(event.keyCode){
case Keyboard.LEFT :
moveLeft();
break;
case Keyboard.RIGHT :
moveRight();
break;
case Keyboard.UP :
moveUp();
break;
case Keyboard.DOWN :
moveDown();
break;
}
}
}
private function moveLeft():void{
var currentScreen = getCurrentScreen();
var left:Array = Screen.screens;
left.sort(sortHorizontal);
for(var i:int = 0; i < left.length - 1; i++){
if(left[i].bounds.left < stage.nativeWindow.bounds.left){
stage.nativeWindow.x +=
left[i].bounds.left - currentScreen.bounds.left;
stage.nativeWindow.y += left[i].bounds.top - currentScreen.bounds.top;
}
}
}
private function moveRight():void{
var currentScreen:Screen = getCurrentScreen();
var left:Array = Screen.screens;
left.sort(sortHorizontal);
for(var i:int = left.length - 1; i > 0; i--){
if(left[i].bounds.left > stage.nativeWindow.bounds.left){
stage.nativeWindow.x +=
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 85
Telas
left[i].bounds.left - currentScreen.bounds.left;
stage.nativeWindow.y += left[i].bounds.top - currentScreen.bounds.top;
}
}
}
private function moveUp():void{
var currentScreen:Screen = getCurrentScreen();
var top:Array = Screen.screens;
top.sort(sortVertical);
for(var i:int = 0; i < top.length - 1; i++){
if(top[i].bounds.top < stage.nativeWindow.bounds.top){
stage.nativeWindow.x += top[i].bounds.left - currentScreen.bounds.left;
stage.nativeWindow.y += top[i].bounds.top - currentScreen.bounds.top;
break;
}
}
}
private function moveDown():void{
var currentScreen:Screen = getCurrentScreen();
var top:Array = Screen.screens;
top.sort(sortVertical);
for(var i:int = top.length - 1; i > 0; i--){
if(top[i].bounds.top > stage.nativeWindow.bounds.top){
stage.nativeWindow.x += top[i].bounds.left - currentScreen.bounds.left;
stage.nativeWindow.y += top[i].bounds.top - currentScreen.bounds.top;
break;
}
}
}
private function sortHorizontal(a:Screen,b:Screen):int{
if (a.bounds.left > b.bounds.left){
return 1;
} else if (a.bounds.left < b.bounds.left){
return -1;
} else {return 0;}
}
private function sortVertical(a:Screen,b:Screen):int{
if (a.bounds.top > b.bounds.top){
return 1;
} else if (a.bounds.top < b.bounds.top){
return -1;
} else {return 0;}
}
private function getCurrentScreen():Screen{
var current:Screen;
var screens:Array = Screen.getScreensForRectangle(stage.nativeWindow.bounds);
(screens.length > 0) ? current = screens[0] : current = Screen.mainScreen;
return current;
}
}
}
86
Capítulo 12: Trabalho com menus nativos
Use as classes na API de menu nativo para definir aplicativo, janela, contexto e menus pop-up.
Informações online adicionais sobre menus nativos
Você pode encontrar mais informações sobre a API de menu nativo e trabalho com menus nativos nestas fontes:
Início rápido (Adobe AIR Developer Connection)
• Adição de menus nativos a um aplicativo AIR
Referência de linguagem
• NativeMenu
• NativeMenuItem
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (pesquisar por 'AIR menus')
Noções básicas do menu AIR
As classes de menu nativo permitem acessar os recursos do menu nativo do sistema operacional em que o aplicativo
está sendo executado. Objetos NativeMenu podem ser usados em menus de aplicativo (disponíveis no Mac OS X),
menus de janela (disponíveis no Windows e no Linux), menus de contexto e menus pop-up.
Classes de menu AIR
As classes de menu Adobe® AIR™ incluem:
Pacote
Classes
flash.display
•
NativeMenu
•
NativeMenuItem
•
ContextMenu
•
ContextMenuItem
•
Evento
•
ContextMenuEvent
flash.ui
flash.events
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 87
Trabalho com menus nativos
Variedades de menu
O AIR oferece suporte aos seguintes tipos de menus:
Menus de aplicativo O menu de aplicativo é um menu global aplicável ao aplicativo inteiro. Há suporte para menus
de aplicativo no Mac OS X, mas não no Windows nem no Linux. No Mac OS X , o sistema operacional cria
automaticamente o menu de aplicativo. Você pode usar a API de menu AIR para adicionar itens e submenus aos
menus padrão. Você pode adicionar ouvintes para tratar os comandos de menu existentes. Ou você pode remover itens
existentes.
Menus de janela O menu de janela está associado a uma única janela e é exibido abaixo da barra de título. Os menus
podem ser adicionados a uma janela, criando um objeto NativeMenu e atribuindo-o à propriedade menu do objeto
NativeWindow. Há suporte para menus de janela nos sistemas operacionais Windows e Linux, mas não no Mac OS X.
Menus de janela nativos só podem ser usados em janelas com o cromo do sistema.
Menus de contexto Os menus de contexto são exibidos em resposta ao clique com o botão direito do mouse ou ao
clique com a tecla Command pressionada em um objeto interativo no conteúdo SWF ou um elemento de documento
no conteúdo HTML. Você pode criar um menu de contexto usando a classe NativeMenu ou ContextMenu. No
conteúdo HTML, você pode usar as APIs de kit da Web HTML e JavaScript para adicionar menus de contexto a
elementos HTML.
Menus de ícone de bandeja do sistema e de encaixe Esses menus de ícone são semelhantes aos menus de contexto e
são atribuídos a um ícone de aplicativo no encaixe do Mac OS X ou nas áreas de notificação do Windows ou do Linux,
na barra de tarefas. Menus de ícone da bandeja do sistema e de encaixe usam a classe NativeMenu. No Mac OS X, os
itens no menu são adicionados acima dos itens padrão do sistema operacional. Não há menu padrão no Windows nem
no Linux.
Menus pop-up O menu pop-up AIR é semelhante ao menu de contexto, mas não está necessariamente associado a um
objeto de aplicativo ou componente específico. Os menus pop-up podem ser exibidos em qualquer lugar na janela,
chamando o método display() de qualquer objeto NativeMenu.
Menus personalizados Menus nativos são inteiramente desenhados pelo sistema operacional e, como tal, estão
presentes fora dos modelos de processamento Flash e HTML. Você tem liberdade para criar seus próprios menus não
nativos usando MXML, ActionScript ou JavaScript. As classes de menu AIR não oferecem nenhuma facilidade para
controlar os desenhos de menus nativos.
Menus padrão
Os menus padrão a seguir são fornecidos pelo sistema operacional ou uma classe incorporada do AIR:
• Menu de aplicativo no Mac OS X
• Menu de ícone de encaixe no Mac OS X
• Menu de contexto de textos e imagens selecionados em conteúdo HTML
• Menu de contexto de texto selecionado no objeto TextField (ou em um objeto que estende o TextField)
Estrutura de menu
Os menus são de natureza hierárquica. Os objetos NativeMenu contêm objetos-filho NativeMenuItem. Os objetos
NativeMenuItem que representam submenus, por sua vez, podem conter objetos NativeMenu. O objeto de menu de
nível superior ou raiz na estrutura representa a barra de menu de menus de aplicativo e janela. (Menus de contexto,
ícone e pop-up não têm uma barra de menu).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 88
Trabalho com menus nativos
O diagrama a seguir ilustra a estrutura de um menu típico. O menu raiz representa a barra de menu e contém dois itens
de menu que fazem referência ao submenu File e ao submenu Edit. O submenu Arquivo nessa estrutura contém dois
itens de comando e um item que faz referência ao submenu Open Recent Menu, que contém, ele mesmo, três itens. O
submenu Edit contém três comandos e um separador.
NativeMenu
Menu de raiz
NativeMenuItem
NativeMenu
“Arquivo”
Menu Arquivo
NativeMenuItem
“Novo”
NativeMenuItem
“Salvar”
NativeMenuItem
“Abrir recente”
NativeMenu
NativeMenuItem
NativeMenu
Menu Abrir recente
NativeMenuItem
“GreatGatsby.pdf”
NativeMenuItem
“WarAndPeace.pdf”
NativeMenuItem
“Iliad.pdf”
“Editar”
Menu Editar
NativeMenuItem
“Copiar”
NativeMenuItem
“Colar”
NativeMenuItem
Separador
NativeMenuItem
“Preferências”
Definir um submenu requer um objeto NativeMenu e um objeto NativeMenuItem. O objeto NativeMenuItem define
o rótulo exibido no menu pai e permite ao usuário abrir o submenu. O objeto NativeMenu funciona como um
recipiente de itens no submenu. O objeto NativeMenuItem se refere ao objeto NativeMenu pela propriedade submenu
NativeMenuItem.
Para exibir um exemplo de código que cria esse menu, consulte “Exemplo: Menu de janela e aplicativo” na página 98.
Eventos menu
Os objetos NativeMenu e NativeMenuItem despacham os eventos displaying e select:
Displaying: Imediatamente antes de o menu ser exibido, o menu e os respectivos itens de menu despacham o evento
displaying para qualquer ouvinte registrado. O evento displaying dá a oportunidade de atualizar o conteúdo de
menu ou a aparência do item antes de ele ser mostrado ao usuário. Por exemplo, no ouvinte do evento displaying
do menu “Open Recent”, você pode alterar os itens de menu para que reflitam a lista atual de documentos exibidos
recentemente.
A propriedade target do objeto event é sempre o menu que está para ser exibido. O currentTarget é o objeto em
que o ouvinte está registrado: o próprio menu ou um de seus itens.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 89
Trabalho com menus nativos
Nota: O evento displaying também é despachado sempre que o estado do menu ou de um de seus itens for acessado.
Select: Quando um item de comando é escolhido pelo usuário, o item despacha um evento select para qualquer
ouvinte registrado. Itens de submenu e separadores não podem ser selecionados, portanto, nunca despacham um
evento select.
O evento select surge em bolha de um item de menu para o menu que o contém, em cima do menu raiz. Você pode
ouvir eventos select diretamente em um item e pode ouvir mais acima na estrutura de menu. Quando você ouvir o
evento select em um menu, poderá identificar o item selecionado usando a propriedade target do evento.
Conforme o evento surge em bolha pela hierarquia de menu, a propriedade currentTarget do objeto event identifica
o objeto de menu atual.
Nota: Os objetos ContextMenu e ContextMenuItem despacham eventos menuItemSelect e menuSelect, bem como
eventos select e displaying.
Equivalentes de tecla de comandos de menu
Você pode atribuir um equivalente de tecla (às vezes chamado de acelerador) em um comando de menu. O item do
menu despacha o evento select para qualquer ouvinte registrado quando a tecla ou combinação de teclas é
pressionada. O menu que contém o item deve ser parte do menu do aplicativo ou a janela ativa do comando que deve
ser chamado.
Os equivalentes de tecla têm duas partes, uma seqüência representando a tecla primária e uma matriz de teclas do
modificador, que também devem ser pressionadas. Para atribuir a tecla primária, defina a propriedade
keyEquivalent do item de menu para a seqüência de caractere único dessa tecla. Se você usar uma letra maiúscula, a
tecla Shift é adicionada à matriz do modificador automaticamente.
No Mac OS X, o modificador padrão é a tecla Command (Keyboard.COMMAND). No Windows e no Linux, é a tecla
Control (Keyboard.CONTROL). Essas teclas padrão são adicionadas automaticamente à matriz do modificador. Para
atribuir teclas do modificador diferentes, atribua uma nova matriz contendo os códigos de tecla desejados à
propriedade keyEquivalentModifiers. A matriz padrão é sobrescrita. Se você usar os modificadores padrão ou
atribuir a sua própria matriz de modificador, a tecla Shift será adicionada, se a seqüência atribuída à propriedade
keyEquivalent for uma letra maiúscula. As constantes dos códigos de tecla para usar nas teclas do modificador são
definidas na classe Keyboard.
A seqüência de equivalente de tecla atribuída é exibida automaticamente ao lado no nome do item de menu. O formato
depende do sistema operacional do usuário e das preferências do sistema.
Nota: Se você atribuir o valor Keyboard.COMMAND a uma matriz de modificador de tecla no sistema operacional do
Windows, nenhum equivalente de tecla será exibido no menu. No entanto, a tecla Control deve ser usada para ativar o
comando de menu.
O exemplo a seguir atribui Ctrl+Shift+G como equivalente de tecla de um item de menu:
var item:NativeMenuItem = new NativeMenuItem("Ungroup");
item.keyEquivalent = "G";
Este exemplo atribui Ctrl+Shift+G como equivalente de tecla, definindo diretamente a matriz do modificador:
var item:NativeMenuItem = new NativeMenuItem("Ungroup");
item.keyEquivalent = "G";
item.keyEquivalentModifiers = [Keyboard.CONTROL];
Nota: Os equivalentes de tecla só são ativados em menus de aplicativo e de janela. Se você adicionar um equivalente de
tecla a um menu de contexto ou de pop-up, o equivalente de tecla é exibido no rótulo do menu, mas o comando de menu
associado nunca será chamado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 90
Trabalho com menus nativos
Mnemônicos
Os mnemônicos são parte da interface de teclado do sistema operacional em menus. Linux, Mac OS X e Windows
permitem a usuários abrir menus e selecionar comandos com o teclado, mas há diferenças sutis.
No Mac OS X, o usuário digita a primeira ou as duas primeiras letras do menu ou comando e, em seguida, pressiona
a tecla retornar. A propriedade mnemonicIndex é ignorada.
No Windows, apenas uma única letra é significativa. Por padrão, a letra significativa é o primeiro caractere no rótulo,
mas se você atribuir um mnemônico ao item de menu, o caractere significativo se torna a letra designada. Se dois itens
em um menu têm o mesmo caractere significativo (quer um mnemônico tenha ou não sido atribuído), a interação de
teclado do usuário com o menu muda um pouco. Em vez de pressionar uma única letra para selecionar o menu ou
comando, o usuário deve pressionar a letra quantas vezes for necessário para realçar o item desejado e, em seguida,
pressionar a tecla Enter para concluir a seleção. Para manter um comportamento consistente, você deve atribuir um
mnemônico exclusivo a cada item no menu, em menus de janela.
No Linux, nenhum mnemônico padrão é fornecido. Você deve especificar um valor para a propriedade
mnemonicIndex de um item de menu para fornecer um mnemônico.
Especifique o caractere mnemônico como índice na seqüência de rótulo. O índice do primeiro caractere em um rótulo
é 0. Portanto, para usar "r" como o mnemônico de um item de menu rotulado, "Format", você deve definir a
propriedade mnemonicIndex igual a 2.
var item:NativeMenuItem = new NativeMenuItem("Format");
item.mnemonicIndex = 2;
Estado do item de menu
Os itens de menu têm duas propriedades de estados, marcados e ativados:
marcado Defina como true para exibir uma marca de seleção ao lado do rótulo de item.
var item:NativeMenuItem = new NativeMenuItem("Format");
item.checked = true;
ativado Alterne o valor entre true e false para controlar se o comando está ativado. Itens desativados ficam
visualmente “esmaecidos” e não despacham eventos select.
var item:NativeMenuItem = new NativeMenuItem("Format");
item.enabled = false;
Anexar objeto a um item de menu
A propriedade data da classe NativeMenuItem permite fazer referência a um objeto arbitrário em cada item. Por
exemplo, no menu "Open Recent", você pode atribuir o objeto File de cada documento a cada item do menu.
var file:File = File.applicationStorageDirectory.resolvePath("GreatGatsby.pdf")
var menuItem:NativeMenuItem = docMenu.addItem(new NativeMenuItem(file.name));
menuItem.data = file;
Criação de menus nativos
Este tópico descreve como criar os vários tipos de menu nativos suportados pelo AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 91
Trabalho com menus nativos
Criação de objeto do menu raiz
Para criar um objeto NativeMenu para servir como raiz do menu, use o construtor NativeMenu:
var root:NativeMenu = new NativeMenu();
Em menus de aplicativo e janela, o menu raiz representa a barra de menu e deve conter apenas itens que abram
submenus. Menus de contexto e pop-up não têm barra de menu, portanto, o menu raiz pode conter comandos e linhas
separadoras, bem como submenus.
Depois que o menu é criado, você pode adicionar itens de menu. Os itens aparecem no menu na ordem em que são
adicionados, a menos que você os adicione em um índice específico, usando o método addItemAt() de um objeto de
menu.
Atribua o menu como aplicativo, janela, ícone ou menu de contexto ou exiba-o como menu pop-up, conforme
mostrado nas seções a seguir:
Configuração do menu de aplicativo
NativeApplication.nativeApplication.menu = root;
Nota: O Mac OS X define um menu contendo itens padrão para cada aplicativo. Atribuir um novo objeto NativeMenu
à propriedade menu do objeto NativeApplication substitui o menu padrão. Você também pode usar o menu padrão, em
vez de substitui-lo.
Configuração de menu de janela
nativeWindowObject.menu = root;
Configuração de menu de contexto em um objeto interativo
interactiveObject.contextMenu = root;
Configuração de menu de ícone de encaixe
DockIcon(NativeApplication.nativeApplication.icon).menu = root;
Nota: O Mac OS X define um menu padrão para o ícone de encaixe do aplicativo. Ao atribuir um novo NativeMenu à
propriedade de menu do objeto DockIcon, os itens nesse menu são exibidos acima dos itens padrão. Você não pode
remover, acessar nem modificar os itens de menu padrão.
Configuração de menu de ícone da bandeja do sistema.
SystemTrayIcon(NativeApplication.nativeApplication.icon).menu = root;
Exibição de menu como pop-up
root.display(stage, x, y);
Criação de submenu
Para criar um submenu, você adiciona o objeto NativeMenuItem ao menu pai e, em seguida, atribui o objeto
NativeMenu, definindo o submenu para a propriedade submenu do item. O AIR oferece duas maneiras de criar itens
de submenu e respectivos objetos de menu associados:
Você pode criar um item de menu e respectivo objeto de menu relacionado em uma etapa, com o método
addSubmenu():
var editMenuItem:NativeMenuItem = root.addSubmenu(new NativeMenu(), "Edit");
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 92
Trabalho com menus nativos
Você também pode criar o item de menu e atribuir separadamente o objeto de menu à respectiva propriedade
submenu:
var editMenuItem:NativeMenuItem = root.addItem("Edit", false);
editMenuItem.submenu = new NativeMenu();
Criação de comando de menu
Para criar um comando de menu, adicione o objeto NativeMenuItem a um menu e adicione um ouvinte de evento que
faça referência à função que implementa o comando de menu:
var copy:NativeMenuItem = new NativeMenuItem("Copy", false);
copy.addEventListener(Event.SELECT, onCopyCommand);
editMenu.addItem(copy);
Você pode ouvir o evento select no próprio item de comando (conforme mostrado no exemplo) ou pode ouvir o
evento select em um objeto de menu pai.
Nota: Os itens de menu que representam submenus e linhas separadoras não despacham eventos select e, portanto,
não podem ser usados como comandos.
Criação de linha separadora de menu
Para criar uma linha separadora, crie um NativeMenuItem, definindo o parâmetro isSeparator como true no
construtor. Em seguida, adicione o item separador ao menu no local correto:
var separatorA:NativeMenuItem = new NativeMenuItem("A", true);
editMenu.addItem(separatorA);
O rótulo especificado para o separador, se houver, não é exibido.
Sobre menus de contexto
No conteúdo SWF, qualquer objeto herdado de InteractiveObject pode ser determinado um menu de contexto
atribuindo um objeto de menu à respectiva propriedade contextMenu. O objeto de menu atribuído ao contextMenu
pode ser do tipo NativeMenu ou do tipo ContextMenu.
Você pode ouvir eventos do menu nativo ou de menus contextuais ao usar as classes ContextMenu e
ContextMenuItem; as duas são despachadas. Um benefício fornecido pelas propriedades do objeto
ContextMenuEvent é que contextMenuOwner identifica o objeto ao qual o menu está associado e mouseTarget
identifica o objeto que foi clicado para abrir o menu. Essas informações não estão disponíveis do objeto
NativeMenuEvent.
O exemplo a seguir cria um Sprite e adiciona um menu de contexto de edição simples:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 93
Trabalho com menus nativos
var sprite:Sprite = new Sprite();
sprite.contextMenu = createContextMenu()
private function createContextMenu():ContextMenu{
var editContextMenu:ContextMenu = new ContextMenu();
var cutItem:ContextMenuItem = new ContextMenuItem("Cut")
cutItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doCutCommand);
editContextMenu.customItems.push(cutItem);
var copyItem:ContextMenuItem = new ContextMenuItem("Copy")
copyItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doCopyCommand);
editContextMenu.customItems.push(copyItem);
var pasteItem:ContextMenuItem = new ContextMenuItem("Paste")
pasteItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, doPasteCommand);
editContextMenu.customItems.push(pasteItem);
return editContextMenu
}
private function doCutCommand(event:ContextMenuEvent):void{trace("cut");}
private function doCopyCommand(event:ContextMenuEvent):void{trace("copy");}
private function doPasteCommand(event:ContextMenuEvent):void{trace("paste");}
Nota: Ao contrário do conteúdo SWF exibido em um ambiente de navegador, os menus de contexto no AIR não têm
nenhum comando incorporado.
Sobre menus de contexto em HTML
No conteúdo HTML, o evento contextmenu pode ser usado para exibir um menu de contexto. Por padrão, o menu
de contexto é exibido automaticamente quando o usuário chama o evento de menu de contexto no texto selecionado
(clicando com o botão direito do mouse ou clicando com a tecla Command pressionada no texto). Para evitar que o
menu padrão seja aberto, ouça o evento contextmenu e chame o método preventDefault() do objeto de evento:
function showContextMenu(event){
event.preventDefault();
}
Em seguida, você pode exibir um menu de contexto personalizado usando técnicas DHTML ou exibindo o menu de
contexto nativo do AIR. O exemplo a seguir exibe um menu de contexto nativo, chamando o método display() do
menu em resposta ao evento contextmenu de HTML:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 94
Trabalho com menus nativos
<html>
<head>
<script src="AIRAliases.js" language="JavaScript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function showContextMenu(event){
event.preventDefault();
contextMenu.display(window.nativeWindow.stage, event.clientX, event.clientY);
}
function createContextMenu(){
var menu = new air.NativeMenu();
var command = menu.addItem(new air.NativeMenuItem("Custom command"));
command.addEventListener(air.Event.SELECT, onCommand);
return menu;
}
function onCommand(){
air.trace("Context command invoked.");
}
var contextMenu = createContextMenu();
</script>
</head>
<body>
<p oncontextmenu="showContextMenu(event)" style="-khtml-user-select:auto;">Custom context
menu.</p>
</body>
</html>
Definição de forma clara de menus nativos
Codificar as propriedades de um menu e de itens de menu pode ser um pouco entediante. No entanto, como os menus
têm uma estrutura hierárquica natural, ela é objetiva para gravar uma função que cria um menu usando a definição
formatada em XML.
A classe a seguir estende o NativeMenu, tomando um objeto XML em seu construtor; para fazer o seguinte apenas:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 95
Trabalho com menus nativos
package
{
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.events.Event;
public class DeclarativeMenu extends NativeMenu
{
public function DeclarativeMenu(XMLMenuDefinition:XML):void
{
super();
addChildrenToMenu(this, XMLMenuDefinition.children());
}
private function addChildrenToMenu(menu:NativeMenu,
children:XMLList):NativeMenuItem
{
var menuItem:NativeMenuItem;
var submenu:NativeMenu;
for each (var child:XML in children)
{
if (String(child.@label).length > 0)
{
menuItem = new NativeMenuItem(child.@label);
menuItem.name = child.name();
}
else
{
menuItem = new NativeMenuItem(child.name());
menuItem.name = child.name();
}
menu.addItem(menuItem);
if (child.children().length() > 0)
{
menuItem.submenu = new NativeMenu();
addChildrenToMenu(menuItem.submenu,child.children());
}
}
return menuItem;
}
} //End class
} //End package
Para criar um menu com essa classe, passe uma definição de menu XML como a seguinte:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 96
Trabalho com menus nativos
var menuDefinition:XML =
<root>
<FileMenu label='File'>
<NewMenu label='New'>
<NewTextFile label='Text file'/>
<NewFolder label='Folder'/>
<NewProject label='Project'/>
</NewMenu>
<OpenCommand label='Open'/>
<SaveCommand label='Save'/>
</FileMenu>
<EditMenu label='Edit'>
<CutCommand label='Cut'/>
<CopyCommand label='Copy'/>
<PasteCommand label='Paste'/>
</EditMenu>
<FoodItems label='Food Items'>
<Jellyfish/>
<Tripe/>
<Gizzard/>
</FoodItems>
</root>;
var test:DeclarativeMenu = new DeclarativeMenu(menuDefinition);
Para ouvir eventos de menu, você pode ouvir em nível de menu raiz e usar a propriedade event.target.name para
detectar que comando foi selecionado. Você também pode pesquisar itens no menu por nome e adicionar ouvintes
individuais de evento.
Exibição de menus pop-up
Você pode exibir qualquer objeto NativeMenu em um tempo e local arbitrários acima de uma janela, chamando o
método display() do menu. O método requer uma referência ao palco, portanto, apenas o conteúdo na caixa de
proteção do aplicativo pode exibir o menu como pop-up.
O método a seguir exibe o menu definido por um objeto NativeMenu chamado popupMenu em resposta a um clique
do mouse:
private function onMouseClick(event:MouseEvent):void {
popupMenu.display(event.target.stage, event.stageX, event.stageY);
}
Nota: O menu não precisa ser exibido em resposta direta ao evento. Qualquer método pode chamar a função display().
Tratamento de itens de menu
O menu despacha eventos quando o usuário o seleciona ou quando seleciona um item de menu.
Resumo de eventos de classes de menu
Adicione ouvintes de eventos a menus ou itens individuais para tratar eventos de menu.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 97
Trabalho com menus nativos
Objeto
Eventos despachados
NativeMenu
NativeMenuEvent.DISPLAYING
NativeMenuEvent.SELECT (propagado a partir de itens filhos e submenus)
NativeMenuItem
NativeMenuEvent.SELECT
NativeMenuEvent.DISPLAYING (propagado a partir do menu pai)
ContextMenu
ContextMenuEvent.MENU_SELECT
ContextMenuItem
ContextMenuEvent.MENU_ITEM_SELECT
NativeMenu.SELECT
Eventos de menu Select
Para manipular o clique de um item de menu, adicione um ouvinte de evento do evento select ao objeto
NativeMenuItem:
var menuCommandX:NativeMenuItem = new NativeMenuItem("Command X");
menuCommand.addEventListener(Event.SELECT, doCommandX)
Como os eventos select surgem em bolhas para os menus que os contêm, você também pode ouvir eventos select em
um menu pai. Ao ouvir no nível de menu, é possível usar a propriedade target do objeto evento para determinar que
comando de menu foi selecionado. O exemplo a seguir rastreia o rótulo do comando selecionado:
var colorMenuItem:NativeMenuItem = new NativeMenuItem("Choose a color");
var colorMenu:NativeMenu = new NativeMenu();
colorMenuItem.submenu = colorMenu;
var red:NativeMenuItem = new NativeMenuItem("Red");
var green:NativeMenuItem = new NativeMenuItem("Green");
var blue:NativeMenuItem = new NativeMenuItem("Blue");
colorMenu.addItem(red);
colorMenu.addItem(green);
colorMenu.addItem(blue);
if(NativeApplication.supportsMenu){
NativeApplication.nativeApplication.menu.addItem(colorMenuItem);
NativeApplication.nativeApplication.menu.addEventListener(Event.SELECT, colorChoice);
} else if (NativeWindow.supportsMenu){
var windowMenu:NativeMenu = new NativeMenu();
this.stage.nativeWindow.menu = windowMenu;
windowMenu.addItem(colorMenuItem);
windowMenu.addEventListener(Event.SELECT, colorChoice);
}
function colorChoice(event:Event):void {
var menuItem:NativeMenuItem = event.target as NativeMenuItem;
trace(menuItem.label + " has been selected");
}
Se você estiver usando a classe ContextMenuItem, poderá ouvir o evento select ou o evento menuItemSelect. O
evento menuItemSelect oferece informações adicionais sobre o objeto pertencente ao menu de contexto, mas não
surge em bolhas para os menus que os contêm.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 98
Trabalho com menus nativos
Exibição de eventos de menu
Para manipular a abertura de um menu, você pode adicionar um ouvinte ao evento displaying, que é despachado
antes de o menu ser exibido. Você pode usar o evento displaying para atualizar o menu, por exemplo, adicionando ou
removendo itens ou atualizando os estados ativados ou marcados de itens individuais.
Exemplo: Menu de janela e aplicativo
O exemplo a seguir cria o menu mostrado em “Estrutura de menu” na página 87.
O menu foi projetado para funcionar no Windows, em que apenas os menus de janela têm suporte, e no Mac OS X,
em que apenas menus de aplicativo têm suporte. Para fazer distinção, o construtor de classe MenuExample verifica as
propriedades supportsMenu estáticas das classes NativeWindow e NativeApplication. Se
NativeWindow.supportsMenu for true, o construtor cria um objeto NativeMenu para a janela e, em seguida, cria e
adiciona os submenus File e Edit. Se NativeApplication.supportsMenu for true, o construtor cria e adiciona os
menus File e Edit ao menu existente fornecido pelo sistema operacional Mac OS X.
O exemplo também ilustra o tratamento de evento de menu. O evento select é manipulado no nível de item e
também no nível de menu. Cada menu na cadeia do menu que contém o item selecionado para o menu raiz responde
ao evento select. O evento displaying é usado com o menu “Open Recent”. Logo antes de o menu ser aberto, os
itens do menu são atualizados da matriz Documentos recentes (que na realidade não é alterada neste exemplo).
Embora não demonstrado nesse exemplo, você também pode ouvir eventos displaying em itens individuais.
package {
import
import
import
import
import
import
import
flash.display.NativeMenu;
flash.display.NativeMenuItem;
flash.display.NativeWindow;
flash.display.Sprite;
flash.events.Event;
flash.filesystem.File;
flash.desktop.NativeApplication;
public class MenuExample extends Sprite
{
private var recentDocuments:Array =
new Array(new File("app-storage:/GreatGatsby.pdf"),
new File("app-storage:/WarAndPeace.pdf"),
new File("app-storage:/Iliad.pdf"));
public function MenuExample()
{
var fileMenu:NativeMenuItem;
var editMenu:NativeMenuItem;
if (NativeWindow.supportsMenu){
stage.nativeWindow.menu = new NativeMenu();
stage.nativeWindow.menu.addEventListener(Event.SELECT, selectCommandMenu);
fileMenu = stage.nativeWindow.menu.addItem(new NativeMenuItem("File"));
fileMenu.submenu = createFileMenu();
editMenu = stage.nativeWindow.menu.addItem(new NativeMenuItem("Edit"));
editMenu.submenu = createEditMenu();
}
if (NativeApplication.supportsMenu){
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 99
Trabalho com menus nativos
NativeApplication.nativeApplication.menu.addEventListener(Event.SELECT,
selectCommandMenu);
fileMenu = NativeApplication.nativeApplication.menu.addItem(new
NativeMenuItem("File"));
fileMenu.submenu = createFileMenu();
editMenu = NativeApplication.nativeApplication.menu.addItem(new
NativeMenuItem("Edit"));
editMenu.submenu = createEditMenu();
}
}
public function createFileMenu():NativeMenu {
var fileMenu:NativeMenu = new NativeMenu();
fileMenu.addEventListener(Event.SELECT, selectCommandMenu);
var newCommand:NativeMenuItem = fileMenu.addItem(new NativeMenuItem("New"));
newCommand.addEventListener(Event.SELECT, selectCommand);
var saveCommand:NativeMenuItem = fileMenu.addItem(new NativeMenuItem("Save"));
saveCommand.addEventListener(Event.SELECT, selectCommand);
var openRecentMenu:NativeMenuItem =
fileMenu.addItem(new NativeMenuItem("Open Recent"));
openRecentMenu.submenu = new NativeMenu();
openRecentMenu.submenu.addEventListener(Event.DISPLAYING,
updateRecentDocumentMenu);
openRecentMenu.submenu.addEventListener(Event.SELECT, selectCommandMenu);
return fileMenu;
}
public function createEditMenu():NativeMenu {
var editMenu:NativeMenu = new NativeMenu();
editMenu.addEventListener(Event.SELECT, selectCommandMenu);
var copyCommand:NativeMenuItem = editMenu.addItem(new NativeMenuItem("Copy"));
copyCommand.addEventListener(Event.SELECT, selectCommand);
copyCommand.keyEquivalent = "c";
var pasteCommand:NativeMenuItem =
editMenu.addItem(new NativeMenuItem("Paste"));
pasteCommand.addEventListener(Event.SELECT, selectCommand);
pasteCommand.keyEquivalent = "v";
editMenu.addItem(new NativeMenuItem("", true));
var preferencesCommand:NativeMenuItem =
editMenu.addItem(new NativeMenuItem("Preferences"));
preferencesCommand.addEventListener(Event.SELECT, selectCommand);
return editMenu;
}
private function updateRecentDocumentMenu(event:Event):void {
trace("Updating recent document menu.");
var docMenu:NativeMenu = NativeMenu(event.target);
for each (var item:NativeMenuItem in docMenu.items) {
docMenu.removeItem(item);
}
for each (var file:File in recentDocuments) {
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 100
Trabalho com menus nativos
var menuItem:NativeMenuItem =
docMenu.addItem(new NativeMenuItem(file.name));
menuItem.data = file;
menuItem.addEventListener(Event.SELECT, selectRecentDocument);
}
}
private function selectRecentDocument(event:Event):void {
trace("Selected recent document: " + event.target.data.name);
}
private function selectCommand(event:Event):void {
trace("Selected command: " + event.target.label);
}
private function selectCommandMenu(event:Event):void {
if (event.currentTarget.parent != null) {
var menuItem:NativeMenuItem =
findItemForMenu(NativeMenu(event.currentTarget));
if (menuItem != null) {
trace("Select event for \"" +
event.target.label +
"\" command handled by menu: " +
menuItem.label);
}
} else {
trace("Select event for \"" +
event.target.label +
"\" command handled by root menu.");
}
}
private function findItemForMenu(menu:NativeMenu):NativeMenuItem {
for each (var item:NativeMenuItem in menu.parent.items) {
if (item != null) {
if (item.submenu == menu) {
return item;
}
}
}
return null;
}
}
}
101
Capítulo 13: Ícones na barra de tarefas
Muitos sistemas operacionais têm uma barra de tarefas, como o encaixe do Mac OS X, que pode conter um ícone
representando um aplicativo. O Adobe® AIR® oferece uma interface que permite interagir com o ícone na barra de
tarefas através da propriedade NativeApplication.nativeApplication.icon.
Informações on-line adicionais sobre ícones da barra de
tarefas
Você encontra mais informações sobre como trabalhar com barras de tarefas nestas fontes:
Início rápido (Adobe AIR Developer Connection)
• Uso dos ícones da bandeja do sistema e do encaixe
Referência de linguagem
• DockIcon
• SystemTrayIcon
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (procure 'ícones na barra de tarefas do AIR')
Sobre ícones na barra de tarefas
O AIR cria o objeto NativeApplication.nativeApplication.icon automaticamente. O tipo de objeto é DockIcon
ou SystemTrayIcon, dependendo do sistema operacional. É possível determinar qual destas subclasses InteractiveIcon
é suportada pelo AIR no sistema operacional atual usando as propriedades NativeApplication.supportsDockIcon
e NativeApplication.supportsSystemTrayIcon. A classe base InteractiveIcon oferece as propriedades width,
height e bitmaps, que você pode usar para alterar a imagem utilizada para o ícone. No entanto, acessar propriedades
específicas de DockIcon ou SystemTrayIcon no sistema operacional incorreto gera um erro de execução.
Para definir ou alterar a imagem usada para um ícone, crie uma matriz que contenha uma ou mais imagens e a atribua
à propriedade NativeApplication.nativeApplication.icon.bitmaps. O tamanho dos ícones na barra de tarefas
pode ser diferente nos diferentes sistemas operacionais. Para evitar a degradação da imagem devido ao
dimensionamento, é possível adicionar vários tamanhos de imagem à matriz bitmaps. Se você fornecer mais de uma
imagem, o AIR selecionará o tamanho mais próximo do tamanho de exibição atual do ícone na barra de tarefas e só o
dimensionará se for necessário. O exemplo abaixo define a imagem para um ícone da barra de tarefas usando duas
imagens:
NativeApplication.nativeApplication.icon.bitmaps =
[bmp16x16.bitmapData, bmp128x128.bitmapData];
Para alterar a imagem de um ícone, atribua uma matriz que contenha a(s) nova(s) imagem(ns) à propriedade bitmaps.
Você pode animar o ícone alterando a imagem em resposta a um evento enterFrame ou timer.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 102
Ícones na barra de tarefas
Para remover o ícone da área de notificação no Windows e no Linux ou para restaurar a aparência do ícone padrão no
Mac OS X, defina bitmaps como uma matriz vazia:
NativeApplication.nativeApplication.icon.bitmaps = [];
Ícones de encaixe
O AIR suporta ícones de encaixe quando NativeApplication.supportsDockIcon é true. A propriedade
NativeApplication.nativeApplication.icon representa o ícone do aplicativo no encaixe (não um ícone de
encaixe na janela).
Nota: O AIR não permite alterar ícones de janela no encaixe do Mac OS X. Além disso, as alterações feitas no ícone de
encaixe de aplicativo só são aplicadas enquanto um aplicativo está em execução — o ícone reassume a aparência normal
quando o aplicativo é encerrado.
Menus com ícone no encaixe
É possível adicionar comandos ao menu de encaixe padrão criando um objeto NativeMenu que contenha os comandos
e atribuindo o objeto à propriedade NativeApplication.nativeApplication.icon.menu. Os itens do menu são
exibidos acima dos itens padrão do menu com ícones no encaixe.
Fazer o encaixe pular
É possível fazer com que o ícone no encaixe pule chamando o método
NativeApplication.nativeApplication.icon.bounce(). Se você definir o parâmetro bounce() priority
como informativo, o ícone pulará uma vez. Se você definir o parâmetro como crítico, o ícone pulará até o usuário ativar
o aplicativo. As constantes do parâmetro priority são definidas na classe NotificationType.
Nota: O ícone não pula se o aplicativo já está ativo.
Eventos de ícones no encaixe
Quando o usuário clica em um ícone no encaixe, o objeto NativeApplication despacha um evento invoke. Se o
aplicativo não estiver em execução, será iniciado pelo sistema. Caso contrário, o evento invoke será entregue à
ocorrência do aplicativo em execução.
Ícones da bandeja do sistema
O AIR oferece suporte a ícones de bandeja do sistema quando NativeApplication.supportsSystemTrayIcon for
true, o que no momento só ocorre no Windows e na maioria das distribuições do Linux. No Windows e no Linux, os
ícones de bandeja do sistema são exibidos na área de notificação da barra de tarefas. Nenhum ícone é exibido por
padrão. Para mostrar um ícone, atribua uma matriz contendo objetos BitmapData à propriedade bitmaps do ícone.
Para alterar a imagem do ícone, atribua uma matriz que contenha as novas imagens a bitmaps. Para remover o ícone,
defina bitmaps como null.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 103
Ícones na barra de tarefas
Menus de ícones da bandeja do sistema
É possível adicionar um menu ao ícone da bandeja do sistema criando-se um objeto NativeMenu e o atribuindo à
propriedade NativeApplication.nativeApplication.icon.menu (o sistema operacional não oferece um menu
padrão). Acesse o menu do ícone da bandeja do sistema clicando no ícone com o botão direito do mouse.
Dicas de ferramentas sobre ícones da bandeja do sistema
Adicione uma dica de ferramenta a um ícone definindo a propriedade tooltip:
NativeApplication.nativeApplication.icon.tooltip = "Application name";
Eventos de ícone da bandeja do sistema
O objeto SystemTrayIcon referenciado pela propriedade NativeApplication.nativeApplication.icon despacha um
ScreenMouseEvent para eventos click, mouseDown, mouseUp, rightClick, rightMouseDown e rightMouseUp. Você
pode usar esses eventos, junto com um menu de ícone, para que os usuários possam interagir com seu aplicativo
quando ele não tiver janelas visíveis.
Exemplo: Criação de um aplicativo sem janelas
O exemplo a seguir cria um aplicativo do AIR que tem um ícone na bandeja do sistema, mas nenhuma janela visível.
O ícone na bandeja do sistema tem um menu com um único comando, que permite sair do aplicativo.
package
{
import
import
import
import
import
import
import
import
import
import
flash.display.Loader;
flash.display.NativeMenu;
flash.display.NativeMenuItem;
flash.display.NativeWindow;
flash.display.Sprite;
flash.desktop.DockIcon;
flash.desktop.SystemTrayIcon;
flash.events.Event;
flash.net.URLRequest;
flash.desktop.NativeApplication;
public class SysTrayApp extends Sprite
{
public function SysTrayApp():void{
NativeApplication.nativeApplication.autoExit = false;
var icon:Loader = new Loader();
var iconMenu:NativeMenu = new NativeMenu();
var exitCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem("Exit"));
exitCommand.addEventListener(Event.SELECT, function(event:Event):void {
NativeApplication.nativeApplication.icon.bitmaps = [];
NativeApplication.nativeApplication.exit();
});
if (NativeApplication.supportsSystemTrayIcon) {
NativeApplication.nativeApplication.autoExit = false;
icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);
icon.load(new URLRequest("icons/AIRApp_16.png"));
var systray:SystemTrayIcon =
NativeApplication.nativeApplication.icon as SystemTrayIcon;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 104
Ícones na barra de tarefas
systray.tooltip = "AIR application";
systray.menu = iconMenu;
}
if (NativeApplication.supportsDockIcon){
icon.contentLoaderInfo.addEventListener(Event.COMPLETE,iconLoadComplete);
icon.load(new URLRequest("icons/AIRApp_128.png"));
var dock:DockIcon = NativeApplication.nativeApplication.icon as DockIcon;
dock.menu = iconMenu;
}
stage.nativeWindow.close();
}
private function iconLoadComplete(event:Event):void
{
NativeApplication.nativeApplication.icon.bitmaps =
[event.target.content.bitmapData];
}
}
}
Nota: O exemplo pressupõe que existem arquivos de imagem chamados AIRApp_16.png e AIRApp_128.png em um
subdiretório icons do aplicativo. (Arquivos de ícone de exemplo, que você pode copiar para a pasta do seu projeto, são
fornecidos no SDK do AIR.)
Ícones e botões da barra de tarefas do Windows
As representações em forma de ícone de janelas geralmente são exibidas na área de janela de uma barra de tarefas ou
de um encaixe, para que os usuários tenham fácil acesso a janelas em segundo plano ou minimizadas. O encaixe do
Mac OS X exibe um ícone do seu aplicativo e um ícone de cada janela minimizada. As barras de tarefas do Microsoft
Windows e do Linux exibem um botão que contém o ícone do programa e o título de cada janela de tipo normal do
seu aplicativo.
Realce do botão da janela na barra de ferramentas
Quando uma janela está em segundo plano, você pode notificar o usuário de que ocorreu um evento de interesse
relacionado à janela. No Mac OS X, você pode notificar o usuário fazendo o ícone de encaixe do aplicativo pular
(conforme descrito em “Fazer o encaixe pular” na página 102). No Windows e no Linux, você pode realçar o botão da
barra de tarefas da janela chamando o método notifyUser() da ocorrência NativeWindow. O parâmetro type
passado para o método determina a urgência da notificação:
•
NotificationType.CRITICAL: o ícone da janela fica piscando até o usuário colocar a janela no primeiro plano.
•
NotificationType.INFORMATIONAL: o ícone da janela fica realçado pela troca de cores.
Nota: No Linux, só há suporte para o tipo informativo de notificação. Passar um dos valores de tipo para a função
notifyUser() criará o mesmo efeito.
A seguinte instrução realça o botão da barra de tarefas de uma janela:
stage.nativeWindow.notifyUser(NotificationType.CRITICAL);
Chamar o método NativeWindow.notifyUser() em um sistema operacional que não dá suporte a notificações
de janela não produz qualquer efeito. Use a propriedade NativeWindow.supportsNotification para determinar
se a notificação de janela é suportada.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 105
Ícones na barra de tarefas
Criação de janelas sem botões ou ícones na barra de tarefas
No sistema operacional Windows, as janelas criadas com os tipos utility ou lightweight não aparecem na barra de
tarefas. As janelas invisíveis também não.
Como a janela inicial é necessariamente do tipo normal, para criar um aplicativo sem nenhuma janela aparecendo na
barra de tarefas, você deve fechar a janela inicial ou deixá-la invisível. Para fechar todas as janelas do seu aplicativo sem
encerrá-lo, defina a propriedade autoExit do objeto NativeApplication como false antes de fechar a última janela.
Para impedir que a janela inicial se torne visível, adicione <visible>false</visible> ao elemento
<initalWindow> do arquivo de descrição do aplicativo (e não defina a propriedade visible como true ou chame o
método activate() da janela).
Nas novas janelas abertas pelo aplicativo, defina a propriedade type do objeto NativeWindowInitOption passado para
o construtor de janela como NativeWindowType.UTILITY ou NativeWindowType.LIGHTWEIGHT.
No Mac OS X, as janelas minimizadas são exibidas na barra de tarefas do encaixe. Para impedir que o ícone
minimizado seja exibido, oculte a janela em vez de minimizá-la. O exemplo a seguir monitora um evento de alteração
nativeWindowDisplayState e o cancela se a janela está sendo minimizada. O manipulador define a propriedade
visible da janela como false:
private function preventMinimize(event:NativeWindowDisplayStateEvent):void{
if(event.afterDisplayState == NativeWindowDisplayState.MINIMIZED){
event.preventDefault();
event.target.visible = false;
}
}
Se uma janela está minimizada no encaixe do Mac OS X quando você define a propriedade visible como false, o
ícone no encaixe não é removido. Um usuário ainda poderá clicar no ícone para fazer com que a janela reapareça.
106
Capítulo 14: Trabalho com o sistema de
arquivos
Você usa as classes fornecidas pela API de sistema de arquivos do Adobe® AIR™ para acessar o sistema de arquivos do
computador host. Usando essas classes, você pode acessar e gerenciar diretórios e arquivos, criar diretórios e arquivos,
gravar dados em arquivos e assim por diante.
Informações adicionais on-line sobre a API de Arquivo
AIR
Você pode encontrar mais informações sobre o uso de classes API de arquivo nas seguintes fontes:
Início rápido (Adobe AIR Developer Connection)
• Criação de editor de arquivo de texto
Referência de linguagem
• Arquivo
• FileStream
• FileMode
Artigos e amostras do Adobe Developer Connection
• Conexão de desenvolvedores do Adobe AIR para Flash (pesquisar por 'AIR filesystem')
Noções básicas do arquivo AIR
O Adobe AIR oferece classes que você pode usar para acessar, criar e gerenciar arquivos e pastas. Essas classes, contidas
no pacote flash.filesystem, são usadas da seguinte forma:
Classes File
Descrição
Arquivo
O objeto File representa um caminho para um arquivo ou um diretório. Você usa o objeto File para criar
um indicador para um arquivo ou pasta, iniciando a interação com o arquivo ou a pasta.
FileMode
A classe FileMode define constantes de string usadas no parâmetro fileMode dos métodos open() e
openAsync() da classe FileStream. O parâmetro fileMode desses métodos determina os recursos
disponíveis para o objeto FileStream depois que o arquivo é aberto, o que inclui gravação, leitura,
acréscimo e atualização.
FileStream
O objeto FileStream é usado para abrir arquivos de leitura e gravação. Depois que você criar o objeto File
apontando para um arquivo novo ou um já existente, passe esse ponteiro para o objeto FileStream, de
modo a poder abrir e, em seguida, manipular dados no arquivo.
Alguns métodos na classe File têm versões síncronas e assíncronas:
•
File.copyTo() e File.copyToAsync()
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 107
Trabalho com o sistema de arquivos
•
File.deleteDirectory() e File.deleteDirectoryAsync()
•
File.deleteFile() e File.deleteFileAsync()
•
File.getDirectoryListing() e File.getDirectoryListingAsync()
•
File.moveTo() e File.moveToAsync()
•
File.moveToTrash() e File.moveToTrashAsync()
Além disso, as operações FileStream funcionam síncrona ou assincronamente, dependendo de como o objeto
FileStream abre o arquivo: chamando o método open() ou o método openAsync().
As versões assíncronas permitem iniciar processos que são executados em segundo plano e despacham eventos quando
concluídos (ou quando ocorrerem eventos de erro). Outro código pode ser executado enquanto esses processos de
segundo plano assíncronos estão ocorrendo. Nas versões assíncronas das operações, você deve configurar funções do
ouvinte de eventos, usando o método addEventListener() do objeto File ou FileStream que chama a função.
As versões síncronas permitem escrever códigos mais simples que não se baseiam na configuração de ouvintes de
evento. No entanto, como nenhum outro código pode ser executado enquanto o método sincrônico está sendo
executado, processos importantes, como processamento e animação de objeto de exibição, podem ser pausados.
Trabalho com objetos File
O objeto File é um ponteiro para um arquivo ou diretório no sistema de arquivos.
A classe File estende a classe FileReference. A classe FileReference, disponível no Adobe® Flash® Player, bem como no
AIR, representa um ponteiro para um arquivo, mas a classe File adiciona propriedades e métodos que não são expostos
no Flash Player (em um SWF em execução no navegador), devido a considerações sobre segurança.
Sobre a classe File
Você pode usar a classe File para o seguinte:
• Obter o caminho para diretórios especiais, incluindo o diretório do usuário, o diretório de documentos do usuário,
o diretório do qual o aplicativo foi iniciado e o diretório de aplicativo.
• Cópia de arquivos e diretórios
• Movimentação de arquivos e diretórios.
• Exclusão de arquivos e diretórios (ou movimentação para a lixeira)
• Lista de arquivos e diretórios contidos em um diretório
• Criação de arquivos e pastas temporários
Depois que o objeto File aponta para um caminho de arquivo, você pode usá-lo para ler e gravar dados de arquivo,
usando a classe FileStream.
O objeto File pode apontar para o caminho de um arquivo ou diretório que ainda não existe. Você pode usar esse
objeto File na criação de arquivos ou diretórios.
Caminhos de objetos File
Cada objeto File tem duas propriedades que definem cada uma o caminho do objeto:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 108
Trabalho com o sistema de arquivos
Propriedade
Descrição
nativePath
Especifica o caminho específico de plataforma para um arquivo. Por exemplo, no Windows o
caminho pode ser "c:\Sample directory\test.txt", enquanto no Mac OS pode ser "/Sample
directory/test.txt". A propriedade nativePath usa o caractere de barra invertida (\) como o
caractere separador de diretório no Windows e o caractere de barra (/) no Mac OS e no Linux.
url
Ela pode usar o esquema de URL de arquivo para apontar para um arquivo. Por exemplo, no Windows
o caminho pode ser "file:///c:/Sample%20directory/teste.txt", enquanto no Mac OS pode ser
"file:///Sample%20directory/teste.txt". O tempo de execução inclui outros esquemas especiais de
URL além de file e são descritos em “Esquemas URL com suporte” na página 112
A classe File inclui propriedades de indicação de diretórios padrão no Mac OS, no Windows e no Linux.
Como apontar um objeto File para um diretório
Há maneiras diferentes de configurar o objeto File para apontar para um diretório.
Apontar para o diretório inicial do usuário
Você pode apontar o objeto File para o diretório inicial do usuário. No Windows, o diretório inicial é o pai do diretório
"My Documents" (por exemplo, "C:\Documents and Settings\userName\My Documents"). No Mac OS, é o diretório
Users/userName. No Linux, é o diretório /home/userName. O código a seguir configura o objeto File para apontar para
o subdiretório AIR Test do diretório inicial:
var file:File = File.userDirectory.resolvePath("AIR Test");
Apontar para o diretório documentos do usuário
Você pode apontar o objeto File para o diretório documentos do usuário. No Windows, o local padrão é o diretório
"My Documents" (por exemplo, "C:\Documents and Settings\userName\My Documents"). No Mac OS, o local padrão
é o diretório Users/userName/Documents. No Linux, o local padrão é o diretório /home/userName/Documents. O
código a seguir configura o objeto File para apontar para o subdiretório AIR Test do diretório documentos:
var file:File = File.documentsDirectory.resolvePath("AIR Test");
Apontar para o diretório da área de trabalho
Você pode apontar o objeto File para a área de trabalho. O código a seguir configura o objeto File para apontar para o
subdiretório AIR Test da área de trabalho:
var file:File = File.desktopDirectory.resolvePath("AIR Test");
Apontar para o diretório de armazenamento do aplicativo
Você pode apontar o objeto File para o diretório de armazenamento do aplicativo. Para cada aplicativo AIR, há um
caminho associado exclusivo que define o diretório de armazenamento do aplicativo. Esse diretório é exclusivo de cada
aplicativo e usuário. Pode ser conveniente usar esse diretório para armazenar dados específicos do usuário e do
aplicativo (como dados do usuário ou arquivos de preferências). Por exemplo, o código a seguir aponta o objeto File
para um arquivo de preferências, prefs.xml, contido no diretório de armazenamento do aplicativo:
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("prefs.xml";
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 109
Trabalho com o sistema de arquivos
A localização do diretório de armazenamento do aplicativo baseia-se no nome do usuário, na ID do aplicativo e na ID
do editor:
• No Mac OS, em:
/Users/user name/Library/Preferences/applicationID.publisherID/Local Store/
Por exemplo:
/Users/babbage/Library/Preferences/com.example.TestApp.02D88EEED35F84C264A183921344EEA353
A629FD.1/Local Store
• No Windows: no diretório Documents and Settings, em:
user name/Application Data/applicationID.publisherID/Local Store/
Por exemplo:
C:\Documents and Settings\babbage\Application
Data\com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Local Store
• No Linux - In:
/home/user name/.appdata/applicationID.publisherID/Local Store/
Por exemplo:
/home/babbage/.appdata/com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1/Loc
al Store
A URL (e a propriedade url) de um objeto File criado com File.applicationStorageDirectory usa o esquema de
URL app-storage (consulte “Esquemas URL com suporte” na página 112), como a seguir:
var dir:File = File.applicationStorageDirectory;
dir = dir.resolvePath("preferences");
trace(dir.url); // app-storage:/preferences
Apontar para o diretório do aplicativo
Você pode apontar o objeto File para o diretório em que o aplicativo foi instalado, conhecido como o diretório do
aplicativo. Você pode fazer referência a esse diretório, usando a propriedade File.applicationDirectory. Você
pode usar esse diretório para examinar o arquivo do descritor do aplicativo ou outros recursos instalados com o
aplicativo. Por exemplo, o código a seguir aponta o objeto File para um diretório chamado images no diretório do
aplicativo:
var dir:File = File.applicationDirectory;
dir = dir.resolvePath("images");
A URL (e propriedade url) de um objeto File criado com File.applicationDirectory usa o esquema de URL app
(consulte “Esquemas URL com suporte” na página 112), como a seguir:
var dir:File = File.applicationDirectory;
dir = dir.resolvePath("images");
trace(dir.url); // app:/images
Apontar para a raiz filesystem
O método File.getRootDirectories() lista todos os volumes de raiz, como C: e volumes montados em um
computador Windows. No Mac OS e no Linux, esse método sempre retorna o diretório raiz exclusivo do computador
(o diretório "/").
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 110
Trabalho com o sistema de arquivos
Como apontar para um diretório explícito
Você pode apontar o objeto File para um diretório explícito, definindo a propriedade nativePath do objeto File,
conforme o seguinte exemplo (no Windows):
var file:File = new File();
file.nativePath = "C:\\AIR Test\";
Navegação para caminhos relativos
Você pode usar o método resolvePath() para obter um caminho relativo a outro caminho determinado. Por
exemplo, o código a seguir configura o objeto File para apontar para o subdiretório "AIR Test" do diretório inicial do
usuário:
var file:File = File.userDirectory;
file = file.resolvePath("AIR Test");
Você também pode usar a propriedade url do objeto File para apontar para um diretório com base em uma seqüência
de URL, conforme segue:
var urlStr:String = "file:///C:/AIR Test/";
var file:File = new File()
file.url = urlStr;
Para obter mais informações, consulte “Modificação de caminhos do File” na página 112.
Permissão para que o usuário navegue para selecionar um diretório
A classe File inclui o método browseForDirectory(), que apresenta uma caixa de diálogo de sistema na qual o
usuário pode selecionar um diretório para atribuir ao objeto. O método browseForDirectory() é assíncrono. Ele
despacha um evento select se o usuário selecionar um diretório e clicar no botão Abrir, ou despacha um evento
cancel se o usuário clicar no botão Cancelar.
Por exemplo, o código a seguir permite que o usuário selecione um diretório e fornece o caminho do diretório na
seleção:
var file:File = new File();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForDirectory("Select a directory");
function dirSelected(e:Event):void {
trace(file.nativePath);
}
Como apontar para o diretório do qual o aplicativo foi chamado
Você pode obter a localização do diretório do qual o aplicativo foi chamado, marcando a propriedade
currentDirectory do objeto InvokeEvent despachada quando o aplicativo é chamado. Para obter detalhes,
consulte“Captura de argumentos de linha de comando” na página 292.
Como apontar um objeto File para um arquivo
Há maneiras diferentes de definir o arquivo para o qual o objeto File aponta.
Apontar para um caminho de arquivo explícito
Você pode usar o método resolvePath() para obter um caminho relativo a outro caminho determinado. Por
exemplo, o código a seguir define que o objeto File aponte para o arquivo log.txt no diretório de armazenamento do
aplicativo:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 111
Trabalho com o sistema de arquivos
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("log.txt");
Você pode usar a propriedade url do objeto File para apontá-lo para um arquivo ou diretório com base em uma
seqüência de URL, conforme segue:
var urlStr:String = "file:///C:/AIR Test/test.txt";
var file:File = new File()
file.url = urlStr;
Você também pode passar a URL para a função de construtor File(), como no seguinte:
var urlStr:String = "file:///C:/AIR Test/test.txt";
var file:File = new File(urlStr);
A propriedade url sempre retorna a versão codificada de URI da URL (por exemplo, espaços em branco são
substituídos por "%20):
file.url = "file:///c:/AIR Test";
trace(file.url); // file:///c:/AIR%20Test
Você também pode usar a propriedade nativePath do objeto File para definir um caminho explícito. Por exemplo, o
código a seguir, quando executado em um computador com o Windows, define um objeto File para o arquivo test.txt
no subdiretório AIR Test da unidade C:
var file:File = new File();
file.nativePath = "C:/AIR Test/test.txt";
Você também pode passar esse caminho para a função de construtor File(), como no seguinte:
var file:File = new File("C:/AIR Test/test.txt");
No Windows, você pode usar o caractere barra (/) ou barra invertida (\) como o delimitador de caminho da
propriedade nativePath. No Mac OS e no Linux, use o caractere barra (/) como o delimitador de caminho para o
nativePath:
var file:File = new File(/Users/dijkstra/AIR Test/test.txt");
Para obter mais informações, consulte “Modificação de caminhos do File” na página 112.
Enumeração de arquivos em um diretório
Você pode usar o método getDirectoryListing() do objeto File para obter uma matriz de objetos File apontando
para arquivos e subdiretórios no nível raiz de um diretório. Para obter mais informações, consulte “Enumeração de
diretórios” na página 117.
Permissão para que o usuário navegue para selecionar um arquivo
A classe File inclui os seguintes métodos que apresentam uma caixa de diálogo de sistema na qual o usuário pode
selecionar um arquivo para atribuir ao objeto:
•
browseForOpen()
•
browseForSave()
•
browseForOpenMultiple()
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 112
Trabalho com o sistema de arquivos
Cada um desses métodos é assíncrono. Os métodos browseForOpen() e browseForSave() despacham o evento
select quando o usuário seleciona um arquivo (ou caminho de destino, no caso de browseForSave()). Com os métodos
browseForOpen() e browseForSave(), na seleção, o objeto File de destino aponta para os arquivos selecionados. O
método browseForOpenMultiple() despacha um evento selectMultiple quando o usuário seleciona arquivos. O
evento selectMultiple é do tipo FileListEvent, que tem a propriedade files, que é uma matriz de objetos File
(apontando para os arquivos selecionados).
Por exemplo, o código a seguir apresenta para o usuário a caixa de diálogo "Abrir", na qual é possível selecionar um
arquivo:
var fileToOpen:File = File.documentsDirectory;
selectTextFile(fileToOpen);
function selectTextFile(root:File):void
{
var txtFilter:FileFilter = new FileFilter("Text", "*.as;*.css;*.html;*.txt;*.xml");
root.browseForOpen("Open", [txtFilter]);
root.addEventListener(Event.SELECT, fileSelected);
}
function fileSelected(event:Event):void
{
trace(fileToOpen.nativePath);
}
Se o aplicativo tiver outra caixa de diálogo de navegação aberta quando você chamar o método de navegação, o tempo
de execução emitirá uma exceção Erro.
Modificação de caminhos do File
Você também pode modificar o caminho de um objeto File existente, chamando o método resolvePath() ou
modificando a propriedade nativePath ou url do objeto, conforme nos exemplos a seguir (no Windows):
var file1:File = File.documentsDirectory;
file1 = file1.resolvePath("AIR Test");
trace(file1.nativePath); // C:\Documents and Settings\userName\My Documents\AIR Test
var file2:File = File.documentsDirectory;
file2 = file2.resolvePath("..");
trace(file2.nativePath); // C:\Documents and Settings\userName
var file3:File = File.documentsDirectory;
file3.nativePath += "/subdirectory";
trace(file3.nativePath); // C:\Documents and Settings\userName\My Documents\subdirectory
var file4:File = new File();
file4.url = "file:///c:/AIR Test/test.txt";
trace(file4.nativePath); // C:\AIR Test\test.txt
Ao usar a propriedade nativePath, você usa o caractere de barra (/) ou barra invertida (\) como o caractere separador
de diretório no Windows; no Mac OS e no Linux, você usa o caractere de barra (/). No Windows, lembre-se de digitar
o caractere de barra invertida duas vezes em uma literal de string.
Esquemas URL com suporte
Você pode usar qualquer um dos seguintes esquemas URL na definição da propriedade url de um objeto File:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 113
Trabalho com o sistema de arquivos
esquema URL
Descrição
file
Use para especificar um caminho relativo à raiz do sistema de arquivos. Por exemplo:
file:///c:/AIR Test/test.txt
A URL padrão especifica se a URL de arquivo usa a forma file://<host>/<path>. Como um caso
especial, <host> pode ser a string vazia, que é interpretada como "a máquina a partir da qual a URL está
sendo interpretada." Por essa razão, as URLs de arquivo normalmente têm três barras (///).
app
Use para especificar um caminho relativo ao diretório raiz do aplicativo instalado (o diretório que contém
o arquivo application.xml do aplicativo instalado). Por exemplo, o caminho a seguir aponta para um
subdiretório de imagens do diretório do aplicativo instalado:
app:/images
app-storage
Use para especificar um caminho relativo ao diretório de armazenamento do aplicativo. Para cada
aplicativo instalado, o AIR define um diretório exclusivo de armazenamento do aplicativo, que é um local
útil para armazenar dados específicos desse aplicativo. Por exemplo, o caminho a seguir aponta para o
arquivo prefs.xml em um subdiretório de configurações do diretório de armazenamento do aplicativo:
app-storage:/settings/prefs.xml
Localização do caminho relativo entre dois arquivos
Você pode usar o método getRelativePath() para localizar o caminho relativo entre dois arquivos:
var file1:File = File.documentsDirectory.resolvePath("AIR Test");
var file2:File = File.documentsDirectory
file2 = file2.resolvePath("AIR Test/bob/test.txt");
trace(file1.getRelativePath(file2)); // bob/test.txt
O segundo parâmetro do método getRelativePath(), o parâmetro useDotDot, permite que a sintaxe .... seja
retornada nos resultados, para indicar diretórios pai:
var file1:File = File.documentsDirectory;
file1 = file1.resolvePath("AIR Test");
var file2:File = File.documentsDirectory;
file2 = file2.resolvePath("AIR Test/bob/test.txt");
var file3:File = File.documentsDirectory;
file3 = file3.resolvePath("AIR Test/susan/test.txt");
trace(file2.getRelativePath(file1, true)); // ../..
trace(file3.getRelativePath(file2, true)); // ../../bob/test.txt
Obtenção de versões canônicas de nomes de arquivo
No Windows e no Mac OS, os nomes e caminhos de arquivo não fazem distinção entre letras maiúsculas e minúsculas.
No exemplo a seguir, dois objetos File apontam para o mesmo arquivo:
File.documentsDirectory.resolvePath("test.txt");
File.documentsDirectory.resolvePath("TeSt.TxT");
No entanto, nomes de documentos e de diretórios incluem o uso de maiúsculas e minúsculas. Por exemplo, o seguinte
assume que há uma pasta com nome AIR Test no diretório de documentos, como nos exemplos a seguir:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 114
Trabalho com o sistema de arquivos
var file:File = File.documentsDirectory.resolvePath("AIR test");
trace(file.nativePath); // ... AIR test
file.canonicalize();
trace(file.nativePath); // ... AIR Test
O método canonicalize() converte o objeto nativePath para usar maiúsculas e minúsculas corretas para o nome
de arquivo ou de diretório. Em sistemas de arquivo que fazem distinção entre maiúsculas e minúsculas (como Linux),
quando vários arquivos possuem nomes cuja distinção é somente a letra maiúscula ou minúscula, o método
canonicalize() ajusta o caminho para que corresponda ao primeiro arquivo encontrado (em uma ordem
determinada pelo sistema de arquivos)
Você também pode usar o método canonicalize() para converter nomes de arquivos pequenos (nomes "8,3") em
nomes de arquivos longos do Windows, como nos exemplos seguintes:
var path:File = new File();
path.nativePath = "C:\\AIR~1";
path.canonicalize();
trace(path.nativePath); // C:\AIR Test
Trabalho com pacotes e links simbólicos
Vários sistemas operacionais oferecem suporte a arquivos de pacote e arquivos de link simbólico:
Pacotes – No Mac OS, os diretórios podem ser designados como pacotes e mostrados no Finder do Mac OS como um
arquivo único, em vez de um diretório.
Links simbólicos — O Mac OS, o Linux e o Windows Vista oferecem suporte a links simbólicos. Os links simbólicos
permitem que um arquivo aponte para outro arquivo ou diretório no disco. Embora semelhantes, os links simbólicos
não são o mesmo que alias. O alias é sempre reportado como arquivo (em vez de diretório), e ler ou gravar em um alias
ou atalho nunca afeta o diretório ou arquivo original para o qual ele aponta. Por outro lado, o link simbólico se
comporta exatamente como o arquivo ou diretório para o qual aponta. Ele pode ser reportado como um arquivo ou
diretório, e ler ou gravar em um link simbólico afetará o arquivo ou diretório para o qual ele aponta, não o link
simbólico propriamente dito. Além disso, no Windows, a propriedade isSymbolicLink de um objeto File que faça
referência a um ponto de junção (usado no sistema de arquivos NTFS) é definida como true.
A classe File inclui as propriedades isPackage e isSymbolicLink para verificar se o objeto File faz referência a um
pacote ou link simbólico.
O código a seguir percorre o diretório da área de trabalho do usuário, listando subdiretórios que não sejam pacotes:
var desktopNodes:File = File.desktopDirectory.getDirectoryListing();
for (var i:uint = 0; i < desktopNodes.length; i++)
{
if (desktopNodes[i].isDirectory && !!desktopNodes[i].isPackage)
{
trace(desktopNodes[i].name);
}
}
O código a seguir percorre o diretório da área de trabalho do usuário, listando arquivos e diretórios que não sejam links
simbólicos:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 115
Trabalho com o sistema de arquivos
var desktopNodes:File = File.desktopDirectory.getDirectoryListing();
for (var i:uint = 0; i < desktopNodes.length; i++)
{
if (!desktopNodes[i].isSymbolicLink)
{
trace(desktopNodes[i].name);
}
}
O método canonicalize() altera o caminho do link simbólico para apontar para o arquivo ou diretório ao qual o
link se refere. O código a seguir percorre o diretório da área de trabalho do usuário e relata os caminhos referenciados
pelos arquivos que sejam links simbólicos:
var desktopNodes:File = File.desktopDirectory.getDirectoryListing();
for (var i:uint = 0; i < desktopNodes.length; i++)
{
if (desktopNodes[i].isSymbolicLink)
{
var linkNode:File = desktopNodes[i] as File;
linkNode.canonicalize();
trace(linkNode.nativePath);
}
}
Determinação de espaço disponível em um volume
A propriedade spaceAvailable do objeto File é o espaço disponível para uso no local do File, em bytes. Por exemplo,
o código a seguir verifica o espaço disponível no diretório de armazenamento do aplicativo:
trace(File.applicationStorageDirectory.spaceAvailable);
Se o objeto File fizer referência a um diretório, a propriedade spaceAvailable indicará o espaço no diretório que os
arquivos podem usar. Se o objeto File fizer referência a um arquivo, a propriedade spaceAvailable indicará o espaço
no qual o arquivo poderá crescer. Se o local do arquivo não existir, a propriedade spaceAvailable será definida como
0. Se o objeto File fizer referência a um link simbólico, a propriedade spaceAvailable será definida como espaço
disponível no local para o qual o link simbólico aponta.
Geralmente o espaço disponível para um diretório ou arquivo é igual ao espaço disponível no volume que contém o
diretório ou o arquivo. No entanto, o espaço disponível pode levar em conta limites por cotas e por diretório.
A adição de um arquivo ou diretório a um volume geralmente requer mais espaço que o tamanho real do arquivo ou
o tamanho do conteúdo do diretório. Por exemplo, o sistema operacional pode exigir mais espaço para armazenar
informações sobre índice. Ou os setores de disco necessários podem usar espaço adicional. Além disso, o espaço
disponível muda dinamicamente. Dessa forma, você não poderá alocar todo o espaço informado para o
armazenamento de arquivos. Para obter informações sobre como gravar no sistema de arquivos, consulte“Leitura e
gravação de arquivos” na página 121.
Obtenção de informações sobre o sistema de arquivos
A classe File inclui as seguintes propriedades estáticas que apresentam algumas informações úteis sobre o sistema de
arquivos:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 116
Trabalho com o sistema de arquivos
Propriedade
Descrição
File.lineEnding
A seqüência de caracteres de final de linha usada pelo sistema operacional de hospedagem. No Mac
OS e no Linux, ele é o caractere de alimentação de linha. No Windows, esse é o caractere de retorno
de carro seguido pelo caractere de alimentação de linha.
File.separator
O caractere separador de componente do caminho do sistema operacional de hospedagem. No Mac
OS e no Linux, ele é o caractere de barra (/). No Windows, ele é o caractere de barra invertida (\).
File.systemCharset
A codificação padrão usada em arquivos pelo sistema operacional de hospedagem. Ela pertence ao
conjunto de caracteres usado pelo sistema operacional, correspondente ao respectivo idioma.
A classe Capabilities também inclui informações úteis sobre o sistema, que podem ser valiosas ao trabalhar com
arquivos:
Propriedade
Descrição
Capabilities.hasIME
Especifica se o player está sendo executado em um sistema que possui (true) ou não possui (false)
um IME (editor de métodos de entrada) instalado.
Capabilities.language
Especifica o código de idioma do sistema no qual o player está sendo executado.
Capabilities.os
Especifica o sistema operacional atual.
Trabalho com diretórios
O tempo de execução oferece a você recursos para trabalhar com diretórios no sistema de arquivos local.
Para obter detalhes sobre a criação de objetos File que apontam para diretórios, consulte “Como apontar um objeto
File para um diretório” na página 108.
Criação de diretórios
O método File.createDirectory() permite criar um diretório. Por exemplo, o código a seguir cria um diretório
com nome AIR Test como um subdiretório do diretório inicial do usuário:
var dir:File = File.userDirectory.resolvePath("AIR Test");
dir.createDirectory();
Se o diretório existir, o método createDirectory() não faz nada.
Além disso, em alguns modos, o objeto FileStream cria diretórios ao abrir arquivos. Diretórios ausentes são criados
quando você cria uma ocorrência FileStream com o parâmetro fileMode do construtor FileStream() definido como
FileMode.APPEND ou FileMode.WRITE. Para obter mais informações, consulte “Fluxo de trabalho de leitura e
gravação de arquivos” na página 121.
Criação de diretório temporário
A classe File inclui o método createTempDirectory(), que cria um diretório na pasta de diretórios temporários do
Sistema, como no exemplo a seguir:
var temp:File = File.createTempDirectory();
O método createTempDirectory() cria automaticamente um diretório temporário exclusivo (poupando o seu
trabalho de determinar um novo local exclusivo).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 117
Trabalho com o sistema de arquivos
Você pode usar um diretório temporário para armazenar temporariamente arquivos temporários usados em uma
sessão do aplicativo. Observe que há um método createTempFile() para criar arquivos temporários novos e
exclusivos no diretório temporário System.
Pode ser conveniente excluir o diretório temporário antes de fechar o aplicativo, uma vez que ele não é excluído
automaticamente.
Enumeração de diretórios
Você pode usar o método getDirectoryListing() ou o método getDirectoryListingAsync() do objeto File
para obter uma matriz de objetos File apontando para arquivos e subpastas em um diretório.
Por exemplo, o código a seguir lista o conteúdo do diretório de documentos do usuário (sem examinar subdiretórios):
var directory:File = File.documentsDirectory;
var contents:Array = directory.getDirectoryListing();
for (var i:uint = 0; i < contents.length; i++)
{
trace(contents[i].name, contents[i].size);
}
Ao usar a versão assíncrona do método, o objeto de evento directoryListing terá a propriedade files que é a
matriz de objetos File pertencentes aos diretórios:
var directory:File = File.documentsDirectory;
directory.getDirectoryListingAsync();
directory.addEventListener(FileListEvent.DIRECTORY_LISTING, dirListHandler);
function dirListHandler(event:FileListEvent):void
{
var contents:Array = event.files;
for (var i:uint = 0; i < contents.length; i++)
{
trace(contents[i].name, contents[i].size);
}
}
Cópia e movimentação de diretórios
Você pode copiar ou mover o diretório, usando os mesmos métodos utilizados para copiar ou mover um arquivo. Por
exemplo, o código a seguir copia um diretório de forma síncrona:
var sourceDir:File = File.documentsDirectory.resolvePath("AIR Test");
var resultDir:File = File.documentsDirectory.resolvePath("AIR Test Copy");
sourceDir.copyTo(resultDir);
Quando você especifica true para o parâmetro overwrite do método copyTo(), todos arquivos e pastas em um
diretório de destino existente são excluídos e substituídos pelos arquivos e pastas no diretório de origem (mesmo se o
arquivo de destino não existir no diretório de origem).
O diretório especificado como o parâmetro newLocation do método copyTo() especifica o caminho para o diretório
resultante; ele não especifica o diretório pai que conterá o diretório resultante.
Para obter detalhes, consulte “Cópia e movimentação de arquivos” na página 119.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 118
Trabalho com o sistema de arquivos
Exclusão de conteúdo do diretório
A classe File inclui os métodos deleteDirectory() e deleteDirectoryAsync(). Esses métodos excluem diretórios;
o primeiro trabalha de forma síncrona, o segundo trabalha de forma assíncrona (consulte “Noções básicas do arquivo
AIR” na página 106). Os dois métodos incluem o parâmetro deleteDirectoryContents (com um valor Booleano);
quando esse parâmetro estiver definido como true (o valor padrão será false) a chamada do método excluirá
diretórios não vazios; caso contrário, apenas diretórios vazios serão excluídos.
Por exemplo, o código a seguir exclui de modo síncrono o subdiretório AIR Test do diretório de documentos do
usuários:
var directory:File = File.documentsDirectory.resolvePath("AIR Test");
directory.deleteDirectory(true);
O código a seguir exclui de modo assíncrono o subdiretório AIR Test do diretório de documentos do usuário:
var directory:File = File.documentsDirectory.resolvePath("AIR Test");
directory.addEventListener(Event.COMPLETE, completeHandler)
directory.deleteDirectoryAsync(true);
function completeHandler(event:Event):void {
trace("Deleted.")
}
Também estão incluídos os métodos moveToTrash() e moveToTrashAsync(), que você pode usar para mover um
diretório para a lixeira do Sistema. Para obter detalhes, consulte “Movimentação de arquivo para a lixeira” na
página 120.
Trabalho com arquivos
Usando a API de arquivo AIR, você pode adicionar recursos básicos de interação de arquivo a seus aplicativos. Por
exemplo, você pode ler e gravar arquivos, copiar e excluir arquivos e assim por diante. Como seus aplicativos podem
acessar o sistema de arquivos local, consulte “Segurança do AIR” na página 23, se ainda não tiver feito isso.
Nota: Você pode associar um tipo de arquivo a um aplicativo AIR (de modo que, quando você clicar nele duas vezes, o
aplicativo seja aberto). Para obter detalhes, consulte “Gerenciamento de associações de arquivos” na página 299.
Obtenção de informações de arquivos
A classe File inclui as seguintes propriedades que oferecem informações sobre um arquivo ou diretório para o qual o
objeto File aponta:
Propriedade File
Descrição
creationDate
A data de criação do arquivo no disco local.
creator
Obsoleto — usa a propriedade extension. (Essa propriedade relata o tipo de criador Macintosh do
arquivo, usado somente nas versões do Mac OS anteriores ao Mac OS X).
exists
Se o arquivo ou diretório referenciado existir.
extension
A extensão de arquivo, que é a parte seguinte ao nome (e não incluindo) o ponto final ("."). Se não
houver ponto no nome do arquivo, a extensão será null.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 119
Trabalho com o sistema de arquivos
Propriedade File
Descrição
icon
Um objeto Icon que contém os ícones definidos para o arquivo.
isDirectory
Se a referência do objeto File for a um diretório.
modificationDate
A data da última modificação do arquivo ou diretório no disco local.
name
O nome do arquivo ou diretório (incluindo a extensão de arquivo, se houver) no disco local.
nativePath
O caminho completo na representação do sistema operacional de hospedagem. Consulte “Caminhos
de objetos File” na página 107.
parent
A pasta que contém a pasta ou o arquivo representado pelo objeto File. Essa propriedade será null se
o objeto File fizer referência a um arquivo ou diretório na raiz do sistema de arquivos.
size
O tamanho do arquivo no disco local, em bytes.
type
Obsoleto — usa a propriedade extension. (No Macintosh, essa propriedade é o tipo de arquivo com
quatro caracteres, usado somente nas versões do Mac OS anteriores ao Mac OS X).
url
A URL do arquivo ou diretório. Consulte “Caminhos de objetos File” na página 107.
Para obter detalhes sobre essas propriedades, consulte a entrada da classe File na Referência de Componentes e
Linguagem do ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_br).
Cópia e movimentação de arquivos
A classe File inclui dois métodos de cópia de arquivos ou diretórios: copyTo() e copyToAsync(). A classe File inclui
dois métodos para mover arquivos ou diretórios: moveTo() e moveToAsync(). Os métodos copyTo() e moveTo()
funcionam de modo síncrono e os métodos copyToAsync() e moveToAsync() funcionam de modo assíncrono
(consulte “Noções básicas do arquivo AIR” na página 106).
Para copiar ou mover um arquivo, defina dois objetos File. Um aponta para o arquivo que deve ser copiado ou movido,
e é o objeto que chama o método de cópia ou movimentação; o outro aponta para o caminho de destino (resultado).
O seguinte copia o arquivo test.txt do subdiretório AIR Test do diretório de documentos do usuário em um arquivo
com nome copy.txt no mesmo diretório:
var original:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var newFile:File = File.resolvePath("AIR Test/copy.txt");
original.copyTo(newFile, true);
Nesse exemplo, o valor do parâmetro overwrite do método copyTo() (o segundo parâmetro) é definido como true.
Definindo-o como true, o arquivo de destino existente é sobrescrito. Esse parâmetro é opcional. Se você defini-lo
como false (o valor padrão), a operação despacha um evento IOErrorEvent se o arquivo de destino existir (e o
arquivo não é copiado).
As versões “Async” dos métodos de cópia e movimentação funcionam de modo assíncrono. Use o método
addEventListener() para monitorar a conclusão da tarefa ou as condições de erro, como no código a seguir:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 120
Trabalho com o sistema de arquivos
var original = File.documentsDirectory;
original = original.resolvePath("AIR Test/test.txt");
var destination:File = File.documentsDirectory;
destination = destination.resolvePath("AIR Test 2/copy.txt");
original.addEventListener(Event.COMPLETE, fileMoveCompleteHandler);
original.addEventListener(IOErrorEvent.IO_ERROR, fileMoveIOErrorEventHandler);
original.moveToAsync(destination);
function fileMoveCompleteHandler(event:Event):void {
trace(event.target); // [object File]
}
function fileMoveIOErrorEventHandler(event:IOErrorEvent):void {
trace("I/O Error.");
}
A classe File também inclui os métodos File.moveToTrash() e File.moveToTrashAsync(), que movem o arquivo
ou diretório para a lixeira do sistema.
Exclusão de arquivo
A classe File inclui os métodos deleteFile() e deleteFileAsync(). Esses métodos excluem arquivos; o primeiro
trabalha de forma síncrona, o segundo trabalha de forma assíncrona (consulte “Noções básicas do arquivo AIR” na
página 106).
Por exemplo, o código a seguir exclui de modo síncrono o arquivo test.txt do diretório de documentos do usuário:
var file:File = File.documentsDirectory.resolvePath("test.txt");
file.deleteFile();
O código a seguir exclui de modo assíncrono o arquivo test.txt do diretório de documentos do usuário:
var file:File = File.documentsDirectory.resolvePath("test.txt");
file.addEventListener(Event.COMPLETE, completeHandler)
file.deleteFileAsync();
function completeHandler(event:Event):void {
trace("Deleted.")
}
Também estão incluídos os métodos moveToTrash() e moveToTrashAsync(), que você pode usar para mover um
arquivo ou diretório para a lixeira do Sistema. Para obter detalhes, consulte “Movimentação de arquivo para a lixeira”
na página 120.
Movimentação de arquivo para a lixeira
A classe File inclui os métodos moveToTrash() e moveToTrashAsync(). Esses métodos enviam um arquivo ou
diretório para a lixeira do Sistema; o primeiro trabalha de forma síncrona, o segundo trabalha de forma assíncrona
(consulte “Noções básicas do arquivo AIR” na página 106).
Por exemplo, o código a seguir move de modo síncrono o arquivo test.txt no diretório de documentos do usuários para
a lixeira do Sistema:
var file:File = File.documentsDirectory.resolvePath("test.txt");
file.moveToTrash();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 121
Trabalho com o sistema de arquivos
Criação de arquivo temporário
A classe File inclui o método createTempFile(), que cria um arquivo na pasta de diretórios temporários do Sistema,
como no exemplo a seguir:
var temp:File = File.createTempFile();
O método createTempFile() cria automaticamente um arquivo temporário exclusivo (poupando o seu trabalho de
determinar um novo local exclusivo).
Você pode usar um arquivo temporário para armazenar temporariamente informações usadas em uma sessão do
aplicativo. Observe que também há o método createTempDirectory() para criar um diretório temporário exclusivo
no diretório temporário System.
Pode ser conveniente excluir o arquivo temporário antes de fechar o aplicativo, uma vez que ele não é excluído
automaticamente.
Leitura e gravação de arquivos
A classe FileStream permite que aplicativos AIR leiam e gravem no sistema de arquivos.
Fluxo de trabalho de leitura e gravação de arquivos
O fluxo de trabalho de leitura e gravação de arquivos é o seguinte.
Inicializa o objeto File que aponta para o caminho.
Esse é o caminho do arquivo com que você deseja trabalhar (ou um arquivo que você criará mais tarde).
var file:File = File.documentsDirectory;
file = file.resolvePath("AIR Test/testFile.txt");
Este exemplo usa a propriedade File.documentsDirectory e o método resolvePath() do objeto File para
inicializá-lo. No entanto, há várias outras maneiras de apontar o objeto File para um arquivo. Para obter mais
informações, consulte “Como apontar um objeto File para um arquivo” na página 110.
Inicializa o objeto FileStream.
Chama o método open() ou openAsync() do objeto FileStream.
O método que você chama depende de você desejar abrir o arquivo para operações síncronas ou assíncronas. Use o
objeto File como parâmetro file do método open. No parâmetro fileMode, especifique uma constante da classe
FileMode que determine o modo como você usará o arquivo.
Por exemplo, o código a seguir inicializa o objeto FileStream que é usado para criar um arquivo e substituir algum dado
existente:
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
Para obter mais informações, consulte“Inicialização de objeto FileStream e abertura e fechamento de arquivos” na
página 123, e “modos de abertura FileStream” na página 122.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 122
Trabalho com o sistema de arquivos
Se você abriu o arquivo de modo assíncrono (usando o método openAsync()), adicione e configure ouvintes de
eventos para o objeto FileStream.
Esses métodos de ouvintes de eventos respondem aos eventos despachados pelo objeto FileStream em uma variedade
de situações, como quando os dados são lidos do arquivo, quando são encontrados erros E/S ou quando a quantidade
completa de dados para gravação tiver sido gravada.
Para obter detalhes, consulte “Programação assíncrona e eventos gerados por um objeto FileStream aberto
assincronicamente” na página 127.
Incluir código de leitura e gravação de dados, conforme necessário.
Há vários métodos da classe FileStream relacionados a leitura e gravação. (Cada um deles inicia com "read" ou "write").
O método escolhido para ser usado na leitura ou gravação de dados depende do formato de dados no arquivo de
destino.
Por exemplo, se os dados no arquivo de destino forem texto de codificação UTF, você pode usar os métodos
readUTFBytes() e writeUTFBytes(). Se desejar tratar os dados como matrizes de bytes, você pode usar os métodos
readByte(), readBytes(), writeByte() e writeBytes(). Para saber detalhes, consulte “Formatos de dados e
seleção de métodos de leitura e gravação para uso” na página 128.
Se você abriu o arquivo de modo assíncrono, certifique-se de que há dados suficientes disponíveis antes de chamar o
método de leitura. Para obter detalhes, consulte “O buffer de leitura e a propriedade bytesAvailable do objeto
FileStream” na página 125.
Antes de fazer a gravação em um arquivo, se desejar verificar a quantidade de espaço em disco disponível, você poderá
assinalar a propriedade spaceAvailable do objeto File. Para obter mais informações, consulte “Determinação de espaço
disponível em um volume” na página 115.
Chama o método close() do objeto FileStream quando você tiver terminado o trabalho no arquivo.
Isso torna o arquivo disponível para outros aplicativos.
Para obter detalhes, consulte “Inicialização de objeto FileStream e abertura e fechamento de arquivos” na página 123.
Para visualizar um aplicativo de amostra que usa a classe FileStream para ler e gravar arquivos, consulte os seguintes
artigos no Centro de desenvolvimento do Adobe AIR:
• Criação de editor de arquivo de texto
Trabalho com objetos FileStream
A classe FileStream define métodos de abertura, leitura e gravação de arquivos.
modos de abertura FileStream
Cada um dos métodos open() e openAsync() do objeto FileStream inclui o parâmetro fileMode, que define algumas
propriedades de um fluxo de arquivo, incluindo o seguinte:
• A capacidade de ler do arquivo
• A capacidade de gravar no arquivo
• Se os dados serão sempre acrescentados ao final do arquivo (durante a gravação).
• O que fazer quando o arquivo não existir (e quando os respectivos diretórios pai não existirem)
A seguir, os vários modos de arquivo (que você pode especificar como o parâmetro fileMode dos métodos open() e
openAsync()):
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 123
Trabalho com o sistema de arquivos
modo File
Descrição
FileMode.READ
Especifica que o arquivo está aberto somente para leitura.
FileMode.WRITE
Especifica que o arquivo está aberto para gravação. Se o arquivo não existir, ele é criado quando o objeto
FileStream é aberto. Se o arquivo existir, todos os dados existentes são excluídos.
FileMode.APPEND
Especifica que o arquivo está aberto para acréscimo. O arquivo é criado se ele não existir. Se o arquivo
existir, os dados existentes não são substituídos e todas as gravações serão iniciadas no final do arquivo.
FileMode.UPDATE
Especifica que o arquivo está aberto para leitura e gravação. Se o arquivo não existir, ele é criado.
Especifique esse modo para acesso de leitura/gravação aleatório ao arquivo. Você pode ler a partir de
qualquer posição no arquivo e, ao gravar no arquivo, apenas os bytes gravados substituirão os bytes
existentes (todos os demais bytes permanecerão inalterados).
Inicialização de objeto FileStream e abertura e fechamento de arquivos
Ao abrir o objeto FileStream, você o torna disponível para a leitura e gravação de dados em um arquivo. Você abre o
objeto FileStream passando o objeto File para o método open() ou openAsync() do objeto FileStream:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.READ);
O parâmetro fileMode (o segundo parâmetro dos métodos open() e openAsync()) especifica o modo em que o
arquivo deve ser aberto: para leitura, gravação, acréscimo ou atualização. Para obter detalhes, consulte a seção
anterior,“modos de abertura FileStream” na página 122.
Se você usar o método openAsync() para abrir o arquivo para operações de arquivo de modo assíncrono, configure
os ouvintes de eventos para tratar os eventos assíncronos:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completeHandler);
myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
myFileStream.addEventListener(IOErrorEvent.IOError, errorHandler);
myFileStream.open(myFile, FileMode.READ);
function completeHandler(event:Event):void {
// ...
}
function progressHandler(event:ProgressEvent):void {
// ...
}
function errorHandler(event:IOErrorEvent):void {
// ...
}
O arquivo é aberto para operações síncronas ou assíncronas, dependendo de você usar o método open() ou
openAsync(). Para obter detalhes, consulte “Noções básicas do arquivo AIR” na página 106.
Se você definir o parâmetro fileMode como FileMode.READ ou FileMode.UPDATE no método de abertura do objeto
FileStream, os dados são lidos no buffer de leitura tão logo você abra o objeto FileStream. Para obter detalhes, consulte
“O buffer de leitura e a propriedade bytesAvailable do objeto FileStream” na página 125.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 124
Trabalho com o sistema de arquivos
Você pode chamar o método close() do objeto FileStream para fechar o arquivo associado, tornando-o disponível
para uso por outros aplicativos.
A propriedade position do objeto FileStream
A propriedade position do objeto FileStream determina quando os dados são lidos ou gravados no próximo método
de leitura ou gravação.
Antes de uma operação de leitura ou gravação, defina a propriedade position como qualquer posição válida no
arquivo.
Por exemplo, o código a seguir grava a seqüência "hello" (na codificação UTF) na posição 8 do arquivo:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.UPDATE);
myFileStream.position = 8;
myFileStream.writeUTFBytes("hello");
Quando você abre pela primeira vez o objeto FileStream, a propriedade position é definida como 0.
Antes de uma operação de leitura, o valor de position deve ser no mínimo 0 e inferior ao número de bytes no arquivo
(que são posições existentes no arquivo).
O valor da propriedade position é modificado apenas nas seguintes condições:
• Quando você define explicitamente a propriedade position.
• Quando você chama o método de leitura.
• Quando você chama o método de gravação.
Quando você chama um método de leitura ou gravação do objeto FileStream, a propriedade position é
imediatamente incrementada pelo número de bytes que você lê ou grava. Dependendo do método de leitura usado, a
propriedade position também é incrementada pelo número de bytes especificado para leitura ou pelo número de
bytes disponível. Quando você chama o método de leitura ou gravação subseqüentemente, ele faz a leitura ou gravação
iniciando na nova posição.
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.UPDATE);
myFileStream.position = 4000;
trace(myFileStream.position); // 4000
myFileStream.writeBytes(myByteArray, 0, 200);
trace(myFileStream.position); // 4200
Há, porém, uma exceção: em um FileStream aberto no modo append, a propriedade position não é alterada após
uma chamada de um método de gravação. (No modo append, os dados são sempre gravados no final do arquivo,
independentemente do valor da propriedade position.)
Em um arquivo aberto para operações assíncronas, a operação de gravação não é concluída antes de a próxima linha
de código ser executada. No entanto, você pode chamar vários métodos assíncronos seqüencialmente e o tempo de
execução os executa em ordem:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 125
Trabalho com o sistema de arquivos
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.openAsync(myFile, FileMode.WRITE);
myFileStream.writeUTFBytes("hello");
myFileStream.writeUTFBytes("world");
myFileStream.addEventListener(Event.CLOSE, closeHandler);
myFileStream.close();
trace("started.");
closeHandler(event:Event):void
{
trace("finished.");
}
A saída trace desse código é a seguinte:
started.
finished.
Você pode especificar o valor position logo após chamar um método de leitura ou gravação (ou a qualquer momento)
e a próxima operação de leitura ou gravação ocorrerá no início dessa posição. Por exemplo, observe que o código a
seguir define a propriedade position logo após uma chamada para a operação writeBytes() e a position é
definida como esse valor (300) mesmo após a operação de gravação ser concluída:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.openAsync(myFile, FileMode.UPDATE);
myFileStream.position = 4000;
trace(myFileStream.position); // 4000
myFileStream.writeBytes(myByteArray, 0, 200);
myFileStream.position = 300;
trace(myFileStream.position); // 300
O buffer de leitura e a propriedade bytesAvailable do objeto FileStream
Quando o objeto FileStream com recursos de leitura (em que o parâmetro fileMode do método open() ou
openAsync() foi definido como READ ou UPDATE) for aberto, o tempo de execução armazena os dados em um buffer
interno. O objeto FileStream começa a fazer a leitura de dados no buffer assim que o arquivo for aberto (chamando o
método open() ou openAsync() do objeto FileStream).
Em um arquivo aberto para operações síncronas (usando o método open()), você sempre poderá definir o ponteiro
position em qualquer posição válida (dentro dos limites do arquivo) e iniciar a leitura de qualquer quantidade de
dados (dentro dos limites do arquivo), conforme mostra o código a seguir (que supõe que o arquivo contém pelo
menos 100 bytes):
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.READ);
myFileStream.position = 10;
myFileStream.readBytes(myByteArray, 0, 20);
myFileStream.position = 89;
myFileStream.readBytes(myByteArray, 0, 10);
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 126
Trabalho com o sistema de arquivos
Quer o arquivo seja aberto para operações síncronas ou assíncronas, os métodos de leitura sempre fazem a leitura dos
bytes "disponíveis", representados pela propriedade bytesAvalable. Ao fazer a leitura sincronicamente, todos os
bytes do arquivo ficam disponíveis o tempo todo. Ao fazer a leitura assincronicamente, os bytes se tornam disponíveis,
iniciando na posição especificada pela propriedade position, em uma série de preenchimentos de buffer assíncronos
assinalados por eventos progress.
Em arquivos abertos para operações síncronas, a propriedade bytesAvailable é sempre definida para representar o
número de bytes da propriedade position no final do arquivo (todos os bytes no arquivo estarão sempre disponíveis
para leitura).
Em arquivos abertos para operações assíncronas, é necessário assegurar que o buffer de leitura consumiu dados
suficientes antes de chamar o método de leitura. Em um arquivo aberto assincronicamente, conforme o andamento da
operação de leitura, os dados do arquivo, iniciando na posição especificada quando a operação de leitura iniciou, são
adicionados ao buffer, e a propriedade bytesAvailable é incrementada com cada byte lido. A propriedade
bytesAvailable indica o número de bytes disponíveis, iniciando com o byte na posição especificada pela
propriedade position até o final do buffer. Periodicamente, o objeto FileStream envia um evento progress.
Em um arquivo aberto sincronicamente, à medida que os dados se tornam disponíveis no buffer de leitura, o objeto
FileStream despacha periodicamente o evento progress. Por exemplo, o código a seguir lê dados em um objeto
ByteArray, bytes, conforme é lido no buffer:
var bytes:ByteArray = new ByteArray();
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
myFileStream.openAsync(myFile, FileMode.READ);
function progressHandler(event:ProgressEvent):void
{
myFileStream.readBytes(bytes, myFileStream.position, myFileStream.bytesAvailable);
}
Em um arquivo aberto assincronicamente, apenas os dados no buffer de leitura podem ser lidos. Além disso, conforme
você lê os dados, eles são removidos do buffer de leitura. Em operações de leitura você precisa assegurar que haja dados
no buffer de leitura antes de chamar uma operação de leitura. Por exemplo, o código a seguir faz a leitura de 8000 bytes
de dados iniciando da posição 4000 no arquivo:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
myFileStream.addEventListener(Event.COMPLETE, completed);
myFileStream.openAsync(myFile, FileMode.READ);
myFileStream.position = 4000;
var str:String = "";
function progressHandler(event:Event):void
{
if (myFileStream.bytesAvailable > 8000 )
{
str += myFileStream.readMultiByte(8000, "iso-8859-1");
}
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 127
Trabalho com o sistema de arquivos
Durante a operação de gravação, o objeto FileStream não faz a leitura de dados no buffer de leitura. Quando a operação
de gravação estiver concluída (todos os dados no buffer de gravação são gravados no arquivo), o objeto FileStream
inicia um novo buffer de leitura (supondo que o objeto FileStream associado foi aberto com recursos de leitura) e inicia
a leitura de dados no buffer de leitura, começando da posição especificada pela propriedade position. A propriedade
position pode ser a posição do último byte gravado ou pode ser uma posição diferente, se o usuário especificar um
valor diferente para o objeto position após a operação de gravação.
Programação assíncrona e eventos gerados por um objeto FileStream aberto
assincronicamente
Quando um arquivo for aberto de modo assíncrono (usando o método openAsync()), os arquivos de leitura e
gravação serão executados de modo assíncrono. À medida que os dados são lidos no buffer de leitura e os dados de
saída começam a ser gravados, outro código ActionScript pode ser executado.
Isso significa que é necessário se registrar para eventos gerados pelo objeto FileStream abertos de modo assíncrono.
Registrando-se para o evento progress, você poderá ser notificado quando novos dados se tornarem disponíveis para
leitura, como no seguinte código:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
myFileStream.openAsync(myFile, FileMode.READ);
var str:String = "";
function progressHandler(event:ProgressEvent):void
{
str += myFileStream.readMultiByte(myFileStream.bytesAvailable, "iso-8859-1");
}
Você pode fazer a leitura de todos os dados se registrando para o evento complete, como no seguinte código:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completed);
myFileStream.openAsync(myFile, FileMode.READ);
var str:String = "";
function completeHandler(event:Event):void
{
str = myFileStream.readMultiByte(myFileStream.bytesAvailable, "iso-8859-1");
}
Da mesma maneira que os dados de entrada são colocados em buffer para permitir a leitura assíncrona, os dados que
você grava em um fluxo assíncrono são colocados em buffer e gravados no arquivo de forma assíncrona. À medida que
os dados são gravados em um arquivo, o objeto FileStream despacha periodicamente o objeto OutputProgressEvent.
O objeto OutputProgressEvent inclui a propriedade bytesPending definida pelo número de bytes restantes para
gravação. Você pode registrar para que o evento outputProgress seja notificado, já que esse buffer é, na realidade,
gravado no arquivo, talvez para exibir uma caixa de diálogo de progresso. No entanto, isso geralmente não é necessário.
Especificamente, você pode chamar o método close() sem se importar com os bytes não gravados. O objeto
FileStream continuará gravando dados e o evento close será entregue após o byte final ser gravado no arquivo e o
arquivo subjacente ser fechado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 128
Trabalho com o sistema de arquivos
Formatos de dados e seleção de métodos de leitura e gravação para uso
Todo arquivo é um conjunto de bytes em um disco. No ActionScript, os dados de um arquivo sempre podem ser
representados como ByteArray. Por exemplo, o código a seguir faz a leitura de dados de um arquivo em um objeto
ByteArray chamado bytes:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completeHandler);
myFileStream.openAsync(myFile, FileMode.READ);
var bytes:ByteArray = new ByteArray();
function completeHandler(event:Event):void
{
myFileStream.readBytes(bytes, 0, myFileStream.bytesAvailable);
}
De forma semelhante, o código seguinte grava dados de um ByteArray chamado bytes em um arquivo:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.WRITE);
myFileStream.writeBytes(bytes, 0, bytes.length);
No entanto, normalmente você não quer armazenar dados em um objeto ByteArray do ActionScript. E, geralmente, o
arquivo de dados está em um formato de arquivo especificado.
Por exemplo, os dados no arquivo podem estar em um formato de arquivo de texto e talvez você deseje representar
esses dados em um objeto String.
Por esse motivo, a classe FileStream inclui métodos de leitura e gravação para leitura e gravação de dados em outros
tipos diferentes dos objetos ByteArray e a partir deles. Por exemplo, o método readMultiByte() permite fazer a
leitura de dados de um arquivo e armazená-los em uma seqüência, como no código a seguir:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.addEventListener(Event.COMPLETE, completed);
myFileStream.openAsync(myFile, FileMode.READ);
var str:String = "";
function completeHandler(event:Event):void
{
str = myFileStream.readMultiByte(myFileStream.bytesAvailable, "iso-8859-1");
}
O segundo parâmetro do método readMultiByte() especifica o formato de texto que o ActionScript usa para
interpretar os dados ("iso-8859-1" no exemplo). O ActionScript oferece suporte às codificações comuns de conjunto
de caracteres e elas são listadas na Referência de Linguagem do ActionScript 3.0 (consulte, Conjuntos de caracteres
com suporteem http://livedocs.macromedia.com/flex/2/langref/charset-codes.html).
A classe FileStream também inclui o método readUTFBytes(), que faz leitura de dados do buffer de leitura em uma
seqüência, usando o conjunto de caracteres UTF-8. Como os caracteres no conjunto de caracteres UTF-8 são de
tamanho variável, não use readUTFBytes() em um método que responde ao evento progress, já que os dados no
final do buffer de leitura podem representar um caractere incompleto. (Isso também é verdadeiro ao usar o método
readMultiByte() com uma codificação de caractere de tamanho variável). Por esse motivo, leia o conjunto de dados
inteiro quando o objeto FileStream despachar o evento complete.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 129
Trabalho com o sistema de arquivos
Também há métodos de gravação semelhantes, writeMultiByte() e writeUTFBytes(), para trabalhar com objetos
String e arquivos de texto.
Os métodos readUTF() e writeUTF() (não confundir com readUTFBytes() e writeUTFBytes()) também fazem
leitura e gravação de dados de texto em um arquivo, mas eles supõem que os dados de texto são precedidos por dados
que especificam o tamanho dos dados de texto, o que não é prática comum em arquivos de texto padrão.
Alguns arquivos de texto de codificação UTF começam com um caractere "UTF-BOM" (marca de ordem de bytes) que
define que a terminação, bem como o formato de codificação (como UTF-16 ou UTF-32).
Para obter um exemplo de leitura e gravação de um arquivo de texto, consulte “Exemplo: Leitura de arquivo XML em
um objeto XML” na página 130.
readObject() e writeObject() são formas convenientes de armazenar e recuperar dados de objetos ActionScript
complexos. Os dados são codificados em AMF (ActionScript Message Format). Esse formato é próprio do
ActionScript. Outros aplicativos, além de AIR, Flash Player, Flash Media Server e Flex Data Services não têm APIs
incorporadas para trabalhar com dados nesse formato.
Há mais alguns métodos de leitura e gravação (comoreadDouble() e writeDouble()). No entanto, se você usá-los,
certifique-se de que o formato de arquivo corresponde ao formato dos dados definidos por esses métodos.
Os formatos de arquivos são normalmente mais complexos do que os formatos de texto simples. Por exemplo, o
arquivo MP3 inclui dados compactados que só podem ser interpretados com a descompactação e os algoritmos de
decodificação específicos para arquivos MP3. Arquivos MP3 também podem incluir marcas ID3 que contêm
informações de metatag sobre o arquivo (como o título e o artista de uma canção). Há várias versões do formato ID3,
mas a mais simples (versão ID3 1) é discutida na seção “Exemplo: Leitura e gravação de dados com acesso aleatório”
na página 131.
Outros formatos de arquivo (de imagens, bancos de dados, documentos de aplicativos etc.) têm estruturas diferentes
e, para trabalhar com os respectivos dados no ActionScript, você deve saber como os dados são estruturados.
Uso dos métodos load() e save()
O Flash Player 10 adicionou os métodos load() e save() à classe FileReference. Esses métodos também estão no AIR
1.5 e a classe File herda os métodos da classe FileReference. Esses métodos foram projetados para fornecer um meio
seguro para usuários carregarem e salvarem dados de arquivo em Flash Player. No entanto, os aplicativos AIR também
podem usar esses métodos como uma maneira fácil de carregar e salvar arquivos de forma assíncrona.
Por exemplo, o código a seguir salva uma seqüência de caracteres em um arquivo de texto:
var file:File = File.applicationStorageDirectory.resolvePath("test.txt");
var str:String = "Hello.";
file.addEventListener(Event.COMPLETE, fileSaved);
file.save(str);
function fileSaved(event:Event):void
{
trace("Done.");
}
O parâmetro data do método save() pode usar um valor String, XML ou ByteArray. Quando o argumento é um valor
String ou XML, o método salva o arquivo como arquivo de texto criptografado UTF-8.
Quando esse exemplo de código é executado, o aplicativo exibe uma caixa de diálogo em que o usuário seleciona o
destino do arquivo salvo.
O código a seguir carrega uma seqüência de caracteres de um arquivo de texto codificado em UTF-8.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 130
Trabalho com o sistema de arquivos
var file:File = File.applicationStorageDirectory.resolvePath("test.txt");
file.addEventListener(Event.COMPLETE, loaded);
file.load();
var str:String;
function loaded(event:Event):void
{
var bytes:ByteArray = file.data;
str = bytes.readUTFBytes(bytes.length);
trace(str);
}
A classe FileStream fornece mais funcionalidade do que os métodos load() e save().
• Usando a classe FileStream, você pode ler e gravar dados de forma síncrona e assíncrona.
• O uso da classe FileStream permite gravar em um arquivo de forma incremental.
• O uso da classe FileStream permite abrir um arquivo para acesso aleatório (para leitura e gravação em qualquer
seção do arquivo).
• A classe FileStream permite especificar o tipo de acesso que você tem ao arquivo, definindo o parâmetro fileMode
do método open() ou openAsync().
• A classe FileStream permite salvar dados em arquivos sem apresentar ao usuário uma caixa de diálogo Abrir ou
Salvar.
• Você pode usar diretamente tipos diferentes de matrizes de bytes ao ler dados com a classe FileStream.
Exemplo: Leitura de arquivo XML em um objeto XML
O exemplo a seguir demonstra como fazer a leitura e a gravação de um arquivo de texto contendo dados XML.
Para ler o arquivo, inicialize os objetos File e FileStream, chame o método readUTFBytes() do FileStream e converta
a seqüência em um objeto XML:
var file:File = File.documentsDirectory.resolvePath("AIR Test/preferences.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var prefsXML:XML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
fileStream.close();
De modo semelhante, gravar dados no arquivo é tão fácil quanto configurar os objetos File e FileStream apropriados
e, em seguida, chamar um método de gravação do objeto FileStream. Passe a versão de seqüência dos dados XML para
o método de gravação, como no código seguinte:
var prefsXML:XML = <prefs><autoSave>true</autoSave></prefs>;
var file:File = File.documentsDirectory.resolvePath("AIR Test/preferences.xml");
fileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
outputString += prefsXML.toXMLString();
fileStream.writeUTFBytes(outputString);
fileStream.close();
Esses exemplos usam os métodos readUTFBytes() e writeUTFBytes(), porque consideram que os arquivos estejam
no formato UTF-8. Caso contrário, você pode precisar usar um método diferente (consulte “Formatos de dados e
seleção de métodos de leitura e gravação para uso” na página 128).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 131
Trabalho com o sistema de arquivos
Os exemplos anteriores usam objetos FileStream abertos para operação síncrona. Você também pode abrir arquivos
para operações assíncronas (que dependem das funções de ouvinte de evento para responder aos eventos). Por
exemplo, o código a seguir mostra como fazer a leitura de um arquivo XML de modo assíncrono:
var file:File = File.documentsDirectory.resolvePath("AIR Test/preferences.xml");
var fileStream:FileStream = new FileStream();
fileStream.addEventListener(Event.COMPLETE, processXMLData);
fileStream.openAsync(file, FileMode.READ);
var prefsXML:XML;
function processXMLData(event:Event):void
{
prefsXML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
fileStream.close();
}
O método processXMLData() é chamado quando o arquivo inteiro é lido no buffer de leitura (quando o objeto
FileStream despacha o evento complete). Ele chama o método readUTFBytes() para obter uma versão de seqüência
dos dados lidos e cria um objeto XML, prefsXML, com base nessa seqüência.
Exemplo: Leitura e gravação de dados com acesso aleatório
Arquivos MP3 podem incluir marcas ID3, que são seções no início ou no final do arquivo, contendo metadados que
identificam a gravação. O próprio formato de marca ID3 tem revisões diferentes. Este exemplo descreve como fazer a
leitura e a gravação de um arquivo MP3 que contém o formato ID3 mais simples (ID3 versão 1.0) usando o "acesso
aleatório a dados do arquivo", o que significa que ele lê a partir de e grava em locais arbitrários no arquivo.
O arquivo MP3 que contém uma marca ID3 versão 1 inclui dados ID3 no final do arquivo, nos últimos 128 bytes.
Ao acessar um arquivo para acesso de leitura e gravação aleatório, é importante especificar FileMode.UPDATE como
o parâmetro fileMode do método open() ou openAsync():
var file:File = File.documentsDirectory.resolvePath("My Music/Sample ID3 v1.mp3");
var fileStr:FileStream = new FileStream();
fileStr.open(file, FileMode.UPDATE);
Isso permite ler e gravar no arquivo.
Ao abrir o arquivo, você pode definir o ponteiro position para a posição de 128 bytes antes do final do arquivo:
fileStr.position = file.size - 128;
Esse código define a propriedade position para esse local no arquivo, porque o formato ID3 v1.0 especifica que os
dados da marca ID3 são armazenados nos últimos 128 bytes do arquivo. A especificação também diz o seguinte:
• Os primeiros 3 bytes da marca contêm a seqüência "TAG".
• Os 30 caracteres seguintes contêm o título da trilha MP3, como uma seqüência.
• Os 30 caracteres seguintes contêm o nome do artista, como uma seqüência.
• Os 30 caracteres seguintes contêm o nome do álbum, como uma seqüência.
• Os 4 caracteres seguintes contêm o ano, como uma seqüência.
• Os 30 caracteres seguintes contêm o comentário, como uma seqüência.
• O byte seguinte contém um código indicando o gênero da trilha.
• Todos os dados de texto estão no formato ISO 8859-1.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 132
Trabalho com o sistema de arquivos
O método id3TagRead() verifica os dados após serem lidos (no evento complete):
function id3TagRead():void
{
if (fileStr.readMultiByte(3, "iso-8859-1").match(/tag/i))
{
var id3Title:String = fileStr.readMultiByte(30, "iso-8859-1");
var id3Artist:String = fileStr.readMultiByte(30, "iso-8859-1");
var id3Album:String = fileStr.readMultiByte(30, "iso-8859-1");
var id3Year:String = fileStr.readMultiByte(4, "iso-8859-1");
var id3Comment:String = fileStr.readMultiByte(30, "iso-8859-1");
var id3GenreCode:String = fileStr.readByte().toString(10);
}
}
Você também pode realizar uma gravação com acesso aleatório no arquivo. Por exemplo, você pode analisar a variável
id3Title para assegurar que ela esteja com as maiúsculas e minúsculas corretas (usando métodos da classe String) e,
em seguida, fazer a gravação de uma seqüência modificada, chamada newTitle, no arquivo, como no seguinte:
fileStr.position = file.length - 125;
// 128 - 3
fileStr.writeMultiByte(newTitle, "iso-8859-1");
Para corresponder à versão 1 padrão do ID3, o tamanho da seqüência newTitle deve ter 30 caracteres, preenchidos
no final com o caractere de código 0 (String.fromCharCode(0)).
133
Capítulo 15: Arrastar e soltar
Use as classes na API de arrastar e soltar para suportar gestos de arrastar e soltar de interface do usuário. Um gesto
neste sentido é uma ação do usuário, mediada pelo sistema operacional e seu aplicativo, expressando uma intenção de
copiar, mover ou vincular informações. Um gesto de arrastar para fora ocorre quando o usuário arrasta um objeto
para fora de um componente ou aplicativo. Um gesto de arrastar para dentro ocorre quando o usuário arrasta para
dentro um objeto de fora um componente ou aplicativo.
Com a API de arrastar e soltar, você pode permitir que um usuário arraste dados entre aplicativos e entre componentes
dentro de um aplicativo. Os formatos de transferência suportados incluem:
• Bitmaps
• Arquivos
• Texto formatado em HTML
• Texto
• Dados em RTF
• URLs
• Objetos serializados
• Referências a objetos (válido somente dentro do aplicativo originador)
Informações online adicionais sobre arrastar e soltar
Você pode encontrar mais informações sobre como trabalhar com a API de arrastar e soltar nessas fontes:
Início rápido (Adobe AIR Developer Connection)
• Suporte a arrastar e soltar e copiar e colar
Referência de Linguagem
• NativeDragManager
• NativeDragOptions
• Clipboard
• NativeDragEvent
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (procurar 'AIR arrastar e soltar')
Conceitos básicos de arrastar e soltar
A API de arrastar e soltar contém as seguintes classes:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 134
Arrastar e soltar
Pacote
Classes
flash.desktop
•
NativeDragManager
•
NativeDragOptions
•
Clipboard
•
NativeDragActions
•
ClipboardFormat
•
ClipboardTransferModes
Constantes usadas com a API de arrastar e soltar são definidas nas seguintes classes:
flash.events
•
NativeDragActions
•
ClipboardFormat
•
ClipboardTransferModes
NativeDragEvent
Estágios do gesto de arrastar e soltar
O gesto de arrastar e soltar possui três estágios:
Iniciação Um usuário inicia uma operação de arrastar e soltar arrastando de um componente, ou um item em um
componente, enquanto mantém pressionado o botão do mouse. O componente que é a origem do item arrastado é
normalmente designado como o iniciador do ação de arrastar e despacha eventos nativeDragStart e
nativeDragComplete. Um aplicativo do Adobe® AIR™ inicia uma operação de arrastar chamando o método
NativeDragManager.doDrag() em resposta a um evento mouseDown ou mouseMove.
Se a operação de arrastar for iniciada de fora do aplicativo do AIR, não haverá nenhum objeto iniciador para despachar
os eventos nativeDragStart ou nativeDragComplete.
Arrastar Ao segurar o botão do mouse, o usuário move o cursor do mouse para outro componente, aplicativo ou a área
de trabalho. Uma vez que a ação de arrastar esteja em andamento, o objeto iniciador despacha eventos
nativeDragUpdate. Quando o usuário move o mouse sobre um possível destino no qual soltar em um aplicativo do
AIR, o destino despacha um evento nativeDragEnter. O manipulador de eventos pode inspecionar o objeto de
evento para determinar se os dados arrastados estão disponíveis em um formato que o destino aceite e, se sim, permitir
ao usuário soltar os dados nele chamando o método NativeDragManager.acceptDragDrop().
Enquanto o gesto de arrastar permanece sobre um objeto interativo, esse objeto despacha eventos nativeDragOver.
Quando o gesto de arrastar deixa o objeto interativo, ele despacha um evento nativeDragExit.
Soltar O usuário libera o mouse sobre um destino de soltar aceitável. Se o destino for um componente ou aplicativo do
AIR, o objeto de destino despacha um evento nativeDragDrop. O manipulador de eventos pode acessar os dados
transferidos do objeto de evento. Se o destino estiver fora do AIR, o sistema operacional ou outro aplicativo
manipulará a ação de soltar. Nos dois casos, o objeto iniciador despacha um evento nativeDragComplete (se a ação
de arrastar tiver iniciado de dentro do AIR).
A classe NativeDragManager controla os gestos de arrastar para dentro e para fora. Todos os membros da classe
NativeDragManager são estáticos, não crie uma instância dessa classe.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 135
Arrastar e soltar
O objeto Clipboard
Os dados arrastados para dentro ou para fora de um aplicativo ou componente são contidos em um objeto Clipboard.
Um único objeto Clipboard pode disponibilizar representações diferentes das mesmas informações para aumentar a
probabilidade de que outro aplicativo possa entender e usar os dados. Por exemplo, uma imagem poderia ser incluída
como dados de imagem, como um objeto Bitmap serializado e como um arquivo. O processamento dos dados em um
formato pode ser adiado para uma função de processamento não chamada até que os dados sejam lidos.
Após um gesto de arrastar ter sido iniciado, o objeto Clipboard pode apenas ser acessado de dentro de um manipulador
de eventos para os eventos nativeDragEnter, nativeDragOver e nativeDragDrop. Após o gesto de arrastar ter sido
finalizado, o objeto Clipboard não poderá ser lido ou reutilizado.
Um objeto de aplicativo pode ser transferido como uma referência e um objeto serializado. As referências são válidas
apenas dentro do aplicativo originador. Transferências de objetos serializados são válidas entre aplicativos do AIR,
mas podem apenas ser usadas com objetos que permanecem válidos quando serializados e desserializados. Objetos
serializados são convertidos no Action Message Format para ActionScript 3 (AMF3), um formato de transferência de
dados baseado em seqüência de caracteres.
Trabalho com a estrutura do Flex
Na maioria dos casos, é melhor usar a API de arrastar e soltar do Adobe® Flex™ ao criar aplicativos do Flex. A estrutura
do Flex fornece um conjunto de recursos equivalente quando um aplicativo do Flex é executado no AIR (ela usa o
NativeDragManager do AIR internamente). O Flex também mantém um conjunto de recursos mais limitado quando
um aplicativo ou componente está em execução dentro do ambiente do navegador mais restritivo. As classes do AIR
não podem ser usadas em componentes ou aplicativos executados fora do ambiente de tempo de execução do AIR.
Suporte ao gesto de arrastar para fora
Para suportar o gesto de arrastar para fora, você deve criar um objeto Clipboard em resposta a um evento mouseDown
e enviá-lo ao método NativeDragManager.doDrag(). Seu aplicativo pode então ouvir o evento
nativeDragComplete sobre o objeto iniciador para determinar que ação tomar quando o usuário conclui ou
abandona o gesto.
Preparação de dados para transferência
Para preparar dados ou um objeto para arrastar, crie um objeto Clipboard e adicione as informações a serem
transferidas em um ou mais formatos. Você pode usar os formatos de dados padrão para transmitir dados, que podem
ser traduzidos automaticamente para formatos nativos da área de transferência, e formatos definidos por aplicativo
para transmitir objetos. Se, do ponto de vista computacional, for caro converter as informações a serem transferidas
para um formato particular, você pode fornecer o nome de uma função de manipulador para realizar a conversão. A
função é chamada se, e apenas se, o componente ou aplicativo receptor ler o formato associado. Para obter mais
informações sobre os formatos da área de transferência, consulte o capítulo Copiar e colar de Programação do
ActionScript 3.0 (http://www.adobe.com/go/learn_fl_cs4_programmingAS3_en).
O exemplo a seguir ilustra como criar um objeto Clipboard contendo um bitmap em vários formatos: um objeto
Bitmap, um formato de bitmap nativo e um formato da lista de arquivo contendo o arquivo do qual o bitmap foi
originalmente carregado:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 136
Arrastar e soltar
import flash.desktop.Clipboard;
import flash.display.Bitmap;
import flash.filesystem.File;
public function createClipboard(image:Bitmap, sourceFile:File):Clipboard{
var transfer:Clipboard = new Clipboard();
transfer.setData("CUSTOM_BITMAP", image, true); //Flash object by value and by reference
transfer.setData(ClipboardFormats.BITMAP_FORMAT, image.bitmapData, false);
transfer.setData(ClipboardFormats.FILE_LIST_FORMAT, new Array(sourceFile), false);
return transfer;
}
Início de uma operação de arrastar e soltar
Para iniciar uma operação de arrastar, chame o método NativeDragManager.doDrag() em resposta a um evento de
mouse para baixo. O método doDrag() é um método estático que adota os seguintes parâmetros:
Parâmetro
Descrição
iniciador
O objeto do qual a ação de arrastar se origina e que despacha os eventos dragStart e dragComplete. O
iniciador deve ser um objeto interativo.
área de transferência
O objeto Clipboard contendo os dados a serem transferidos. O objeto Clipboard é referenciado nos objetos
NativeDragEvent despachados durante a seqüência de arrastar e soltar.
dragImage
(Opcional) Um objeto BitmapData a ser exibido durante a ação de arrastar. A imagem pode especificar um
valor alpha. (Observação: o Microsoft Windows sempre aplica uma atenuação alfa fixa a imagens de arrastar).
deslocamento
(Opcional) Um objeto Point especificando o deslocamento da imagem de arrastar do ponto ativo do mouse.
Use coordenadas negativas para mover a imagem de arrastar para cima e à esquerda com relação ao cursor
do mouse. Se nenhum deslocamento for fornecido, o canto superior esquerdo da imagem de arrastar será
posicionado no ponto ativo do mouse.
actionsAllowed
(Opcional) Um objeto NativeDragOptions especificando que ações (copiar, mover ou vincular) são válidas
para a operação de arrastar. Se nenhum argumento for fornecido, todas as ações serão permitidas. O objeto
DragOptions é referenciado em objetos NativeDragEvent para permitir que um possível destino da ação de
arrastar verifique se as ações permitidas são compatíveis com o objetivo do componente de destino. Por
exemplo, um componente “trash” pode aceitar apenas gestos de arrastar que permitem a ação de mover.
O exemplo a seguir ilustra como iniciar uma operação de arrastar para um objeto de bitmap carregado de um arquivo.
O exemplo carrega uma imagem e, em um evento mouseDown, inicia a operação de arrastar.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 137
Arrastar e soltar
package
{
import flash.desktop.NativeDragManager;
import mx.core.UIComponent;
import flash.display.Sprite;
import flash.display.Loader;
import flash.system.LoaderContext;
import flash.net.URLRequest;
import flash.geom.Point;
import flash.desktop.Clipboard;
import flash.display.Bitmap;
import flash.filesystem.File;
import flash.events.Event;
import flash.events.MouseEvent;
public class DragOutExample extends UIComponent Sprite {
protected var fileURL:String = "app:/image.jpg";
protected var display:Bitmap;
private function init():void {
loadImage();
}
private function onMouseDown(event:MouseEvent):void {
var bitmapFile:File = new File(fileURL);
var transferObject:Clipboard = createClipboard(display, bitmapFile);
NativeDragManager.doDrag(this,
transferObject,
display.bitmapData,
new Point(-mouseX,-mouseY));
}
public function createClipboard(image:Bitmap, sourceFile:File):Clipboard {
var transfer:Clipboard = new Clipboard();
transfer.setData("bitmap",
image,
true);
// ActionScript 3 Bitmap object by value and by reference
transfer.setData(ClipboardFormats.BITMAP_FORMAT,
image.bitmapData,
false);
// Standard BitmapData format
transfer.setData(ClipboardFormats.FILE_LIST_FORMAT,
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 138
Arrastar e soltar
new Array(sourceFile),
false);
// Standard file list format
return transfer;
}
private function loadImage():void {
var url:URLRequest = new URLRequest(fileURL);
var loader:Loader = new Loader();
loader.load(url,new LoaderContext());
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
}
private function onLoadComplete(event:Event):void {
display = event.target.loader.content;
var flexWrapper:UIComponent = new UIComponent();
flexWrapper.addChild(event.target.loader.content);
addChild(flexWrapper);
flexWrapper.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
}
}
Conclusão de uma transferência de arrastar para fora
Quando um usuário solta o item arrastado liberando o mouse, o objeto iniciador despacha um evento
nativeDragComplete. Você pode verificar a propriedade dropAction do objeto de evento e executar a ação
apropriada. Por exemplo, se a ação for NativeDragAction.MOVE, você poderia remover o item de origem de seu local
original. O usuário pode abandonar um gesto de arrastar liberando o botão do mouse enquanto o cursor está fora de
um destino de arrastar aceitável. O gerente de arrastar define a propriedade dropAction para um gesto abandonado
a NativeDragAction.NONE.
Suporte ao gesto de arrastar para dentro
Para suportar o gesto de arrastar para dentro, seu aplicativo (ou, mais tipicamente, um componente visual do seu
aplicativo) deve responder aos eventos nativeDragEnter ou nativeDragOver.
Etapas em uma operação típica de arrastar
A seguinte seqüência de eventos é típica para uma operação de arrastar:
1 O usuário arrasta um objeto da área de transferência sobre um componente.
2 O componente despacha um evento nativeDragEnter.
3 O manipulador de eventos nativeDragEnter examina o objeto de evento para verificar os formatos de dados
disponíveis e as ações permitidas. Se o componente pode manipular a ação de soltar, ele chama
NativeDragManager.acceptDragDrop().
4 O NativeDragManager altera o cursor do mouse para indicar que o objeto pode ser solto.
5 O usuário solta o objeto sobre o componente.
6 O componente receptor despacha um evento nativeDragDrop.
7 O componente receptor lê os dados no formato desejado do objeto Clipboard dentro do objeto de evento.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 139
Arrastar e soltar
8 Se o gesto de arrastar foi originado no aplicativo do AIR, o objeto interativo iniciador despacha um evento
nativeDragComplete. Se o gesto foi originado fora do AIR, nenhum comentário é enviado.
Reconhecimento de um gesto de arrastar para dentro
Quando um usuário arrasta um item da área de transferência para dentro dos limites de um componente visual, o
componente despacha eventos nativeDragEnter e nativeDragOver. Para determinar se o componente pode aceitar
o item da área de transferência, os manipuladores para esses eventos pode verificar as propriedades clipboard e
allowedActions do objeto de evento. Para sinalizar que o componente pode aceitar a ação de soltar, o manipulador
de eventos deve chamar o método NativeDragManager.acceptDragDrop(), transmitindo uma referência ao
componente receptor. Se mais de um ouvinte de evento registrado chamar o método acceptDragDrop(), o último
manipulador da lista tem precedência. A chamada acceptDragDrop() permanece válida até que o mouse deixe os
limites do objeto recebedor, disparando o evento nativeDragExit.
Se mais de uma ação for permitida no parâmetro allowedActions transmitido a doDrag(), o usuário pode indicar
qual das ações permitidas pretende mantendo pressionada uma tecla de modificador. O gerente de arrastar altera a
imagem do cursor para dizer ao usuário que ação ocorreria se ele concluísse a ação de soltar. A ação pretendida é
reportado pela propriedade dropAction do evento NativeDragEvent. O conjunto de ação para um gesto de arrastar é
apenas consultivo. Os componentes envolvidos na transferência devem implementar o comportamento apropriado.
Para completar uma ação de mover, por exemplo, o iniciador de arrastar poderia remover o item arrastado e o destino
de soltar poderia adicioná-lo.
Seu destino de arrastar pode limitar a ação de soltar para uma das três ações possíveis definindo a propriedade
dropAction da classe NativeDragManager. Se um usuário tenta escolher uma ação diferente usando o teclado,
NativeDragManager exibe o cursor unavailable. Define a propriedade dropAction nos manipuladores para os eventos
nativeDragEnter e nativeDragOver.
O exemplo a seguir ilustra um manipulador de eventos para um evento nativeDragEnter ou nativeDragOver. Esse
manipulador aceita apenas um gesto de arrastar para dentro se a área de transferência sendo arrastada contiver dados
em formato de texto.
import flash.desktop.NativeDragManager;
import flash.events.NativeDragEvent;
public function onDragIn(event:NativeDragEvent):void{
NativeDragManager.dropAction = NativeDragActions.MOVE;
if(event.clipboard.hasFormat(ClipboardFormats.TEXT_FORMAT)){
NativeDragManager.acceptDragDrop(this); //'this' is the receiving component
}
}
Conclusão da ação de soltar
Quando o usuário solta um item arrastado em um objeto interativo que aceitou o gesto, o objeto interativo despacha
um evento nativeDragDrop. O manipulador desse evento pode extrair os dados a propriedade clipboard do objeto
de evento.
Quando a área de transferência contém um formato definido por aplicativo, o parâmetro transferMode transmitido
ao método getData() do objeto Clipboard determina se o gerenciador de arrastar retorna uma referência ou uma
versão serializada do objeto.
O exemplo a seguir ilustra um manipulador de eventos para o evento nativeDragDrop:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 140
Arrastar e soltar
import flash.desktop.Clipboard;
import flash.events.NativeDragEvent;
public function onDrop(event:NativeDragEvent):void {
if (event.clipboard.hasFormat(ClipboardFormats.TEXT_FORMAT)) {
var text:String =
String(event.clipboard.getData(ClipboardFormats.TEXT_FORMAT,
ClipboardTransferMode.ORIGINAL_PREFERRED));
}
Depois que o manipulador de eventos for encerrado, o objeto Clipboard não será mais válido. Qualquer tentativa de
acessar o objeto ou seus dados gera um erro.
Atualização da aparência visual de um componente
Um componente pode atualizar sua aparência visual com base nos eventos NativeDragEvent. A tabela a seguir
descreve os tipos de alterações que um componente típico faria em resposta aos diferentes eventos:
Evento
Descrição
nativeDragStart
O objeto interativo iniciante pode usar o evento nativeDragStart para fornecer comentários visuais que
o gesto de arrastar originou desse objeto interativo.
nativeDragUpdate
O objeto interativo iniciante pode usar o evento nativeDragUpdate para atualizar seu estado durante o gesto.
nativeDragEnter
Um possível objeto interativo receptor pode usar esse evento para assumir o foco ou indicar visualmente que
ele pode ou não aceitar a ação de soltar.
nativeDragOver
Um possível objeto interativo receptor pode usar esse evento para responder ao movimento do mouse
dentro do objeto interativo, como quando o mouse insere uma região “ativa” de um componente complexo,
como uma exibição de mapa de rua.
nativeDragExit
Um possível objeto interativo receptor pode usar esse evento para restaurar seu estado quando um gesto de
arrastar se move para fora de seus limites.
nativeDragComplete
O objeto interativo iniciante pode usar esse evento para atualizar seu modelo de dados associado, como
removendo um item de uma lista e para restaurar seu estado visual.
Rastreamento da posição do mouse durante um gesto de arrastar para dentro
Enquanto um gesto de arrastar permanece sobre um componente, esse componente despacha eventos
nativeDragOver. Esses eventos são despachados a cada poucos milissegundos e também sempre que o mouse se
move. O objeto de evento nativeDragOver pode ser usado para determinar a posição do mouse sobre o componente.
Ter acesso à posição do mouse pode ser útil em situações onde o componente receptor é complexo, mas não é formado
de subcomponentes. Por exemplo, se seu aplicativo exibiu um bitmap contendo um mapa de rua e você desejava
realçar zonas no mapa quando o usuário arrastasse informações a eles, você poderia usar as coordenadas do mouse
reportadas no evento nativeDragOver para rastrear a posição do mouse no mapa.
HTML arrastar e soltar
Para arrastar dados para dentro e fora de um aplicativo baseado em HTML (ou para dentro e fora do HTML exibido
em um HTMLLoader), você pode usar eventos de arrastar e soltar HTML. A API de arrastar e soltar HTML permite
que você arraste para e de elementos DOM no conteúdo HTML.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 141
Arrastar e soltar
Nota: Você também pode usar as APIs NativeDragEvent e NativeDragManager do AIR ouvindo eventos no objeto
HTMLLoader contendo o conteúdo HTML. No entanto, a API HTML é melhor integrada com o DOM HTML e oferece
a você controle do comportamento padrão.
Comportamento padrão de arrastar e soltar
O ambiente HTML fornece o comportamento padrão para gestos de arrastar e soltar envolvendo texto, imagens e
URLs. Usando o comportamento padrão, você sempre pode arrastar esses tipos de dados para fora de um elemento.
No entanto, você pode apenas arrastar texto em um elemento e apenas a elementos em uma região editável de uma
página. Quando você arrasta texto entre ou dentro de regiões editáveis de uma página, o comportamento padrão
executa uma ação de mover. Quando você arrasta texto para uma região editável de uma região não-editável ou de fora
do aplicativo, o comportamento padrão executa uma ação de copiar.
Você pode substituir o comportamento padrão manipulando os eventos de arrastar e soltar sozinho. Para cancelar o
comportamento padrão, você deve chamar os métodos preventDefault() dos objetos despachados para os eventos
de arrastar e soltar. Você pode então inserir dados no destino de soltar e remover dados da origem de arrastar
conforme necessário para executar a ação escolhida.
Por padrão, o usuário pode selecionar e arrastar qualquer texto e arrastar imagens e links. Você pode usar a
propriedade WebKit CSS, -webkit-user-select, para controlar como qualquer elemento HTML pode ser
selecionado. Por exemplo, se você definir -webkit-user-select como none, o conteúdo do elemento não podem ser
selecionados e, portanto, não podem ser arrastados. Você também pode usar a propriedade CSS -webkit-user-drag
para controlar se um elemento como um todo pode ser arrastado. No entanto, o conteúdo do elemento é tratado
separadamente. O usuário poderia ainda arrastar uma parte selecionada do texto. Para obter mais informações,
consulte “Extensões para o CSS” na página 231.
Eventos de arrastar e soltar em HTML
Os eventos despachados pelo elemento iniciador do qual uma ação de arrastar se origina são:
Evento
Descrição
dragstart
Despachado quando o usuário inicia o gesto de arrastar. O manipulador desse evento pode impedir a ação de
arrastar, se necessário, chamando o método preventDefault() do objeto de evento. Para controlar se os dados
arrastados podem ser copiados, vinculados ou movidos, defina a propriedade effectAllowed. Texto, imagens
e links selecionados são colocados na área de transferência pelo comportamento padrão, mas você pode
definir dados diferentes para o gesto de arrastar usando a propriedade dataTransfer do objeto de evento.
arrastar
Despachado continuamente durante o gesto de arrastar.
dragend
Despachado quando o usuário libera o botão do mouse para encerrar o gesto de arrastar.
Os eventos despachados por um destino de arrastar são:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 142
Arrastar e soltar
Evento
Descrição
dragover
Despachado continuamente enquanto o gesto de arrastar permanece dentro dos limites do elemento. O
manipulador para esse evento deve definir a propriedade dataTransfer.dropEffect para indicar se a ação de
soltar resultará em uma ação de copiar, mover ou vincular se o usuário liberar o mouse.
dragenter
Despachado quando o gesto de soltar entrar nos limites de um elemento.
Se você alterar alguma propriedade de um objeto dataTransfer em um manipulador de eventos dragenter,
essas alterações serão rapidamente substituídas pelo próximo evento dragover. Por outro lado, existe um
pequeno atraso entre um evento dragenter e o primeiro dragover que pode fazer com que o cursor pisque se
diferentes propriedades forem definidas. Em vários casos, você pode usar o mesmo manipulador de eventos
para ambos os eventos.
dragleave
Despachado quando o gesto de arrastar deixa os limites do elemento.
drop
Despachado quando o usuário solta os dados no elemento. Os dados sendo arrastados podem apenas ser
acessados dentro do manipulador desse evento.
O objeto de evento despachado em resposta a esses eventos é similar a um evento do mouse. Você pode usar
propriedades de evento de mouse como (clientX, clientY) e (screenX, screenY), para determinar a posição do
mouse.
A propriedade mais importante de um objeto de evento arrastar é dataTransfer, que contém os dados que estão
sendo arrastados. O objeto dataTransfer em si possui as seguintes propriedades e métodos:
Propriedade ou método
Descrição
effectAllowed
O efeito permitido pela origem da ação de arrastar. Normalmente, o manipulador do evento dragstart define
esse valor. Consulte “Efeitos de arrastar em HTML” na página 143.
dropEffect
O efeito escolhido pelo destino ou usuário. Se você define dropEffect em um manipulador de eventos
dragover ou dragenter, o AIR atualiza o cursor do mouse para indicar o efeito que ocorre se o usuário libera
o mouse. Se a definição de dropEffect não corresponder a um dos efeitos permitidos, nenhuma ação de
soltar será permitida e o cursor unavailable será exibido. Se não tiver definido dropEffect em resposta a um
evento dragover ou dragenter mais recente, o usuário poderá escolher dentre os efeitos permitidos com
as teclas do modificador do sistema operacional padrão.
O efeito final é relatado pela propriedade dropEffect do objeto despachado para dragend. Se o usuário
abandonar a ação de soltar liberando o mouse fora de um destino aceitável, dropEffect será definido como
none.
tipos
Uma matriz contendo as seqüências de caracteres de tipo MIME para cada formato de dados é apresentada
no objeto dataTransfer.
getData(mimeType)
Obtém os dados no formato especificado pelo parâmetro mimeType.
O método getData() pode apenas ser chamado em resposta ao evento drop.
setData(mimeType)
Adiciona dados a dataTransfer no formato especificado pelo parâmetro mimeType. Você pode adicionar
dados em vários formatos chamando setData() para cada tipo MIME. Qualquer dado colocado no objeto
dataTransfer pelo comportamento de arrastar padrão é limpo.
O método setData() pode apenas ser chamado em resposta ao evento dragstart.
clearData(mimeType)
Limpa qualquer dado no formato especificado pelo parâmetro mimeType.
setDragImage(image,
offsetX, offsetY)
Define uma imagem de arrastar personalizada. O método setDragImage() pode apenas ser chamado em
resposta ao evento dragstart.
Tipos MIME para arrastar e soltar HTML
Os tipos MIME a usar com o objeto dataTransfer de um evento arrastar e soltar HTML incluem:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 143
Arrastar e soltar
Formato de dados
Tipo MIME
Texto
"text/plain"
HTML
"text/html"
URL
"text/uri-list"
Bitmap
"image/x-vnd.adobe.air.bitmap"
Lista de arquivos
"application/x-vnd.adobe.air.file-list"
Você também pode usar outras seqüências de caracteres MIME, incluindo as definidas por aplicativo. No entanto,
outros aplicativos não podem reconhecer ou usar os dados transferidos. É sua responsabilidade adicionar dados ao
objeto dataTransfer no formato esperado.
Importante: Apenas código em execução na caixa de proteção do aplicativo pode acessar arquivos soltos. Tentar ler ou
definir qualquer propriedade de um objeto File em uma caixa de proteção de não-aplicativo gera um erro de segurança.
Consulte “Tratamento de arquivos soltos em caixas de proteção HTML de não-aplicativo” na página 147 para obter mais
informações.
Efeitos de arrastar em HTML
O iniciador do gesto de arrastar pode limitar os efeitos de arrastar permitido definindo a propriedade
dataTransfer.effectAllowed no manipulador para o evento dragstart. Os seguintes valores de seqüências de
caracteres podem ser usados:
Valor de string
Descrição
"none"
Nenhuma operação de arrastar é permitida.
"copy"
Os dados serão copiados ao destino, deixando o original no lugar.
"link"
Os dados serão compartilhados com o destino de soltar usando um link de volta ao original.
"mover”
Os dados serão copiados para o destino e removidos do local original.
"copyLink"
Os dados podem ser copiados ou vinculados.
"copyMove"
Os dados podem ser copiados ou movidos.
"linkMove"
Os dados podem ser vinculados ou movidos.
"all"
Os dados podem ser copiados, movidos ou vinculados. All é o efeito padrão quando você impede o
comportamento padrão.
O destino do gesto de arrastar pode definir a propriedade dataTransfer.dropEffect para indicar a ação tomada se
o usuário concluir a ação de soltar. Se o efeito de soltar for uma das ações permitidas, o sistema exibe o cursor
apropriado de copiar, mover ou vincular. Caso contrário, o sistema exibe o cursor unavailable. Se nenhum efeito de
soltar for definido pelo destino, o usuário poderá escolher dentre as ações permitidas com as teclas do modificador.
Defina o valor dropEffect nos manipuladores para os eventos dragover e dragenter:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 144
Arrastar e soltar
function doDragStart(event) {
event.dataTransfer.setData("text/plain","Text to drag");
event.dataTransfer.effectAllowed = "copyMove";
}
function doDragOver(event) {
event.dataTransfer.dropEffect = "copy";
}
function doDragEnter(event) {
event.dataTransfer.dropEffect = "copy";
}
Nota: Embora você deva sempre definir a propriedade dropEffect no manipulador para dragenter, esteja ciente que
o próximo evento dragover redefine a propriedade para seu valor padrão. Defina dropEffect em resposta aos dois
eventos.
Arrastar dados para fora de um elemento HTML
O comportamento padrão permite que a maior parte do conteúdo em uma página HTML seja copiada pela ação de
arrastar. Você pode controlar o conteúdo permitido a ser arrastado usando as propriedades CSS -webkit-userselect e -webkit-user-drag.
Substitua o comportamento padrão de arrastar para fora no manipulador para o evento dragstart. Chame o método
setData() da propriedade dataTransfer do objeto de evento para colocar seus próprios dados no gesto de arrastar.
Para indicar que efeitos de arrastar um objeto de origem suporta quando você não está contando com o
comportamento padrão, define a propriedade dataTransfer.effectAllowed do objeto de evento despachado para
o evento dragstart. Você pode escolher qualquer combinação de efeitos. Por exemplo, se um elemento de origem
suportar os efeitos copy e link, defina a propriedade como "copyLink".
Definição dos dados arrastados
Adicione os dados para o gesto de arrastar no manipulador para o evento dragstart com a propriedade
dataTransfer. Use o método dataTransfer.setData() para colocar dados na área de transferência, transmitindo
o tipo MIME e os dados a transferir.
Por exemplo, se você tinha um elemento de imagem no seu aplicativo, com a id imageOfGeorge, você poderia usar o
seguinte manipulador de eventos dragstart. Esse exemplo adiciona representações de uma imagem de George em
vários formatos de dados, que aumenta a probabilidade de que outros aplicativos possam usar os dados arrastados.
function dragStartHandler(event){
event.dataTransfer.effectAllowed = "copy";
var dragImage = document.getElementById("imageOfGeorge");
var dragFile = new air.File(dragImage.src);
event.dataTransfer.setData("text/plain","A picture of George");
event.dataTransfer.setData("image/x-vnd.adobe.air.bitmap", dragImage);
event.dataTransfer.setData("application/x-vnd.adobe.air.file-list",
new Array(dragFile));
}
Nota: Quando você chama o método setData() de objeto dataTransfer, nenhum dado é adicionado pelo
comportamento padrão de arrastar e soltar.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 145
Arrastar e soltar
Arrastar dados para dentro de um elemento HTML
O comportamento padrão apenas permite que texto seja arrastado em regiões editáveis da página. Você pode
especificar que um elemento e seus filhos podem se tornar editáveis incluindo o atributo contenteditable na tag de
abertura do elemento. Você também pode tornar um documento inteiro editável definindo a propriedade designMode
de objeto de documento como "on".
Você pode suportar um comportamento alternativo de arrastar para dentro em uma página manipulando os eventos
dragenter, dragover e drop para qualquer elemento que pode aceitar dados arrastados.
Ativação de arrastar para dentro
Para manipular o gesto de arrastar para dentro, você deve primeiro cancelar o comportamento padrão. Ouça os
eventos dragenter e dragover em qualquer elemento HTML que deseja usar como destinos de soltar. Nos
manipuladores desses eventos, chame o método preventDefault() do objeto de evento despachado. Cancelar o
comportamento padrão permite que regiões não editáveis recebam uma ação de soltar.
Obtenção de dados soltos
Você pode acessar os dados soltos no manipulador para o evento ondrop:
function doDrop(event){
droppedText = event.dataTransfer.getData("text/plain");
}
Use o método dataTransfer.getData() para ler dados na área de transferência, transmitindo o tipo MIME do
formato de dados a ler. Você pode descobrir que formatos de dados estão disponíveis usando a propriedade types do
objeto dataTransfer. A matriz types contém a seqüência de caracteres de tipo MIME de cada formato disponível.
Quando você cancela o comportamento padrão nos eventos dragenter ou dragover, você é responsável por inserir
qualquer dado solto em seu próprio lugar no documento. Nenhuma API existe para converter uma posição do mouse
em um ponto de inserção dentro de um elemento. Essa limitação pode dificultar a implementação de gestos de arrastar
de tipo de inserção.
Exemplo: Substituição do comportamento padrão de arrastar para dentro
HTML
Esse exemplo implementa um destino de soltar que exibe uma tabela mostrando cada formato de dados disponível no
item solto.
O comportamento padrão é usado para permitir que texto, links e imagens sejam arrastados no aplicativo. O exemplo
substitui o comportamento padrão de arrastar para dentro para o elemento div que serve como o destino de soltar. A
etapa principal para habilitar conteúdo não-editável para aceitar um gesto de arrastar para dentro é chamar o método
preventDefault() do objeto de evento despachado para os eventos dragenter e dragover. Em resposta a um
evento drop, o manipulador converte os dados transferidos em um elemento de linha HTML e insere a linha em uma
tabela para exibição.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 146
Arrastar e soltar
<html>
<head>
<title>Drag-and-drop</title>
<script language="javascript" type="text/javascript" src="AIRAliases.js"></script>
<script language="javascript">
function init(){
var target = document.getElementById('target');
target.addEventListener("dragenter", dragEnterOverHandler);
target.addEventListener("dragover", dragEnterOverHandler);
target.addEventListener("drop", dropHandler);
var source = document.getElementById('source');
source.addEventListener("dragstart", dragStartHandler);
source.addEventListener("dragend", dragEndHandler);
emptyRow = document.getElementById("emptyTargetRow");
}
function dragStartHandler(event){
event.dataTransfer.effectAllowed = "copy";
}
function dragEndHandler(event){
air.trace(event.type + ": " + event.dataTransfer.dropEffect);
}
function dragEnterOverHandler(event){
event.preventDefault();
}
var emptyRow;
function dropHandler(event){
for(var prop in event){
air.trace(prop + " = " + event[prop]);
}
var row = document.createElement('tr');
row.innerHTML = "<td>" + event.dataTransfer.getData("text/plain") + "</td>" +
"<td>" + event.dataTransfer.getData("text/html") + "</td>" +
"<td>" + event.dataTransfer.getData("text/uri-list") + "</td>" +
"<td>" + event.dataTransfer.getData("application/x-vnd.adobe.air.file-list") +
"</td>";
var imageCell = document.createElement('td');
if((event.dataTransfer.types.toString()).search("image/x-vnd.adobe.air.bitmap") > 1){
imageCell.appendChild(event.dataTransfer.getData("image/xvnd.adobe.air.bitmap"));
}
row.appendChild(imageCell);
var parent = emptyRow.parentNode;
parent.insertBefore(row, emptyRow);
}
</script>
</head>
<body onLoad="init()" style="padding:5px">
<div>
<h1>Source</h1>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 147
Arrastar e soltar
<p>Items to drag:</p>
<ul id="source">
<li>Plain text.</li>
<li>HTML <b>formatted</b> text.</li>
<li>A <a href="http://www.adobe.com">URL.</a></li>
<li><img src="icons/AIRApp_16.png" alt="An image"/></li>
<li style="-webkit-user-drag:none;">
Uses "-webkit-user-drag:none" style.
</li>
<li style="-webkit-user-select:none;">
Uses "-webkit-user-select:none" style.
</li>
</ul>
</div>
<div id="target" style="border-style:dashed;">
<h1 >Target</h1>
<p>Drag items from the source list (or elsewhere).</p>
<table id="displayTable" border="1">
<tr><th>Plain text</th><th>Html text</th><th>URL</th><th>File list</th><th>Bitmap
Data</th></tr>
<tr
id="emptyTargetRow"><td> </td><td> </td><td> </td><td> </td><td> </
td></tr>
</table>
</div>
</div>
</body>
</html>
Tratamento de arquivos soltos em caixas de proteção HTML de não-aplicativo
O conteúdo de não-aplicativo não pode acessar os objetos File resultantes quando arquivos são arrastados em um
aplicativo do AIR. Nem é possível transmitir um desses objetos File para conteúdo de aplicativo por uma ponte de
caixa de proteção. (As propriedades do objeto devem ser acessadas durante a serialização.) No entanto, você pode
ainda soltar arquivos no seu aplicativo ouvindo os eventos nativeDragDrop do AIR no objeto HTMLLoader.
Normalmente, se um usuário solta um arquivo em um quadro que hospeda conteúdo de não-aplicativo, o evento de
soltar não propaga do filho ao pai. No entanto, como os eventos despachados pelo HTMLLoader (que é o contêiner
para todo o conteúdo HTML em um aplicativo do AIR) não são parte do fluxo de evento HTML, você pode ainda
receber o evento de soltar em conteúdo de aplicativo.
Para receber o evento para um arquivo solto, o documento pai adiciona um ouvinte de evento ao objeto HTMLLoader
usando a referência fornecida por window.htmlLoader:
window.htmlLoader.addEventListener("nativeDragDrop",function(event){
var filelist = event.clipboard.getData(air.ClipboardFormats.FILE_LIST_FORMAT);
air.trace(filelist[0].url);
});
O exemplo a seguir usa um documento pai que carrega uma página filha em uma caixa de proteção remota
(http://localhost/). O pai ouve o evento nativeDragDrop no objeto HTMLLoader e marca a URL do arquivo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 148
Arrastar e soltar
<html>
<head>
<title>Drag-and-drop in a remote sandbox</title>
<script language="javascript" type="text/javascript" src="AIRAliases.js"></script>
<script language="javascript">
window.htmlLoader.addEventListener("nativeDragDrop",function(event){
var filelist = event.clipboard.getData(air.ClipboardFormats.FILE_LIST_FORMAT);
air.trace(filelist[0].url);
});
</script>
</head>
<body>
<iframe src="child.html"
sandboxRoot="http://localhost/"
documentRoot="app:/"
frameBorder="0" width="100%" height="100%">
</iframe>
</body>
</html>
O documento filho deve apresentar um destino de soltar válido impedindo que o método preventDefault() do
objeto Event nos manipuladores de eventos dragenter e dragover HTML ou o evento de soltar nunca pode ocorrer.
<html>
<head>
<title>Drag and drop target</title>
<script language="javascript" type="text/javascript">
function preventDefault(event){
event.preventDefault();
}
</script>
</head>
<body ondragenter="preventDefault(event)" ondragover="preventDefault(event)">
<div>
<h1>Drop Files Here</h1>
</div>
</body>
</html>
Para obter mais informações, consulte “Programação em HTML e JavaScript” na página 233.
149
Capítulo 16: Copiar e colar
Use as classes na API da área de transferência para copiar informações para e da área de transferência do sistema. Os
formatos de dados que podem ser transferidos para ou de um aplicativo do Adobe® AIR™ incluem:
• Bitmaps
• Arquivos
• Texto
• Texto formatado em HTML
• Dados em RTF
• Strings URL
• Objetos serializados
• Referências a objetos (válido somente dentro do aplicativo originador)
O Adobe Flash Player 10 adicionou a funcionalidade de copiar e colar que foi introduzida no AIR 1.0. Este capítulo
discute a funcionalidade de copiar e colar única do Adobe AIR. Para obter detalhes sobre esta funcionalidade
compartilhada, consulte Copiar e colar (no livro Programação do Adobe ActionScript 3.0.
Informações online adicionais sobre copiar e colar
Você pode encontrar mais informações sobre copiar e colar nessas fontes:
Início rápido (Adobe AIR Developer Connection)
• Suporte a arrastar e soltar e copiar e colar
Referência de Linguagem
• Clipboard
• ClipboardFormats
• ClipboardTransferMode
Mais informações
• Copiar e colar (no livro Programação do Adobe ActionScript 3.0)
• Conexão de desenvolvedores do Adobe AIR para Flash (procurar 'AIR copiar e colar')
Copiar e colar HTML
O ambiente HTML fornece seu próprio conjunto de eventos e comportamento padrão para copiar e colar. Apenas
códigos em execução na caixa de proteção do aplicativo podem acessar a área de transferência do sistema diretamente
pelo objeto do AIR Clipboard.generalClipboard. Códigos JavaScript em uma caixa de proteção de não-aplicativo
podem acessar a área de transferência pelo objeto de evento despachado em resposta a um dos eventos de copiar ou
colar despachados por um elemento em um documento HTML.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 150
Copiar e colar
Os eventos de copiar e colar incluem: copy, cut e paste. O objeto despachado para esses eventos fornece acesso à área
de transferência pela propriedade clipboardData.
Comportamento padrão
Por padrão, o AIR copia itens selecionados em resposta ao comando de copiar, que pode ser gerado por um atalho do
teclado ou um menu de contexto. Em regiões editáveis, o AIR recorta textos em resposta ao comando de recortar ou
cola textos para o cursor ou seleção em resposta ao comando de colar.
Para impedir o comportamento padrão, seu manipulador de eventos pode chamar o método preventDefault() do
objeto de evento despachado.
Uso da propriedade clipboardData do objeto de evento
A propriedade clipboardData do objeto de evento despachado como um resultado de um dos eventos de copiar ou
colar permite que você leia e escreva dados da área de transferência.
Para escrever na área de transferência ao manipular um evento de copiar ou recortar, use o método setData() do
objeto clipboardData, transmitindo os dados para copiar e o tipo MIME:
function customCopy(event){
event.clipboardData.setData("text/plain", "A copied string.");
}
Para acessar os dados que estão sendo colados, você pode usar o método getData() do objeto clipboardData,
transmitindo o tipo MIME do formato de dados. Os formatos disponíveis são relatados pela propriedade types.
function customPaste(event){
var pastedData = event.clipboardData("text/plain");
}
O método getData() e a propriedade types podem apenas ser acessados no objeto de evento despachado pelo evento
paste.
O exemplo a seguir ilustra como substituir o comportamento de copiar e colar padrão em uma página HTML. O
manipulador de eventos copy coloca em itálico o texto copiado e o copia para a área de transferência como texto
HTML. O manipulador de eventos cut copia os dados selecionados para a área de transferência e os remove do
documento. O manipulador paste insere o conteúdo da área de transferência como HTML e aplica um estilo na
inserção como texto em negrito.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 151
Copiar e colar
<html>
<head>
<title>Copy and Paste</title>
<script language="javascript" type="text/javascript">
function onCopy(event){
var selection = window.getSelection();
event.clipboardData.setData("text/html","<i>" + selection + "</i>");
event.preventDefault();
}
function onCut(event){
var selection = window.getSelection();
event.clipboardData.setData("text/html","<i>" + selection + "</i>");
var range = selection.getRangeAt(0);
range.extractContents();
event.preventDefault();
}
function onPaste(event){
var insertion = document.createElement("b");
insertion.innerHTML = event.clipboardData.getData("text/html");
var selection = window.getSelection();
var range = selection.getRangeAt(0);
range.insertNode(insertion);
event.preventDefault();
}
</script>
</head>
<body onCopy="onCopy(event)"
onPaste="onPaste(event)"
onCut="onCut(event)">
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam
voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur
magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
</body>
</html>
Comandos de menu e pressionamentos de tecla para
copiar e colar
A funcionalidade de copiar e colar é comumente disparada pelos comandos de menu e atalhos do teclado. No OS X,
um menu de edição com os comandos de copiar e colar é criado automaticamente pelo sistema operacional, mas você
deve adicionar ouvintes a esses comandos de menu para fazer a junção com suas próprias funções de copiar e colar.
No Windows, você pode adicionar um menu de edição nativo a qualquer janela que use o cromo do sistema. (Você
também pode criar menus não-nativos com Flex e ActionScript, ou, em conteúdo HTML, você pode usar DHTML,
mas isso está além do escopo desta discussão.)
Para disparar comandos de copiar e colar em resposta a atalhos do teclado, você pode atribuir teclas equivalentes aos
itens de comando apropriados em um aplicativo nativo ou menu de janela ou você pode ouvir os pressionamentos de
tecla diretamente.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 152
Copiar e colar
Inicialização de uma operação de copiar ou colar com um comando de menu
Para disparar uma operação de copiar ou colar com um comando de menu, você deve adicionar ouvintes ao evento
select nos itens de menu que chamam as funções do seu manipulador.
Quando a função do seu manipulador é chamada, você pode encontrar o objeto a ser copiado de ou colado usando a
propriedade focus do estágio. Você pode então chamar o método apropriado do objeto focado (ou um método de
fallback geral, se nenhum objeto possui foco) para realizar a lógica de copiar, recortar ou colar. Por exemplo, o seguinte
manipulador de eventos copy verifica se o objeto focado é do tipo correto, nesse caso, uma classe chamada Scrap, e
chama o método doCopy() do objeto.
function copyCommand(event:Event):void{
if(NativeApplication.nativeApplication.activeWindow.stage.focus is Scrap){
Scrap(NativeApplication.nativeApplication.activeWindow.stage.focus).doCopy();
} else {
NativeApplication.nativeApplication.copy();
}
}
Se copyCommand() no exemplo não reconhecer a classe do objeto focado, ele chamará o método copy()
NativeApplication. O método copy() NativeApplication envia um comando de cópia interno para o objeto focado. Se
o objeto for uma classe incorporada que implementa copiar e colar internamente, o objeto executará o comando. As
classes Textfield e HTMLLoader são atualmente as únicas classes incorporadas. Outros objetos interativos
despacharão o evento copy. Comandos similares estão disponíveis para recortar, colar, selecionar tudo e para
TextArea apenas, limpar, desfazer e refazer.
Em conteúdo HTML, o comportamento padrão de copiar e colar pode ser disparado usando os comandos de editar
NativeApplication. O exemplo a seguir cria um menu de edição para um documento HTML editável:
O exemplo anterior substitui o menu do aplicativo no Mac OS X, mas você também pode usar o menu Editar padrão
encontrando os itens existentes e adicionando ouvintes de eventos a eles.
Se você usar um menu de contexto para invocar um comando de copiar ou colar, poderá usar a propriedade
contextMenuOwner do objeto ContextMenuEvent despachado quando o menu for aberto ou um item for selecionado
para determinar qual objeto é o destino adequado do comando de copiar ou colar.
Localização de itens de menu padrão no Mac OS X
Para encontrar o menu de edição padrão e os itens de comando copiar, recortar e colar específicos no menu do aplicativo
no Mac OS X, você pode pesquisar pela hierarquia do menu usando a propriedade label dos objetos NativeMenuItem.
Por exemplo, a função a seguir adota um nome e encontra o item com o rótulo correspondente no menu:
private function findItemByName(menu:NativeMenu,
name:String,
recurse:Boolean = false):NativeMenuItem{
var searchItem:NativeMenuItem = null;
for each (var item:NativeMenuItem in menu.items){
if(item.label == name){
searchItem = item;
break;
}
if((item.submenu != null) && recurse){
searchItem = findItemByName(item.submenu, name);
}
}
return searchItem;
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 153
Copiar e colar
Você pode definir o parâmetro recurse como true para incluir submenus na pesquisa ou false para incluir apenas
o menu transmitido.
Iniciando um comando de copiar ou colar com um pressionamento de tecla
Se seu aplicativo usa a janela nativa ou menus do aplicativo para copiar e colar, você pode adicionar equivalentes de
teclas aos itens de menu para implementar atalhos do teclado.
Se seu aplicativo usa a janela nativa ou menus do aplicativo para copiar e colar, você pode adicionar equivalentes de
teclas aos itens de menu para implementar atalhos do teclado. De outro modo, você pode ouvir por si só
pressionamentos de teclas relevantes, como demonstrado no seguinte exemplo:
private function init():void{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyListener);
}
private function keyListener(event:KeyboardEvent):void{
if(event.ctrlKey){
event.preventDefault();
switch(String.fromCharCode(event.charCode)){
case "c":
NativeApplication.nativeApplication.copy();
break;
case "x":
NativeApplication.nativeApplication.cut();
break;
case "v":
NativeApplication.nativeApplication.paste();
break;
case "a":
NativeApplication.nativeApplication.selectAll();
break;
case "z":
NativeApplication.nativeApplication.undo();
break;
case "y":
NativeApplication.nativeApplication.redo();
break;
}
}
}
Em conteúdo HTML, os atalhos do teclado para comandos de copiar e colar são implementados por padrão. Não é
possível capturar todos os pressionamentos de tecla comumente usados para copiar e colar usando um ouvinte de
eventos de tecla. Se você precisar substituir o comportamento padrão, uma estratégia melhor seria ouvir os próprios
eventos copy e paste.
154
Capítulo 17: Trabalhar com matrizes de
bytes
A classe ByteArray permite que você leia de e escreva para um fluxo de dados binário, que é essencialmente uma matriz
de bytes. Essa classe fornece uma maneira de acessar dados no nível mais elementar. Como os dados do computador
consistem em bytes, ou grupos de 8 bits, a capacidade de ler dados em bytes significa que você pode acessar dados para
os quais classes e métodos de acesso não existem. A classe ByteArray permite que você analise qualquer fluxo de dados,
de um bitmap a um fluxo de dados que viaje pela rede, no nível de byte.
O método writeObject() permite que você escreva um objeto em AMF serializado para um ByteArray, enquanto o
método readObject() permite que você leia um objeto serializado de um ByteArray para uma variável do tipo de
dados original. Você pode serializar qualquer objeto, exceto objetos de exibição, que são aqueles que podem ser
colocados na lista de exibição. Você também pode atribuir objetos serializados de volta às instâncias de classe
personalizada se a classe personalizada estiver disponível para o tempo de execução. Após converter um objeto para
AMF, você pode transferi-lo de modo eficiente por uma conexão de rede ou salvá-lo em um arquivo.
O aplicativo de exemplo do Adobe® AIR™ descrito aqui lê um arquivo .zip como um exemplo de processar um fluxo
de bytes; extraindo uma lista dos arquivos contidos no arquivo .zip e escrevendo-os na área de trabalho.
Ler e escrever um ByteArray
A classe ByteArray é parte do pacote flash.utils. Para criar um objeto ByteArray no ActionScript 3.0, importe a classe
ByteArray e invoque o construtor, conforme exibido no seguinte exemplo:
import flash.utils.ByteArray;
var stream:ByteArray = new ByteArray();
Métodos ByteArray
Qualquer fluxo de dados significativo é organizado em um formato que você pode analisar para encontrar as
informações desejadas. Um registro em um simples arquivo de um funcionário, por exemplo, provavelmente incluiria
um número de ID, um nome, um endereço, um número de telefone e assim por diante. Um arquivo de áudio MP3
contém uma marca ID3 que identifica o título, autor, álbum, data de publicação e gênero do arquivo que está sendo
obtido por download. O formato permite que você saiba a ordem na qual esperar os dados no fluxo de dados. Ele
permite que você leia o fluxo de bytes de modo inteligente.
A classe ByteArray inclui vários métodos que facilitam ler de e escrever para um fluxo de dados. Alguns desses métodos
incluem readBytes() e writeBytes(), readInt() e writeInt(), readFloat() e writeFloat(), readObject() e
writeObject() e readUTFBytes() e writeUTFBytes(). Esses métodos permitem que você leia dados do fluxo de
dados em variáveis de tipos de dados específicos e escreva de tipos de dados específicos diretamente para o fluxo de
dados binário.
Por exemplo, o código a seguir lê uma matriz simples de seqüências de caracteres e números de ponto flutuante e
escreve cada elemento em um ByteArray. A organização da matriz permite que o código chame os métodos ByteArray
apropriados (writeUTFBytes() e writeFloat()) para escrever os dados. O padrão de dados repetitivo possibilita ler
a matriz com um loop.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 155
Trabalhar com matrizes de bytes
// The following example reads a simple Array (groceries), made up of strings
// and floating-point numbers, and writes it to a ByteArray.
import flash.utils.ByteArray;
// define the grocery list Array
var groceries:Array = ["milk", 4.50, "soup", 1.79, "eggs", 3.19, "bread" , 2.35]
// define the ByteArray
var bytes:ByteArray = new ByteArray();
// for each item in the array
for (var i:int = 0; i < groceries.length; i++) {
bytes.writeUTFBytes(groceries[i++]); //write the string and position to the next item
bytes.writeFloat(groceries[i]);// write the float
trace("bytes.position is: " + bytes.position);//display the position in ByteArray
}
trace("bytes length is: " + bytes.length);// display the length
A propriedade position
A propriedade position armazena a posição atual do ponteiro que indexa ByteArray durante a leitura ou escrita. O
valor inicial da propriedade position é 0 (zero), como exibido no seguinte código:
var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
Quando você lê de ou escreve em um ByteArray, o método usado atualiza a propriedade position para apontar para o
local imediatamente seguindo o último byte lido ou escrito. Por exemplo, o código a seguir escreve uma seqüência de
caracteres em um ByteArray e, posteriormente, a propriedade position aponta para o byte imediatamente seguindo a
seqüência de caracteres no ByteArray:
var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
bytes.writeUTFBytes("Hello World!");
trace("bytes.position is now: " + bytes.position);// 12
Da mesma forma, uma operação de leitura incrementa a propriedade position pelo número de bytes lidos.
var bytes:ByteArray = new ByteArray();
trace("bytes.position is initially: " + bytes.position); // 0
bytes.writeUTFBytes("Hello World!");
trace("bytes.position is now: " + bytes.position);// 12
bytes.position = 0;
trace("The first 6 bytes are: " + (bytes.readUTFBytes(6)));//Hello
trace("And the next 6 bytes are: " + (bytes.readUTFBytes(6)));// World!
Observe que você pode definir a propriedade position para um local específico no ByteArray para ler ou escrever
naquele deslocamento.
As propriedades bytesAvailable e length
As propriedades length e bytesAvailable dizem a você quanto tempo um ByteArray possui e quantos bytes
permanecem nele da posição atual até o fim. O exemplo a seguir ilustra como você pode usar essas propriedades. O
exemplo escreve uma seqüência de caracteres de texto para o ByteArray e, em seguida, lê um byte de cada vez do
ByteArray até que ele encontre o caractere “a” ou o final (bytesAvailable <= 0).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 156
Trabalhar com matrizes de bytes
var bytes:ByteArray = new ByteArray();
var text:String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus etc.";
bytes.writeUTFBytes(text); // write the text to the ByteArray
trace("The length of the ByteArray is: " + bytes.length);// 70
bytes.position = 0; // reset position
while (bytes.bytesAvailable > 0 && (bytes.readUTFBytes(1) != 'a')) {
//read to letter a or end of bytes
}
if (bytes.position < bytes.bytesAvailable) {
trace("Found the letter a; position is: " + bytes.position); // 23
trace("and the number of bytes available is: " + bytes.bytesAvailable);// 47
}
A propriedade endian
Os computadores podem diferir em como armazenam números de vários bytes, isto é, números que exigem mais de
um 1 byte de memória para armazená-los. Um inteiro, por exemplo, pode levar 4 bytes, ou 32 bits, de memória. Alguns
computadores armazenam o byte mais significativo do número primeiro, no endereço de memória mais baixo e outros
armazenam o byte menos significativo primeiro. Esse atributo de um computador, ou de uma ordem de bytes, é
conhecido como sendo big endian (byte mais significativo primeiro) ou little endian (byte menos significativo
primeiro). Por exemplo, o número 0x31323334 seria armazenado da seguinte forma para ordem de bytes big endian e
little endian, onde a0 representa o endereço de memória mais baixo dos 4 bytes e a3 representa o mais alto:
Big
Endian
Big
Endian
Big
Endian
Big
Endian
a0
a1
a2
a3
31
32
33
34
Little
Endian
Little
Endian
Little
Endian
Little
Endian
a0
a1
a2
a3
34
33
32
31
A propriedade endian da classe ByteArray permite que você denote essa ordem de bytes para números de vários bytes
que você esteja processando. Os valores aceitáveis para essa propriedade são "bigEndian" ou "littleEndian" e a
classe Endian define as constantes BIG_ENDIAN e LITTLE_ENDIAN para definir a propriedade endian com essas
seqüências de caracteres.
Os métodos compress() e uncompress()
O método compress() permite que você compacte um ByteArray de acordo com um algoritmo de compactação
especificado como um parâmetro. O método uncompress() permite que você descompacte um ByteArray
compactado de acordo com um algoritmo de compactação. Após chamar compress() e uncompress(), o
comprimento da matriz de bytes é definida para o novo comprimento e a propriedade position é definida para o fim.
A classe CompressionAlgorithm define constantes que você pode usar para especificar o algoritmo de compactação.
O AIR suporta os algoritmos deflate e zlib. O algoritmo de compactação deflate é usado em vários formatos de
compactação, tais como zlib, gzip e algumas implementações zip. O formato de dados compactado zlib é descrito em
http://www.ietf.org/rfc/rfc1950.txt e o algoritmo de compactação deflate é descrito em
http://www.ietf.org/rfc/rfc1951.txt.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 157
Trabalhar com matrizes de bytes
O exemplo a seguir compacta um ByteArray chamado bytes usando o algoritmo deflate:
bytes.compress(CompressionAlgorithm.DEFLATE);
O exemplo a seguir descompacta um ByteArray compactado usando o algoritmo deflate:
bytes.uncompress(CompressionAlgorithm.DEFLATE);
Leitura e escrita de objetos
Os métodos readObject() e writeObject() lêem um objeto de e escrevem um objeto para um ByteArray,
codificado em AMF serializado. AMF é um protocolo de mensagens proprietário criado pela Adobe e usado por várias
classes do ActionScript 3.0, incluindo Netstream, NetConnection, NetStream, LocalConnection e Shared Objects.
Um marcador de tipo de um byte descreve o tipo dos dados codificados que segue. O AMF usa os 13 tipos de dados a
seguir:
value-type = undefined-marker | null-marker | false-marker | true-marker | integer-type |
double-type | string-type | xml-doc-type | date-type | array-type | object-type |
xml-type | byte-array-type
Os dados codificados seguem o marcador de tipo, a menos que o marcador represente um único valor possível, como
null ou true ou false, em cujo caso nada mais é codificado.
Existem duas versões do AMF: AMF0 e AMF3. O AMF 0 suporta o envio de objetos complexos por referência e
permite pontos de extremidade para restaurar as relações entre objetos. O AMF 3 melhora o AMF 0 enviando
características de objetos e seqüências de caracteres por referência, além de referências de objetos, e suportando novos
tipos de dados introduzidos no ActionScript 3.0. A propriedade ByteArray.objectEcoding especifica a versão do
AMF usada para codificar os dados do objeto. A classe flash.net.ObjectEncoding define constantes para especificar a
versão do AMF: ObjectEncoding.AMF0 e ObjectEncoding.AMF3.
import flash.filesystem.*;
import flash.utils.ByteArray;
// Label component must be in Library
import fl.controls.Label;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 158
Trabalhar com matrizes de bytes
var bytes:ByteArray = new ByteArray();
var myLabel:Label = new Label();
myLabel.move(150, 150);
myLabel.width = 200;
addChild(myLabel);
var myXML:XML =
<order>
<item id='1'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>
// Write XML object to ByteArray
bytes.writeObject(myXML);
bytes.position = 0;//reset position to beginning
bytes.compress(CompressionAlgorithm.DEFLATE);// compress ByteArray
outFile("order", bytes);
myLabel.text = "Wrote order file to desktop!";
function outFile(fileName:String, data:ByteArray):void {
var outFile:File = File.desktopDirectory; // dest folder is desktop
outFile = outFile.resolvePath(fileName); // name of file to write
var outStream:FileStream = new FileStream();
// open output file stream in WRITE mode
outStream.open(outFile, FileMode.WRITE);
// write out the file
outStream.writeBytes(data, 0, data.length);
// close it
outStream.close();
}
O método readObject() lê um objeto no AMF serializado de um ByteArray e o armazena em um objeto do tipo
especificado. O exemplo a seguir lê o arquivo order da área de trabalho em um ByteArray (inBytes), o descompacta
e chama readObject() para armazená-lo no objeto XML orderXML. O exemplo usa uma construção de loop for
each() para adicionar cada nó a uma área de texto para exibição. O exemplo também exibe o valor da propriedade
objectEncoding juntamente com um cabeçalho para o conteúdo do arquivo order.
import flash.filesystem.*;
import flash.utils.ByteArray;
// TextArea component must be in Library
import fl.controls.TextArea;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 159
Trabalhar com matrizes de bytes
var inBytes:ByteArray = new ByteArray();
// define text area for displaying XML content
var myTxt:TextArea = new TextArea();
myTxt.width = 550;
myTxt.height = 400;
addChild(myTxt);
//display objectEncoding and file heading
myTxt.text = "Object encoding is: " + inBytes.objectEncoding + "\n\n" + "order file: \n\n";
readFile("order", inBytes);
inBytes.position = 0; // reset position to beginning
inBytes.uncompress(CompressionAlgorithm.DEFLATE);
inBytes.position = 0;//reset position to beginning
// read XML Object
var orderXML:XML = inBytes.readObject();
//for each node in orderXML
for each(var child:XML in orderXML) {
// append child node to text area
myTxt.text += child + "\n";
}
// read specified file into byte array
function readFile(fileName:String, data:ByteArray) {
var inFile:File = File.desktopDirectory; // source folder is desktop
inFile = inFile.resolvePath(fileName); // name of file to read
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(data, 0, data.length);
inStream.close();
}
Exemplo de ByteArray: leitura de um arquivo .zip
Esse exemplo demonstra como ler um simples arquivo .zip contendo vários arquivos de diferentes tipos. Ele faz isso
extraindo dados relevantes dos metadados para cada arquivo, descompactando cada arquivo em um ByteArray e
escrevendo o arquivo na área de trabalho.
A estrutura geral de um arquivo .zip é baseada na especificação de PKWARE Inc., mantida em
http://www.pkware.com/documents/casestudies/APPNOTE.TXT. Primeiramente, está o cabeçalho de um arquivo e
os dados do arquivo para o primeiro arquivo no arquivo .zip, seguido por um cabeçalho de arquivo e par de dados de
arquivo para cada arquivo adicional. (A estrutura do cabeçalho do arquivo é descrita posteriormente.) Em seguida, o
arquivo .zip inclui opcionalmente um registro de descritor de dados (normalmente quando o arquivo zip de saída foi
criado na memória, e não salvo em um disco). Em seguida, estão vários elementos opcionais adicionais: cabeçalho de
descriptografia do arquivo, registro de dados extra do arquivo, estrutura de diretório central, final Zip64 de registro de
diretório central, final Zip64 de localizador de diretório central e final de registro de diretório central.
O código nesse exemplo é escrito para analisar apenas arquivos zip que não contêm pastas e ele não espera registros
de descritor de dados. Ele ignora todas as informações seguindo os dados do último arquivo.
O formato do cabeçalho do arquivo para cada arquivo é o seguinte:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 160
Trabalhar com matrizes de bytes
assinatura do cabeçalho do arquivo
4 bytes
versão necessária
2 bytes
sinalizador de bits de propósito geral
2 bytes
método de compactação
2 bytes (8=DEFLATE; 0=UNCOMPRESSED)
última hora de modificação do arquivo
2 bytes
última data de modificação do arquivo
2 bytes
crc-32
4 bytes
tamanho compactado
4 bytes
tamanho descompactado
4 bytes
comprimento do nome do arquivo
2 bytes
comprimento de campo extra
2 bytes
nome de arquivo
variável
campo extra
variável
Seguindo o cabeçalho do arquivo estão os dados reais do arquivo, que podem ser compactados ou não, dependendo
do sinalizador de método de compactação. O sinalizador é 0 (zero) se os dados do arquivo são descompactados, 8 se
os dados são compactados usando o algoritmo DEFLATE ou outro valor para outros algoritmos de compactação.
A interface de usuário para esse exemplo consiste de um rótulo e uma área de texto (taFiles). O aplicativo escreve as
seguintes informações na área de texto para cada arquivo encontrado no arquivo .zip: o nome de arquivo, o tamanho
compactado e o tamanho descompactado.
O início do programa executa as seguintes tarefas:
• Importa as classes necessárias
import flash.filesystem.*;
import flash.utils.ByteArray;
import flash.events.Event;
• Define a interface de usuário
import fl.controls.*;
//requires TextArea and Label components in the Library
var taFiles = new TextArea();
var output = new Label();
taFiles.setSize(320, 150);
taFiles.move(10, 30);
output.move(10, 10);
output.width = 150;
output.text = "Contents of HelloAir.zip";
addChild(taFiles);
addChild(output);
• Define o ByteArray bytes
var bytes:ByteArray = new ByteArray();
• Define variáveis para armazenar metadados do cabeçalho do arquivo
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 161
Trabalhar com matrizes de bytes
//
var
var
var
var
var
var
var
var
variables for reading fixed portion of file header
fileName:String = new String();
flNameLength:uint;
xfldLength:uint;
offset:uint;
compSize:uint;
uncompSize:uint;
compMethod:int;
signature:int;
• Define os objetos File (zfile) e FileStream (zStream) para representar o arquivo .zip e especifica o local do arquivo
.zip a partir do qual os arquivos são extraídos — um arquivo chamado “HelloAIR.zip” no diretório da área de
trabalho.
// File variables for accessing .zip file
var zfile:File = File.desktopDirectory.resolvePath("HelloAIR.zip");
var zStream:FileStream = new FileStream();
O programa começa abrindo o arquivo .zip em modo READ.
zStream.open(zfile, FileMode.READ);
Ele, em seguida, define a propriedade endian de bytes para LITTLE_ENDIAN para indicar que a ordem de bytes de
campos numéricos possui o byte menos significativo primeiro.
bytes.endian = Endian.LITTLE_ENDIAN;
Em seguida, uma instrução while() começa um loop que continua até que a posição atual no fluxo do arquivo seja
maior que ou igual ao tamanho do arquivo.
while (zStream.position < zfile.size)
{
A primeira instrução dentro do loop lê os primeiros 30 bytes do fluxo do arquivo no ByteArray bytes. Os primeiros
30 bytes formam a parte de tamanho fixo do cabeçalho do primeiro arquivo.
// read fixed metadata portion of local file header
zStream.readBytes(bytes, 0, 30);
Em seguida, o código lê um inteiro (signature) dos primeiros bytes do cabeçalho de 30 bytes. A definição do formato
ZIP especifica que a assinatura para cada cabeçalho de arquivo é o valor hexadecimal 0x04034b50; se a assinatura for
diferente, significa que o código se moveu além da parte do arquivo .zip e não existem mais arquivos para extrair. Nesse
caso, o código sai do loop while imediatamente, em vez de esperar pelo final da matriz de bytes.
bytes.position = 0;
signature = bytes.readInt();
// if no longer reading data files, quit
if (signature != 0x04034b50)
{
break;
}
A parte seguinte do código lê o byte do cabeçalho na posição de deslocamento 8 e armazena o valor na variável
compMethod. Esse byte contém um valor que indica o método de compactação usado para compactar esse arquivo.
Vários métodos de compactação são permitidos, mas, na prática, praticamente todos os arquivos .zip usam o algoritmo
de compactação DEFLATE. Se o arquivo atual é compactado com a compactação DEFLATE, compMethod é 8; se o
arquivo é descompactado, compMethod é 0.
bytes.position = 8;
compMethod = bytes.readByte();
// store compression method (8 == Deflate)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 162
Trabalhar com matrizes de bytes
Seguindo os primeiros 30 bytes está uma parte de comprimento variável do cabeçalho que contém o nome do arquivo
e, possivelmente, um campo extra. A variável offset armazena o tamanho dessa parte. O tamanho é calculado pela
adição do comprimento do nome do arquivo e o comprimento do campo extra, lido do cabeçalho nos deslocamentos
26 e 28.
offset = 0;// stores length of variable portion of metadata
bytes.position = 26; // offset to file name length
flNameLength = bytes.readShort();// store file name
offset += flNameLength; // add length of file name
bytes.position = 28;// offset to extra field length
xfldLength = bytes.readShort();
offset += xfldLength;// add length of extra field
Em seguida, o programa lê a parte de comprimento variável do cabeçalho do arquivo para o número de bytes
armazenados na variável offset.
// read variable length bytes between fixed-length header and compressed file data
zStream.readBytes(bytes, 30, offset);
O programa lê o nome do arquivo da parte de comprimento variável do cabeçalho e o exibe na área de texto,
juntamente com os tamanhos compactados (zip) e descompactados (original) do arquivo.
bytes.position = 30;
fileName = bytes.readUTFBytes(flNameLength); // read file name
taFiles.appendText(fileName + "\n"); // write file name to text area
bytes.position = 18;
compSize = bytes.readUnsignedInt(); // store size of compressed portion
taFiles.appendText("\tCompressed size is: " + compSize + '\n');
bytes.position = 22; // offset to uncompressed size
uncompSize = bytes.readUnsignedInt(); // store uncompressed size
taFiles.appendText("\tUncompressed size is: " + uncompSize + '\n');
O exemplo lê o resto do arquivo do fluxo de arquivos em bytes para o comprimento especificado pelo tamanho
compactado, substituindo o cabeçalho do arquivo nos primeiros 30 bytes. O tamanho compactado é preciso, mesmo
se o arquivo não está compactado, porque, nesse caso, o tamanho compactado é igual ao tamanho descompactado do
arquivo.
// read compressed file to offset 0 of bytes; for uncompressed files
// the compressed and uncompressed size is the same
zStream.readBytes(bytes, 0, compSize);
Em seguida, o exemplo descompacta o arquivo compactado e chama a função outfile() para escrevê-la no fluxo de
arquivos de saída. Ele transmite a outfile() o nome do arquivo e a matriz de bytes que contém os dados do arquivo.
if (compMethod == 8) // if file is compressed, uncompress
{
bytes.uncompress(CompressionAlgorithm.DEFLATE);
}
outFile(fileName, bytes);
// call outFile() to write out the file
A chave de fechamento indica o final do loop while e do código do aplicativo, exceto para o método outFile(). A
execução volta ao início do loop while e continua processando os próximos bytes no arquivo .zip — extraindo outro
arquivo ou finalizando o processamento do arquivo .zip se o último arquivo tiver sido processado.
} // end of while loop
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 163
Trabalhar com matrizes de bytes
A função outfile() abre um arquivo de saída no modo WRITE na área de trabalho, dando a ele o nome fornecido
pelo parâmetro filename. Ela, em seguida, escreve os dados do arquivo do parâmetro data para o fluxo do arquivo
de saída (outStream) e fecha o arquivo.
function outFile(fileName:String, data:ByteArray):void
{
var outFile:File = File.desktopDirectory; // destination folder is desktop
outFile = outFile.resolvePath(fileName); // name of file to write
var outStream:FileStream = new FileStream();
// open output file stream in WRITE mode
outStream.open(outFile, FileMode.WRITE);
// write out the file
outStream.writeBytes(data, 0, data.length);
// close it
outStream.close();
}
164
Capítulo 18: Trabalhar com bancos de
dados SQL locais
O Adobe AIR permite criar e trabalhar com bancos de dados SQL locais. O tempo de execução inclui um mecanismo
de banco de dados SQL com suporte para muitos recursos SQL padrão através do sistema de banco de dados de códigofonte aberto SQLite. Um banco de dados SQL local pode ser usado para armazenar dados locais persistentes. Por
exemplo, ele pode ser usado para dados de aplicativo, configurações de usuários de aplicativo, documentos ou
qualquer outro tipo de dados que você desejar que o aplicativo salve localmente.
Mais informações on-line sobre bancos de dados SQL
locais
Você encontra mais informações sobre como trabalhar com bancos de dados SQL locais nestas fontes:
Início rápido (Adobe AIR Developer Connection)
• Trabalhar assincronamente com um banco de dados SQL local
• Trabalhar sincronamente com um banco de dados SQL local
• Usar banco de dados criptografado
Referência de linguagem
• SQLCollationType
• SQLColumnNameStyle
• SQLColumnSchema
• SQLConnection
• SQLError
• SQLErrorEvent
• SQLErrorOperation
• SQLEvent
• SQLIndexSchema
• SQLMode
• SQLResult
• SQLSchema
• SQLSchemaResult
• SQLStatement
• SQLTableSchema
• SQLTransactionLockType
• SQLTriggerSchema
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 165
Trabalhar com bancos de dados SQL locais
• SQLUpdateEvent
• SQLViewSchema
Artigos e amostras do Adobe Developer Connection
• Adobe AIR Developer Connection para Flash (procure ‘AIR SQL’)
Sobre bancos de dados SQL locais
O Adobe AIR inclui um mecanismo de banco de dados relacional baseado em SQL que é executado no tempo de
execução, com dados armazenados localmente em arquivos de banco de dados no computador em que o aplicativo do
AIR é executado (no disco rígido do computador, por exemplo). Como a execução do banco de dados ocorre
localmente, da mesma forma que o armazenamento dos arquivos de dados, um banco de dados pode ser usado por um
aplicativo do AIR independentemente de haver uma conexão de rede disponível. Por isso, o mecanismo de banco de
dados SQL local do tempo de execução é conveniente para armazenar dados de aplicativo locais persistentes,
principalmente se você tem experiência em SQL e bancos de dados relacionais.
Usos de bancos de dados SQL locais
A funcionalidade de banco de dados SQL local do AIR pode ser utilizada para qualquer finalidade quando você quiser
armazenar dados de aplicativo no computador local de um usuário. O Adobe AIR inclui diversos mecanismos para
armazenar dados localmente, e cada um deles tem suas próprias vantagens. Veja abaixo alguns dos usos possíveis de
um banco de dados SQL local no aplicativo do AIR:
• No caso de um aplicativo orientado a dados (um catálogo de endereços, por exemplo), é possível usar um banco de
dados para armazenar os principais dados de aplicativo.
• No caso de um aplicativo orientado a documento, em que os usuários criam documentos para salvá-los e
possivelmente compartilhá-los, cada documento pode ser salvo como um arquivo de banco de dados em um local
designado pelo usuário. (Observe, no entanto, que a menos que o banco de dados seja criptografado, qualquer
aplicativo do AIR poderia abrir o arquivo do banco de dados. A criptografia é recomendada para documentos
potencialmente confidenciais.)
• No caso de um aplicativo com reconhecimento de rede, é possível usar um banco de dados para armazenar um
cache local de dados de aplicativo ou para armazenar dados temporariamente quando não há uma conexão de rede
disponível. Você pode criar um mecanismo para sincronizar o banco de dados local com o armazenamento de
dados da rede.
• No caso de qualquer aplicativo, um banco de dados pode ser usado para armazenar configurações de aplicativo de
um usuário, como opções ou informações do aplicativo (por exemplo, o tamanho e a posição das janelas).
Sobre bancos de dados AIR e arquivos de banco de dados
Um banco de dados SQL local do Adobe AIR é armazenado como um único arquivo no sistema de arquivos do
computador. O tempo de execução inclui o mecanismo de banco de dados SQL que gerencia a criação e a estruturação
de arquivos de banco de dados, bem como a manipulação e a recuperação de dados de um arquivo de banco de dados.
O tempo de execução não especifica como ou onde os dados de banco de dados são armazenados no sistema de
arquivos; cada banco de dados é armazenado por completo em um único arquivo. Você especifica o local no sistema
de arquivos em que o arquivo do banco de dados deve ser armazenado. Um único aplicativo do AIR pode acessar um
ou vários bancos de dados separados (isto é, arquivos de banco de dados separados). Como o tempo de execução
armazena cada banco de dados como um único arquivo no sistema de arquivos, você pode localizar o seu banco de
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 166
Trabalhar com bancos de dados SQL locais
dados quando necessário pelo design das restrições do sistema operacional quanto ao acesso a aplicativos e arquivos.
Cada usuário pode ter um arquivo de banco de dados à parte para seus dados específicos, ou um arquivo de banco de
dados pode ser acessado por todos os usuários do aplicativo em um único computador para dados compartilhados.
Como os dados estão armazenados localmente em um único computador, eles não são compartilhados
automaticamente em diferentes computadores. O mecanismo de banco de dados SQL local não tem um recurso que
permita executar instruções SQL em um banco de dados remoto ou baseado em servidor.
Sobre bancos de dados relacionais
Um banco de dados relacional consiste em um mecanismo para armazenar (e recuperar) dados em um computador.
Os dados são organizados em tabelas: as linhas representam registros ou itens, e as colunas (também chamadas de
“campos”) dividem cada registro em valores individuais. Por exemplo, um aplicativo de catálogo de endereços pode
conter uma tabela chamada “amigos”. Cada linha da tabela representa um único amigo armazenado no banco de
dados. As colunas da tabela representam dados como nome, sobrenome, data de nascimento e assim por diante. Para
cada linha de amigo na tabela, o banco de dados armazena um valor em separado para cada coluna.
Os bancos de dados relacionais têm a finalidade de armazenar dados complexos, em que um item é associado ou
relacionado a itens de outro tipo. Em um banco de dados relacional, qualquer dado que tem um relacionamento umpara-muitos — em que um único registro pode estar relacionado a vários registros de um tipo diferente — deve ser
dividido entre diferentes tabelas. Por exemplo, suponha que você queira que o aplicativo de catálogo de endereços
armazene vários números de telefone de cada amigo; isto é um relacionamento um-para-muitos. A tabela “amigos”
contém todas as informações pessoais de cada amigo. Uma tabela à parte chamada “números de telefone” contém
todos os números de telefone de todos os amigos.
Além de armazenar os dados de amigos e os números de telefone, cada tabela precisa de dados para controlar os
relacionamentos entre as duas tabelas — a fim de comparar registros de amigo individuais com seus números de
telefone. Esses dados são chamados de chave primária, um identificador exclusivo que diferencia cada linha de uma
tabela das demais linhas dessa tabela. A chave primária pode ser uma “chave natural”, ou seja, um dos itens de dados
que diferencia cada registro de uma tabela naturalmente. Na tabela “amigos”, se você souber que nenhum dos seus
amigos tem a mesma data de aniversário, poderá usar a coluna de data de nascimento como a chave primária (uma
chave natural) dessa tabela. Se não houver uma chave natural, crie uma coluna de chave primária em separado, como
“id de amigo”: um valor artificial que o aplicativo usa para diferenciar entre as linhas.
Utilizando uma chave primária, você pode configurar relacionamentos entre várias tabelas. Por exemplo, suponha que
na tabela "amigos" exista uma coluna chamada "id de amigo", que contém um número exclusivo para cada linha (cada
amigo). A tabela “números de telefone” relacionada pode ser estruturada com duas colunas: uma com o “id de amigo”
do amigo a quem pertence o número de telefone e outra com o número de telefone propriamente dito. Assim,
independentemente de quantos números de telefones um só amigo tiver, todos poderão ser armazenados na tabela
“números de telefone” e vinculados ao amigo relacionado através da chave primária “id de amigo”. Quando uma chave
primária de uma tabela é usada em uma tabela relacionada para especificar a conexão entre os registros, o valor contido
na tabela é chamado de chave externa. Diferentemente de muitos bancos de dados, o mecanismo de banco de dados
local do AIR não permite criar restrições de chave externa, que são restrições que automaticamente verificam se um
valor de chave externa inserido ou atualizado tem uma linha correspondente na tabela de chave primária. Todavia, os
relacionamentos de chave externa são uma parte importante da estrutura de um banco de dados relacional, e as chaves
externas devem ser usadas quando você cria relacionamentos entre as tabelas do banco de dados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 167
Trabalhar com bancos de dados SQL locais
Sobre a SQL
A SQL (linguagem de consulta estruturada) é usada com bancos de dados relacionais para manipular e recuperar
dados. A SQL é uma linguagem descritiva e não de procedimento. Em vez de dar ao computador instruções sobre
como recuperar dados, uma instrução SQL descreve o conjunto de dados desejado. O mecanismo de banco de dados
determina como recuperar esses dados.
A linguagem SQL foi padronizada pelo ANSI (American National Standards Institute). O banco de dados SQL local
do Adobe AIR suporta a maior parte do padrão SQL-92. Para obter descrições específicas da linguagem SQL suportada
no Adobe AIR, consulte o apêndice “Suporte a SQL em bancos de dados locais“ na Referência dos componentes e da
linguagem do ActionScript 3.0.
Sobre classes de banco de dados SQL
Para trabalhar com bancos de dados SQL locais no ActionScript 3.0, você deve usar ocorrências destas classes do
pacote flash.data:
Classe
Descrição
flash.data.SQLConnection
Oferece um modo de criar e abrir bancos de dados (arquivos de banco de dados), bem como métodos para
executar operações no nível de banco de dados e controlar transações de banco de dados.
flash.data.SQLStatement
Representa uma única instrução SQL (uma única consulta ou comando) que é executada em um banco de
dados, incluindo a definição do texto da instrução e a configuração dos valores de parâmetro.
flash.data.SQLResult
Oferece um modo de obter informações sobre execução de uma instrução ou os resultados dela, como as
linhas de resultado de uma instrução SELECT, o número de linhas afetadas por uma instrução UPDATE ou
DELETE e assim por diante.
Para obter informações de esquema que descrevam a estrutura de um banco de dados, use estas classes do pacote
flash.data:
Classe
Descrição
flash.data.SQLSchemaResult
Funciona como um contêiner de resultados do esquema de banco de dados gerados pela chamada do
método SQLConnection.loadSchema().
flash.data.SQLTableSchema
Fornece informações que descrevem uma única tabela de um banco de dados.
flash.data.SQLViewSchema
Fornece informações que descrevem uma única visualização de um banco de dados.
flash.data.SQLIndexSchema
Fornece informações que descrevem uma única coluna de uma tabela ou visualização de um banco de
dados.
flash.data.SQLTriggerSchem
a
Fornece informações que descrevem um único disparador de um banco de dados.
Outras classes do pacote flash.data fornecem constantes que são utilizadas com as classes SQLConnection e
SQLColumnSchema:
Classe
Descrição
flash.data.SQLMode
Define um conjunto de constantes que representam os valores possíveis para o parâmetro openMode dos
métodos SQLConnection.open() e SQLConnection.openAsync().
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 168
Trabalhar com bancos de dados SQL locais
Classe
Descrição
flash.data.SQLColumnNameStyle
Define um conjunto de constantes que representam os valores possíveis para a propriedade
SQLConnection.columnNameStyle.
flash.data.SQLTransactionLockType Define um conjunto de constantes que representam os valores possíveis para o parâmetro de opção do
método SQLConnection.begin().
flash.data.SQLCollationType
Define um conjunto de constantes que representam os valores possíveis para a propriedade
SQLColumnSchema.defaultCollationType e o parâmetro defaultCollationType do construtor
SQLColumnSchema().
Além disso, as seguintes classes do pacote flash.events representam os eventos (e as constantes de suporte) que você
utiliza:
Classe
Descrição
flash.data.SQLEvent
Define os eventos que uma ocorrência de SQLConnection ou SQLStatement despacha quando alguma de
suas operações é executada com êxito. Cada operação tem uma constante de tipo de evento associada
definida na classe SQLEvent.
flash.data.SQLErrorEvent
Define o evento que uma ocorrência de SQLConnection ou SQLStatement despacha quando alguma de
suas operações resulta em erro.
flash.data.SQLUpdateEvent
Define o evento que uma ocorrência de SQLConnection despacha quando dados de tabela de um dos
bancos de dados conectados são alterados como resultado da execução de uma instrução SQL INSERT,
UPDATE ou DELETE.
Para finalizar, as seguintes classes do pacote flash.errors fornecem informações sobre erros de operação do banco de
dados:
Classe
Descrição
flash.data.SQLError
Fornece informações sobre um erro de funcionamento do banco de dados, incluindo a operação que foi
tentada e a causa da falha.
flash.data.SQLErrorEvent
Define um conjunto de constantes que representam os valores possíveis para a propriedade operation da
classe SQLError, que indica a operação de banco de dados que resultou em erro.
Sobre modos de execução síncrona e assíncrona
Quando você cria código para trabalhar com um banco de dados SQL local, especifica que a execução das operações
de banco de dados ocorra de um destes dois modos de execução: modo de execução assíncrona ou síncrona. Em geral,
os exemplos de código mostram como executar cada operação das duas maneiras, para que você possa usar o exemplo
mais adequado às suas necessidades.
No modo de execução assíncrona, você dá uma instrução ao tempo de execução, que despacha um evento quando a
operação solicitada é concluída ou quando falha. Primeiro você instrui o mecanismo de banco de dados a executar uma
operação. O mecanismo de banco de dados trabalha em segundo plano enquanto o aplicativo continua a executar. Por
último, quando a operação é concluída (ou se falha), o mecanismo de banco de dados despacha um evento. O seu
código, disparado pelo evento, executa operações subseqüentes. Esta abordagem tem uma vantagem significativa: o
tempo de execução realiza as operações de banco de dados em segundo plano enquanto o código do aplicativo
principal continua en execução. Se a operação de banco de dados demorar muito tempo, o aplicativo continuará
executando. O mais importante é que o usuário pode continuar a interagir com ele sem que a tela congele. Entretanto,
o código de operação assíncrona pode ser mais complexo de criar do que outro código. Essa complexidade geralmente
ocorre quando várias operações dependentes devem ser divididas entre diversos métodos de ouvinte de evento.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 169
Trabalhar com bancos de dados SQL locais
Em termos conceituais, é mais fácil codificar operações como uma seqüência simples de etapas (um conjunto de
operações síncronas) e não como um conjunto de operações divididas em vários métodos de ouvinte de evento. Além
das operações de banco de dados assíncronas, o Adobe AIR também permite executar operações de banco de dados de
maneira síncrona. No modo de execução síncrona, as operações não são executadas em segundo plano. Elas ocorrem
na mesma seqüência de execução que todos os outros códigos de aplicativo. Você instrui o mecanismo de banco de
dados a executar uma operação. Em seguida, o código pausa nesse ponto enquanto o mecanismo de banco de dados
faz o seu trabalho. Quando a operação é concluída, a execução prossegue com a próxima linha do código que você
criou.
O fato de as operações serem executadas de maneira assíncrona ou síncrona é definido no nível de SQLConnection.
Usando uma única conexão de banco de dados, você não consegue executar algumas operações ou instruções em
modo síncrono e outras em modo assíncrono. Você especifica se uma classe SQLConnection opera no modo de
execução síncrono ou assíncrono chamando um método SQLConnection para abrir o banco de dados. Se você chamar
SQLConnection.open(), a conexão funcionará no modo de execução síncrona; se você chamar
SQLConnection.openAsync(), ela funcionará no modo de execução assíncrona. Uma vez que uma ocorrência de
SQLConnection é conectada a um banco de dados usando open() ou openAsync(), ela é fixada ao modo de execução
síncrona ou assíncrona, a menos que você feche e reabra a conexão com o banco de dados.
Cada modo de execução tem suas vantagens. Apesar da semelhança entre a maioria dos aspectos de cada modo,
existem algumas diferenças das quais você deve se lembrar quando trabalhar neles. Para obter mais informações sobre
estes tópicos, e sugestões de como trabalhar em cada modo, consulte “Uso de operações de banco de dados síncronas
e assíncronas” na página 190.
Criação e modificação de um banco de dados
Para que o seu aplicativo adicione ou recupere dados, deve haver um banco de dados com tabelas definidas nele que
possam ser acessadas pelo aplicativo. Descrevemos aqui as tarefas de criação de um banco de dados e da estrutura de
dados de um banco de dados. Embora usadas com menos freqüência do que a inserção e a recuperação de dados, estas
tarefas são necessárias para a maioria dos aplicativos.
Criação de um banco de dados
Para criar um arquivo de banco de dados, primeiro você deve criar uma ocorrência de SQLConnection. Chame o
método open() correspondente para abri-la no modo de execução síncrona ou o método openAsync() para abri-la
no modo de execução assíncrona. Os métodos open() e openAsync() são usados para abrir uma conexão com um
banco de dados. Se você passar uma ocorrência de File que se refira a um local de arquivo não existente para o
parâmetro reference (o primeiro parâmetro), o método open() ou openAsync() criará um arquivo de banco de
dados no local do arquivo e abrirá uma conexão com o banco de dados recém-criado.
Independentemente de você chamar o método open() ou openAsync() para criar um banco de dados, o nome do
arquivo do banco de dados poderá ser qualquer nome de arquivo válido com qualquer extensão de nome de arquivo.
Se você chamar o método open() ou openAsync() com null para o parâmetro reference, será criado um novo
banco de dados na memória e não um arquivo de banco de dados no disco.
A listagem de código a seguir mostra o processo de criação de um arquivo de banco de dados (um novo banco de
dados) usando o modo de execução assíncrona. Nesse caso, o arquivo de banco de dados é salvo no diretório de
armazenamento do aplicativo com o nome de arquivo “DBSample.db”:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 170
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
conn.openAsync(dbFile);
function openHandler(event:SQLEvent):void
{
trace("the database was created successfully");
}
function errorHandler(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
Para executar operações de maneira síncrona, quando abrir uma conexão de banco de dados com a ocorrência de
SQLConnection, chame o método open(). O seguinte exemplo mostra como criar e abrir uma ocorrência de
SQLConnection que execute suas operações de maneira síncrona:
import flash.data.SQLConnection;
import flash.errors.SQLError;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
try
{
conn.open(dbFile);
trace("the database was created successfully");
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
Criação de tabelas de banco de dados
Criar uma tabela em um banco de dados envolve executar uma instrução SQL nesse banco de dados usando o mesmo
processo seguido para executar uma instrução SQL, como SELECT, INSERT, entre outras. Para criar uma tabela, use
uma instrução CREATE TABLE, que inclui definições de colunas e restrições para a nova tabela. Para obter mais
informações sobre como executar instruções SQL, consulte “Trabalhar com instruções SQL” na página 173.
O exemplo a seguir demonstra como criar uma tabela chamada “employees” em um arquivo de banco de dados
existente usando o modo de execução assíncrona. Observe que este código presume que há uma ocorrência de
SQLConnection denominada conn já instanciada e conectada a um banco de dados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 171
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
// ... create and open the SQLConnection instance named conn ...
var createStmt:SQLStatement = new SQLStatement();
createStmt.sqlConnection = conn;
var sql:String =
"CREATE TABLE IF NOT EXISTS employees (" +
"
empId INTEGER PRIMARY KEY AUTOINCREMENT, " +
"
firstName TEXT, " +
"
lastName TEXT, " +
"
salary NUMERIC CHECK (salary > 0)" +
")";
createStmt.text = sql;
createStmt.addEventListener(SQLEvent.RESULT, createResult);
createStmt.addEventListener(SQLErrorEvent.ERROR, createError);
createStmt.execute();
function createResult(event:SQLEvent):void
{
trace("Table created");
}
function createError(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
O exemplo a seguir demonstra como criar uma tabela chamada “employees” em um arquivo de banco de dados
existente usando o modo de execução síncrona. Observe que este código presume que há uma ocorrência de
SQLConnection denominada conn já instanciada e conectada a um banco de dados.
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.errors.SQLError;
// ... create and open the SQLConnection instance named conn ...
var createStmt:SQLStatement = new SQLStatement();
createStmt.sqlConnection = conn;
var sql:String =
"CREATE TABLE IF NOT EXISTS employees (" +
"
empId INTEGER PRIMARY KEY AUTOINCREMENT, " +
"
firstName TEXT, " +
"
lastName TEXT, " +
"
salary NUMERIC CHECK (salary > 0)" +
")";
createStmt.text = sql;
try
{
createStmt.execute();
trace("Table created");
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 172
Trabalhar com bancos de dados SQL locais
Manipulação de dados de um banco de dados SQL
Existem algumas tarefas comuns que você executa ao trabalhar com bancos de dados SQL locais. Essas tarefas incluem
conectar-se a um banco de dados, adicionar dados a tabelas e recuperar dados de tabelas em um banco de dados.
Também há vários problemas dos quais você deve estar ciente quando executa essas tarefas, como trabalhar com tipos
de dados e tratar de erros.
Além disso, há diversas tarefas de banco de dados que envolvem coisas com as quais você lidará menos
freqüentemente, mas que deverá fazer para poder executar essas tarefas mais comuns. Por exemplo, para poder se
conectar a um banco de dados e recuperar dados de uma tabela, você terá de criar o banco de dados e a estrutura de
tabelas nele. Essas tarefas de configuração inicial menos freqüentes são discutidas em “Criação e modificação de um
banco de dados” na página 169.
Você pode optar por executar operações de banco de dados assincronamente, o que significa que o mecanismo de
banco de dados é executado em segundo plano e despacha um evento para notificar o usuário quando a operação é
bem-sucedida ou quando falha. Também é possível executar estas operações de forma síncrona. Nesse caso, as
operações de banco de dados são executadas uma após a outra, e o aplicativo inteiro (inclusive atualizações da tela)
espera até que as operações sejam concluídas para poder executar outro código. Os exemplos desta seção demonstram
como executar as operações de modo assíncrono e síncrono. Para obter mais informações sobre como trabalhar no
modo de execução assíncrona ou síncrona, consulte “Uso de operações de banco de dados síncronas e assíncronas” na
página 190.
Conexão com um banco de dados
Para que você possa executar qualquer operação de banco de dados, primeiro abra uma conexão com o arquivo de
banco de dados. Uma ocorrência de SQLConnection é usada para representar uma conexão com um ou mais bancos
de dados. O primeiro banco de dados conectado usando uma ocorrência de SQLConnection é chamado de banco de
dados "principal". Esse banco de dados é conectado através do método open() (para o modo de execução síncrona)
ou do método openAsync() (para o modo de execução assíncrona).
Se você abrir um banco de dados usando a operação openAsync() assíncrona, registre-se para o evento open da
ocorrência de SQLConnection para saber quando a operação openAsync() for concluída. Registre-se para o evento
error da ocorrência de SQLConnection para determinar se a operação falhou.
O exemplo a seguir mostra como abrir um arquivo de banco de dados existente para execução assíncrona. O arquivo
de banco de dados chama-se “DBSample.db” e está localizado no diretório de armazenamento de aplicativo do
usuário.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 173
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLMode;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
conn.openAsync(dbFile, SQLMode.UPDATE);
function openHandler(event:SQLEvent):void
{
trace("the database opened successfully");
}
function errorHandler(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
O exemplo a seguir mostra como abrir um arquivo de banco de dados existente para execução síncrona. O arquivo de
banco de dados chama-se “DBSample.db” e está localizado no diretório de armazenamento de aplicativo do usuário.
import flash.data.SQLConnection;
import flash.data.SQLMode;
import flash.errors.SQLError;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
try
{
conn.open(dbFile, SQLMode.UPDATE);
trace("the database opened successfully");
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
Observe que, na chamada do método openAsync() no exemplo de operação assíncrona e na chamada do método
open() no exemplo de operação síncrona, o segundo argumento é a constante SQLMode.UPDATE. Especificar
SQLMode.UPDATE para o segundo parâmetro (openMode) faz com que o tempo de execução despache um erro se o
arquivo especificado não existe. Caso você passe SQLMode.CREATE para o parâmetro openMode (ou caso deixe o
parâmetro openMode como off), o tempo de execução tentará criar um arquivo de banco de dados se o arquivo
especificado não existir. No entanto, se o arquivo existir, será aberto, o que é o mesmo que usar SQLMode.Update.
Também é possível especificar SQLMode.READ para o parâmetro openMode para abrir um banco de dados existente em
modo somente leitura. Nesse caso, os dados podem ser recuperados do banco de dados, mas não é possível adicionar,
excluir ou alterar nenhum dado.
Trabalhar com instruções SQL
Uma instrução SQL individual (consulta ou comando) é representada no tempo de execução como um objeto
SQLStatement. Siga estas etapas para criar e executar uma instrução SQL:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 174
Trabalhar com bancos de dados SQL locais
Crie uma ocorrência de SQLStatement.
O objeto SQLStatement representa a instrução SQL no seu aplicativo.
var selectData:SQLStatement = new SQLStatement();
Especifique em que banco de dados a consulta é executada.
Para isso, defina a propriedade sqlConnection do objeto SQLStatement como a ocorrência de SQLConnection que
está conectada ao banco de dados desejado.
// A SQLConnection named "conn" has been created previously
selectData.sqlConnection = conn;
Especifique a instrução SQL propriamente dita.
Crie o texto da instrução como String e o atribua à propriedade text da ocorrência de SQLStatement.
selectData.text = "SELECT col1, col2 FROM my_table WHERE col1 = :param1";
Defina funções para trabalhar com o resultado da operação de execução (somente no modo de execução
assíncrona).
Use o método addEventListener() para registrar funções como ouvintes para os eventos result e error da
ocorrência de SQLStatement.
// using listener methods and addEventListener();
selectData.addEventListener(SQLEvent.RESULT, resultHandler);
selectData.addEventListener(SQLErrorEvent.ERROR, errorHandler);
function resultHandler(event:SQLEvent):void
{
// do something after the statement execution succeeds
}
function errorHandler(event:SQLErrorEvent):void
{
// do something after the statement execution fails
}
Se preferir, você pode especificar métodos de ouvinte usando um objeto Responder. Nesse caso, crie a ocorrência de
Responder e vincule os métodos de ouvinte a ela.
// using a Responder (flash.net.Responder)
var selectResponder = new Responder(onResult, onError);
function onResult(result:SQLResult):void
{
// do something after the statement execution succeeds
}
function onError(error:SQLError):void
{
// do something after the statement execution fails
}
Se o texto da instrução incluir definições de parâmetro, atribua valores para esses parâmetros.
Para atribuir valores de parâmetro, use a propriedade de matriz associativa parameters da ocorrência de
SQLStatement.
selectData.parameters[":param1"] = 25;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 175
Trabalhar com bancos de dados SQL locais
Execute a instrução SQL.
Chame o método execute() da ocorrência de SQLStatement.
// using synchronous execution mode
// or listener methods in asynchronous execution mode
selectData.execute();
Além disso, se você estiver usando um Responder em vez de ouvintes de evento no modo de execução assíncrona, passe
a ocorrência de Responder para o método execute().
// using a Responder in asynchronous execution mode
selectData.execute(-1, selectResponder);
Para obter exemplos específicos que demonstrem estas etapas, consulte os seguintes tópicos:
“Recuperação de dados de um banco de dados” na página 177
“Inserção de dados” na página 183
“Alteração ou exclusão de dados” na página 185
Uso de parâmetros em instruções
Um parâmetro de instrução SQL permite criar uma instrução SQL reutilizável. Quando você usa parâmetros de
instrução, os valores na instrução podem mudar (como os que estão sendo adicionados a uma instrução INSERT), mas
o texto básico dela permanece inalterado. Conseqüentemente, usar parâmetros oferece o benefício do desempenho,
além de facilitar a codificação de um aplicativo.
Noções básicas sobre parâmetros de instrução
É freqüente um aplicativo usar uma única instrução SQL várias vezes, com uma leve variação. Por exemplo, considere
um aplicativo de controle de inventário no qual um usuário pode adicionar itens de inventário ao banco de dados. O
código do aplicativo que adiciona um item de inventário ao banco de dados executa uma instrução SQL INSERT que,
na verdade, adiciona os dados ao banco de dados. No entanto, cada vez que a instrução é executada, há uma leve
variação. Especificamente, os valores reais inseridos na tabela são diferentes porque são específicos do item de
inventário que está sendo adicionado.
Em casos nos quais você tem uma instrução SQL que é usada várias vezes com diferentes valores na instrução, a melhor
abordagem é utilizar uma instrução SQL que inclua parâmetros em vez de valores literais no texto SQL. Um parâmetro
consiste em um alocador de espaço no texto da instrução que é substituído por um valor real sempre que a instrução
é executada. Para usar parâmetros em uma instrução SQL, crie a ocorrência de SQLStatement como de costume. No
caso da instrução SQL propriamente dita atribuída à propriedade text, use alocadores de espaço de parâmetro em vez
de valores literais. Em seguida, defina o valor para cada parâmetro definindo o valor de um elemento na propriedade
parameters da ocorrência de SQLStatement. A propriedade parameters é uma matriz associativa, por isso você define
um valor em particular usando a seguinte sintaxe:
statement.parameters[parameter_identifier] = value;
parameter_identifier é uma string (se você está usando um parâmetro nomeado) ou um índice de inteiro (se está
usando um parâmetro sem nome).
Uso de parâmetros nomeados
Um parâmetro pode ser um parâmetro nomeado. Um parâmetro nomeado tem um nome específico que o banco de
dados utiliza para comparar o valor do parâmetro à localização do alocador de espaço no texto da instrução. Um nome
de parâmetro consiste no caractere “:” ou “@” seguido de um nome, como nestes exemplos:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 176
Trabalhar com bancos de dados SQL locais
:itemName
@firstName
A seguinte listagem de código demonstra o uso de parâmetros nomeados:
var sql:String =
"INSERT INTO inventoryItems (name, productCode)" +
"VALUES (:name, :productCode)";
var addItemStmt:SQLStatement = new SQLStatement();
addItemStmt.sqlConnection = conn;
addItemStmt.text = sql;
// set parameter values
addItemStmt.parameters[":name"] = "Item name";
addItemStmt.parameters[":productCode"] = "12345";
addItemStmt.execute();
Uso de parâmetros sem nome
Como alternativa ao uso de parâmetros nomeados, também é possível utilizar parâmetros sem nome. Para usar um
parâmetro sem nome, indique um parâmetro em uma instrução SQL usando um caractere “?” . Cada parâmetro recebe
um índice numérico conforme a ordem dos parâmetros da instrução, começando com o índice 0 para o primeiro
parâmetro. Este exemplo demonstra uma versão do exemplo anterior usando parâmetros sem nome:
var sql:String =
"INSERT INTO inventoryItems (name, productCode)" +
"VALUES (?, ?)";
var addItemStmt:SQLStatement = new SQLStatement();
addItemStmt.sqlConnection = conn;
addItemStmt.text = sql;
// set parameter values
addItemStmt.parameters[0] = "Item name";
addItemStmt.parameters[1] = "12345";
addItemStmt.execute();
Benefícios do uso de parâmetros
O uso de parâmetros em uma instrução SQL proporciona vários benefícios:
Melhor desempenho Uma ocorrência de SQLStatement que usa parâmetros é executada com mais eficiência se
comparada a uma que cria o texto SQL dinamicamente sempre que é executada. A melhoria do desempenho ocorre
porque a instrução é preparada uma única vez e pode ser executada várias vezes usando-se diferentes valores de
parâmetro, sem a necessidade de recompilar a instrução SQL.
Digitação de dados explícita Os parâmetros são usados para permitir a substituição de valores digitados que são
desconhecidos no momento em que a instrução SQL é construída. O uso de parâmetros é o único modo de garantir a
classe de armazenamento para um valor passado ao banco de dados. Quando parâmetros não são usados, o tempo de
execução tenta converter todos os valores de sua representação em texto para uma classe de armazenamento com base
na afinidade de tipo da coluna associada. Para obter mais informações sobre classes de armazenamento e afinidade de
coluna, consulte a seção “Suporte ao tipo de dados“ no apêndice “Suporte a SQL em bancos de dados locais“ da
Referência dos componentes e da linguagem do ActionScript 3.0.
Mais segurança O uso de parâmetros ajuda a impedir uma técnica mal-intencionada conhecida como ataque de
injeção SQL. Em um ataque de injeção SQL, um usuário insere o código SQL em um local acessível ao usuário (por
exemplo, um campo de entrada de dados). Se o código do aplicativo construir uma instrução SQL concatenando
diretamente a entrada do usuário no texto SQL, o código SQL inserido pelo usuário será executado em relação ao
banco de dados. A lista a seguir mostra um exemplo de concatenação da entrada do usuário no texto SQL. Não use
esta técnica:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 177
Trabalhar com bancos de dados SQL locais
// assume the variables "username" and "password"
// contain user-entered data
var sql:String =
"SELECT userId " +
"FROM users " +
"WHERE username = '" + username + "' " +
"
AND password = '" + password + "'";
var statement:SQLStatement = new SQLStatement();
statement.text = sql;
O uso de parâmetros de instrução em vez de concatenar valores inseridos pelo usuário no texto de uma instrução
impede o ataque de injeção SQL. A injeção de SQL não ocorre porque os valores de parâmetro são tratados
explicitamente como valores substituídos, em vez de se tornarem parte do texto da instrução literal. Esta é uma
alternativa recomendável à listagem anterior:
// assume the variables "username" and "password"
// contain user-entered data
var sql:String =
"SELECT userId " +
"FROM users " +
"WHERE username = :username " +
"
AND password = :password";
var statement:SQLStatement = new SQLStatement();
statement.text = sql;
// set parameter values
statement.parameters[":username"] = username;
statement.parameters[":password"] = password;
Recuperação de dados de um banco de dados
A recuperação de dados de um banco de dados envolve duas etapas. Primeiro, você executa uma instrução SQL SELECT
que descreve o conjunto de dados desejado do banco de dados. Em seguida, você acessa os dados recuperados e os
exibe ou manipula conforme exigido pelo aplicativo.
Execução de uma instrução SELECT
Para recuperar dados existentes de um banco de dados, use uma ocorrência de SQLStatement. Atribua a instrução SQL
SELECT adequada à propriedade text da ocorrência e, depois, chame o método execute() correspondente.
Para obter detalhes da sintaxe da instrução SELECT, consulte o apêndice “Suporte a SQL em bancos de dados locais"
da Referência dos componentes e da linguagem do ActionScript 3.0.
O exemplo abaixo mostra como executar uma instrução SELECT para recuperar dados de uma tabela chamada
“products” usando o modo de execução assíncrona:
var selectStmt:SQLStatement = new SQLStatement();
// A SQLConnection named "conn" has been created previously
selectStmt.sqlConnection = conn;
selectStmt.text = "SELECT itemId, itemName, price FROM products";
// The resultHandler and errorHandler are listener methods are
// described in a subsequent code listing
selectStmt.addEventListener(SQLEvent.RESULT, resultHandler);
selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler);
selectStmt.execute();
O exemplo abaixo mostra como executar uma instrução SELECT para recuperar dados de uma tabela chamada
“products” usando o modo de execução assíncrona:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 178
Trabalhar com bancos de dados SQL locais
var selectStmt:SQLStatement = new SQLStatement();
// A SQLConnection named "conn" has been created previously
selectStmt.sqlConnection = conn;
selectStmt.text = "SELECT itemId, itemName, price FROM products";
// This try..catch block is fleshed out in
// a subsequent code listing
try
{
selectStmt.execute();
// accessing the data is shown in a subsequent code listing
}
catch (error:SQLError)
{
// error handling is shown in a subsequent code listing
}
No modo de execução assíncrona, quando a execução da instrução é concluída, a ocorrência de SQLStatement
despacha um evento result (SQLEvent.RESULT) que indica que a instrução foi executada com sucesso. Como
alternativa, se um objeto Responder for passado como argumento na chamada de execute(), a função do
manipulador resultante do objeto Responder será chamada. No modo de execução síncrona, a execução pausa até que
a operação execute() seja concluída e, em seguida, prossegue com a próxima linha de código.
Acesso a dados de resultados da instrução SELECT
Uma vez concluída a execução da instrução SELECT, a próxima etapa é acessar os dados que foram recuperados. Cada
linha de dados do conjunto de resultados de SELECT torna-se uma ocorrência de Object. Esse objeto tem propriedades
cujos nomes correspondem aos nomes de coluna do conjunto de resultados. As propriedades contêm os valores das
colunas do conjunto de resultados. Por exemplo, suponha que uma instrução SELECT especifique um conjunto de
resultados com três colunas chamadas “itemId”, “itemName” e “price”. Para cada linha do conjunto de resultados, é
criada uma ocorrência de Object com propriedades chamadas itemId, itemName e price. Essas propriedades contêm
os valores das respectivas colunas.
A listagem de código a seguir dá continuidade à listagem de código anterior para recuperar dados no modo de
execução assíncrona. Ela mostra como acessar os dados recuperados no método do ouvinte de evento resultante.
function resultHandler(event:SQLEvent):void
{
var result:SQLResult = selectStmt.getResult();
var numResults:int = result.data.length;
for (var i:int = 0; i < numResults; i++)
{
var row:Object = result.data[i];
var output:String = "itemId: " + row.itemId;
output += "; itemName: " + row.itemName;
output += "; price: " + row.price;
trace(output);
}
}
function errorHandler(event:SQLErrorEvent):void
{
// Information about the error is available in the
// event.error property, which is an instance of
// the SQLError class.
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 179
Trabalhar com bancos de dados SQL locais
A listagem de código a seguir expande a listagem de código anterior para recuperar dados no modo de execução
síncrona. Ela expande o bloco try..catch do exemplo anterior de execução síncrona, mostrando como acessar os
dados recuperados.
try
{
selectStmt.execute();
var result:SQLResult = selectStmt.getResult();
var numResults:int = result.data.length;
for (var i:int = 0; i < numResults; i++)
{
var row:Object = result.data[i];
var output:String = "itemId: " + row.itemId;
output += "; itemName: " + row.itemName;
output += "; price: " + row.price;
trace(output);
}
}
catch (error:SQLError)
{
// Information about the error is available in the
// error variable, which is an instance of
// the SQLError class.
}
Quando as listagens de código anteriores são exibidas, os objetos resultantes estão contidos em uma matriz disponível
como a propriedade data de uma ocorrência de SQLResult. Se você estiver usando a execução assíncrona com um
ouvinte de evento, para recuperar essa ocorrência de SQLResult, terá de chamar o método getResult() da ocorrência
de SQLStatement. Se você especificar um argumento Responder na chamada de execute(), a ocorrência de
SQLResult será passada para a função do manipulador resultante como um argumento. No modo de execução
síncrona, você chama o método getResult() da ocorrência de SQLStatement a qualquer momento depois da
chamada do método execute(). Em ambos os casos, depois que você tiver o objeto SQLResult, poderá acessar as
linhas de resultado utilizando a propriedade de matriz data.
A listagem de código a seguir define uma ocorrência de SQLStatement cujo texto é uma instrução SELECT. A instrução
recupera linhas que contêm os valores de coluna firstName e lastName de todas as linhas de uma tabela denominada
employees. Este exemplo utiliza o modo de execução assíncrona. Quando a execução é concluída, o método
selectResult() é chamado, e as linhas de dados resultantes são acessadas usando SQLStatement.getResult() e
exibidas usando o método trace(). Observe que esta listagem presume que existe uma ocorrência de SQLConnection
denominada conn que já foi instanciada e já está conectada ao banco de dados. Ela também presume que a tabela
“employees” já foi criada e preenchida com dados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 180
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
// ... create and open the SQLConnection instance named conn ...
// create the SQL statement
var selectStmt:SQLStatement = new SQLStatement();
selectStmt.sqlConnection = conn;
// define the SQL text
var sql:String =
"SELECT firstName, lastName " +
"FROM employees";
selectStmt.text = sql;
// register listeners for the result and error events
selectStmt.addEventListener(SQLEvent.RESULT, selectResult);
selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError);
// execute the statement
selectStmt.execute();
function selectResult(event:SQLEvent):void
{
// access the result data
var result:SQLResult = selectStmt.getResult();
var numRows:int = result.data.length;
for (var i:int = 0; i < numRows; i++)
{
var output:String = "";
for (var columnName:String in result.data[i])
{
output += columnName + ": " + result.data[i][columnName] + "; ";
}
trace("row[" + i.toString() + "]\t", output);
}
}
function selectError(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
A listagem de código a seguir demonstra as mesmas técnicas que a anterior, mas usa o modo de execução síncrona. O
exemplo define uma ocorrência de SQLStatement cujo texto é uma instrução SELECT. A instrução recupera linhas que
contêm os valores de coluna firstName e lastName de todas as linhas de uma tabela denominada employees. As
linhas de dados resultantes são acessadas usando SQLStatement.getResult() e exibidas usando o método trace().
Observe que esta listagem presume que existe uma ocorrência de SQLConnection denominada conn que já foi
instanciada e já está conectada ao banco de dados. Ela também presume que a tabela “employees” já foi criada e
preenchida com dados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 181
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.errors.SQLError;
// ... create and open the SQLConnection instance named conn ...
// create the SQL statement
var selectStmt:SQLStatement = new SQLStatement();
selectStmt.sqlConnection = conn;
// define the SQL text
var sql:String =
"SELECT firstName, lastName " +
"FROM employees";
selectStmt.text = sql;
try
{
// execute the statement
selectStmt.execute();
// access the result data
var result:SQLResult = selectStmt.getResult();
var numRows:int = result.data.length;
for (var i:int = 0; i < numRows; i++)
{
var output:String = "";
for (var columnName:String in result.data[i])
{
output += columnName + ": " + result.data[i][columnName] + "; ";
}
trace("row[" + i.toString() + "]\t", output);
}
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
Definição do tipo de dados dos dados resultantes de SELECT
Por padrão, cada linha retornada por uma instrução SELECT é criada como uma ocorrência de Object com
propriedades nomeadas para os nomes de coluna do conjunto de resultados e com o valor de cada coluna como o valor
da propriedade associada. Porém, antes de executar uma instrução SQL SELECT, você pode definir a propriedade
itemClass da ocorrência de SQLStatement para uma classe. Quando é definida a propriedade itemClass, cada linha
retornada pela instrução SELECT é criada como ocorrência da classe designada. O tempo de execução atribui valores
de coluna resultantes a valores de propriedade comparando os nomes de coluna do conjunto de resultados de SELECT
com os nomes das propriedades da classe itemClass.
Qualquer classe designada como um valor da propriedade itemClass deve ter um construtor que não exija
parâmetros. Além disso, a classe deve ter uma única propriedade para cada coluna retornada pela instrução SELECT.
Será considerado um erro se uma coluna da lista SELECT não tiver um nome de propriedade correspondente na classe
itemClass.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 182
Trabalhar com bancos de dados SQL locais
Recuperação dos resultados de SELECT em partes
Por padrão, a execução de uma instrução SELECT recupera todas as linhas do conjunto de resultados de uma só vez.
Uma vez concluída a instrução, geralmente você processa os dados recuperados de alguma forma; por exemplo,
criando objetos ou exibindo os dados na tela. Se a instrução retornar muitas linhas, processar todos os dados de uma
só vez pode exigir bastante do computador, o que, por sua vez, faz com que a interface do usuário não se redesenhe.
É possível melhorar o desempenho percebido do aplicativo instruindo o tempo de execução a retornar um
determinado número de linhas de resultado por vez. Isso faz com que os dados resultantes iniciais sejam retornados
mais rapidamente. Isso também permite dividir as linhas de resultados em conjuntos, para que a interface de usuário
seja atualizada depois do processamento de cada conjunto de linhas. Só é prático usar esta técnica no modo de
execução assíncrona.
Para recuperar os resultados de SELECT em partes, especifique um valor para o primeiro parâmetro do método
SQLStatement.execute() (o parâmetro prefetch). O parâmetro prefetch indica o número de linhas a serem
recuperadas na primeira vez que a instrução é executada. Quando chamar o método execute() de uma ocorrência de
SQLStatement, especifique um valor de parâmetro prefetch e somente essas linhas serão recuperadas:
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = conn;
stmt.text = "SELECT ...";
stmt.addEventListener(SQLEvent.RESULT, selectResult);
stmt.execute(20); // only the first 20 rows (or fewer) are returned
A instrução despacha o evento result, indicando que o primeiro conjunto de linhas de resultado está disponível. A
propriedade data da ocorrência de SQLResult resultante contém as linhas de dados, e sua propriedade complete
indica se existem mais linhas de resultado a serem recuperadas. Para recuperar linhas de resultados adicionais, chame
o método next() da ocorrência de SQLStatement. Assim como o método execute(), o primeiro parâmetro do
método next() é utilizado para indicar quantas linhas deverão ser recuperadas na próxima vez que o evento result for
despachado.
function selectResult(event:SQLEvent):void
{
var result:SQLResult = stmt.getResult();
if (result.data != null)
{
// ... loop through the rows or perform other processing ...
if (!result.complete)
{
stmt.next(20); // retrieve the next 20 rows
}
else
{
stmt.removeEventListener(SQLEvent.RESULT, selectResult);
}
}
}
SQLStatement despacha um evento result sempre que o método next() retorna um conjunto subseqüente de linhas
de resultado. Conseqüentemente, a mesma função de ouvinte pode ser usada para continuar processando os resultados
(de chamadas de next()) até que todas as linhas sejam recuperadas.
Para obter mais informações, consulte as descrições dos métodos SQLStatement.execute() (a descrição do
parâmetro prefetch) e SQLStatement.next() na referência de linguagem.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 183
Trabalhar com bancos de dados SQL locais
Inserção de dados
A recuperação de dados de um banco de dados envolve executar uma instrução SQL INSERT. Depois de concluída a
execução da instrução, você poderá acessar a chave primária da linha recém-inserida se a chave tiver sido gerada pelo
banco de dados.
Execução de uma instrução INSERT
Para adicionar dados a uma tabela de um banco de dados, crie e execute uma ocorrência de SQLStatement cujo texto
é uma instrução SQL INSERT.
O exemplo a seguir usa uma ocorrência de SQLStatement para adicionar uma linha de dados à tabela employees já
existente. Este exemplo demonstra como inserir dados usando o modo de execução assíncrona. Observe que esta
listagem presume que existe uma ocorrência de SQLConnection denominada conn que já foi instanciada e já está
conectada a um banco de dados. Ela também presume que a tabela “employees” já foi criada.
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
// ... create and open the SQLConnection instance named conn ...
// create the SQL statement
var insertStmt:SQLStatement = new SQLStatement();
insertStmt.sqlConnection = conn;
// define the SQL text
var sql:String =
"INSERT INTO employees (firstName, lastName, salary) " +
"VALUES ('Bob', 'Smith', 8000)";
insertStmt.text = sql;
// register listeners for the result and failure (status) events
insertStmt.addEventListener(SQLEvent.RESULT, insertResult);
insertStmt.addEventListener(SQLErrorEvent.ERROR, insertError);
// execute the statement
insertStmt.execute();
function insertResult(event:SQLEvent):void
{
trace("INSERT statement succeeded");
}
function insertError(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
O exemplo a seguir adiciona uma linha de dados à tabela employees já existente usando o modo de execução síncrona.
Observe que esta listagem presume que existe uma ocorrência de SQLConnection denominada conn que já foi
instanciada e já está conectada a um banco de dados. Ela também presume que a tabela “employees” já foi criada.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 184
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.errors.SQLError;
// ... create and open the SQLConnection instance named conn ...
// create the SQL statement
var insertStmt:SQLStatement = new SQLStatement();
insertStmt.sqlConnection = conn;
// define the SQL text
var sql:String =
"INSERT INTO employees (firstName, lastName, salary) " +
"VALUES ('Bob', 'Smith', 8000)";
insertStmt.text = sql;
try
{
// execute the statement
insertStmt.execute();
trace("INSERT statement succeeded");
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
Recuperação de uma chave primária gerada pelo banco de dados de uma linha inserida
Com freqüência, depois de inserir uma linha de dados a uma tabela, o código precisa ser informado sobre uma chave
primária gerada pelo banco de dados ou o valor do identificador da linha recém-inserida. Por exemplo, depois de
inserir uma linha em uma tabela, você deve adicionar linhas a uma tabela relacionada. Nesse caso, convém inserir o
valor da chave primária como chave externa na tabela relacionada. A chave primária de uma linha recém-inserida pode
ser recuperada usando o objeto SQLResult gerado pela execução da instrução. É o mesmo objeto usado para acessar
dados de resultado depois que uma instrução SELECT é executada. Assim como ocorre com qualquer instrução SQL,
quando a execução de uma instrução INSERT é concluída, o tempo de execução cria uma ocorrência de SQLResult.
Para acessar a ocorrência de SQLResult, chame o método getResult() do objeto SQLStatement se você estiver
usando um ouvinte de evento ou o modo de execução síncrona. Se preferir, caso esteja usando o modo de execução
assíncrona e passe uma ocorrência de Responder para a chamada de execute(), a ocorrência de SQLResult será passada
como argumento para a função do manipulador resultante. Seja como for, a ocorrência de SQLResult tem uma
propriedade, chamada lastInsertRowID, que contém o identificador de linha da linha inserida mais recentemente
se a instrução SQL executada é uma instrução INSERT.
Este exemplo mostra como acessar a chave primária de uma linha inserida no modo de execução assíncrona:
insertStmt.text = "INSERT INTO ...";
insertStmt.addEventListener(SQLEvent.RESULT, resultHandler);
insertStmt.execute();
function resultHandler(event:SQLEvent):void
{
// get the primary key
var result:SQLResult = insertStmt.getResult();
var primaryKey:Number = result.lastInsertRowID;
// do something with the primary key
}
Este exemplo mostra como acessar a chave primária de uma linha inserida no modo de execução síncrona:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 185
Trabalhar com bancos de dados SQL locais
insertStmt.text = "INSERT INTO ...";
try
{
insertStmt.execute();
// get the primary key
var result:SQLResult = insertStmt.getResult();
var primaryKey:Number = result.lastInsertRowID;
// do something with the primary key
}
catch (error:SQLError)
{
// respond to the error
}
Observe que o identificador de linha pode ou não ser o valor da coluna designada como a coluna de chave primária na
definição de tabela, de acordo com a seguinte regra:
• Se a tabela está definida com uma coluna de chave primária cuja afinidade (tipo de dados da coluna) é INTEGER, a
propriedade lastInsertRowID contém o valor inserido nessa linha (ou o valor gerado pelo tempo de execução, no
caso de uma coluna AUTOINCREMENT).
• Se a tabela está definida com várias colunas de chave primária (uma chave composta) ou com uma única coluna de
chave primária cuja afinidade não é INTEGER, o banco de dados gera um valor de identificador de coluna para a
linha em segundo plano. Esse valor gerado é o valor da propriedade lastInsertRowID.
• O valor é sempre o identificador de linha da linha inserida mais recentemente. Se uma instrução INSERT faz com
que seja acionado um disparador que, por sua vez, insere uma linha, a propriedade lastInsertRowID contém o
identificador de linha da última linha inserida pelo disparador em vez da linha criada pela instrução INSERT.
Conseqüentemente, se você quiser ter uma coluna de chave primária definida explicitamente cujo valor fica
disponível após um comando INSERT através da propriedade SQLResult.lastInsertRowID, a coluna deverá ser
definida como uma coluna INTEGER PRIMARY KEY. Porém, mesmo que a tabela não inclua uma coluna INTEGER
PRIMARY KEY explícita, será igualmente aceitável usar o identificador de linha gerado pelo banco de dados como
uma chave primária para a sua tabela com o intuito de definir relacionamentos com tabelas relacionadas. O valor
da coluna do identificador de linha fica disponível em qualquer instrução SQL através do uso de um dos nomes de
coluna especiais ROWID, _ROWID_ ou OID. É possível criar uma coluna de chave externa em uma tabela relacionada
e usar o valor do identificador de linha como o valor da coluna de chave externa, assim como você faria com uma
coluna INTEGER PRIMARY KEY declarada explicitamente. Nesse sentido, se estiver usando uma chave primária
arbitrária em vez de uma chave natural, e desde que não se importe que o tempo de execução gere o valor da chave
primária para você, faz pouca diferença se você usa uma coluna INTEGER PRIMARY KEY ou o identificador de linha
gerado pelo sistema como a chave primária de uma tabela para definir um relacionamento de chave externa entre
duas tabelas.
Para obter mais informações sobre chaves primárias e identificadores de linha gerados, consulte as seções “CREATE
TABLE” e “Expressões” no apêndice “Suporte a SQL em bancos de dados locais” da Referência dos componentes e da
linguagem do ActionScript 3.0.
Alteração ou exclusão de dados
O processo para executar outras operações de manipulação de dados é idêntico ao seguido para executar uma
instrução SQL SELECT ou INSERT. Basta substituir uma instrução SQL diferente na propriedade text da ocorrência
de SQLStatement:
• Para alterar dados existentes em uma tabela, use uma instrução UPDATE.
• Para excluir uma ou mais linhas de dados de uma tabela, use uma instrução DELETE.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 186
Trabalhar com bancos de dados SQL locais
Para obter a descrição dessas instruções, consulte o apêndice “Suporte a SQL em bancos de dados locais” da Referência
dos componentes e da linguagem do ActionScript 3.0.
Trabalhar com vários bancos de dados
Use o método SQLConnection.attach() para abrir uma conexão com um banco de dados adicional em uma
ocorrência de SQLConnection que já tem um banco de dados aberto. Dê um nome ao banco de dados anexado usando
o parâmetro de nome na chamada do método attach(). Ao escrever instruções para manipular esse banco de dados,
você poderá usar esse nome em um prefixo (no formato nome-do-bancodedados.nome-da-tabela) para qualificar
qualquer nome de tabela em suas instruções SQL, indicando ao tempo de execução que a tabela pode ser encontrada
no banco de dados nomeado.
É possível executar uma única instrução SQL que inclua tabelas de vários bancos de dados conectados à mesma
ocorrência de SQLConnection. Se uma transação for criada na ocorrência de SQLConnection, ela será aplicada a todas
as instruções SQL executadas usando a ocorrência de SQLConnection. Isso é válido independentemente do banco de
dados anexado no qual a instrução é executada.
Se preferir, você também pode criar várias ocorrências de SQLConnection em um aplicativo, cada uma delas conectada
a um ou a vários bancos de dados. Contudo, se você usar várias conexões com o mesmo banco de dados, lembre-se de
que uma transação de banco de dados não é compartilhada entre ocorrências de SQLConnection. Conseqüentemente,
se você se conectar ao mesmo arquivo de banco de dados usando várias ocorrências de SQLConnection, não poderá
contar que as alterações de dados em ambas as conexões sejam aplicadas da maneira esperada. Por exemplo, se duas
instruções UPDATE ou DELETE forem executadas no mesmo banco de dados através de diferentes ocorrências de
SQLConnection e acontecer um erro de aplicativo depois de executada uma operação, os dados do banco de dados
poderão ficar em um estado intermediário irreversível que talvez afete a integridade do banco de dados (e,
conseqüentemente, o aplicativo).
Tratamento de erros de banco de dados
Em geral, o tratamento de erros de banco de dados é parecido com o de outros erros de tempo de execução. Você deve
criar um código preparado para eventuais erros e para responder a eles em vez de deixar que o tempo de execução faça
isso. De um modo geral, os erros de banco de dados possíveis dividem-se em três categorias: erros de conexão, de
sintaxe SQL e de restrição.
Erro de conexão
A maioria dos erros de banco de dados são de conexão, e eles podem ocorrer durante qualquer operação. Embora haja
estratégias para prevenir erros de conexão, raramente existe uma forma simples de se recuperar tranqüilamente de um
erro desse tipo se o banco de dados é um componente crítico do seu aplicativo.
A maior parte dos erros de conexão tem a ver com a maneira como o tempo de execução interage com o sistema
operacional, o sistema de arquivos e o arquivo de banco de dados. Por exemplo, ocorre um erro de conexão quando o
usuário não tem permissão para criar um arquivo de banco de dados em um determinado local do sistema de arquivos.
As seguintes estratégias ajudam a prevenir erros de conexão:
Utilize arquivos de banco de dados específicos do usuário Em vez de usar um único arquivo de banco de dados para
todos os usuários que utilizam um mesmo computador, dê a cada usuário seu próprio arquivo de banco de dados. O
arquivo deve estar localizado em um diretório associado com a conta do usuário. Por exemplo, ele pode estar no
diretório de armazenamento do aplicativo, na pasta de documentos do usuário, na área de trabalho dele, e assim por
diante.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 187
Trabalhar com bancos de dados SQL locais
Leve em consideração diferentes tipos de usuário Teste seu aplicativo com diferentes tipos de contas de usuário em
diferentes sistemas operacionais. Não suponha que o usuário tem permissão de administrador no computador.
Também não presuma que quem instalou o aplicativo é o usuário que o está executando.
Leve em consideração localizações de arquivo diferentes Se você permitir que um usuário especifique onde salvar um
arquivo de banco de dados ou selecione um arquivo a ser aberto, considere as possíveis localizações de arquivo que os
usuários podem usar. Além disso, considere a possibilidade de definir limites quanto aos locais em que os usuários
podem armazenar (ou abrir) arquivos de banco de dados. Por exemplo, você só deve permitir que eles abram arquivos
existentes no local de armazenamento de suas contas de usuário.
Se acontecer um erro de conexão, é mais provável que ele ocorra na primeira tentativa de criar ou abrir o banco de
dados. Isso significa que o usuário não consegue fazer nenhuma operação relacionada a banco de dados no aplicativo.
Para certos tipos de erros, como erros de permissão ou somente leitura, uma técnica de recuperação possível consiste
em copiar o arquivo de banco de dados para outro local. O aplicativo pode copiar o arquivo de banco de dados para
outro local, em que o usuário tenha permissão para criar e gravar em arquivos, e pode usar esse local.
Erros de sintaxe
Um erro de sintaxe ocorre quando uma instrução SQL está formada incorretamente e o aplicativo tenta executá-la.
Como as instruções SQL de banco de dados local são criadas como strings, não é possível fazer a verificação da sintaxe
SQL durante a compilação. Todas as instruções SQL devem ser executadas para verificar sua sintaxe. Adote as
seguintes estratégias para evitar erros de sintaxe SQL:
Teste todas as instruções SQL integralmente Se possível, enquanto desenvolve o aplicativo, teste as instruções SQL
separadamente antes de codificá-las como texto de instrução no código do aplicativo. Além disso, use uma abordagem
de teste do código, como teste de unidade, para criar um conjunto de testes que aplique todas as opções e variações
possíveis no código.
Use parâmetros de instrução e evite concatenar (gerar dinamicamente) o SQL Usar parâmetros, e evitar instruções
SQL criadas dinamicamente, significa que o mesmo texto de instrução SQL é usado sempre que uma instrução é
executada. Conseqüentemente, é bem mais fácil testar suas instruções e limitar a variação possível. Se você tiver de
gerar uma instrução SQL dinamicamente, use o mínimo possível de partes dinâmicas na instrução. Além disso, seja
cauteloso ao validar qualquer entrada de usuário para se certificar de que ela não causará erros de sintaxe.
Para se recuperar de um erro de sintaxe, um aplicativo precisa de uma lógica complexa que permita examinar uma
instrução SQL e corrigir sua sintaxe. Se forem seguidas as diretrizes acima para evitar erros de sintaxe, o código
conseguirá identificar qualquer possível origem de tempo de execução de erros de sintaxe SQL (como entradas de
usuário utilizadas em uma instrução). Para se recuperar de um erro de sintaxe, oriente o usuário. Indique o que deve
ser corrigido para que a instrução seja executada corretamente.
Erros de restrição
Erros de restrição ocorrem quando uma instrução INSERT ou UPDATE tenta adicionar dados a uma coluna. O erro
acontece se os novos dados violam uma das restrições definidas para a tabela ou coluna. O conjunto de restrições
possíveis inclui:
Restrição exclusiva Indica que, entre todas as linhas de uma tabela, não pode existir valores duplicados em uma
coluna. Como alternativa, quando várias colunas são combinadas em uma restrição exclusiva, a combinação de valores
dessas colunas não deve ser duplicada. Em outras palavras, em termos da(s) coluna(s) exclusiva(s) especificada(s), cada
linha deve ser distinta.
Restrição de chave primária Em termos dos dados permitidos e não permitidos por uma restrição, a restrição de chave
primária é idêntica a uma restrição exclusiva.
Restrição não nula Especifica que uma única coluna não pode armazenar um valor NULL e, conseqüentemente, que em
cada linha essa coluna deve ter um valor.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 188
Trabalhar com bancos de dados SQL locais
Restrição de verificação Permite especificar uma restrição arbitrária em uma ou mais tabelas. Uma restrição de
verificação comum é uma regra que define que o valor de uma coluna deve estar dentro de certos limites (por exemplo,
que o valor de uma coluna numérica deve ser maior que 0). Outro tipo de restrição de verificação comum especifica
relacionamentos entre valores de coluna (por exemplo, que o valor de uma coluna deve ser diferente do de outra
coluna na mesma linha).
Restrição de tipo de dados (afinidade de coluna) O tempo de execução impõe o tipo de dados de valores de colunas, e
ocorre um erro se é feita uma tentativa de armazenar um valor de tipo incorreto em uma coluna. No entanto, em
muitas condições os valores são convertidos para corresponder ao tipo de dados declarado da coluna. Consulte
“Trabalhar com tipos de dados de banco de dados” na página 189 para obter mais informações.
O tempo de execução não impõe restrições quanto a valores de chave externa. Em outras palavras, os valores de chave
externa não precisam corresponder ao valor de uma chave primária existente.
Além dos tipos de restrição predefinidos, o mecanismo SQL de tempo de execução permite o uso de disparadores. O
disparador é como um manipulador de eventos. Ele consiste em um conjunto de instruções predefinidas que são
executadas quando acontece uma determinada ação. Por exemplo, é possível definir um disparador que seja executado
quando dados forem inseridos ou excluídos de uma tabela específica. Um uso possível de um disparador é examinar
alterações feitas em dados e fazer com que ocorra um erro se as condições especificadas não forem atendidas.
Conseqüentemente, um disparador pode atender ao mesmo objetivo de uma restrição, e as estratégias para evitar e se
recuperar de erros de restrição também se aplicam a erros gerados por disparadores. Porém, a id de erro dos erros
gerados por disparadores é diferente da id de erro dos erros de restrição.
O conjunto de restrições que se aplicam a uma tabela em particular é determinado enquanto você está criando um
aplicativo. Elaborar restrições com consciência facilita que você crie o aplicativo para evitar e se recuperar de erros de
constrição. No entanto, os erros de restrição são difíceis de prever e impedir sistematicamente. A previsão é difícil
porque os erros de restrição só aparecem depois que são adicionados os dados do aplicativo. Os erros de restrição
acontecem com dados que são adicionados a um banco de dados após sua criação. Com freqüência, esses erros são
resultado do relacionamento entre os novos dados e os dados já existentes no banco de dados. As seguintes estratégias
podem ajudá-lo a evitar muitos erros de restrição:
Planeje cautelosamente a estrutura e as restrições do banco de dados A finalidade das restrições é impor regras de
aplicativo e ajudar a proteger a integridade dos dados do banco de dados. Quando estiver planejando seu aplicativo,
pense em como estruturar o banco de dados para dar suporte ao aplicativo. Como parte desse processo, identifique
regras para seus dados; por exemplo, se certos valores não necessários, se um valor tem um padrão, se são permitidos
valores duplicados e assim por diante. Essas regras orientam a definição de restrições do banco de dados.
Especifique nomes de coluna explicitamente É possível criar uma instrução INSERT sem especificar explicitamente as
colunas em que os valores deverão ser inseridos, mas fazê-lo é um risco desnecessário. Quando você nomeia
explicitamente as colunas em que os valores deverão ser inseridos, pode permitir valores gerados de forma automática,
colunas com valores padrão e colunas que permitam valores NULL. Além disso, quando você faz isso pode assegurar
que todas as colunas NOT NULL terão um valor explícito inserido.
Use valores padrão Sempre que você especificar uma restrição NOT NULL para uma coluna, se possível, especifique um
valor padrão na definição de coluna. O código do aplicativo também pode fornecer valores padrão. Por exemplo, o
código pode verificar se uma variável String é null e atribuir um valor a ela antes de usá-la para definir um valor de
parâmetro de instrução.
Valide os dados inseridos pelos usuários Verifique com antecedência os dados inseridos pelos usuários para ter
certeza de que obedecem aos limites especificados pelas restrições, principalmente no caso de restrições NOT NULL e
CHECK. Naturalmente, uma restrição UNIQUE é mais difícil de verificar porque, para fazer a verificação, é necessário
executar uma consulta SELECT para determinar se os dados são exclusivos.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 189
Trabalhar com bancos de dados SQL locais
Use disparadores Você pode criar um disparador que valide (e possivelmente substitua) os dados inseridos ou que
tome outras medidas para corrigir dados inválidos. Esse procedimento de validação e correção pode evitar que
aconteça um erro de restrição.
Em vários aspectos, é mais difícil evitar os erros de restrição do que outros tipos de erro. Felizmente, existem diversas
estratégias para se recuperar de erros de restrição sem tornar o aplicativo instável ou inutilizável:
Use algoritmos de conflito Quando você define uma restrição em uma coluna, e quando cria uma instrução INSERT
ou UPDATE, tem a opção de especificar um algoritmo de conflito. Um algoritmo de conflito define a ação que o banco
de dados executa quando ocorre uma violação de restrição. Há várias ações possíveis que o mecanismo de banco de
dados pode executar. O mecanismo de banco de dados pode encerrar uma única instrução ou uma transação inteira.
Ele pode ignorar o erro. Ele pode até mesmo remover dados antigos e substituí-los pelos dados que o código está
tentando armazenar.
Para obter mais informações, consulte a seção “ON CONFLICT (algoritmos de conflito)” no apêndice “Suporte a SQL
em bancos de dados locais” da Referência dos componentes e da linguagem do ActionScript 3.0.
Disponibilize feedback de correção É possível identificar antecipadamente o conjunto de restrições que pode afetar
um determinado comando SQL. Como conseqüência, você consegue prever os erros de restrição que podem ser
causados por uma instrução. Dispondo dessa informação, você pode desenvolver a lógica do aplicativo para responder
a um erro de restrição. Por exemplo, suponha que um aplicativo inclui um formulário de entrada de dados que permite
inserir novos produtos. Se a coluna de nome de produto no banco de dados estiver definida com uma restrição UNIQUE,
a ação de inserir uma linha de novo produto no banco de dados poderá causar um erro de restrição.
Conseqüentemente, o aplicativo deve prever um erro de restrição. Quando o erro acontece, o aplicativo alerta o
usuário indicando que o nome de produto especificado já está sendo utilizado e pede a ele para escolher outro nome.
Outra resposta possível é permitir que o usuário visualize informações sobre o outro produto que tem o mesmo nome.
Trabalhar com tipos de dados de banco de dados
Quando uma tabela é criada em um banco de dados, a instrução SQL usada para criar a tabela define a afinidade, ou o
tipo de dados, de cada coluna da tabela. Embora seja possível omitir declarações de afinidade, é uma boa idéia declarar
explicitamente a afinidade de coluna nas instruções SQL CREATE TABLE.
Como regra geral, qualquer objeto que você armazena em um banco de dados usando uma instrução INSERT é
retornado como ocorrência do mesmo tipo de dados quando é executada uma instrução SELECT. No entanto, o tipo
de dados do valor recuperado pode ser diferente, dependendo da afinidade da coluna do banco de dados na qual o valor
está armazenado. Quando um valor é armazenado em uma coluna, se o respectivo tipo de dados não corresponde à
afinidade de coluna, o banco de dados tenta converter o valor para que corresponda à afinidade de coluna. Por
exemplo, se uma coluna de banco de dados está declarada com afinidade NUMERIC, o banco de dados tenta converter
os dados inseridos em uma classe de armazenamento numérica (INTEGER ou REAL) antes de armazenar os dados. O
banco de dados gera um erro se não é possível converter os dados. De acordo com esta regra, se a String “12345” é
inserida em uma coluna NUMERIC, o banco de dados automaticamente a converte no valor inteiro 12345 antes de
armazená-la no banco de dados. Quando recuperado com uma instrução SELECT, o valor é retornado como uma
ocorrência de um tipo de dados numérico (por exemplo, Number) e não como uma ocorrência de String.
A melhor maneira de evitar a conversão indesejada de tipos de dados é seguir duas regras. Primeiro, defina cada coluna
com a afinidade que corresponda ao tipo de dados que pretende armazenar. Em seguida, insira apenas valores cujo
tipo de dados corresponda à afinidade definida. Se você seguir essas regras, terá dois benefícios. Quando você inserir
os dados, eles não serão convertidos inesperadamente (com a possibilidade de perderem o significado pretendido).
Além disso, quando você recupera os dados, eles são retornados com o tipo de dados original.
Para obter mais informações sobre os tipos de afinidade de coluna disponíveis e como usar tipos de dados em
instruções SQL, consulte a seção “Suporte ao tipo de dados” no apêndice “Suporte a SQL em bancos de dados locais”
da Referência dos componentes e da linguagem do ActionScript 3.0.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 190
Trabalhar com bancos de dados SQL locais
Uso de operações de banco de dados síncronas e
assíncronas
As seções anteriores descreveram operações comuns de banco de dados, como recuperar, inserir, atualizar e excluir
dados, além da criação de um arquivo de banco de dados e de tabelas e outros objetos de um banco de dados. Os
exemplos demonstraram como executar essas operações de maneira assíncrona e síncrona.
Como lembrete, no modo de execução assíncrona, você instrui o mecanismo de banco de dados a executar uma
operação. O mecanismo de banco de dados então trabalha em segundo plano enquanto o aplicativo continua a
executar. Quando a operação é concluída, o mecanismo de banco de dados despacha um evento para alertar você sobre
o fato. O principal benefício da execução assíncrona é que o tempo de execução realiza as operações de banco de dados
em segundo plano, enquanto o código do aplicativo principal continua a executar. Isso é importante principalmente
quando a operação é bastante demorada.
Por outro lado, no modo de execução síncrona, as operações não são executadas em segundo plano. Você instrui o
mecanismo de banco de dados a executar uma operação. O código pausa nesse ponto enquanto o mecanismo de banco
de dados faz o seu trabalho. Quando a operação é concluída, a execução prossegue com a próxima linha do código que
você criou.
Uma única conexão de banco de dados não pode executar algumas operações ou instruções em modo síncrono e outras
em modo assíncrono. Você especifica se SQLConnection opera de forma síncrona ou assíncrona quando abre a
conexão com o banco de dados. Se você chamar SQLConnection.open(), a conexão funcionará no modo de execução
síncrona; se você chamar SQLConnection.openAsync(), ela funcionará no modo de execução assíncrona. Uma vez
que uma ocorrência de SQLConnection é conectada a um banco de dados usando open() ou openAsync(), ela é
fixada à execução síncrona ou assíncrona.
Uso de operações de banco de dados síncronas
Há pouca diferente no código que você usa para executar e responder a operações na execução síncrona em
comparação com o código para o modo de execução assíncrona. As principais diferenças entre as duas abordagens
estão em duas áreas. A primeira é executar uma operação que depende de outra operação (como linhas de resultado
SELECT ou a chave primária da linha adicionada por uma instrução INSERT). A segunda área de diferença é o
tratamento de erros.
Criação de código para operações síncronas
A principal diferença entre a execução síncrona e assíncrona é que, no modo síncrono, você cria o código como uma
única série de etapas. Por outro lado, no código assíncrono, você registra ouvintes de evento e com freqüência divide
as operações entre métodos de ouvinte. Quando um banco de dados é conectado no modo de execução síncrona, você
pode executar uma série de operações de banco de dados em seqüência em um único bloco de código. O exemplo
abaixo demonstra esta técnica:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 191
Trabalhar com bancos de dados SQL locais
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
// open the database
conn.open(dbFile, OpenMode.UPDATE);
// start a transaction
conn.begin();
// add the customer record to the database
var insertCustomer:SQLStatement = new SQLStatement();
insertCustomer.sqlConnection = conn;
insertCustomer.text =
"INSERT INTO customers (firstName, lastName) " +
"VALUES ('Bob', 'Jones')";
insertCustomer.execute();
var customerId:Number = insertCustomer.getResult().lastInsertRowID;
// add a related phone number record for the customer
var insertPhoneNumber:SQLStatement = new SQLStatement();
insertPhoneNumber.sqlConnection = conn;
insertPhoneNumber.text =
"INSERT INTO customerPhoneNumbers (customerId, number) " +
"VALUES (:customerId, '800-555-1234')";
insertPhoneNumber.parameters[":customerId"] = customerId;
insertPhoneNumber.execute();
// commit the transaction
conn.commit();
Como você pode ver, é possível chamar os mesmos métodos para executar operações de banco de dados
independentemente de usar a execução síncrona ou assíncrona. As principais diferenças entre as duas abordagens são
executar uma operação que depende de outra operação e como tratar de erros.
Execução de uma operação que depende de outra
Quando você usa o modo de execução síncrona, não precisa criar um código que monitore um evento para determinar
quando uma operação é concluída. Em vez disso, você pode presumir que, se uma operação em uma linha de código
foi concluída com sucesso, a execução continuará na próxima linha de código. Conseqüentemente, para executar uma
operação que depende do sucesso de outra, basta criar o código dependente logo depois da operação da qual ela
depende. Por exemplo, para codificar um aplicativo para iniciar uma transação, executar uma instrução INSERT,
recuperar a chave primária da linha inserida, inserir essa chave primária em outra linha de uma outra tabela e, por fim,
confirmar a transação, o código pode ser todo criado como uma série de instruções. O seguinte exemplo demonstra
essas operações:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 192
Trabalhar com bancos de dados SQL locais
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
// open the database
conn.open(dbFile, SQLMode.UPDATE);
// start a transaction
conn.begin();
// add the customer record to the database
var insertCustomer:SQLStatement = new SQLStatement();
insertCustomer.sqlConnection = conn;
insertCustomer.text =
"INSERT INTO customers (firstName, lastName) " +
"VALUES ('Bob', 'Jones')";
insertCustomer.execute();
var customerId:Number = insertCustomer.getResult().lastInsertRowID;
// add a related phone number record for the customer
var insertPhoneNumber:SQLStatement = new SQLStatement();
insertPhoneNumber.sqlConnection = conn;
insertPhoneNumber.text =
"INSERT INTO customerPhoneNumbers (customerId, number) " +
"VALUES (:customerId, '800-555-1234')";
insertPhoneNumber.parameters[":customerId"] = customerId;
insertPhoneNumber.execute();
// commit the transaction
conn.commit();
Tratamento de erros na execução síncrona
No modo de execução síncrona, você não monitora um evento de erro para determinar se uma operação falhou. Em
vez disso, coloque qualquer código que possa disparar erros em um conjunto de blocos de código
try..catch..finally. Coloque o código gerador de erro no bloco try. Grave as ações a serem executadas em
resposta a cada tipo de erro em blocos catch separados. Coloque qualquer código que você queira sempre executar
independentemente de sucesso ou falha (por exemplo, encerrar uma conexão de banco de dados não mais necessária)
em um bloco finally. O exemplo a seguir demonstra o uso de blocos try..catch..finally para tratamento de
erros. Ele aproveita o exemplo anterior adicionando código de tratamento de erro:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 193
Trabalhar com bancos de dados SQL locais
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
// open the database
conn.open(dbFile, SQLMode.UPDATE);
// start a transaction
conn.begin();
try
{
// add the customer record to the database
var insertCustomer:SQLStatement = new SQLStatement();
insertCustomer.sqlConnection = conn;
insertCustomer.text =
"INSERT INTO customers (firstName, lastName)" +
"VALUES ('Bob', 'Jones')";
insertCustomer.execute();
var customerId:Number = insertCustomer.getResult().lastInsertRowID;
// add a related phone number record for the customer
var insertPhoneNumber:SQLStatement = new SQLStatement();
insertPhoneNumber.sqlConnection = conn;
insertPhoneNumber.text =
"INSERT INTO customerPhoneNumbers (customerId, number)" +
"VALUES (:customerId, '800-555-1234')";
insertPhoneNumber.parameters[":customerId"] = customerId;
insertPhoneNumber.execute();
// if we've gotten to this point without errors, commit the transaction
conn.commit();
}
catch (error:SQLError)
{
// rollback the transaction
conn.rollback();
}
Noções básicas sobre o modelo de execução assíncrona
Uma preocupação comum sobre o uso do modo de execução assíncrona é a suposição de que não é possível começar
a executar uma ocorrência de SQLStatement se outra ocorrência de SQLStatement está em execução na mesma
conexão de banco de dados. Na verdade, essa suposição não está correta. Durante a execução de uma ocorrência de
SQLStatement, não é possível alterar a propriedade text da instrução. Contudo, se você usar uma ocorrência de
SQLStatement à parte para cada instrução SQL que deseja executar, poderá chamar o método execute() de um
SQLStatement enquanto outra ocorrência de SQLStatement ainda estiver sendo executada, sem causar erro.
Internamente, quando você executa operações de banco de dados utilizando o modo de execução assíncrona, cada
conexão de banco de dados (cada ocorrência de SQLConnection) tem sua própria fila ou lista de operações que está
instruída a executar. O tempo de execução realiza cada operação em seqüência, na ordem em que são adicionadas à
fila. Quando você cria uma ocorrência de SQLStatement e chama o método execute() relacionado, a operação de
execução dessa instrução é adicionada à fila da conexão. Se nenhuma operação estiver sendo executada nessa
ocorrência de SQLConnection, a instrução começará a ser executada em segundo plano. Suponha que, dentro do
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 194
Trabalhar com bancos de dados SQL locais
mesmo bloco de código, você crie outra ocorrência de SQLStatement e também chame o método execute() daquele
método. A operação que executa essa segunda instrução é adicionada à fila depois da primeira instrução. Assim que é
concluída a execução da primeira instrução, o tempo de execução passa para a próxima operação da fila. O
processamento das operações subseqüentes na fila acontece em segundo plano, mesmo quando o evento result da
primeira operação está sendo despachado no código do aplicativo principal. O código abaixo demonstra esta técnica:
// Using asynchronous execution mode
var stmt1:SQLStatement = new SQLStatement();
stmt1.sqlConnection = conn;
// ... Set statement text and parameters, and register event listeners ...
stmt1.execute();
// At this point stmt1's execute() operation is added to conn's execution queue.
var stmt2:SQLStatement = new SQLStatement();
stmt2.sqlConnection = conn;
// ... Set statement text and parameters, and register event listeners ...
stmt2.execute();
// At this point stmt2's execute() operation is added to conn's execution queue.
// When stmt1 finishes executing, stmt2 will immediately begin executing
// in the background.
Ocorre um importante efeito colateral pelo fato de o banco de dados executar as próximas instruções em fila de
maneira automática. Se uma instrução depende do resultado de outra operação, não é possível adicioná-la à fila (em
outras palavras, você não pode chamar o método execute() relacionado) até a primeira operação ser concluída. Isso
acontece porque, depois que você chamou o método execute() da segunda instrução, não é possível alterar as
propriedades text ou parameters dela. Nesse caso, você deve aguardar o evento indicando que a primeira operação
foi concluída antes de iniciar a próxima operação. Por exemplo, se você quiser executar uma instrução no contexto de
uma transação, a execução da instrução dependerá da operação de abrir a transação. Após chamar o método
SQLConnection.begin() para abrir a transação, você terá de aguardar que a ocorrência de SQLConnection despache
seu evento begin. Só então você poderá chamar o método execute() da ocorrência de SQLStatement. Neste exemplo,
o modo mais simples de organizar o aplicativo para assegurar que as operações sejam executadas corretamente é criar
um método que seja registrado como ouvinte do evento begin. O código para chamar o método
SQLStatement.execute() é colocado dentro do método desse ouvinte.
Uso da criptografia com bancos de dados SQL
Todos os aplicativos do Adobe AIR compartilham o mesmo mecanismo do banco de dados local. Conseqüentemente,
qualquer aplicativo do AIR pode se conectar, ler e gravar em qualquer arquivo do banco de dados não criptografado.
Começando com o Adobe AIR 1.5, o AIR inclui a capacidade de criar e se conectar a arquivos do banco de dados
criptografado. Quando você usa um banco de dados criptografado, para se conectar a ele um aplicativo deve fornecer
a chave de criptografia correta. Se a chave de criptografia incorreta (ou nenhuma chave) for fornecida, o aplicativo não
poderá se conectar ao banco de dados. Conseqüentemente, o aplicativo não poderá ler, gravar ou alterar dados do
banco de dados.
Para usar um banco de dados criptografado, você deve criar o banco de dados como banco de dados criptografado.
Com um banco de dados criptografado existente, é possível abrir uma conexão com o banco de dados. Você também
pode alterar a chave de criptografia de um banco de dados criptografado. Em vez de criar e estabelecer conexão com
bancos de dados criptografados, as técnicas para trabalhar com um banco de dados criptografado são as mesmas que
para um banco de dados não criptografado. Especificamente, a execução de instruções SQL ocorre da mesma forma
em bancos de dados criptografados e não criptografados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 195
Trabalhar com bancos de dados SQL locais
Uso de um banco de dados criptografado
A criptografia é útil sempre que você desejar restringir o acesso às informações armazenadas em um banco de dados.
A funcionalidade de criptografia do banco de dados do Adobe AIR pode ser usada para várias finalidades. Estes são
exemplos de casos em que você pode usar um banco de dados criptografado:
• Um cache somente leitura de dados de aplicativos privados baixados de um servidor
• Um armazenamento de aplicativo local para dados privados sincronizado com um servidor (os dados são enviados
e carregados do servidor)
• Arquivos criptografados usados como formato de arquivo para documentos criados e editados pelo aplicativo. Os
arquivos podem ser privados para um usuário ou projetados para compartilhamento entre todos os usuários do
aplicativo.
• Qualquer outro uso de um armazenamento local de dados, como os descrito em “Usos de bancos de dados SQL
locais” na página 165, onde os dados devem ser mantidos privados de pessoas com acesso ao computador ou aos
arquivos do banco de dados.
Compreender o motivo pelo qual você deseja usar um banco de dados criptografado ajuda a decidir como arquitetar
seu aplicativo. Especificamente, ele pode afetar a forma que seu aplicativo cria, obtém ou armazena a chave de
criptografia para o banco de dados. Para obter mais informações sobre essas considerações, consulte “Considerações
para usar criptografia com um banco de dados” na página 199.
Diferente de um banco de dados criptografado, um mecanismo alternativo para manter dados confidenciais privados
é o armazenamento local criptografado. Com o armazenamento local criptografado, você armazena um único valor
ByteArray usando uma chave String. Apenas o aplicativo do AIR que armazenou o valor pode acessá-lo, e somente no
computador em que ele está armazenado. Com o armazenamento local criptografado, não é necessário criar sua
própria chave de criptografia. Por esses motivos, o armazenamento local criptografado é mais adequado para
armazenar facilmente um único valor ou um conjunto de valores que possa ser facilmente codificado em um
ByteArray. Um banco de dados criptografado é mais adequado para conjuntos de dados maiores, onde o
armazenamento de dados e consultas estruturadas são desejáveis. Para obter mais informações sobre o uso de
armazenamento local criptografado, consulte “Armazenamento de dados criptografados” na página 215.
Criação de um banco de dados criptografado
Para usar um banco de dados criptografado, o arquivo do banco de dados deve ser criptografado quando ele for criado.
Quando um banco de dados é criado como não criptografado, ele pode não ser criptografado posteriormente. Da
mesma forma, um banco de dados criptografado não pode passar a não criptografado posteriormente. Se necessário,
você também pode alterar a chave de criptografia de um banco de dados criptografado. Para obter detalhes, consulte
“Alteração da chave de criptografia de um banco de dados” na página 198. Se você tiver um banco de dados existente
que não seja criptografado e desejar usar a criptografia de banco de dados, poderá criar um novo banco de dados
criptografado e copiar a estrutura de tabela e os dados existentes no novo banco de dados.
Criar um banco de dados criptografado é quase idêntico a criar um banco de dados não criptografado, como descrito
em “Criação de um banco de dados” na página 169. Primeiro você cria uma instância do SQLConnection que
representa a conexão ao banco de dados. Crie o banco de dados chamando o método open() ou o método
openAsync() do objeto do SQLConnection, especificando para a localização do banco de dados um arquivo que ainda
não exista. A única diferença na criação de um banco de dados criptografado é que você fornece um valor para o
parâmetro encryptionKey (o quinto parâmetro do método open() e o sexto parâmetro do método openAsync()).
Um valor do parâmetro encryptionKey válido é um objeto ByteArray contendo exatamente 16 bytes.
O exemplo a seguir demonstra a criação de um banco de dados criptografado que é aberto no modo de execução
assíncrona. Para simplicidade, neste exemplo a chave de criptografia é codificada no código do aplicativo. No entanto,
essa técnica é altamente desencorajada, pois não é segura.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 196
Trabalhar com bancos de dados SQL locais
import
import
import
import
import
flash.data.SQLConnection;
flash.data.SQLMode;
flash.events.SQLErrorEvent;
flash.events.SQLEvent;
flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
var encryptionKey:ByteArray = new ByteArray();
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure!
conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey);
function openHandler(event:SQLEvent):void
{
trace("the database was created successfully");
}
function errorHandler(event:SQLErrorEvent):void
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
O exemplo a seguir demonstra a criação de um banco de dados criptografado que é aberto no modo de execução
síncrona. Para simplicidade, neste exemplo a chave de criptografia é codificada no código do aplicativo. No entanto,
essa técnica é altamente desencorajada, pois não é segura.
import flash.data.SQLConnection;
import flash.data.SQLMode;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
var encryptionKey:ByteArray = new ByteArray();
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure!
try
{
conn.open(dbFile, SQLMode.CREATE, false, 1024, encryptionKey);
trace("the database was created successfully");
}
catch (error:SQLError)
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
Para obter um exemplo que demonstre uma forma recomendada de gerar uma chave de criptografia, consulte
“Exemplo: Geração e uso de uma chave de criptografia” na página 200.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 197
Trabalhar com bancos de dados SQL locais
Conexão com um banco de dados criptografado
Da mesma forma que criar um banco de dados criptografado, o procedimento para abrir uma conexão com um banco
de dados criptografado é como conectar-se a um banco de dados não criptografado. Esse procedimento é descrito com
mais detalhes em “Conexão com um banco de dados” na página 172. Use o método open() para abrir uma conexão
no modo de execução síncrona ou o método openAsync() para abri-la no modo de execução assíncrona. A única
diferença é que para abrir um banco de dados criptografado, especifica o valor correto para o parâmetro
encryptionKey (o quinto parâmetro do método open() e o sexto parâmetro do método openAsync()).
Se a chave de criptografia fornecida não for a correta, ocorre um erro. Para o método open(), é lançada uma exceção
SQLError. Para o método openAsync(), o objeto SQLConnection despacha um SQLErrorEvent, cuja propriedade
error contém um objeto SQLError. Em qualquer um dos casos, o objeto SQLError gerado pela exceção tem o valor
de propriedade errorID 3138. Essa ID de erro corresponde à mensagem de erro "Arquivo aberto não é arquivo do
banco de dados".
O exemplo a seguir demonstra a abertura de um banco de dados criptografado em modo de execução assíncrona. Para
simplicidade, neste exemplo a chave de criptografia é codificada no código do aplicativo. No entanto, essa técnica é
altamente desencorajada, pois não é segura.
import
import
import
import
import
flash.data.SQLConnection;
flash.data.SQLMode;
flash.events.SQLErrorEvent;
flash.events.SQLEvent;
flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
var encryptionKey:ByteArray = new ByteArray();
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure!
conn.openAsync(dbFile, SQLMode.UPDATE, null, false, 1024, encryptionKey);
function openHandler(event:SQLEvent):void
{
trace("the database opened successfully");
}
function errorHandler(event:SQLErrorEvent):void
{
if (event.error.errorID == 3138)
{
trace("Incorrect encryption key");
}
else
{
trace("Error message:", event.error.message);
trace("Details:", event.error.details);
}
}
O exemplo a seguir demonstra a abertura de um banco de dados criptografado em modo de execução síncrona. Para
simplicidade, neste exemplo a chave de criptografia é codificada no código do aplicativo. No entanto, essa técnica é
altamente desencorajada, pois não é segura.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 198
Trabalhar com bancos de dados SQL locais
import flash.data.SQLConnection;
import flash.data.SQLMode;
import flash.filesystem.File;
var conn:SQLConnection = new SQLConnection();
var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
var encryptionKey:ByteArray = new ByteArray();
encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure!
try
{
conn.open(dbFile, SQLMode.UPDATE, false, 1024, encryptionKey);
trace("the database was created successfully");
}
catch (error:SQLError)
{
if (error.errorID == 3138)
{
trace("Incorrect encryption key");
}
else
{
trace("Error message:", error.message);
trace("Details:", error.details);
}
}
Para obter um exemplo que demonstre uma forma recomendada de gerar uma chave de criptografia, consulte
“Exemplo: Geração e uso de uma chave de criptografia” na página 200.
Alteração da chave de criptografia de um banco de dados
Quando um banco de dados é criptografado, você pode alterar a chave de criptografia para o banco de dados
posteriormente. Para isso, primeiro abra uma conexão com o banco de dados criando uma instância de
SQLConnection e chamando seu método open() ou openAsync(). Quando o banco de dados for conectado, chame
o método reencrypt(), enviando a nova chave de criptografia como um argumento.
Como a maioria das operações de banco de dados, o comportamento do método reencrypt() depende se a conexão
do banco de dados usa modo de execução síncrona ou assíncrona. Se você usar o método open() para conectar-se ao
banco de dados, a operação de reencrypt() será executada de forma síncrona. Quando a operação é concluída, a
execução prossegue com a próxima linha do código.
var newKey:ByteArray = new ByteArray();
// ... generate the new key and store it in newKey
conn.reencrypt(newKey);
Por outro lado, se a conexão do banco de dados for aberta com o método openAsync(), a operação de reencrypt()
será assíncrona. Chamar reencrypt() inicia o processo de recriptografia. Quando a operação é concluída, o objeto
SQLConnection despacha um evento reencrypt. Use um ouvinte de evento para determinar quando a recriptografia
será concluída:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 199
Trabalhar com bancos de dados SQL locais
var newKey:ByteArray = new ByteArray();
// ... generate the new key and store it in newKey
conn.addEventListener(SQLEvent.REENCRYPT, reencryptHandler);
conn.reencrypt(newKey);
function reencryptHandler(event:SQLEvent):void
{
// save the fact that the key changed
}
A operação reencrypt() será executada na sua própria transação. Se a operação for interrompida ou falhar (por
exemplo, se o aplicativo for fechado antes da conclusão da operação), a transação será revertida. Nesse caso, a chave
de criptografia ainda será a chave de criptografia do banco de dados.
O método reencrypt() não pode ser usado para remover a criptografia de um banco de dados. Enviar um valor null
ou chave de criptografia que não seja um ByteArray de 16 bytes para o método reencrypt() resulta em erro.
Considerações para usar criptografia com um banco de dados
A seção “Uso de um banco de dados criptografado” na página 195 apresenta vários casos em que você pode usar um
banco de dados criptografado. É óbvio que as situações de uso dos aplicativos diferentes (incluindo essas e outras
situações) têm requisitos de privacidade diferentes. A forma que você arquiteta o uso de criptografia no seu aplicativo
tem importante papel no controle do grau de privacidade dos dados de um banco de dados. Por exemplo, se você
estiver usando um banco de dados criptografado para manter os dados pessoais privados, mesmo de usuários do
mesmo computador, o banco de dados de cada usuário deverá ter a própria chave de criptografia. Para obter segurança
máxima, seu aplicativo pode gerar a chave de uma senha digitada por um usuário. Basear a chave de criptografia em
uma senha garante que os dados se mantenham preservados, mesmo se qualquer outra pessoa entrar na conta do
usuário no computador. Por outro lado, suponha que você deseje que um arquivo do banco de dados seja legível para
qualquer usuário do seu aplicativo, mas não para os demais aplicativos. Nesse caso, todas as cópias do aplicativo
instaladas precisam de acesso a uma chave de criptografia compartilhada.
Você pode projetar seu aplicativo e, em particular, a técnica usada para gerar a chave de criptografia, de acordo com o
nível de privacidade que você deseja para os dados do aplicativo. A lista a seguir fornece sugestões de design para vários
níveis de privacidade de dados.
• Para tornar um banco de dados acessível a qualquer usuário que tenha acesso ao aplicativo em qualquer
computador, use uma única chave disponível em todas as instâncias do aplicativo. Por exemplo, na primeira vez
que um aplicativo for executado, ele poderá baixar a chave de criptografia compartilhada de um servidor usando
um protocolo seguro, como SSL. Em seguida, ele poderá salvar a chave no armazenamento local criptografado para
uso futuro. Como alternativa, criptografe os dados por usuário no computador e sincronize os dados com um
armazenamento de dados remoto, como servidor, para tornar os dados portáteis.
• Para tornar um banco de dados acessível para um único usuário em qualquer computador, gere a chave de
criptografia a partir de um segredo do usuário (como uma senha). Especificamente, não use nenhum valor
associado a um computador específico (como um valor armazenado no armazenamento local criptografado) para
gerar a chave. Como alternativa, criptografe os dados por usuário no computador e sincronize os dados com um
armazenamento de dados remoto, como servidor, para tornar os dados portáteis.
• Para tornar um banco de dados acessível somente para um único indivíduo em um único computador, gere a chave
de uma senha e um salt gerado. Para obter um exemplo dessa técnica, consulte “Exemplo: Geração e uso de uma
chave de criptografia” na página 200.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 200
Trabalhar com bancos de dados SQL locais
A seguir há algumas considerações adicionais sobre segurança que são importantes lembrar ao projetar um aplicativo
para usar um banco de dados criptografado.
• Um sistema só é seguro como seu link mais fraco. Se você estiver usando uma senha gerada pelo usuário para gerar
uma chave de criptografia, considere impor o restrições de complexidade e tamanho mínimo às senhas. Uma senha
curta que use somente caracteres básicos pode ser adivinhada rapidamente.
• O código-fonte de um aplicativo do AIR é armazenado no computador de um usuário em texto simples (para
conteúdo HTML) ou em um formato binário facilmente descompilável (para conteúdo SWF). Como o códigofonte é acessível, dois pontos a lembrar são:
• Nunca codifique uma chave de criptografia no seu código-fonte
• Sempre suponha que a técnica usada para gerar uma chave de criptografia (como gerador aleatório de caracteres
ou um algoritmo de hash específico) possa ser facilmente descoberta por um invasor
• A criptografia do banco de dados AIR usa o modo AES (padrão de criptografia avançado) com CCM (contador com
CBC-MAC). Essa cifra de criptografia requer a combinação de uma chave inserida pelo usuário com um valor salt
para ser segura. Para obter um exemplo, consulte “Exemplo: Geração e uso de uma chave de criptografia” na
página 200.
• Quando você opta por criptografar um banco de dados, todos os arquivos de discos usados pelo mecanismo de
banco de dados juntamente com esse banco de dados são criptografados. No entanto, o mecanismo do banco de
dados retém alguns dados temporariamente em um cache na memória para aprimorar o desempenho de tempos
de leitura e gravação em transações. Todos os dados residentes na memória são criptografados. Se um invasor
puder acessar a memória usada por um aplicativo do AIR, por exemplo usando um depurador, os dados do banco
de dados aberto atualmente e não criptografado ficarão disponíveis.
Exemplo: Geração e uso de uma chave de criptografia
Esse aplicativo de exemplo demonstra uma técnica para gerar uma chave de criptografia. Esse aplicativo foi projetado
para fornecer o nível mais alto de privacidade e segurança para dados do usuário. Um aspecto importante da segurança
de dados privados é exigir que o usuário digite uma senha sempre que o aplicativo se conectar ao banco de dados.
Conseqüentemente, conforme mostrado no exemplo, um aplicativo que requer este nível de privacidade nunca deverá
armazenar diretamente a chave de criptografia do banco de dados.
O aplicativo consiste em duas partes: uma classe ActionScript que gera uma chave de criptografia (a classe
EncryptionKeyGenerator) e uma interface do usuário básica que demonstra como usar a classe. Para obter o códigofonte completo, consulte “Exemplo completo de código para gerar e usar chave de criptografia” na página 208.
Usar a classe EncryptionKeyGenerator para obter uma cjave de criptografia segura
A seção “Noções básicas da classe EncryptionKeyGenerator” na página 202 detalha as técnicas que a classe
EncryptionKeyGenerator usa para gerar uma chave de criptografia de um banco de dados. No entanto, não é
necessário entender esses detalhes para usar a classe EncryptionKeyGenerator no seu aplicativo.
Siga essas etapas para usar a classe EncryptionKeyGenerator no seu aplicativo:
1 A classe EncryptionKeyGenerator está incluída no projeto biblioteca principal (as3corelib) do ActionScript 3.0 de
código-fonte aberto. Você pode baixar o pacote as3corelib incluindo o código-fonte e a documentação. Você
também pode baixar os arquivos SWC ou de código-fonte na página do projeto.
2 Coloque o código-fonte da classe EncryptionKeyGenerator (ou o SWC as3corelib) em um local onde o código-
fonte do seu aplicativo possa encontrá-lo.
3 No código-fonte do aplicativo, adicione uma instrução import para a classe EncryptionKeyGenerator.
import com.adobe.air.crypto.EncryptionKeyGenerator;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 201
Trabalhar com bancos de dados SQL locais
4 Antes do ponto onde o código cria o banco de dados ou abre uma conexão para ele, adicione o código para criar
uma ocorrência EncryptionKeyGenerator chamando o construtor EncryptionKeyGenerator().
var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator();
5 Obtenha uma senha do usuário:
var password:String = passwordInput.text;
if (!keyGenerator.validateStrongPassword(password))
{
// display an error message
return;
}
A ocorrência EncryptionKeyGenerator usa essa senha como base da chave de criptografia (mostrado na próxima
etapa). A ocorrência EncryptionKeyGenerator testa a senha em relação a alguns requisitos de validação de senha
forte. Em caso de falha na validação, ocorre um erro. Como o código de exemplo mostra, você pode verificar a senha
antecipadamente chamando o método validateStrongPassword() do objeto EncryptionKeyGenerator. Dessa
forma, você pode determinar se a senha atende aos requisitos mínimos de uma senha forte e evita que haja erro.
6 Gere a chave de criptografia da senha:
var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);
O método getEncryptionKey() gera e retorna a chave de criptografia (um ByteArray de 16 bytes). Em seguida,
você pode usar a chave de criptografia para criar seu novo banco de dados criptografado ou abrir um já existente.
O método getEncryptionKey() tem um parâmetro obrigatório, que é a senha obtida na etapa 5.
Nota: Para manter o maior nível de segurança e privacidade dos dados, o aplicativo deve requerer que o usuário digite
uma senha sempre que se conectar ao banco de dados. Não armazene diretamente a senha do usuário ou a chave de
criptografia do banco de dados. Isso expõe a riscos de segurança. Em vez disso, conforme demonstrado nesse exemplo,
o aplicativo deve usar a mesma técnica para derivar a chade de criptografia da senha, ao criar o banco de dados
criptografado e quando se conectar a ele mais tarde.
O método getEncryptionKey() também aceita um segundo parâmetro (opcional), o parâmetro
overrideSaltELSKey. O EncryptionKeyGenerator cria um valor aleatório (conhecido como salt) que é usado
como parte da chave de criptografia. Para ser capaz de criar novamente a chave de criptografia, o valor salt é
armazenado no armazenamento local criptografado (ELS) do seu aplicativo do AIR. Por padrão, a classe
EncryptionKeyGenerator usa uma String específica como chave ELS. Embora improvável, é possível que a chave
possa entrar em conflito com outra chave que o aplicativo usa. Em vez de usar a chave padrão, talvez você deseje
especificar sua própria chave ELS. Nesse caso, especifique uma chave personalizada, passando-a como segundo
parâmetro getEncryptionKey(), conforme mostrado aqui:
var customKey:String = "My custom ELS salt key";
var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password, customKey);
7 Criar ou abrir o banco de dados
Com a chave de criptografia retornada pelo método getEncryptionKey(), o código pode criar um novo banco de
dados criptografado ou tentar abrir o banco de dados criptografado existente. Em ambos os casos, você usa o
método open() ou openAsync() da classe SQLConnection, conforme descrito em “Criação de um banco de dados
criptografado” na página 195 e “Conexão com um banco de dados criptografado” na página 197.
Nesse exemplo, o aplicativo foi projetado para abrir o banco de dados em modo de execução assíncrona. O código
configura os ouvintes do evento apropriados e chama o método openAsync(), enviando a chave de criptografia
como argumento final.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 202
Trabalhar com bancos de dados SQL locais
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, openError);
conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey);
Nos métodos do ouvinte, o código remove os registros do ouvinte do evento. Em seguida, ele exibe uma mensagem
de status indicando se o banco de dados foi criado, aberto ou se ocorreu um erro. A parte mais notável desses
manipuladores de eventos está no método openError(). Nesse método, a instrução if verifica se o banco de dados
existe (o que significa que o código está tentando se conectar a um banco de dados existente) e se a ID do erro
corresponde à constante EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID. Se ambas as
condições forem verdadeiras, isso significa provavelmente que a senha inserida pelo usuário está incorreta. (Isso
também pode significar que o arquivo especificado não é de maneira nenhuma um arquivo de banco de dados.) A
seguir temos o código que verifica a ID do erro:
if (!createNewDB && event.error.errorID ==
EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID)
{
statusMsg.text = "Incorrect password!";
}
else
{
statusMsg.text = "Error creating or opening database.";
}
Para obter o código completo dos ouvintes de eventos de exemplo, consulte “Exemplo completo de código para
gerar e usar chave de criptografia” na página 208.
Noções básicas da classe EncryptionKeyGenerator
Não é necessário compreender o funcionamento interno da classe EncryptionKeyGenerator para usá-la com o fim de
criar uma chave de criptografia segura para o banco de dados do aplicativo. O processo para usar a classe está explicado
em “Usar a classe EncryptionKeyGenerator para obter uma cjave de criptografia segura” na página 200. No entanto,
pode ser conveniente entender as técnicas que a classe utiliza. Por exemplo, pode ser conveniente adaptar a classe ou
incorporar algumas de suas técnicas em situações nas quais um nível diferente de privacidade de dados é desejado.
A classe EncryptionKeyGenerator está incluída no projeto de biblioteca central (as3corelib) do ActionScript 3.0 de
código-fonte aberto. Você pode fazer o download dopacote as3corelib, incluindo o código-fonte e a documentação.
Também é possível exibir o código-fonte no site do projeto ou baixá-lo para acompanhar juntamente com as
explicações.
Quando o código cria uma ocorrência EncryptionKeyGenerator e chama o respectivo método getEncryptionKey(),
várias etapas são realizadas para garantir que apenas o usuário com permissão possa acessar os dados. O processo é o
mesmo para gerar uma chave de criptografia de uma senha inserida pelo usuário antes de o banco de dados ter sido
criado, bem como criar novamente a chave de criptografia para abrir o banco de dados.
Obter e validar uma senha forte
Quando o código chama o método getEncryptionKey(), ele passa uma senha como um parâmetro. A senha é usada
como base para a chave de criptografia. Usando informações que somente o usuário conheça, esse design garante que
somente o usuário que saiba a senha possa acessar os dados do banco de dados. Mesmo se um invasor acessar a conta
do usuário no computador, não poderá entrar no banco de dados sem saber a senha. Para fornecer máxima proteção,
o aplicativo nunca armazena a senha.
No aplicativo de exemplo, passwordInput é o nome da ocorrência de um componente TextInput em que o usuário
digita a senha. Em vez de manipular o valor text do componente diretamente, o aplicativo copia a senha em uma
variável chamada password.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 203
Trabalhar com bancos de dados SQL locais
var password:String = passwordInput.text;
Em seguida, o aplicativo de exemplo cria uma ocorrência EncryptionKeyGenerator e chama seu método
getEncryptionKey(), usando a variável password como argumento:
var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator();
var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);
A primeira etapa que a classe EncryptionKeyGenerator executa quando o método getEncryptionKey() é chamado,
é verificar a senha digitada pelo usuário para garantir que ela atende aos requisitos de senha forte. Nesse caso, a senha
deve ter entre 8 e 32 caracteres. Ela deve conter letras maiúsculas e minúsculas e pelo menos um número ou caractere
simbólico.
A expressão regular que marca esse padrão é definida como uma constante chamada de STRONG_PASSWORD_PATTERN:
private static const STRONG_PASSWORD_PATTERN:RegExp =
/(?=^.{8,32}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/;
O código que verifica a senha está no método validateStrongPassword() da classe EncryptionKeyGenerator. O
código é o seguinte:
public function vaidateStrongPassword(password:String):Boolean
{
if (password == null || password.length <= 0)
{
return false;
}
return STRONG_PASSWORD_PATTERN.test(password))
}
O método getEncryptionKey() chama o método validateStrongPassword() e, se a senha não é válida, lança uma
exceção. O método validateStrongPassword() é um método público para que o código possa verificar a senha sem
chamar o método getEncryptionKey(), para evitar um erro.
Expanda a senha para 256 bits
Mais tarde no processo, a senha deverá ter 256 bits. Em vez de exigir que cada usuário insira uma senha com
exatamente 256 bits (32 caracteres), o código cria uma senha maior, repetindo os caracteres da senha.
O método getEncryptionKey() chama o método concatenatePassword() para executar a tarefa de criar a senha
longa.
var concatenatedPassword:String = concatenatePassword(password);
A seguir, temos o código do método concatenatePassword():
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 204
Trabalhar com bancos de dados SQL locais
private function concatenatePassword(pwd:String):String
{
var len:int = pwd.length;
var targetLength:int = 32;
if (len == targetLength)
{
return pwd;
}
var repetitions:int = Math.floor(targetLength / len);
var excess:int = targetLength % len;
var result:String = "";
for (var i:uint = 0; i < repetitions; i++)
{
result += pwd;
}
result += pwd.substr(0, excess);
return result;
}
Se a senha tem menos de 256 bits, o código concatena a senha com ele mesmo para torná-la 256 bits. Se o comprimento
não funcionar exatamente, a última repetição será reduzida para obter exatamente 256 bits.
Gerar ou recuperar um valor de salt de 256 bits
A próxima etapa é obter um valor de salt de 256 bits que, posteriormente, será combinado com a senha. Um salt é um
valor aleatório adicionado ou combinado com um valor inserido pelo usuário para formar uma senha. Usar um salt
com uma senha garante que mesmo se um usuário escolher uma palavra real ou termo comum como senha, a
combinação senha mais salt que o sistema usa será um valor aleatório. Isso, de maneira não aleatória, ajuda a proteger
contra um ataque ao dicionário, em que um invasor usa uma lista de palavras para tentar adivinhar uma senha. Além
disso, gerando o valor salt e armazenando-o no armazenamento local criptografado, ele é associado à conta do usuário
no computador em que o arquivo do banco de dados está localizado.
Se o aplicativo estiver chamando o método getEncryptionKey() pela primeira vez, o código criará um valor salt
aleatório de 256 bits. Caso contrário, o código carregará o valor de salt do armazenamento local criptografado.
O salt é armazenado em uma variável chamada de salt. O código determina se já foi criado um salt, ao tentar carregar
o salt do armazenamento local criptografado:
var salt:ByteArray = EncryptedLocalStore.getItem(saltKey);
if (salt == null)
{
salt = makeSalt();
EncryptedLocalStore.setItem(saltKey, salt);
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 205
Trabalhar com bancos de dados SQL locais
Se o código estiver criando um novo valor salt, o método makeSalt() gera um valor aleatório de 256 bits. Como o
valor é eventualmente armazenado no armazenamento local criptografado, ele é gerado como um objeto ByteArray.
O método makeSalt() usa o método Math.random() para gerar aleatoriamente o valor. O método Math.random()
não pode gerar 256 bits de uma vez. Em vez disso, o código usa um loop para chamar o Math.random() oito vezes. A
cada vez, um valor uint aleatório entre 0 e 4294967295 (o valor uint máximo) é gerado. Um valor uint é usado por
conveniência, pois um uint usa exatamente 32 bits. Quando oito valores uint são gravados no ByteArray, é gerado um
valor de 256 bits. Este é o código para o método makeSalt():
private function makeSalt():ByteArray
{
var result:ByteArray = new ByteArray;
for (var i:uint = 0; i < 8; i++)
{
result.writeUnsignedInt(Math.round(Math.random() * uint.MAX_VALUE));
}
return result;
}
Quando o código está salvando o salt no armazenamento local criptografado (ELS) ou recuperando o salt do ELS, ele
precisa da chave String com a qual o salt é salvo. Sem saber a chave, o valor salt não pode ser recuperado. Nesse caso,
a chave de criptografia não pode ser recriada todas as vezes para abrir novamente o banco de dados. Por padrão, o
EncryptionKeyGenerator usa uma chave ELS predefinida que é definida na constante SALT_ELS_KEY. Em vez de usar
a chave padrão, o código do aplicativo também pode especificar uma chave ELS para usar na chamada do método
getEncryptionKey(). A Chave ELS padrão ou a chave ELS salt especificada pelo aplicativo é armazenada em uma
variável chamada de saltKey. Essa variável é usada nas chamadas de EncryptedLocalStore.setItem() e
EncryptedLocalStore.getItem(), como mostrado em uma listagem de código anterior.
Combinar a senha de 256 bits e o salt usando o operador XOR
O código agora tem uma senha de 256 bits e um valor salt de 256 bits. Em seguida, ele usa uma operação XOR em nível
de bits para combinar o salt e a senha concatenada em um único valor. Efetivamente, essa técnica cria um senha de 256
bits que consiste em caracteres do intervalo inteiro de caracteres possíveis. Esse princípio é verdadeiro, embora muito
provavelmente a entrada de senha real consista principalmente em caracteres alfanuméricos. Essa não-aleatoriedade
elevada oferece o benefício de tornar o conjunto de senhas possíveis maior, sem exigir que o usuário digite uma senha
longa e complexa.
O resultado da operação XOR é armazenado na variável unhashedKey. O processo real de execução de um XOR em
nível de bits nos dois valores ocorre no método xorBytes():
var unhashedKey:ByteArray = xorBytes(concatenatedPassword, salt);
O operador XOR em nível de bits (^) retira dois valores uint e retorna um valor uint. (Um valor uint contém 32 bits.)
Os valores de entrada enviados como argumentos para o método xorBytes() são uma String (a senha) e um
ByteArray (o salt). Conseqüentemente, o código usa um loop para extrair 32 bits de uma vez de cada entrada para
combinar usando o operador XOR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 206
Trabalhar com bancos de dados SQL locais
private function xorBytes(passwordString:String, salt:ByteArray):ByteArray
{
var result:ByteArray = new ByteArray();
for (var i:uint = 0; i < 32; i += 4)
{
// ...
}
return result;
}
No loop, os primeiros 32 bits (4 bytes) são extraídos do parâmetro passwordString. Esses bits são extraídos e
convertidos em um uint (o1) em um processo de duas partes. Primeiro, o método charCodeAt() obtém cada valor
numérico do caractere. Depois, esse valor é desviado para a posição apropriada na unidade usando o operador de
desvio à esquerda em nível de bits (<<) e o valor desviado é adicionado ao o1. Por exemplo, o primeiro caractere (i) se
torna os primeiros 8 bits usando o operador de desvio à esquerda em nível de bits (<<) para desviar os bits deixados
por 24 bits e atribuindo esse valor ao o1. O segundo caractere (i + 1) se torna os segundos 8 bits desviando seu valor
16 bits à esquerda e adicionando o resultado a o1. Os valores do terceiro e do quarto caracteres são adicionados da
mesma forma.
// ...
// Extract 4 bytes from the password string and convert to a uint
var o1:uint = passwordString.charCodeAt(i) << 24;
o1 += passwordString.charCodeAt(i + 1) << 16;
o1 += passwordString.charCodeAt(i + 2) << 8;
o1 += passwordString.charCodeAt(i + 3);
// ...
A variável o1 agora contém 32 bits do parâmetro passwordString. Em seguida, 32 bits são extraídos do parâmetro
salt, chamando seu método readUnsignedInt(). Os 32 bits são armazenados em uma variável uint o2.
// ...
salt.position = i;
var o2:uint = salt.readUnsignedInt();
// ...
Finalmente, os dois valores de 32 bits (uint) são combinados usando o operador XOR, e o resultado é gravado em um
ByteArray chamado de result.
// ...
var xor:uint = o1 ^ o2;
result.writeUnsignedInt(xor);
// ...
Quando o loop é concluído, o ByteArray contendo o resultado XOR é retornado.
// ...
}
return result;
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 207
Trabalhar com bancos de dados SQL locais
Hash da chave
Após a senha concatenada e o salt serem combinados, a próxima etapa é oferecer proteção adicional a esse valor,
fazendo hash dele por meio do algoritmo de hash SHA-256. O processo de hash dificulta para um invasor realizar a
engenharia reversa no valor.
Nesse ponto, o código tem um ByteArray chamado de unhashedKey, que contém a senha concatenada combinada
com o salt. O projeto de biblioteca central (as3corelib) do ActionScript 3.0 inclui uma classe SHA256 no pacote
com.adobe.crypto. O método SHA256.hashBytes(), que realiza um hash de SHA-256 em um ByteArray e retorna
uma String contendo o resultado do hash de 256 bits como um número decimal. A classe EncryptionKeyGenerator
usa a classe SHA256 para aplicar hash à chave:
var hashedKey:String = SHA256.hashBytes(unhashedKey);
Extrair a chave de criptografia do hash
A chave de criptografia deve ser um ByteArray com exatamente 16 bytes (128 bits). O resultado do algoritmo de hash
SHA-256 tem sempre 256 bits. Conseqüentemente, a etapa final é selecionar 128 bits do resultado com hash para usar
como chave de criptografia real.
Na classe EncryptionKeyGenerator, o código reduz a chave para 128 bits chamando o método
generateEncryptionKey(). Em seguida, ele retorna esse resultado do método como o resultado do método
getEncryptionKey():
var encryptionKey:ByteArray = generateEncryptionKey(hashedKey);
return encryptionKey;
É necessário usar os primeiros 128 bits como a chave de criptografia. Você pode selecionar um intervalo de bits
iniciando em algum ponto arbitrário, pode selecionar todos os outros bits ou usar alguma outra maneira de selecionar
bits. O importante é que o código selecione 128 bits diferentes e que os mesmos 128 bits sejam usados a cada vez.
Nesse caso, o método generateEncryptionKey() usa o intervalo de bits que começa no 18º byte como a chave de
criptografia. Como mencionado antes, a classe SHA256 retorna uma String contendo um hash de 256 bits como
número hexadecimal. Um único bloco de 128 bits não tem muitos bytes a acrescentar a um ByteArray de uma vez.
Conseqüentemente, o código usa um loop for para extrair caracteres da String hexadecimal, convertendo-os em
valores numéricos reais e adicionando-os ao ByteArray. A String de resultado SHA-256 tem 64 caracteres. Um
intervalo de 128 bits equivale a 32 caracteres na String, e cada caractere representa 4 bits. O menor incremento de
dados que você pode adicionar a um ByteArray é um byte (8 bits), o que é equivalente a dois caracteres na String hash.
Conseqüentemente, o loop conta de 0 a 31 (32 caracteres) em incrementos de 2 caracteres.
Dentro do loop, o código determina primeiro a posição inicial do par de caracteres atual. Como o intervalo desejado
começa na posição de indexação 17 (o 18º byte) do caractere, a variável position é atribuída ao valor iterador da
corrente (i) mais 17. O código usa o método substr() do objeto da String para extrair os dois caracteres na posição
atual. Esses caracteres são armazenados na variável hex. Em seguida, o código usa o método parseInt() para
converter a String hex a um valor inteiro decimal. Ele armazena esse valor na variável byte. Finalmente, o código
adiciona o valor de byte ao ByteArray result usando o método writeByte(). Quando o loop é concluído, o
ByteArray result contém 16 bytes e está pronto para ser usado como chave de criptografia do banco de dados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 208
Trabalhar com bancos de dados SQL locais
private function generateEncryptionKey(hash:String):ByteArray
{
var result:ByteArray = new ByteArray();
for (var i:uint = 0; i < 32; i += 2)
{
var position:uint = i + 17;
var hex:String = hash.substr(position, 2);
var byte:int = parseInt(hex, 16);
result.writeByte(byte);
}
return result;
}
Exemplo completo de código para gerar e usar chave de criptografia
A seguir há um exemplo completo de um código para a aplicação de “Geração e uso da chave de criptografia”. O código
consiste em duas partes.
O exemplo usa a classe EncryptionKeyGenerator para criar uma chave de criptografia a partir de uma senha. A classe
EncryptionKeyGenerator está incluída no projeto de biblioteca central (as3corelib) do ActionScript 3.0 de códigofonte aberto. Você pode baixar o pacote as3corelib incluindo o código-fonte e a documentação. Você também pode
baixar os arquivos SWC ou de código-fonte na página do projeto.
O arquivo FLA do aplicativo contém o código fonte de um aplicativo simples que cria ou abre uma conexão para um
banco de dados criptografado. O arquivo FLA tem quatro componentes colocados no palco:
Nome da
ocorrência
Tipo do componente
Descrição
instruções
Label
Contém as instruções fornecidas ao usuário
passwordInput
TextInput
Campo de entrada onde o usuário digita a senha
openButton
Button
Botão em que o usuário clica após digitar a senha
statusMsg
Label
Exibe mensagens de status (êxito ou falha)
O código do aplicativo é definido em um quadro-chave no quadro 1 da linha do tempo principal. Este é o código do
aplicativo:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 209
Trabalhar com bancos de dados SQL locais
import com.adobe.air.crypto.EncryptionKeyGenerator;
const dbFileName:String = "encryptedDatabase.db";
var dbFile:File;
var createNewDB:Boolean = true;
var conn:SQLConnection;
init();
// ------- Event handling ------function init():void
{
passwordInput.displayAsPassword = true;
openButton.addEventListener(MouseEvent.CLICK, openConnection);
statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x990000));
conn = new SQLConnection();
dbFile = File.applicationStorageDirectory.resolvePath(dbFileName);
if (dbFile.exists)
{
createNewDB = false;
instructions.text = "Enter your database password to open the encrypted database.";
openButton.label = "Open Database";
}
else
{
instructions.text = "Enter a password to create an encrypted database. The next time
you open the application, you will need to re-enter the password to open the database again.";
openButton.label = "Create Database";
}
}
function openConnection(event:MouseEvent):void
{
var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator();
var password:String = passwordInput.text;
if (password == null || password.length <= 0)
{
statusMsg.text = "Please specify a password.";
return;
}
if (!keyGenerator.validateStrongPassword(password))
{
statusMsg.text = "The password must be 8-32 characters long. It must contain at least
one lowercase letter, at least one uppercase letter, and at least one number or symbol.";
return;
}
passwordInput.text = "";
passwordInput.enabled = false;
openButton.enabled = false;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 210
Trabalhar com bancos de dados SQL locais
var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, openError);
conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey);
}
function openHandler(event:SQLEvent):void
{
conn.removeEventListener(SQLEvent.OPEN, openHandler);
conn.removeEventListener(SQLErrorEvent.ERROR, openError);
statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x009900));
if (createNewDB)
{
statusMsg.text = "The encrypted database was created successfully.";
}
else
{
statusMsg.text = "The encrypted database was opened successfully.";
}
}
function openError(event:SQLErrorEvent):void
{
conn.removeEventListener(SQLEvent.OPEN, openHandler);
conn.removeEventListener(SQLErrorEvent.ERROR, openError);
if (!createNewDB && event.error.errorID ==
EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID)
{
statusMsg.text = "Incorrect password!";
}
else
{
statusMsg.text = "Error creating or opening database.";
}
}
Estratégias para trabalhar com bancos de dados SQL
Existem várias maneiras pelas quais um aplicativo pode acessar e trabalhar com um banco de dados SQL local. O
design do aplicativo pode variar em termos de como seu código é organizado, a seqüência e o intervalo de execução
das operações, e assim por diante. As técnicas que você escolhe podem afetar a facilidade com que o aplicativo é
desenvolvido. Elas podem afetar a facilidade com que você modificará o aplicativo em futuras atualizações. Elas
também podem afetar o desempenho do aplicativo do ponto de vista dos usuários.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 211
Trabalhar com bancos de dados SQL locais
Distribuição de um banco de dados previamente preenchido
Quando você usa um banco de dados SQL local do AIR no seu aplicativo, este espera um banco de dados com uma
certa estrutura de tabelas, colunas e assim por diante. Alguns aplicativos também esperam que certos dados estejam
previamente preenchidos no arquivo de banco de dados. Uma forma de assegurar que o banco de dados tenha a
estrutura apropriada é criar um banco de dados no código do aplicativo. Quando o aplicativo é carregado, ele verifica
se o arquivo de banco de dados correspondente existe em um determinado local. Se o arquivo não existir, o aplicativo
executará um conjunto de comandos para criar o arquivo de banco de dados, criar a estrutura do banco de dados e
preencher as tabelas com os dados iniciais.
O código que cria o banco de dados e suas tabelas geralmente é complexo. Com freqüência, ele só é usado uma vez
durante o período em que o aplicativo fica instalado, mas ainda assim aumenta o tamanho e a complexidade do
aplicativo. Como alternativa à criação do banco de dados, da estrutura e dos dados de modo programático, você pode
distribuir um banco de dados previamente preenchido com o aplicativo. Para distribuir um banco de dados
predefinido, inclua o arquivo correspondente no pacote AIR do aplicativo.
Como todos os arquivos que são incluídos em um pacote AIR, um arquivo de banco de dados compactado é instalado
no diretório do aplicativo (o diretório representado pela propriedade File.applicationDirectory). No entanto, os
arquivos desse diretório são somente leitura. Use o arquivo do pacote AIR como um banco de dados “modelo”. Na
primeira vez que um usuário executar o aplicativo, copie o arquivo de banco de dados original para o diretório de
armazenamento do aplicativo do usuário (ou outro local) e use esse banco de dados no aplicativo.
Aperfeiçoamento do desempenho do banco de dados
Várias técnicas incorporadas ao Adobe AIR permitem melhorar o desempenho de operações de banco de dados em
seu aplicativo.
Além das técnicas descritas aqui, a forma como uma instrução SQL é criada também pode afetar o desempenho do
banco de dados. Com freqüência, existem diversas maneiras de criar uma instrução SQL SELECT para recuperar um
conjunto de resultados específico. Em alguns casos, as diferentes abordagens exigem mais ou menos trabalho da parte
do mecanismo de banco de dados. Este aspecto de se aprimorar o desempenho do banco de dados (criando instruções
SQL que proporcionem melhor desempenho) não é abordado na documentação do Adobe AIR.
Use uma ocorrência de SQLStatement para cada instrução SQL
Antes de qualquer instrução SQL ser executada, o tempo de execução a prepara (compila) para determinar as etapas
realizadas internamente para executar a instrução. Quando você chama SQLStatement.execute() em uma
ocorrência de SQLStatement que não foi executada anteriormente, a instrução é preparada de forma automática antes
de ser executada. Nas chamadas subseqüentes do método execute(), desde que a propriedade SQLStatement.text
não tenha sido alterada, a instrução ainda será preparada. Como resultado, ela será executada mais rapidamente.
Para aproveitar ao máximo a capacidade de reutilizar instruções, se for necessário alterar valores entre as execuções de
uma instrução, utilize parâmetros de instrução para personalizar a sua instrução. (Os parâmetros de instrução são
especificados através da propriedade de matriz associativa SQLStatement.parameters.) Diferentemente de quando
se altera a propriedade text da ocorrência de SQLStatement, se você alterar os valores de parâmetros de instrução, o
tempo de execução não terá de preparar a instrução novamente. Para obter mais informações sobre como usar
parâmetros em instruções, consulte “Uso de parâmetros em instruções” na página 175.
Preparar e executar uma instrução pode ser uma operação trabalhosa, por isso uma boa estratégia é pré-carregar os
dados iniciais e então executar outras instruções em segundo plano. Carregue os dados de que o aplicativo precisa
primeiro. Quando as primeiras operações de inicialização do aplicativo forem concluídas, ou durante algum período
de “inatividade” no aplicativo, execute outras instruções. Por exemplo, se o aplicativo não acessa o banco de dados para
exibir a tela inicial, aguarde até que essa tela seja exibida, abra a conexão com o banco de dados e, então, crie as
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 212
Trabalhar com bancos de dados SQL locais
ocorrências de SQLStatement e execute qualquer uma delas. Como alternativa, suponha que, quando o seu aplicativo
é inicializado, ele imediatamente exibe alguns dados, como o resultado de uma determinada consulta. Nesse caso, vá
em frente e execute a ocorrência de SQLStatement referente a essa consulta. Depois que os dados iniciais forem
carregados e exibidos, crie ocorrências de SQLStatement para outras operações de banco de dados e, se possível,
execute outras instruções que serão necessárias posteriormente.
Quando você reutiliza uma ocorrência de SQLStatement, o aplicativo precisa manter uma referência à ocorrência de
SQLStatement depois que ela foi preparada. Para isso, declare a variável como uma variável com escopo de classe e não
como uma variável com escopo de função. Uma boa maneira de fazer isso é estruturar o aplicativo para que a instrução
SQL seja colocada em uma única classe. Um grupo de instruções que são executadas em combinação também pode ser
colocado em uma única classe. Se você definir a(s) ocorrência(s) de SQLStatement como variáveis de membro da
classe, elas persistirão desde que a ocorrência da classe wrapper exista no aplicativo. No mínimo, basta definir uma
variável que contenha a ocorrência de SQLStatement fora de uma função para que a ocorrência persista na memória.
Por exemplo, declare a ocorrência de SQLStatement como variável de membro em uma classe do ActionScript ou
como variável não-função em um arquivo JavaScript. Em seguida, você pode definir os valores de parâmetro da
instrução e chamar o método execute() correspondente quando quiser executar a consulta.
Agrupamento de várias operações em uma transação
Suponha que você está executando muitas instruções SQL que envolvem a inclusão ou a alteração de dados
(instruçõesINSERT ou UPDATE). Você pode conseguir um aumento de desempenho considerável se executar todas as
instruções em uma transação explícita. Se você não iniciar uma transação de forma explícita, cada uma das instruções
será executada em sua própria transação criada automaticamente. Depois que a execução de cada transação (cada
instrução) for concluída, o tempo de execução gravará os dados resultantes no arquivo de banco de dados do disco.
Por outro lado, pense no que acontece se você cria uma transação explicitamente e executa as instruções no contexto
dessa transação. O tempo de execução faz todas as alterações na memória e, depois, grava todas as alterações no
arquivo de banco de dados de uma só vez quando a transação é confirmada. Gravar dados em disco normalmente é a
parte mais demorada da operação. Como conseqüência, gravar no disco de uma só vez e não uma vez por instrução
SQL pode melhorar o desempenho significativamente.
Minimizar o processamento do tempo de execução
O uso das seguintes técnicas pode evitar trabalho desnecessário por parte do mecanismo de banco de dados e melhorar
o desempenho dos aplicativos:
• Sempre especifique os nomes de banco de dados explicitamente junto com os nomes de tabela em uma instrução.
(Use “main” se for o banco de dados principal). Por exemplo, use SELECT employeeId FROM main.employees
em vez de SELECT employeeId FROM employees. Quando você especifica o nome do banco de dados de maneira
explícita, evita que o tempo de execução tenha de verificar cada banco de dados para encontrar a tabela
correspondente. Isso também evita a possibilidade de o tempo de execução escolher o banco de dados errado. Siga
esta regra mesmo que um SQLConnection esteja conectado a apenas um banco de dados, porque em segundo plano
o SQLConnection também está conectado a um banco de dados temporário que pode ser acessado através de
instruções SQL.
• Sempre especifique os nomes de coluna explicitamente em uma instrução SELECT ou INSERT.
• Divida as linhas retornadas por uma instrução SELECT que recupera um número grande de linhas: consulte
“Recuperação dos resultados de SELECT em partes” na página 182.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 213
Trabalhar com bancos de dados SQL locais
Evite alterações em esquemas
Se possível, evite alterar o esquema (estrutura de tabelas) de um banco de dados depois de adicionar dados às tabelas.
Normalmente, um arquivo de banco de dados é estruturado com as definições de tabela no início do arquivo. Quando
você abre uma conexão com um banco de dados, o tempo de execução carrega essas definições. Quando você adiciona
dados a tabelas de um banco de dados, eles são adicionados ao arquivo após os dados de definição de tabela. Entretanto,
se você fizer alterações no esquema, como adicionar uma coluna a uma tabela ou adicionar uma nova tabela, os novos
dados de definição de tabela serão combinados com os dados de tabela no arquivo de banco de dados. Se os dados de
definição de tabela não estiverem todos no início do arquivo de banco de dados, demorará mais para abrir uma
conexão com o banco de dados, pois o tempo de execução lê esses dados de diferentes partes do arquivo.
Caso você não precise fazer alterações no esquema, poderá chamar o método SQLConnection.compact() depois de
concluir as alterações. Esta operação reestrutura o arquivo de banco de dados para que os dados de definição de tabela
fiquem localizados juntos no início do arquivo. No entanto, a operação compact() pode ser demorada,
principalmente quando um arquivo de banco de dados aumenta de tamanho.
Práticas recomendadas de trabalho com bancos de dados SQL locais
A lista a seguir é um conjunto de técnicas sugeridas que você pode usar para melhorar o desempenho, a segurança e a
facilidade de manutenção dos seus aplicativos quando trabalhar com bancos de dados SQL locais. Para conhecer outras
técnicas para aprimorar aplicativos de banco de dados, consulte “Aperfeiçoamento do desempenho do banco de
dados” na página 211.
Crie conexões de banco de dados previamente
Mesmo que o seu aplicativo não execute nenhuma instrução quando inicialmente carregado, instancie um objeto
SQLConnection e chame o método open() ou openAsync() correspondente com antecedência (por exemplo, após a
inicialização do aplicativo) para evitar atrasos na execução de instruções. Consulte “Conexão com um banco de dados”
na página 172.
Reutilize conexões de banco de dados
Se você acessa um certo banco de dados ao longo da execução do seu aplicativo, mantenha uma referência à ocorrência
de SQLConnection e a reutilize no aplicativo inteiro em vez de fechar e reabrir a conexão. Consulte “Conexão com um
banco de dados” na página 172.
Dê preferência ao modo de execução assíncrona
Quando criamos um código de acesso a dados, pode ser tentador executar operações de maneira síncrona em vez de
assíncrona, porque usar operações síncronas geralmente requer um código mais curto e menos complexo. Porém,
conforme descrito na seção “Uso de operações de banco de dados síncronas e assíncronas” na página 190, as operações
síncronas podem ter um impacto no desempenho que é óbvio para os usuários e prejudicial para a experiência deles
no aplicativo. O tempo usado para uma única operação varia conforme a operação e, principalmente, o volume de
dados envolvido. Por exemplo, uma instrução SQL INSERT que só adiciona uma linha ao banco de dados demora
menos tempo do que uma instrução SELECT que recupera milhares de linhas de dados. No entanto, quando você usa
a execução síncrona para realizar várias operações, as operações normalmente são encadeadas. Mesmo que o tempo
que cada operação leve seja muito curto, o aplicativo fica congelado até a conclusão de todas as operações síncronas.
Por isso, o tempo acumulado de várias operações encadeadas pode ser suficiente para paralisar o aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 214
Trabalhar com bancos de dados SQL locais
Use operações assíncronas como uma abordagem padrão, principalmente no caso de operações que envolvem um
grande número de linhas. Há uma técnica para dividir o processamento de grandes conjuntos de resultados de
instruções SELECT, descrita em “Recuperação dos resultados de SELECT em partes” na página 182. No entanto, ela só
pode ser usada no modo de execução assíncrona. Utilize operações síncronas apenas quando não conseguir obter uma
certa funcionalidade usando programação assíncrona, quando tiver considerado as vantagens e desvantagens para os
usuários do aplicativo em termos de desempenho e quando testar o aplicativo e perceber que o desempenho foi
afetado. O uso da execução assíncrona pode envolver uma codificação mais complexa. Porém, lembre-se de que você
só precisa criar o código uma vez, mas que os usuários do aplicativo têm de usá-lo repetidas vezes, de forma ágil ou
lentamente.
Em muitos casos, usando uma ocorrência de SQLStatement à parte para cada instrução SQL a ser executada, é possível
enfileirar várias operações SQL de uma só vez, o que torna o código assíncrono parecido com o código síncrono quanto
à maneira como ele é criado. Para obter mais informações, consulte “Noções básicas sobre o modelo de execução
assíncrona” na página 193.
Use instruções SQL separadas e não altere a propriedade text de SQLStatement
Para qualquer instrução SQL executada mais de uma vez em um aplicativo, crie uma ocorrência de SQLStatement à
parte para cada instrução SQL. Use essa ocorrência de SQLStatement sempre que esse comando SQL for executado.
Por exemplo, suponha que você está criando um aplicativo que inclui quatro operações SQL diferentes executadas
várias vezes. Nesse caso, crie quatro ocorrências separadas de SQLStatement e chame o método execute() de cada
instrução para executá-la. Evite a alternativa de usar uma única ocorrência de SQLStatement para todas as instruções
SQL, sempre redefinindo sua propriedade text antes de executar a instrução. Consulte “Use uma ocorrência de
SQLStatement para cada instrução SQL” na página 211 para obter mais informações.
Use parâmetros de instrução
Use parâmetros SQLStatement — nunca concatene a entrada do usuário no texto da instrução. O uso de parâmetros
torna o seu aplicativo mais seguro porque impede a possibilidade de ataques de injeção SQL. Isso permite usar objetos
em consultas (e não apenas valores literais SQL). Também torna a execução das instruções mais eficiente, porque elas
podem ser reutilizadas sem que você precise recompilá-las todas as vezes que forem executadas. Consulte “Uso de
parâmetros em instruções” na página 175 para obter mais informações.
Use restrições para nomes de colunas e de parâmetros
Quando você não especifica uma classe itemClass para um SQLStatement, para evitar erros de ortografia, defina
constantes String que contenham os nomes das colunas de uma tabela. Use essas constantes no texto da instrução e
para os nomes de propriedade quando recuperar valores dos objetos resultantes. Também use constantes para os
nomes de parâmetros.
215
Capítulo 19: Armazenamento de dados
criptografados
O tempo de execução do Adobe® AIR™ fornece um armazenamento local criptografado persistente para cada aplicativo
do AIR instalado no computador de um usuário. Isso permite que você salve e recupere dados armazenados no disco
rígido local do usuário em um formato criptografado que não possa ser facilmente decifrado por outros aplicativos ou
usuários. Um armazenamento local criptografado separado é usado para cada aplicativo do AIR, e cada aplicativo do
AIR usa um armazenamento local criptografado separado para cada usuário.
Nota: Além do armazenamento local criptografado, o AIR também fornece criptografia para conteúdo armazenado em
bancos de dados do SQL. Para obter detalhes, consulte “Uso da criptografia com bancos de dados SQL” na página 194.
Você pode querer usar o armazenamento local criptografado para armazenar informações que devem ser protegidas,
como credenciais de login para serviços da Web.
O AIR usa o DPAPI no Windows, o KeyChain no Mac OS e o KeyRing ou KWallet no Linux para associar o
armazenamento local criptografado a cada aplicativo e usuário. O armazenamento local criptografado usa a
criptografia AES-CBC de 128 bits.
As informações no armazenamento local criptografado estão disponíveis apenas a conteúdo de aplicativos do AIR na
caixa de proteção de segurança do aplicativo.
Use os métodos estáticos setItem() e removeItem() da classe EncryptedLocalStore para armazenar e recuperar
dados do armazenamento local. Os dados são armazenados em uma tabela de hash, usando seqüências de caracteres
como chaves, com os dados armazenados como matrizes de bytes.
Por exemplo, o código a seguir armazena uma seqüência de caracteres no armazenamento local criptografado:
var str:String = "Bob";
var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes(str);
EncryptedLocalStore.setItem("firstName", bytes);
var storedValue:ByteArray = EncryptedLocalStore.getItem("firstName");
trace(storedValue.readUTFBytes(storedValue.length)); // "Bob"
O terceiro parâmetro do método setItem(), o parâmetro stronglyBound, é opcional. Quando esse parâmetro é
definido como true, o armazenamento local criptografado fornece um nível mais alto de segurança, ligando o item
armazenado aos bits e à assinatura digital do aplicativo do AIR de armazenamento, bem como à ID do editor do
aplicativo quando:
var str:String = "Bob";
var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes(str);
EncryptedLocalStore.setItem("firstName", bytes, true);
Para um item armazenado com stronglyBound definido como true, as chamadas subseqüentes a getItem() apenas
são bem-sucedidas se o aplicativo do AIR de chamada for idêntico ao aplicativo de armazenamento (se nenhum dado
nos arquivos do diretório do aplicativo tiver sido alterado). Se o aplicativo do AIR de chamada for diferente do
aplicativo de armazenamento, o aplicativo lançará uma exceção de erro quando você chamar getItem() para um item
fortemente ligado. Se você atualizar seu aplicativo, ele não será capaz de ler os dados fortemente ligados previamente
gravados no armazenamento local criptografado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 216
Armazenamento de dados criptografados
Por padrão, um aplicativo do AIR não consegue ler o armazenamento local criptografado de outro aplicativo. A
definição stronglyBound fornece ligação extra (aos dados nos bits do aplicativo) para impedir que um aplicativo
invasor tente ler o armazenamento local criptografado de seu aplicativo apoderando-se da ID do editor do aplicativo.
Se você atualizar um aplicativo para usar um certificado de assinatura diferente (usando uma assinatura de migração),
a versão atualizada não poderá acessar nenhum dos itens no armazenamento original, mesmo se o parâmetro
stronglyBound foi definido como falso. Para obter mais informações, consulte “Alteração de certificados” na
página 325.
Você pode excluir um valor do armazenamento local criptografado usando o método
EncryptedLocalStore.removeItem(), como no seguinte exemplo:
EncryptedLocalStore.removeItem("firstName");
Você pode limpar todos os dados do armazenamento local criptografado chamando o método
EncryptedLocalStore.reset(), como no seguinte exemplo:
EncryptedLocalStore.reset();
Ao depurar um aplicativo no ADL (AIR Debug Launcher), o aplicativo usa um armazenamento local criptografado
diferente do que é usado na versão instalada do aplicativo.
O armazenamento local criptografado poderá ficar mais lento se os dados armazenados excederem 10 MB.
Quando você desinstala um aplicativo do AIR, o desinstalador não exclui os dados armazenados no armazenamento
local criptografado.
Os dados do armazenamento local criptografado são colocados em um subdiretório do diretório de dados do
aplicativo do usuário; o caminho do subdiretório é Adobe/AIR/ELS/ seguindo da ID do aplicativo.
217
Capítulo 20: Sobre o ambiente HTML
O Adobe®AIR™ usa WebKit (www.webkit.org), também usado pelo navegador da Web Safari, para analisar, alterar o
layout e processar conteúdo HTML e JavaScript. Usar as APIs do AIR em conteúdo HTML é opcional. Você pode
programar no conteúdo de um objeto HTMLLoader ou janela HTML inteiramente com HTML e JavaScript. A maioria
dos aplicativos e páginas HTML existentes deve ser executada com algumas alterações (supondo que eles usam
recursos HTML, CSS, DOM e JavaScript compatíveis com WebKit).
Como aplicativos AIR são executados diretamente na área de trabalho, com acesso completo ao sistema de arquivos,
o modelo de segurança para conteúdo HTML é mais rigoroso que o modelo de segurança de um navegador da Web
típico. No AIR, apenas o conteúdo carregado do diretório de instalação do aplicativo é colocado na caixa de proteção
do aplicativo. A caixa de proteção do aplicativo tem o nível mais alto de privilégio e permite acesso às APIs do AIR. O
AIR coloca outro conteúdo em caixas de proteção isoladas com base na origem do conteúdo. Arquivos carregados do
sistema de arquivos entram em uma caixa de proteção local. Arquivos carregados da rede usando os protocolos http:
ou https: entram em uma caixa de proteção baseada no domínio do servidor remoto. O conteúdo nessas caixas de
proteção que não são de aplicativo não pode acessar nenhuma API do AIR e é executado da mesma forma que em um
navegador da Web típico.
O AIR usa WebKit (www.webkit.org), também usado pelo navegador da Web Safari, para analisar, alterar o layout e
processar conteúdo HTML e JavaScript. As classes e objetos de host incorporados do AIR fornecem uma API para
recursos tradicionalmente associados a aplicativos de área de trabalho. Tais recursos incluem ler e escrever arquivos e
gerenciar janelas. O Adobe AIR também herda APIs do Adobe® Flash® Player, o que inclui recursos como soquetes
binários e de som.
O conteúdo HTML no AIR não exibe conteúdo SWF ou PDF se as configurações de alfa, dimensionamento ou
transparência forem aplicadas. Para obter mais informações, consulte Considerações ao carregar conteúdo SWF ou
PDF em uma página HTML e “Transparência de janelas” na página 63.
Visão geral do ambiente HTML
O Adobe AIR fornece um ambiente JavaScript completo do tipo de navegador com um processador de HTML, um
modelo de objeto de documento e um intérprete do JavaScript. O ambiente JavaScript é representado pela classe
HTMLLoader do AIR. Em janelas HTML, um objeto HTMLLoader contém todo o conteúdo HTML e está, por sua
vez, contido em um objeto NativeWindow. Em conteúdo SWF, a classe HTMLLoader, que estende a classe Sprite, pode
ser adicionada à lista de exibição de um estágio como qualquer outro objeto de exibição. As propriedades do
ActionScript™ da classe são descritas em “Gravação de script de contêiner HTML” na página 258 e também na
Referência de linguagem do ActionScript do Flex 3.
Sobre o ambiente JavaScript e seu relacionamento com o AIR
O diagrama a seguir ilustra o relacionamento entre o ambiente JavaScript e o ambiente de tempo de execução do AIR.
Embora apenas uma única janela nativa seja exibida, um aplicativo AIR pode conter várias janelas. (E uma única janela
pode conter vários objetos HTMLLoader.)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 218
Sobre o ambiente HTML
Ambiente de tempo de execução do AIR
NativeWindow
HTMLLoader
janela
Ambiente do
JavaScript
janela
janela
corpo
cabeçalho
htmlLoader
native4Window
tempo de
execução
h1
div
table
p
O ambiente JavaScript possui seus próprios objetos Document e Window. O código JavaScript pode interagir com o ambiente de tempo de
execução do AIR por meio das propriedades runtime, nativeWindow e htmlLoader. O código ActionScript pode interagir com o ambiente
JavaScript pela propriedade window de um objeto HTMLLoader, que é uma referência ao objeto Window do JavaScript. Além disso, os objetos
ActionScript e JavaScript podem ouvir eventos despachados por objetos AIR e JavaScript.
A propriedade runtime fornece acesso a classes API do AIR, permitindo que você crie novos objetos do AIR, bem
como membros de classe de acesso (também chamados estáticos). Para acessar uma API do AIR, você adiciona o nome
da classe, com pacote, à propriedade runtime. Por exemplo, para criar um objeto File, você usaria a instrução:
var file = new window.runtime.filesystem.File();
Nota: O SDK do AIR fornece um arquivo JavaScript, AIRAliases.js, que define aliases mais convenientes para as
classes do AIR usadas mais comumente. Quando você importa esse arquivo, pode usar a forma mais curta air.Class em
vez de window.runtime.package.Class. Por exemplo, você poderia criar o objeto File com new air.File().
O objeto NativeWindow fornece propriedades para controlar a janela da área de trabalho. De uma página HTML, você
pode acessar o objeto NativeWindow contido com a propriedade window.nativeWindow.
O objeto HTMLLoader fornece propriedades, métodos e eventos para controlar como o conteúdo é carregado e
processado. De uma página HTML, você pode acessar o objeto HTMLLoader pai com a propriedade
window.htmlLoader.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 219
Sobre o ambiente HTML
Importante: Apenas páginas instaladas como parte de um aplicativo possuem as propriedades htmlLoader,
nativeWindow ou runtime e apenas quando carregadas como o documento de nível superior. Essas propriedades não
são adicionadas quando um documento é carregado em um frame ou iframe. (Um documento filho pode acessar essas
propriedades no documento pai desde que ele esteja na mesma caixa de proteção de segurança. Por exemplo, um
documento carregado em um frame poderia acessar a propriedade runtime de seu pai com parent.runtime.)
Sobre a segurança
O AIR executa todos os códigos em uma caixa de proteção de segurança baseada no domínio de origem. O conteúdo
do aplicativo, limitado ao conteúdo carregado do diretório de instalação do aplicativo, é colocado na caixa de proteção
do aplicativo. O acesso ao ambiente de tempo de execução e às APIs do AIR está disponível apenas para HTML e
JavaScript em execução nessa caixa de proteção. Ao mesmo tempo, a maior parte da execução e avaliação dinâmica de
JavaScript é bloqueada na caixa de proteção do aplicativo após todos os manipuladores da página de evento load terem
sido retornados.
Você pode mapear uma página de aplicativo em uma caixa de proteção que não seja de aplicativo carregando a página
em um frame ou iframe e definindo os atributos sandboxRoot e documentRoot específicos do AIR do frame.
Definindo o valor sandboxRoot para um domínio remoto real, você pode habilitar o conteúdo da caixa de proteção
para cruzar conteúdo de scripts nesse domínio. Mapear páginas dessa maneira pode ser útil ao carregar e fazer o script
de conteúdo remoto, como em um aplicativo mash-up.
Outra maneira de permitir que o conteúdo de aplicativo e que não é de aplicativo cruze scripts entre si, e a única
maneira de fornecer acesso a conteúdo de não-aplicativo às APIs do AIR, é criar uma ponte de caixa de proteção. Uma
ponte pai-para-filho permite conteúdo em um frame filho, iframe ou window para acessar métodos designados e
propriedades definidas na caixa de proteção do aplicativo. Por outro lado, uma ponte filho-para-pai permite que
conteúdo de aplicativo acesse métodos e propriedades designadas definidas na caixa de proteção do filho. As pontes
de caixa de proteção são estabelecidas pela definição das propriedades parentSandboxBridge e
childSandboxBridge do objeto window. Para obter mais informações, consulte “segurança HTML” na página 30 e
“Elementos HTML frame e iframe” na página 227.
Sobre plug-ins e objetos incorporados
O AIR suporta o plug-in do Adobe® Acrobat®. Os usuários devem ter o Acrobat ou Adobe® Reader® 8.1 (ou superior)
para exibir conteúdo PDF. O objeto HTMLLoader fornece uma propriedade para verificar se o sistema de um usuário
pode exibir PDF. O conteúdo de arquivo SWF também pode ser exibido no ambiente HTML, mas esse recurso é
incorporado ao AIR e não usa um plug-in externo.
Nenhum outro plug-in de Webkit é suportado no AIR.
Consulte também
“segurança HTML” na página 30
“Caixas de proteção HTML” na página 220
“Elementos HTML frame e iframe” na página 227
“Objeto Window do JavaScript” na página 226
“O objeto XMLHttpRequest” na página 221
“Adição de conteúdo em PDF” na página 272
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 220
Sobre o ambiente HTML
Extensões do AIR e Webkit
O Adobe AIR usa o mecanismo do Webkit de código aberto, também usado no navegador da Web Safari. O AIR
adiciona várias extensões para permitir acesso às classes e objetos runtime, bem como à segurança. Além disso, o
Webkit por si só adiciona recursos não incluídos nos padrões da W3C para HTML, CSS e JavaScript.
Apenas as adições do AIR e as extensões do Webkit mais dignas de nota são tratadas aqui. Para obter uma
documentação adicional sobre HTML não-padrão, CSS e JavaScript, consulte www.webkit.org e developer.apple.com.
Para obter informações sobre padrões, consulte o site da W3C . O Mozilla também fornece uma referência geral valiosa
sobre tópicos HTML, CSS e DOM (é claro que os mecanismos do Webkit e Mozilla não são idênticos).
Nota: O AIR não suporta os seguintes recursos do WebKit padrão e estendidos: o método print() do objeto Window
do JavaScript; plug-ins, exceto Acrobat ou Adobe Reader 8.1+; SVG (gráficos vetoriais escaláveis), a propriedade
opacity do CSS.
JavaScript no AIR
O AIR faz várias alterações no comportamento típico de objetos JavaScript comuns. Várias dessas alterações são feitas
para tornar fácil escrever aplicativos seguros no AIR. Ao mesmo tempo, essas diferenças em comportamento
significam que alguns padrões de codificação JavaScript comuns, e aplicativos Web existentes usando esses padrões,
nem sempre podem executar conforme esperado no AIR. Para obter informações sobre como corrigir esses tipos de
problemas, consulte “Como evitar erros JavaScript relacionados à segurança” na página 235.
Caixas de proteção HTML
O AIR coloca conteúdo em caixas de proteção isoladas de acordo com a origem do conteúdo. As regras da caixa de
proteção são consistentes com a política de mesma origem implementada pela maioria dos navegadores da Web, bem
como as regras para caixas de proteção implementadas pelo Adobe Flash Player. Além disso, o AIR fornece um novo
tipo de caixa de proteção do aplicativo para conter e proteger conteúdo do aplicativo. Consulte “Caixas de proteção”
na página 27 para obter mais informações sobre os tipos de caixas de proteção que você pode encontrar ao desenvolver
aplicativos AIR.
O acesso ao ambiente de tempo de execução e às APIs do AIR está disponível apenas para HTML e JavaScript em
execução na caixa de proteção do aplicativo. Ao mesmo tempo, no entanto, a execução e avaliação dinâmica de
JavaScript, em suas várias formas, são amplamente restritas na caixa de proteção do aplicativo por razões de segurança.
Essas restrições são adequadas quer seu aplicativo realmente carregue ou não informações diretamente de um servidor.
(Até mesmo conteúdo de arquivo, seqüências de caracteres coladas e entrada do usuário direta podem ser incertos.)
A origem do conteúdo em uma página determina a caixa de proteção à qual ele é consignado. Apenas o conteúdo
carregado do diretório do aplicativo (o diretório de instalação referenciado pelo app: esquema de URL) é colocado na
caixa de proteção do aplicativo. O conteúdo carregado do sistema de arquivos é colocado na caixa de proteção local
com sistema de arquivos ou confiável local, que permite acesso e interação com conteúdo no sistema de arquivos local,
mas não conteúdo remoto. O conteúdo carregado da rede é colocado em uma caixa de proteção remota
correspondente ao seu domínio de origem.
Para permitir que uma página de aplicativo interaja livremente com o conteúdo em uma caixa de proteção remota, a
página pode ser mapeada para o mesmo domínio do conteúdo remoto. Por exemplo, se você escreve um aplicativo que
exibe dados de mapas de um serviço de Internet, a página do seu aplicativo que carrega e exibe conteúdo do serviço
poderia ser mapeada para o domínio de serviço. Os atributos para mapear páginas em um domínio e uma caixa de
proteção remota são novos atributos adicionados aos elementos HTML frame e iframe.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 221
Sobre o ambiente HTML
Para permitir conteúdo em uma caixa de proteção que não seja de aplicativo para usar com segurança recursos do AIR,
você pode configurar uma ponte de caixa de proteção pai. Para permitir que o conteúdo de aplicativo chame com
segurança métodos e acesse propriedades de conteúdo em outras caixas de proteção, você pode configurar uma ponte
de caixa de proteção filha. Segurança aqui significa que o conteúdo remoto não pode obter acidentalmente referências
a objetos, propriedades ou métodos que não são expostos explicitamente. Apenas tipos de dados simples, funções e
objetos anônimos podem ser transmitidos pela ponte. No entanto, você ainda deve evitar expor explicitamente funções
potencialmente perigosas. Se, por exemplo, você expôs uma interface que permitiu ao conteúdo remoto ler e escrever
arquivos em qualquer lugar no sistema de um usuário, você pode estar fornecendo ao conteúdo remoto o meio para
fazer um dano considerável aos seus usuários.
Função eval() do JavaScript
O uso da função eval() é restrito à caixa de proteção do aplicativo depois que o carregamento de uma página tiver
sido concluído. Alguns usos são permitidos para que dados formatados por JSON possam ser analisados com
segurança, mas qualquer avaliação que resulte em instruções executáveis terá como conseqüência um erro. O capítulo
“Restrições de código de conteúdo em caixas de proteção distintas” na página 32 descreve os usos permitidos da função
eval().
Construtores de funções
Na caixa de proteção do aplicativo, os construtores de funções podem ser usados antes que o carregamento de uma
página tenha sido concluído. Após todos os manipuladores de eventos load da página terem sido concluídos, novas
funções não podem ser criadas.
Carregamento de scripts externos
As páginas HTML na caixa de proteção do aplicativo não podem usar a tag de script para carregar arquivos de
JavaScript de fora do diretório do aplicativo. Para uma página no seu aplicativo carregar um script de fora do diretório
do aplicativo, a página deve ser mapeada para uma caixa de proteção que não seja de aplicativo.
O objeto XMLHttpRequest
O AIR fornece um objeto XMLHttpRequest (XHR) que os aplicativos podem usar para fazer solicitações de dados. O
exemplo a seguir ilustra uma solicitação de dados simples:
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http:/www.example.com/file.data", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
//do something with data...
}
}
xmlhttp.send(null);
Em contraste com um navegador, o AIR permite que o conteúdo em execução na caixa de proteção do aplicativo
solicite dados de qualquer domínio. O resultado de um XHR que contém uma seqüência de caracteres JSON pode ser
avaliado em objetos de dados, a menos que o resultado também contenha código executável. Se instruções executáveis
estão presentes no resultado de XHR, um erro é lançado e a tentativa de avaliação falha.
Para impedir a injeção acidental de código de fontes remotas, os XHRs síncronos retornam um resultado vazio se feito
antes que o carregamento de uma página seja concluído. Os XHRs assíncronos sempre são retornados após o
carregamento de uma página.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 222
Sobre o ambiente HTML
Por padrão, o AIR bloqueia XMLHttpRequests entre vários domínios em caixas de proteção de não-aplicativos. Uma
janela pai na caixa de proteção do aplicativo pode optar por permitir solicitações entre domínios em um frame filho
com conteúdo em uma caixa de proteção que não seja de aplicativo definindo allowCrossDomainXHR, um atributo
adicionado pelo AIR, como true no elemento frame ou iframe contido:
<iframe id="mashup"
src="http://www.example.com/map.html"
allowCrossDomainXHR="true"
</iframe>
Nota: Quando conveniente, a classe URLStream do AIR também pode ser usada para fazer o download de dados.
Se você despachar um XMLHttpRequest para um servidor remoto de um frame ou iframe contendo conteúdo de
aplicativo que tenha sido mapeado para uma caixa de proteção remota, verifique se a URL de mapeamento não
mascara o endereço do servidor usado no XHR. Por exemplo, considere a seguinte definição de iframe, que mapeia
conteúdo de aplicativo em uma caixa de proteção remota para o domínio example.com:
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/"
allowCrossDomainXHR="true"
</iframe>
Como o atributo sandboxRoot remapeia a URL raiz do endereço www.example.com, todas as solicitações são
carregadas do diretório do aplicativo, e não do servidor remoto. As solicitações são remapeadas derivem elas de
navegação de página ou de um XMLHttpRequest.
Para evitar bloquear solicitações de dados acidentalmente para o seu servidor remoto, mapeie sandboxRoot para um
subdiretório da URL remota, e não da raiz. O diretório não precisa existir. Por exemplo, para permitir solicitações ao
www.example.com para ser carregado do servidor remoto, e não do diretório do aplicativo, altere o iframe anterior
para o seguinte:
<iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"
allowCrossDomainXHR="true"
</iframe>
Nesse caso, apenas conteúdo no subdiretório air é carregado localmente.
Para obter mais informações sobre o mapeamento de caixa de proteção, consulte “Elementos HTML frame e iframe”
na página 227 e “segurança HTML” na página 30.
O objeto Canvas
O objeto Canvas define uma API para desenhar formas geométricas como linhas, arcos, elipses e polígonos. Para usar
a API canvas, você adiciona primeiro um elemento canvas ao documento e, em seguida, desenha nele usando a API
Canvas de JavaScript. Na maior parte dos outros aspectos, o objeto Canvas se comporta como uma imagem.
O exemplo a seguir desenha um triângulo usando um objeto Canvas:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 223
Sobre o ambiente HTML
<html>
<body>
<canvas id="triangleCanvas" style="width:40px; height:40px;"></canvas>
<script>
var canvas = document.getElementById("triangleCanvas");
var context = canvas.getContext("2d");
context.lineWidth = 3;
context.strokeStyle = "#457232";
context.beginPath();
context.moveTo(5,5);
context.lineTo(35,5);
context.lineTo(20,35);
context.lineTo(5,5);
context.lineTo(6,5);
context.stroke();
</script>
</body>
</html>
Para obter mais documentação sobre a API Canvas, consulte a Referência em JavaScript do Safari da Apple. Observe
que o projeto do Webkit começou recentemente alterando a API Canvas para ser padronizada no HTML 5 Working
Draft proposto pela WHATWG (Web Hypertext Application Technology Working Group) e pela W3C. Como
resultado, uma parte da documentação na Referência em JavaScript do Safari pode estar inconsistente com a versão de
canvas presente no AIR.
Cookies
Em aplicativos do AIR, apenas o conteúdo em caixas de proteção remotas (conteúdo carregado de fontes http: e https:)
pode usar cookies (a propriedade document.cookie). Na caixa de proteção do aplicativo, as APIs do AIR fornecem
outro meio para armazenar dados persistentes (como classes EncryptedLocalStore e FileStream).
O objeto Clipboard
A API Clipboard do WebKit é conduzida com os seguintes eventos: copy, cut e paste. O objeto event transmitido
nesses eventos fornece acesso à área de transferência pela propriedade clipboardData. Use os seguintes métodos do
objeto clipboardData para ler ou escrever dados da área de transferência:
Método
Descrição
clearData(mimeType)
Limpa os dados da área de transferência. Defina o parâmetro mimeType para o tipo MIME dos dados a apagar.
getData(mimeType)
Obtém os dados da área de transferência. Esse método pode ser chamado apenas em um manipulador para
o evento paste. Defina o parâmetro mimeType para o tipo MIME dos dados a retornar.
setData(mimeType, data)
Copia dados para a área de transferência. Defina o parâmetro mimeType para o tipo MIME dos dados.
O código JavaScript fora da caixa de proteção do aplicativo pode acessar apenas a área de transferência por esses
eventos. No entanto, o conteúdo na caixa de proteção do aplicativo pode acessar a área de transferência do sistema
diretamente usando a classe Clipboard do AIR. Por exemplo, você poderia usar a seguinte instrução para obter dados
do formato do texto na área de transferência:
var clipping = air.Clipboard.generalClipboard.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
Os tipos MIME de dados válidos são:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 224
Sobre o ambiente HTML
Tipo MIME
Valor
Texto
"text/plain"
HTML
"text/html"
URL
"text/uri-list"
Bitmap
"image/x-vnd.adobe.air.bitmap"
Lista de arquivos
"application/x-vnd.adobe.air.file-list"
Importante: Apenas conteúdo na caixa de proteção do aplicativo pode acessar dados de arquivos presentes na área de
transferência. Se um conteúdo que não seja de aplicativo tentar acessar um objeto de arquivo da área de transferência,
será lançado um erro de segurança.
Para obter mais informações sobre o uso da área de transferência, consulte “Copiar e colar” na página 149 e Utilização
da área de trabalho de JavaScript (Centro de desenvolvedores da Apple).
Arrastar e soltar
Gestos de arrastar e soltar para dentro e para fora do HTML produzem os seguintes eventos DOM: dragstart, drag,
dragend, dragenter, dragover, dragleave e drop. O objeto event transmitido nesses eventos fornece acesso aos
dados arrastados pela propriedade dataTransfer. A propriedade dataTransfer faz referência a um objeto que
fornece os mesmos métodos do objeto clipboardData associado a um evento clipboard. Por exemplo, você poderia
usar a seguinte função para obter dados do formato de um evento drop:
function onDrop(dragEvent){
return dragEvent.dataTransfer.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
}
O objeto dataTransfer possui os seguintes membros importantes:
Membro
Descrição
clearData(mimeType)
Limpa os dados. Defina o parâmetro mimeType para o tipo MIME da representação de dados para apagar.
getData(mimeType)
Obtém os dados arrastados. Esse método pode ser chamado apenas em um manipulador para o evento drop.
Defina o parâmetro mimeType para o tipo MIME dos dados a obter.
setData(mimeType, data)
Defina os dados a serem arrastados. Defina o parâmetro mimeType para o tipo MIME dos dados.
tipos
Uma matriz de seqüências de caracteres contendo os tipos MIME de todas as representações de dados
disponíveis no momento no objeto dataTransfer.
effectsAllowed
Especifica se os dados que estão sendo arrastados podem ser copiados, movidos, vinculados ou alguma
combinação disso. Defina a propriedade effectsAllowed no manipulador para o evento dragstart.
dropEffect
Especifica quais dos efeitos drop permitidos são suportados por um drag target. Defina a propriedade
dropEffect no manipulador para o evento dragEnter. Durante a ação de arrastar, o cursor muda para
indicar que efeito ocorreria se o usuário soltasse o mouse. Se nenhum dropEffect for especificado, um
efeito da propriedade effectsAllowed será escolhido. O efeito de copiar tem prioridade sobre o efeito de
mover, que por si só tem prioridade sobre o efeito de vincular. O usuário pode modificar a prioridade padrão
usando o teclado.
Para obter mais informações sobre como adicionar suporte para arrastar e soltar em um aplicativo do AIR, consulte
“Arrastar e soltar” na página 133 e Utilização de arrastar e soltar de JavaScript (Centro de desenvolvedores da Apple).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 225
Sobre o ambiente HTML
Propriedades innerHTML e outerHTML
O AIR coloca restrições de segurança sobre o uso das propriedades innerHTML e outerHTML para conteúdo em
execução na caixa de proteção do aplicativo. Antes do evento de carregamento da página, bem como durante a
execução de qualquer manipulador de evento de carregamento, o uso das propriedades innerHTML e outerHTML é
irrestrito. No entanto, depois que a página é carregada, você pode apenas usar as propriedades innerHTML ou
outerHTML para adicionar conteúdo estático ao documento. Qualquer instrução na seqüência de caracteres atribuída
a innerHTML ou outerHTML avaliada como código executável é ignorada. Por exemplo, se você incluir um atributo de
retorno de evento em uma definição de elemento, o ouvinte de eventos não será adicionado. Da mesma forma, tags
<script> incorporadas não são avaliadas. Para obter mais informações, consulte “segurança HTML” na página 30.
Métodos Document.write() e Document.writeln()
O uso dos métodos write() e writeln() não é restrito à caixa de proteção do aplicativo antes do evento load da
página. No entanto, depois que a página é carregada, chamar um desses métodos não limpa a página ou cria uma nova.
Em uma caixa de proteção que não seja de aplicativo, como na maioria dos navegadores da Web, chamar
document.write() ou writeln(), após a conclusão do carregamento de uma página, limpa a página atual e abre uma
nova em branco.
Propriedade Document.designMode
Defina a propriedade document.designMode para um valor de on para tornar todos os elementos do documento
editáveis. O suporte a editor incorporado inclui editar texto, copiar, colar e arrastar e soltar. Definir designMode como
on é equivalente a definir a propriedade contentEditable do elemento body como true. Você pode usar a
propriedade contentEditable na maioria dos elementos HTML para definir que seções de um documento são
editáveis. Consulte “Atributo contentEditable HTML” na página 230 para obter informações adicionais.
Eventos unload (para objetos body e frameset)
Na tag de nível superior frameset ou body de uma janela (incluindo a janela principal do aplicativo), não use o evento
unload para responder à janela (ou aplicativo) que está sendo fechada. Em vez disso, use o evento exiting do objeto
NativeApplication (para detectar quando um aplicativo está sendo fechando). Em vez disso, use o evento exiting do
objeto NativeWindow (para detectar quando um aplicativo está sendo fechado). Por exemplo, o seguinte código
JavaScript exibe uma mensagem ("Goodbye.") quando o usuário fecha o aplicativo:
var app = air.NativeApplication.nativeApplication;
app.addEventListener(air.Event.EXITING, closeHandler);
function closeHandler(event)
{
alert("Goodbye.");
}
No entanto, scripts podem responder com êxito ao evento unload causado pela navegação de um conteúdo frame,
iframe ou window de nível superior.
Nota: Essas limitações podem ser removidas em uma versão futura do Adobe AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 226
Sobre o ambiente HTML
Objeto Window do JavaScript
O objeto Window permanece o objeto global no contexto de execução do JavaScript. Na caixa de proteção do
aplicativo, o AIR adiciona novas propriedades ao objeto Window do JavaScript para fornecer acesso às classes
incorporadas do AIR, bem como importantes objetos de host. Além disso, alguns métodos e propriedades se
comportam de modo diferente dependendo se estão ou não na caixa de proteção do aplicativo.
Propriedade Window.runtime A propriedade runtime permite que você instancie e use classes runtime incorporadas
da caixa de proteção do aplicativo. Essas classes incluem APIs do AIR e do Flash Player (mas não, por exemplo, a
estrutura do Flex). Por exemplo, a seguinte instrução cria um objeto de arquivo do AIR:
var preferencesFile = new window.runtime.flash.filesystem.File();
O arquivo AIRAliases.js, fornecido no SDK do AIR, contém definições de aliases que permitem a você encurtar tais
referências. Por exemplo, quando AIRAliases.js é importado em uma página, um objeto File pode ser criado com a
seguinte instrução:
var preferencesFile = new air.File();
A propriedade window.runtime somente é definida para conteúdo dentro da caixa de proteção do aplicativo e apenas
para o documento pai de uma página com frames ou iframes.
Consulte “Uso do arquivo AIRAliases.js” na página 239.
Propriedade Window.nativeWindow A propriedade nativeWindow fornece uma referência ao objeto de janela nativa
subjacente. Com essa propriedade, você pode fazer o script de funções e propriedades de janela, como posição da tela,
tamanho e visibilidade e manipular eventos de janela, como fechar, redimensionar e mover. Por exemplo, a seguinte
instrução fecha a janela:
window.nativeWindow.close();
Nota: Os recursos de controle da janela fornecidos pelo objeto NativeWindow sobrepõem os recursos fornecidos pelo
objeto Window do JavaScript. Em tais casos, você pode usar qualquer método que considerar mais conveniente.
A propriedade window.nativeWindow somente é definida para conteúdo dentro da caixa de proteção do aplicativo e
apenas para o documento pai de uma página com frames ou iframes.
Propriedade Window.htmlLoader A propriedade htmlLoader fornece uma referência ao objeto AIR HTMLLoader
que contém o conteúdo HTML. Com essa propriedade, você pode fazer o script da aparência e do comportamento do
ambiente HTML. Por exemplo, você pode usar a propriedade htmlLoader.paintsDefaultBackground para
determinar se o controle pinta um plano de fundo branco padrão:
window.htmlLoader.paintsDefaultBackground = false;
Nota: O objeto HTMLLoader por si só possui uma propriedade window, que faz referência ao objeto Window do
JavaScript do conteúdo HTML contido nele. Você pode usar essa propriedade para acessar o ambiente JavaScript por
uma referência ao HTMLLoader contido.
A propriedade window.htmlLoader somente é definida para conteúdo dentro da caixa de proteção do aplicativo e
apenas para o documento pai de uma página com frames ou iframes.
Propriedades Window.parentSandboxBridge e Window.childSandboxBridge As propriedades
parentSandboxBridge e childSandboxBridge permitem que você defina uma interface entre um frame filho e um
pai. Para obter mais informações, consulte “Conteúdo entre scripts em caixas de proteção de segurança distintas” na
página 248.
Funções Window.setTimeout() e Window.setInterval() O AIR coloca restrições de segurança sobre o uso das funções
setTimeout() e setInterval() na caixa de proteção do aplicativo. Não é possível definir o código a ser executado
como uma seqüência de caracteres ao chamar setTimeout() ou setInterval(). É necessário usar uma referência
de função. Para obter mais informações, consulte “setTimeout() e setInterval()” na página 237.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 227
Sobre o ambiente HTML
Função Window.open() Quando chamado por código em execução em uma caixa de proteção que não seja de
aplicativo, o método open() abrirá somente uma janela quando chamado como resultado da interação do usuário
(como um clique do mouse ou pressionamento de tecla). Além disso, o título da janela é prefixado com o título do
aplicativo (para impedir que janelas sejam abertas por conteúdo remoto personifiquem janelas abertas pelo aplicativo).
Para obter mais informações, consulte o capítulo “Restrições na chamada do método window.open() de JavaScript” na
página 35.
Objeto air.NativeApplication
O objeto NativeApplication fornece informações sobre o estado do aplicativo, despacha vários eventos de nível de
aplicativo importantes e fornece funções úteis para controlar o comportamento do aplicativo. Uma única instância do
objeto NativeApplication é criada automaticamente e pode ser acessada pela propriedade
NativeApplication.nativeApplication definida pela classe.
Para acessar o objeto do código JavaScript, você poderia usar:
var app = window.runtime.flash.desktop.NativeApplication.nativeApplication;
Ou, se o script AIRAliases.js tiver sido importado, você poderia usar a forma mais curta:
var app = air.NativeApplication.nativeApplication;
O objeto NativeApplication pode apenas ser acessado de dentro da caixa de proteção do aplicativo. A interação com o
sistema operacional “Trabalho com tempo de execução e informações do sistema operacional” na página 299 descreve
o objeto NativeApplication em detalhes.
O esquema de URL JavaScript
A execução do código definida em um esquema de URL de JavaScript (como em
href="javascript:alert('Test')") é bloqueada na caixa de proteção do aplicativo. Nenhum erro é lançado.
Extensões para HTML
O AIR e o WebKit definem alguns atributos e elementos HTML não-padrão, incluindo:
“Elementos HTML frame e iframe” na página 227
“Elemento Canvas HTML” na página 229
“Manipuladores de eventos de elementos HTML” na página 230
Elementos HTML frame e iframe
O AIR adiciona novos atributos aos elementos frame e iframe de conteúdo na caixa de proteção do aplicativo:
Atributo sandboxRoot O atributo sandboxRoot especifica um domínio de origem alternativo que não seja de
aplicativo para o arquivo especificado pelo atributo src do frame. O arquivo é carregado na caixa de proteção que não
seja de aplicativo correspondente ao domínio especificado. O conteúdo no arquivo e o conteúdo carregado do domínio
especificado podem cruzar scripts entre si.
Importante: Se você definir o valor de sandboxRoot para a URL base do domínio, todas as solicitações para conteúdo
desse domínio serão carregadas do diretório do aplicativo, e não do servidor remoto (resulte a solicitação de navegação
de página, de um XMLHttpRequest ou de qualquer outro meio de carregar conteúdo).
Atributo documentRoot O atributo documentRoot especifica o diretório local a partir do qual carregar URLs que
procuram endereços para arquivos no local especificado por sandboxRoot.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 228
Sobre o ambiente HTML
Ao consultar endereços de URLs, no atributo src do frame ou no conteúdo carregado no frame, a parte da URL que
corresponde ao valor especificado em sandboxRoot é substituída pelo valor especificado em documentRoot. Portanto,
na seguinte tag de frame:
<iframe src="http://www.example.com/air/child.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"/>
child.html é carregado do subdiretório sandbox da pasta de instalação do aplicativo. Os endereços das URLs
relativas em child.html são procurados com base no diretório sandbox. Observe que qualquer arquivo no servidor
remoto em www.example.com/air não pode ser acessado no frame, uma vez que o AIR tentaria carregá-lo do
diretório app:/sandbox/.
Atributo allowCrossDomainXHR Inclua allowCrossDomainXHR="allowCrossDomainXHR" na tag de frame de
abertura para permitir que o conteúdo no frame faça XMLHttpRequests para qualquer domínio remoto. Por padrão,
o conteúdo que não é de aplicativo apenas pode fazer tais solicitações em seu próprio domínio de origem. Existem
implicações de segurança sérias envolvidas na permissão de XHRs entre domínios. O código da página pode trocar
dados com qualquer domínio. Se o conteúdo mal-intencionado é de certa forma injetado na página, qualquer dado
acessível para código na caixa de proteção atual pode ficar comprometido. Apenas ative XHRs entre domínios para
páginas que você cria e controla e somente quando o carregamento de dados entre domínios for realmente necessário.
Além disso, valide cuidadosamente todos os dados externos carregados pela página para impedir a injeção de dados
ou outras formas de ataque.
Importante: Se o atributo allowCrossDomainXHR for incluído em um elemento frame ou iframe, XHRs entre domínios
serão ativados (a menos que o valor atribuído seja "0" ou comece com as letras "f" ou "n"). Por exemplo, definir
allowCrossDomainXHR como "deny" ainda ativaria XHRs entre domínios. Deixe o atributo totalmente fora da
declaração do elemento se não desejar ativar solicitações entre domínios.
Atributo ondominitialize Especifica um manipulador de eventos para o evento dominitialize de um frame. Esse é
um evento específico do AIR disparado quando os objetos window e document do frame tiverem sido criados, mas
antes que qualquer script tenha sido analisado ou elementos document tenham sido criados.
O frame despacha o evento dominitialize cedo o suficiente na seqüência de carregamento de forma que qualquer
script na página filha possa se referir a objetos, variáveis e funções adicionadas ao documento filho pelo manipulador
dominitialize. A página pai deve estar na mesma caixa de proteção da filha para adicionar ou acessar diretamente
qualquer objeto em um documento filho. No entanto, um pai na caixa de proteção do aplicativo pode estabelecer uma
ponte de caixa de proteção para se comunicar com conteúdo em uma caixa de proteção que não seja de aplicativo.
Os exemplos a seguir ilustram o uso da tag iframe no AIR:
Coloque child.html em uma caixa de proteção remota, sem mapear para um domínio real em um servidor remoto:
<iframe src="http://localhost/air/child.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://localhost/air/"/>
Coloque child.html em uma caixa de proteção remota, permitindo XMLHttpRequests apenas para
www.example.com:
<iframe src="http://www.example.com/air/child.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"/>
Coloque child.html em uma caixa de proteção remota, permitindo XMLHttpRequests para qualquer domínio
remoto:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 229
Sobre o ambiente HTML
<iframe src="http://www.example.com/air/child.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"
allowCrossDomainXHR="allowCrossDomainXHR"/>
Coloque child.html em uma caixa de proteção local com sistema de arquivos:
<iframe
src="file:///templates/child.html"
documentRoot="app:/sandbox/"
sandboxRoot="app-storage:/templates/"/>
Coloque child.html em uma caixa de proteção remota, usando o evento dominitialize para estabelecer uma ponte
de caixa de proteção:
<html>
<head>
<script>
var bridgeInterface = {};
bridgeInterface.testProperty = "Bridge engaged";
function engageBridge(){
document.getElementById("sandbox").parentSandboxBridge = bridgeInterface;
}
</script>
</head>
<body>
<iframe id="sandbox"
src="http://www.example.com/air/child.html"
documentRoot="app:/"
sandboxRoot="http://www.example.com/air/"
ondominitialize="engageBridge()"/>
</body>
</html>
O documento child.html a seguir ilustra como o conteúdo filho pode acessar a ponte de caixa de proteção pai:
<html>
<head>
<script>
document.write(window.parentSandboxBridge.testProperty);
</script>
</head>
<body></body>
</html>
Para obter mais informações, consulte “Conteúdo entre scripts em caixas de proteção de segurança distintas” na
página 248 e “segurança HTML” na página 30.
Elemento Canvas HTML
Define uma área de desenho para uso com a API Canvas do Webkit. Comandos gráficos não podem ser especificados
na tag em si. Para desenhar na tela, chame os métodos de desenho de tela por JavaScript.
<canvas id="drawingAtrium" style="width:300px; height:300px;"></canvas>
Para obter mais informações, consulte “O objeto Canvas” na página 222.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 230
Sobre o ambiente HTML
Manipuladores de eventos de elementos HTML
Objetos DOM no AIR e no Webkit despacham alguns eventos não encontrados no modelo de eventos DOM padrão.
A tabela a seguir lista os atributos de eventos relacionados que podem ser usados para especificar manipuladores para
estes eventos:
Nome do atributo de
retorno de chamada
Descrição
oncontextmenu
Chamado quando um menu de contexto é invocado, como pelo
clique do botão direito do mouse ou clique da tecla Command no
texto selecionado.
oncopy
Chamado quando uma seleção em um elemento é copiada.
oncut
Chamado quando uma seleção em um elemento é cortada.
ondominitialize
Chamado quando o DOM de um documento carregado em um
frame ou iframe é criado, mas antes que qualquer elemento de DOM
seja criado ou script analisado.
ondrag
Chamado quando um elemento é arrastado.
ondragend
Chamado quando uma ação de arrastar é liberada.
ondragenter
Chamado quando um gesto de ação de arrastar entra nos limites de
um elemento.
ondragleave
Chamado quando um gesto de ação de arrastar deixa os limites de
um elemento.
ondragover
Chamado continuamente enquanto um gesto de ação de arrastar
está dentro dos limites de um elemento.
ondragstart
Chamado quando um gesto de ação de arrastar é iniciado.
ondrop
Chamado quando um gesto de ação de arrastar é liberado sobre um
elemento.
onerror
Chamado quando um erro ocorre ao carregar um elemento.
oninput
Chamado quanto o texto é inserido em um elemento de formulário.
onpaste
Chamado quando um item é colado em um elemento.
onscroll
Chamado quando o conteúdo de um elemento rolável é rolado.
onsearch
Chamado quando um elemento é copiado (? docs da Apple corretos
?)
onselectstart
Chamado quando uma seleção é iniciada.
Atributo contentEditable HTML
Você pode adicionar o atributo contentEditable a qualquer elemento HTML para permitir aos usuários editar o
conteúdo do elemento. Por exemplo, o seguinte código de exemplo HTML define todo o documento como editável,
exceto para o primeiro elemento p:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 231
Sobre o ambiente HTML
<html>
<head/>
<body contentEditable="true">
<h1>de Finibus Bonorum et Malorum</h1>
<p contentEditable="false">Sed ut perspiciatis unde omnis iste natus error.</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis.</p>
</body>
</html>
Nota: Se você define a propriedade document.designMode como on, todos os elementos do documento são editáveis,
independentemente da configuração de contentEditable para um elemento individual. No entanto, definir
designMode como off não desativa a edição de elementos para os quais contentEditable é true. Consulte
“Propriedade Document.designMode” na página 225 para obter informações adicionais.
Extensões para o CSS
O WebKit suporta várias propriedades CSS estendidas. A tabela a seguir lista as propriedades estendidas para as quais
o suporte é estabelecido. As propriedades adicionais não-padrão estão disponíveis no WebKit, mas não são totalmente
suportadas no AIR, porque ainda estão em desenvolvimento no WebKit ou porque são recursos experimentais que
podem ser removidos no futuro.
Nome de propriedade CSS
Valores
Descrição
-webkit-border-horizontal-spacing
Unidade de comprimento não-negativa
Especifica o componente horizontal do
espaçamento da borda.
-webkit-border-vertical-spacing
Unidade de comprimento não-negativa
Especifica o componente vertical do
espaçamento da borda.
-webkit-line-break
after-white-space, normal
Especifica a regra de quebra de linha a ser
usada para texto em chinês, japonês e
coreano (CJK).
-webkit-margin-bottom-collapse
collapse, discard, separate
Define como a margem inferior de uma
célula de tabela é recolhida.
-webkit-margin-collapse
collapse, discard, separate
Define como as margem superior e inferior
de uma célula de tabela é recolhida.
-webkit-margin-start
Qualquer unidade de comprimento.
A largura da margem inicial. Para texto da
esquerda para a direita, essa propriedade
substitui a margem esquerda. Para texto
da direita para a esquerda, essa
propriedade substitui a margem direita.
-webkit-margin-top-collapse
collapse, discard, separate
Define como a margem superior de uma
célula de tabela é recolhida.
-webkit-nbsp-mode
normal, space
Define o comportamento de espaços nãoseparáveis no conteúdo delimitado.
-webkit-padding-start
Qualquer unidade de comprimento.
Especifica a largura do preenchimento
inicial. Para texto da esquerda para a
direita, essa propriedade substitui o valor
do preenchimento esquerdo. Para texto
da direita para a esquerda, essa
propriedade substitui o valor do
preenchimento direito.
-webkit-rtl-ordering
logical, visual
Substitui a manipulação padrão de texto
mesclado da esquerda para a direita e da
direita para a esquerda.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 232
Sobre o ambiente HTML
Nome de propriedade CSS
Valores
Descrição
-webkit-text-fill-color
Qualquer cor nomeada ou valor de cor
numérico
Especifica a cor de preenchimento do
texto.
-webkit-text-security
circle, disc, none, square
Especifica a forma de substituição a ser
usada em um campo de entrada de senha.
-webkit-user-drag
•
auto — Comportamento padrão
Substitui o comportamento de ação de
arrastar automático.
•
element — Todo o elemento é
arrastado
•
none — O elemento não pode ser
arrastado
-webkit-user-modify
read-only, read-write, read-writeplaintext-only
Especifica se o conteúdo de um elemento
pode ser editado.
-webkit-user-select
•
auto — Comportamento padrão
Especifica se um usuário pode selecionar o
conteúdo de um elemento.
•
none — O elemento não pode ser
selecionado
•
text — É possível selecionar apenas
texto no elemento
Para obter mais informações, consulte a Referência do CSS do Apple Safari
(http://developer.apple.com/documentation/AppleApplications/Reference/SafariCSSRef/).
233
Capítulo 21: Programação em HTML e
JavaScript
Vários tópicos de programação são exclusivos para o desenvolvimento de aplicativos Adobe® AIR™ com HTML e
JavaScript. As seguintes informações são importantes caso você esteja programando um aplicativo baseado em HTML
ou um aplicativo AIR baseado em SWF que execute HTML e JavaScript usando a classe HTMLLoader (ou o
componente mx:HTML Flex™).
Sobre a classe HTMLLoader
A classe HTMLLoader do Adobe AIR define o objeto de exibição que pode exibir conteúdo HTML em um aplicativo
AIR. Os aplicativos baseados em SWF podem adicionar um controle HTMLLoader a uma janela existente ou criar uma
janela HTML que contenha automaticamente um objeto HTMLLoader com HTMLLoader.createRootWindow(). O
objeto HTMLLoader pode ser acessado por meio da propriedade window.htmlLoader de JavaScript de dentro da
página HTML carregada.
Carregamento de conteúdo HTML de uma URL
O código a seguir carrega uma URL no objeto HTMLLoader (adicione o HTMLLoader como filho do estágio ou outro
contêiner do objeto de exibição para exibir o conteúdo HTML no seu aplicativo):
import flash.html.HTMLLoader;
var html:HTMLLoader = new HTMLLoader;
html.width = 400;
html.height = 600;
var urlReq:URLRequest = new URLRequest("http://www.adobe.com/");
html.load(urlReq);
Por padrão, as propriedades width e height de um objeto HTMLLoader são definidas como 0. Você desejará definir
essas dimensões quando adicionar um objeto HTMLLoader ao palco. O HTMLLoader despacha diversos eventos à
medida que a página carrega. Você pode usar esses eventos para determinar quando é seguro interagir com a página
carregada. Esses eventos são descritos em “Tratamento de eventos relacionados a HTML” na página 252.
Você também pode processar texto HTML usando a classe TextField, mas os respectivos recursos são limitados. A
classe Textfield do Adobe® Flash® Player oferece suporte a um subconjunto de markup de HTML, mas, devido a
limitações de tamanho, os recursos respectivos são limitados. (A classe HTMLLoader incluída no Adobe AIR não está
disponível no Flash Player.)
Carregamento de conteúdo HTML de uma string
O método loadString() do objeto HTMLLoader carrega uma string de conteúdo HTML no objeto HTMLLoader:
var html:HTMLLoader = new HTMLLoader();
var htmlStr:String = "<html><body>Hello <b>world</b>.</body></html>";
html.loadString(htmlStr);
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 234
Programação em HTML e JavaScript
Por padrão, o conteúdo carregado por meio do método loadString() é colocado em uma caixa de proteção que não
é aplicativo com as seguintes características:
• Ela tem acesso ao conteúdo carregado da rede (mas não do sistema de arquivos).
• Ela não pode carregar dados usando XMLHttpRequest.
• A propriedade window.location é definida como "about:blank".
• O conteúdo não pode acessar a propriedade window.runtime (como pode em qualquer caixa de proteção que não
é aplicativo).
No AIR 1.5, a classe HTMLLoader inclui uma propriedade placeLoadStringContentInApplicationSandbox.
Quando essa propriedade é definida como true para um objeto HTMLLoader, o conteúdo carregado pelo método
loadString() é colocado na caixa de proteção do aplicativo. (O valor padrão é false.) Isso fornece ao conteúdo
carregado pelo método loadString() acesso à propriedade window.runtime e a todas as APIs do ARI. Se você
definir essa propriedade como true, assegure que a fonte de dados para uma seqüência de caracteres usada em uma
chamada para o método loadString() seja confiável. As instruções de código na seqüência de caracteres HTML são
executadas com privilégios totais de aplicativo quando essa propriedade é definida como true. Só defina a propriedade
como true quando estiver certo de que a seqüência de caracteres não possa conter código nocivo.
Em aplicativos compilados com SDKs do AIR 1.0 ou 1.1, o conteúdo carregado pelo método loadString() é inserido
na caixa de proteção do aplicativo.
Regras de segurança importantes no uso de HTML em aplicativos AIR
Os arquivos instalados com o aplicativo AIR têm acesso às respectivas APIs. Por motivos de segurança, o conteúdo de
outras fontes não tem acesso. Por exemplo, essa restrição impede que conteúdo de um domínio remoto (como
http://example.com) leia o conteúdo de diretório da área de trabalho do usuário (ou algo pior).
Como há buracos de segurança que podem ser explorados através da chamada da função eval() (e APIs
relacionadas), o conteúdo instalado com o aplicativo, por padrão, não pode usar esses métodos. No entanto, algumas
estruturas Ajax usam a chamada da função eval() e APIs relacionadas.
Para estruturar adequadamente o conteúdo para trabalhar em um aplicativo AIR, você deve considerar as regras das
restrições de segurança sobre conteúdo de fontes diversas. O conteúdo de fontes diversas é colocado em classificações
de segurança distintas, chamadas de caixas de proteção (consulte “Caixas de proteção” na página 27). Por padrão, o
conteúdo instalado com o aplicativo está instalado em uma caixa de proteção conhecida como caixa de proteção de
aplicativo e isso concede a ele acesso às APIs do AIR. Normalmente, a caixa de proteção do aplicativo é a mais segura,
com restrições projetadas para impedir a execução de código não confiável.
O tempo de execução permite carregar o conteúdo instalado com o aplicativo em uma caixa de proteção diferente da
caixa de proteção do aplicativo. O conteúdo em caixas de proteção não-aplicativo opera em um ambiente de segurança
semelhante ao de um navegador da Web típico. Por exemplo, o código das caixas de proteção não-aplicativos pode
usar eval() e métodos relacionados (mas, ao mesmo tempo, não é permitido acesso às APIs do AIR). O tempo de
execução inclui maneiras de fazer com que o conteúdo em caixas de proteção distintas se comuniquem com segurança
(sem expor, por exemplo, as APIs do AIR a conteúdo de não-aplicativo). Para obter detalhes, consulte “Conteúdo entre
scripts em caixas de proteção de segurança distintas” na página 248.
Se você chamar um código com uso restrito em uma caixa de proteção por motivos de segurança, o tempo de execução
despachará um erro JavaScript: "Violação de segurança de tempo de execução do Adobe AIR para código JavaScript
na caixa de proteção de segurança do aplicativo."
Para evitar esse erro, siga as práticas de codificação descritas na próxima seção, “Como evitar erros JavaScript
relacionados à segurança” na página 235.
Para obter mais informações, consulte “segurança HTML” na página 30.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 235
Programação em HTML e JavaScript
Como evitar erros JavaScript relacionados à segurança
Se você chamar um código com uso restrito em uma caixa de proteção, devido a essas restrições de segurança, o tempo
de execução despachará um erro de JavaScript: "Violação de segurança de tempo de execução do Adobe AIR para
código JavaScript na caixa de proteção de segurança do aplicativo." Para evitar esse erro, siga essas práticas de
codificação.
Causas de erros JavaScript relacionados à segurança
O código em execução na caixa de proteção do aplicativo está restrito à maioria das operações que envolvem avaliação
e execução de seqüências depois que o evento load tiver sido disparado e todos os manipuladores de evento load
tiverem encerrado. A tentativa de usar os seguintes tipos de instruções JavaScript que avaliam e executam strings
potencialmente inseguras gera erros JavaScript:
• função eval()
• setTimeout() e setInterval()
• Construtor de funções
Além disso, os tipos de instruções JavaScript seguintes falham sem gerar um erro JavaScript inseguro:
• javascript: URLs
• Retornos de chamada de evento atribuídos por meio de atributos onevent em instruções innerHTML e outerHTML
• Carregamento de arquivos JavaScript externos ao diretório de instalação do aplicativo
• document.write() e document.writeln()
• XMLHttpRequests síncronas antes do evento load ou durante um manipulador de eventos load
• Elementos de script criados dinamicamente
Nota: Em alguns casos restritos, a avaliação de strings é permitida. Consulte “Restrições de código de conteúdo em
caixas de proteção distintas” na página 32 para obter mais informações.
A Adobe mantém uma lista das estruturas Ajax conhecidas para oferecer suporte à caixa de proteção de segurança
do aplicativo em http://www.adobe.com/go/airappsandboxframeworks_br.
As seções seguintes descrevem como regravar os scripts para evitar esses erros JavaScript inseguro e falhas
silenciosas do código em execução na caixa de proteção do aplicativo.
Mapeamento de conteúdo do aplicativo para uma caixa de proteção distinta
Na maioria dos casos, você pode regravar ou reestruturar o aplicativo para evitar erros JavaScript relacionados à
segurança. No entanto, quando não for possível regra ou reestruturar, você poderá carregar o conteúdo do aplicativo
em uma caixa de proteção distinta usando a técnica descrita em “Carregamento de conteúdo do aplicativo em uma
caixa de proteção "não aplicativo"” na página 248. Se esse conteúdo também deve acessar as APIs do AIR, você pode
criar uma ponte de caixa de proteção, conforme descrito em “Configuração de interface de ponte de caixa de proteção”
na página 249.
função eval()
Na caixa de proteção do aplicativo, a função eval() só pode ser usada antes do evento load da página ou durante o
manipulador de eventos load. Após a página ter sido carregada, as chamadas para eval() não executarão código. No
entanto, nos seguintes casos, você pode regravar o código para evitar o uso de eval().
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 236
Programação em HTML e JavaScript
Atribuição de propriedades a um objeto
Em vez de analisar uma string para criar o acessador de propriedades:
eval("obj." + propName + " = " + val);
acesse propriedades com notação entre colchetes:
obj[propName] = val;
Criação de função com variáveis disponíveis no contexto
Substitua instruções como as seguintes:
function compile(var1, var2){
eval("var fn = function(){ this."+var1+"(var2) }");
return fn;
}
com:
function compile(var1, var2){
var self = this;
return function(){ self[var1](var2) };
}
Criação de objeto usando o nome da classe como parâmetro de seqüência
Considere uma classe JavaScript hipotética definida com o seguinte código:
var CustomClass =
{
Utils:
{
Parser: function(){ alert('constructor') }
},
Data:
{
}
};
var constructorClassName = "CustomClass.Utils.Parser";
A maneira mais simples de criar uma ocorrência é usar eval():
var myObj;
eval('myObj=new ' + constructorClassName +'()')
No entanto, você pode evitar a chamada para eval(), analisando cada componente de nome de classe e criando o novo
objeto usando notação entre colchetes:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 237
Programação em HTML e JavaScript
function getter(str)
{
var obj = window;
var names = str.split('.');
for(var i=0;i<names.length;i++){
if(typeof obj[names[i]]=='undefined'){
var undefstring = names[0];
for(var j=1;j<=i;j++)
undefstring+="."+names[j];
throw new Error(undefstring+" is undefined");
}
obj = obj[names[i]];
}
return obj;
}
Para criar a ocorrência, use:
try{
var Parser = getter(constructorClassName);
var a = new Parser();
}catch(e){
alert(e);
}
setTimeout() e setInterval()
Substitua a string passada como a função do manipulador por uma referência de função ou objeto. Por exemplo,
substitua uma instrução como a seguinte:
setTimeout("alert('Timeout')", 10);
com:
setTimeout(alert('Timeout'), 10);
Ou, quando a função precisar que o objeto this seja definido pelo chamador, substitua uma instrução como:
this.appTimer = setInterval("obj.customFunction();", 100);
pelo seguinte:
var _self = this;
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);
Construtor de funções
As chamadas para new Function(param, body) podem ser substituídas por uma declaração de função inline ou
usadas apenas antes que o evento load da página tenha sido tratado.
javascript: URLs
O código definido em um link usando o javascript: O esquema de URL é ignorado na caixa de proteção do aplicativo.
Não é gerado nenhum erro JavaScript inseguro. Você pode substituir links usando javascript: URLs, como:
<a href="javascript:code()">Click Me</a>
com:
<a href="#" onclick="code()">Click Me</a>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 238
Programação em HTML e JavaScript
Retornos de chamada de evento atribuídos por meio de atributos onevent em
instruções innerHTML e outerHTML
Ao usar innerHTML ou outerHTML para adicionar elementos ao DOM de um documento, todos os retornos de
chamadas de evento atribuídos na instrução, como onclick ou onmouseover, são ignorados. Nenhum erro de
segurança é gerado. Em vez disso, você pode atribuir um atributo id aos novos elementos e definir as funções de
retorno de chamada do manipulador de eventos, usando o método addEventListener().
Por exemplo, determinado um elemento de destino em um documento, como:
<div id="container"></div>
Substitua instruções como:
document.getElementById('container').innerHTML =
'<a href="#" onclick="code()">Click Me.</a>';
com:
document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>';
document.getElementById('smith').addEventListener("click", function() { code(); });
Carregamento de arquivos JavaScript externos ao diretório de instalação do
aplicativo
Não é permitido o carregamento de arquivos de script externos à caixa de proteção do aplicativo. Nenhum erro de
segurança é gerado. Todos os arquivos de script que são executados na caixa de proteção do aplicativo devem ser
instalados no diretório do aplicativo. Para usar scripts externos em uma página, você deve mapear a página para uma
caixa de proteção distinta. Consulte “Carregamento de conteúdo do aplicativo em uma caixa de proteção "não
aplicativo"” na página 248.
document.write() e document.writeln()
As chamadas para document.write() ou document.writeln() serão ignoradas após o evento load da página ser
tratado. Nenhum erro de segurança é gerado. Como alternativa, você pode carregar um novo arquivo ou substituir o
corpo do documento usando técnicas de manipulação DOM.
XMLHttpRequests síncronas antes do evento load ou durante um
manipulador de eventos load
As XMLHttpRequests síncronas iniciadas antes do evento load da página ou durante um manipulador de eventos
load não retornam nenhum conteúdo. As XMLHttpRequests assíncronas podem ser iniciadas, mas não retornam até
depois do evento load. Após o evento load ser tratado, as XMLHttpRequests síncronas se comportam normalmente.
Elementos de script criados dinamicamente
Elementos de script criados dinamicamente, como quando criados com o innerHTML ou o método
document.createElement(), são ignorados.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 239
Programação em HTML e JavaScript
Acesso às classes API do AIR no JavaScript
Além dos elementos padrão e estendidos de kit da Web, o código HTML e JavaScript pode acessar as classes host
fornecidas pelo tempo de execução. Essas classes permitem acessar os recursos avançados que o AIR oferece,
incluindo:
• Acesso ao sistema de arquivos
• Uso de bancos de dados SQL locais
• Controle de menus de janela e aplicativo
• Acesso a soquetes de rede
• Uso de classes e objetos definidos pelo usuário
• Recursos de som
Por exemplo, a API de arquivo do AIR inclui uma classe File, contida no pacote flash.filesystem. Você pode criar
um objeto File em JavaScript da seguinte forma:
var myFile = new window.runtime.flash.filesystem.File();
O objeto runtime é um objeto JavaScript especial, disponível para conteúdo HTML em execução no AIR na caixa
de proteção do aplicativo. Ele permite acessar as classes de tempo de execução do JavaScript. A propriedade flash
do objeto runtime oferece acesso ao pacote flash. Por sua vez, a propriedade flash.filesystem do objeto
runtime oferece acesso ao pacote flash.filesystem (e esse pacote inclui a classe File). Os pacotes são uma maneira
de organizar as classes usadas no ActionScript.
Nota: A propriedade runtime não é adicionada automaticamente aos objetos window de páginas carregadas em um
frame ou iframe. No entanto, desde que o documento filho esteja na caixa de proteção do aplicativo, o filho poderá
acessar a propriedade runtime do pai.
Como a estrutura de pacote das classes de tempo de execução exigem que os desenvolvedores digitem longas
seqüências de código JavaScript para acessar cada classe (como em
window.runtime.flash.desktop.NativeApplication), o AIR SDK inclui o arquivo AIRAliases.js, que permite
acessar as classes de tempo de execução mais facilmente (por exemplo, digitando simplesmente
air.NativeApplication).
As classes API do AIR são discutidas em todo este guia. Outras classes da API do Flash Player, que possam ser de
interesse dos desenvolvedores HTML, são descritas na Referência da Linguagem do Adobe AIR para
Desenvolvedores de HTML. ActionScript é a linguagem usada em conteúdo SWF (Flash Player). No entanto, as
sintaxes JavaScript e ActionScript são semelhantes. (ambas se baseiam nas versões da linguagem ECMAScript.)
Todas as classes incorporadas estão disponíveis em JavaScript (em conteúdo HTML) e ActionScript (em conteúdo
SWF).
Nota: O código JavaScript não pode usar as classes Dictionary, XML e XMLList, que estão disponíveis no
ActionScript.
Uso do arquivo AIRAliases.js
As classes de tempo de execução são organizadas em uma estrutura de pacote, da seguinte forma:
•
window.runtime.flash.desktop.NativeApplication
•
window.runtime.flash.desktop.ClipboardManager
•
window.runtime.flash.filesystem.FileStream
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 240
Programação em HTML e JavaScript
•
window.runtime.flash.data.SQLDatabase
No AIR SDK está incluído o arquivo AIRAliases.js que oferece definições de "alias" que permitem acessar as classes
de tempo de execução com menos digitação. Por exemplo, você pode acessar as classes listadas acima, bastando,
para isso, digitar o seguinte:
•
air.NativeApplication
•
air.Clipboard
•
air.FileStream
•
air.SQLDatabase
A lista é apenas um pequeno subconjunto das classes no arquivo AIRAliases.js. A lista completa de classes e funções
em nível de pacote é fornecida na Referência da Linguagem do Adobe AIR para Desenvolvedores de HTML.
Além das classes de tempo de execução usadas normalmente, o arquivo AIRAliases.js inclui alias para as funções
em nível do pacote usadas com mais freqüência. window.runtime.trace(),
window.runtime.flash.net.navigateToURL() e window.runtime.flash.net.sendToURL(), com alias
air.trace(), air.navigateToURL() e air.sendToURL().
Para usar o arquivo AIRAliases.js, inclua a seguinte referência de script em sua página HTML:
<script src="AIRAliases.js"></script>
Ajuste o caminho na referência src, conforme necessário.
Importante: Exceto quando observado, o código de exemplo JavaScript nesta documentação pressupõe que você
incluiu o arquivo AIRAliases.js em sua página HTML.
Sobre URLs no AIR
No conteúdo HTML em execução no AIR, você pode usar qualquer um dos seguintes esquemas de URL na definição
de atributos src para img, frame, iframe e tags de script, no atributo href de uma tag link ou qualquer outro local
que você possa fornecer uma URL.
esquema de URL Descrição
Exemplo
file
Um caminho relativo à raiz do sistema de arquivos.
file:///c:/AIR Test/test.txt
app
Um caminho relativo à raiz do diretório do aplicativo
instalado.
app:/images
app-storage
Um caminho relativo ao diretório de armazenamento do
aplicativo. Para cada aplicativo instalado, o AIR define um
diretório exclusivo de armazenamento do aplicativo, que é
um local útil para armazenar dados específicos desse
aplicativo.
app-storage:/settings/prefs.xml
http
Uma solicitação HTTP padrão.
http://www.adobe.com
https
Uma solicitação HTTPS padrão.
https://secure.example.com
Para obter mais informações sobre o uso de esquemas de URL no AIR, consulte “Uso de esquemas de URL do AIR em
URLs” na página 306.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 241
Programação em HTML e JavaScript
Muitas das APIs do AIR, incluindo as classes File, Loader, URLStream e Sound, usam um objeto URLRequest em vez
de uma string contendo a URL. O próprio objeto URLRequest é inicializado com uma string, que pode usar qualquer
um dos mesmos esquemas de URL. Por exemplo, a seguinte instrução cria um objeto URLRequest que pode ser usado
para solicitar a home page da Adobe:
var urlReq = new air.URLRequest("http://www.adobe.com/");
Para obter informações sobre objetos URLRequest, consulte “Solicitações de URL e rede” na página 305.
Como tornar objetos ActionScript disponíveis para
JavaScript
O JavaScript na página HTML carregada pelo objeto HTMLLoader pode chamar as classes, os objetos e as funções
definidas no contexto de execução do ActionScript, usando as propriedades window.runtime, window.htmlLoader
e window.nativeWindow da página HTML. Você também pode tornar objetos e funções ActionScript disponíveis
para código JavaScript, criando referências para eles no contexto de execução do JavaScript.
Um exemplo básico de como acessar objetos JavaScript do ActionScript
O seguinte exemplo ilustra como adicionar propriedades que fazem referência a objetos ActionScript ao objeto
window global de uma página HTML.
var html:HTMLLoader = new HTMLLoader();
var foo:String = "Hello from container SWF."
function helloFromJS(message:String):void {
trace("JavaScript says:", message);
}
var urlReq:URLRequest = new URLRequest("test.html");
html.addEventListener(Event.COMPLETE, loaded);
html.load(urlReq);
function loaded(e:Event):void{
html.window.foo = foo;
html.window.helloFromJS = helloFromJS;
}
O conteúdo HTML (no arquivo chamado test.html), carregado no objeto HTMLLoader no exemplo anterior, pode
acessar a propriedade foo e o método helloFromJS() definidos no arquivo SWF pai:
<html>
<script>
function alertFoo() {
alert(foo);
}
</script>
<body>
<button onClick="alertFoo()">
What is foo?
</button>
<p><button onClick="helloFromJS('Hi.')">
Call helloFromJS() function.
</button></p>
</body>
</html>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 242
Programação em HTML e JavaScript
Ao acessar o contexto JavaScript de um documento que está sendo carregado, você pode usar o evento
htmlDOMInitialize para criar objetos na seqüência de construção da página, cedo o bastante para que qualquer
script definido na página possa acessá-los. Se você aguardar o evento complete, somente scripts da página executados
depois do evento load da página poderão acessar os objetos adicionados.
Como tornar as definições de classe disponíveis para JavaScript
Para disponibilizar as classes ActionScript do aplicativo em JavaScript, você pode atribuir o conteúdo HTML
carregado ao domínio de aplicativo que contém as definições de classe. O domínio de aplicativo do contexto de
execução do JavaScript pode ser definido com a propriedade runtimeApplicationDomain do objeto HTMLLoader.
Para definir o domínio de aplicativo como domínio de aplicativo primário, por exemplo, defina
runtimeApplicationDomain como ApplicationDomain.currentDomain, conforme mostra o código a seguir:
html.runtimeApplicationDomain = ApplicationDomain.currentDomain;
Depois que a propriedade runtimeApplicationDomain for definida, o contexto JavaScript compartilha as definições
de classe com o domínio atribuído. Para criar uma ocorrência de classe personalizada em JavaScript, faça referência à
definição de classe por meio da propriedade window.runtime e use o operador novo:
var customClassObject = new window.runtime.CustomClass();
O conteúdo HTML deve ser de um domínio de segurança compatível. Se o conteúdo HTML for de um domínio de
segurança diferente do domínio de aplicativo que você atribuir, em vez disso a página usará um domínio de aplicativo
padrão. Por exemplo, se você carregar uma página remota da Internet, não poderá atribuir
ApplicationDomain.currentDomain como domínio de aplicativo da página.
Remoção de ouvintes de eventos
Quando você adiciona ouvintes de eventos JavaScript a objetos fora da página atual, incluindo objetos de tempo de
execução, objetos no conteúdo SWF carregado e até objetos JavaScript em execução em outras páginas, deve sempre
remover esses ouvintes de eventos quando a página for descarregada. Do contrário, o ouvinte de evento despacha o
evento para uma função do manipulador que não existe mais. Se isso acontecer, você verá a seguinte mensagem de
erro: "O aplicativo tentou fazer referência a um objeto JavaScript em uma página HTML que não é mais carregada". A
remoção de ouvintes de eventos desnecessários também permite que o AIR recupere a memória associada. Para obter
mais informações, consulte “Remoção de ouvintes de eventos nas páginas HTML que navegam” na página 256.
Acesso a objetos HTML DOM e JavaScript do
ActionScript
Após o objeto HTMLLoader despachar o evento complete, você poderá acessar todos os objetos no HTML DOM
(modelo de objeto de documento) da página. Os objetos acessíveis incluem os elementos de exibição (como os objetos
div e p na página), bem como as variáveis e funções JavaScript. O evento complete corresponde ao evento load da
página em JavaScript. Antes que complete seja despachado, os elementos DOM, as variáveis e as funções poderão não
ter sido analisados nem criados. Se possível, aguarde o evento complete antes de acessar o HTML DOM.
Por exemplo, considere a seguinte página HTML:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 243
Programação em HTML e JavaScript
<html>
<script>
foo = 333;
function test() {
return "OK.";
}
</script>
<body>
<p id="p1">Hi.</p>
</body>
</html>
Essa página HTML simples define uma variável JavaScript chamada foo e uma função JavaScript chamada test(). As
duas propriedades são propriedades do objeto window global da página. Além disso, o objeto window.document inclui
um elemento chamado P (com a ID p1), que você pode acessar usando o método getElementById(). Depois que a
página for carregada (quando o objeto HTMLLoader despachar o evento complete), você poderá acessar cada um
desses objetos do ActionScript, conforme mostra o seguinte código ActionScript:
var html:HTMLLoader = new HTMLLoader();
html.width = 300;
html.height = 300;
html.addEventListener(Event.COMPLETE, completeHandler);
var xhtml:XML =
<html>
<script>
foo = 333;
function test() {
return "OK.";
}
</script>
<body>
<p id="p1">Hi.</p>
</body>
</html>;
html.loadString(xhtml.toString());
function completeHandler(e:Event):void {
trace(html.window.foo); // 333
trace(html.window.document.getElementById("p1").innerHTML); // Hi.
trace(html.window.test()); // OK.
}
Para acessar o conteúdo de um elemento HTML, use a propriedade innerHTML. Por exemplo, o código anterior usa
html.window.document.getElementById("p1").innerHTML para obter o conteúdo do elemento HTML chamado p1.
Você também pode definir propriedades da página HTML do ActionScript. Por exemplo, o seguinte exemplo define
o conteúdo do elemento p1 e o valor da variável JavaScript foo na página, usando uma referência ao objeto
HTMLLoader que a contém:
html.window.document.getElementById("p1").innerHTML = "Goodbye";
html.window.foo = 66;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 244
Programação em HTML e JavaScript
Incorporação de conteúdo SWF em HTML
Você pode incorporar o conteúdo SWF em um conteúdo HTML do aplicativo AIR da mesma forma que em um
navegador. Incorpore o conteúdo SWF usando a tag object, a tag embed ou as duas.
Nota: Uma prática comum de desenvolvimento é usar tanto uma tag object quanto uma tag embed para exibir
conteúdo SWF em uma página HTML. Essa prática não tem nenhum benefício no AIR. Você pode usar a própria tag
object padrão W3C no conteúdo para ser exibido no AIR. Ao mesmo tempo, você pode continuar usando as tags
object e embed juntas, se necessário, para conteúdo HTML exibido também no navegador.
O seguinte exemplo ilustra o uso da tag object HTML para exibir um arquivo SWF no conteúdo HTML. O arquivo
SWF é carregado do diretório do aplicativo, mas você pode usar qualquer um dos esquemas de URL suportados pelo
AIR. (O local do qual o arquivo SWF é carregado determina a caixa de proteção de segurança em que o AIR coloca o
conteúdo.)
<object type="application/x-shockwave-flash" width="100%" height="100%">
<param name="movie" value="app:/SWFFile.swf"></param>
</object>
Você também pode usar um script para carregar conteúdo dinamicamente. O seguinte exemplo cria um nó object
para exibir o arquivo SWF especificado no parâmetro urlString. O exemplo adiciona o nó como filho do elemento
de página com a ID especificada pelo parâmetro elementID:
<script>
function showSWF(urlString, elementID){
var displayContainer = document.getElementById(elementID);
displayContainer.appendChild(createSWFObject(urlString,650,650));
}
function createSWFObject(urlString, width, height){
var SWFObject = document.createElement("object");
SWFObject.setAttribute("type","application/x-shockwave-flash");
SWFObject.setAttribute("width","100%");
SWFObject.setAttribute("height","100%");
var movieParam = document.createElement("param");
movieParam.setAttribute("name","movie");
movieParam.setAttribute("value",urlString);
SWFObject.appendChild(movieParam);
return SWFObject;
}
</script>
Uso de bibliotecas do ActionScript em uma página
HTML
O AIR estende o elemento de script HTML para que a página possa importar classes ActionScript em um arquivo SWF
compilado. Por exemplo, para importar uma biblioteca chamada myClasses.swf, localizada no subdiretório lib da
pasta raiz do aplicativo, inclua a seguinte tag de script no arquivo HTML:
<script src="lib/myClasses.swf" type="application/x-shockwave-flash"></script>
Importante: O atributo de tipo deve ser type="application/x-shockwave-flash" para que a biblioteca seja
carregada corretamente.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 245
Programação em HTML e JavaScript
Se o conteúdo SWF for compilado como Flash Player 10 ou AIR 1.5 SWF, você deverá definir o namespace do descritor
do aplicativo como espaço para nome do AIR 1.5. Para obter mais informações, consulte “Definição de propriedades
no arquivo do descritor do aplicativo” na página 45.
O diretório lib e o arquivo myClasses.swf também deve ser incluído quando o arquivo AIR for empacotado.
Acesse as classes importadas por meio da propriedade runtime do objeto da janela JavaScript:
var libraryObject = new window.runtime.LibraryClass();
Se as classes no arquivo SWF estiverem organizadas em pacotes, você também deverá incluir o nome do pacote. Por
exemplo, se a definição LibraryClass estivesse em um pacote chamado utilities, você deveria criar uma ocorrência da
classe com a seguinte instrução:
var libraryObject = new window.runtime.utilities.LibraryClass();
Nota: Para compilar uma biblioteca SWF do ActionScript para usar como parte da página HTML no AIR, use o
compilador acompc. O utilitário acompc é parte do Flex 3 SDK e está descrito na Documentação do Flex 3 SDK.
Acesso aos objetos HTML DOM e JavaScript de um arquivo ActionScript
importado
Para acessar objetos em uma página HTML do ActionScript em um arquivo SWF importado na página usando a tag
<script>, passe uma referência para um objeto JavaScript, como window ou document, em uma função definida no
código do ActionScript. Use a referência na função para acessar o objeto JavaScript (ou outros objetos acessíveis por
meio da referência passada).
Por exemplo, considere a seguinte página HTML:
<html>
<script src="ASLibrary.swf" type="application/x-shockwave-flash"></script>
<script>
num = 254;
function getStatus() {
return "OK.";
}
function runASFunction(window){
var obj = new runtime.ASClass();
obj.accessDOM(window);
}
</script>
<body onload="runASFunction">
<p id="p1">Body text.</p>
</body>
</html>
Essa página HTML simples tem uma variável JavaScript chamada num e uma função JavaScript chamada getStatus().
As duas propriedades são propriedades do objeto window da página. Além disso, o objeto window.document inclui
um elemento chamado P (com a ID p1).
A página carrega o arquivo ActionScript, "ASLibrary.swf," que contém a classe ASClass. A ASClass define a função
chamada accessDOM() que simplesmente rastreia os valores desses objetos JavaScript. O método accessDOM()
considera o objeto de janela JavaScript como um argumento. Ao usar essa referência de janela, ele pode acessar outros
objetos na página, incluindo variáveis, funções e elementos DOM, conforme ilustrado na definição a seguir:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 246
Programação em HTML e JavaScript
public class ASClass{
public function accessDOM(window:*):void {
trace(window.num); // 254
trace(window.document.getElementById("p1").innerHTML); // Body text..
trace(window.getStatus()); // OK.
}
}
Você pode obter e definir propriedades da página HTML de uma classe ActionScript importada. Por exemplo, a
seguinte função define o conteúdo do elemento p1 na página e define o valor da variável de JavaScript foo na página:
public function modifyDOM(window:*):void {
window.document.getElementById("p1").innerHTML = "Bye";
window.foo = 66;
Conversão de objetos Date e RegExp
As linguagens JavaScript e ActionScript definem as classes Date e RegExp, mas os objetos desses tipos não são
convertidos automaticamente entre os dois contextos de execução. Você deve converter os objetos Date e RegExp para
o tipo equivalente antes de usá-los para definir parâmetros de propriedades ou funções no contexto de execução
alternativo.
Por exemplo, o seguinte código ActionScript converte o objeto Date de JavaScript chamado jsDate em um objeto
Date do ActionScript:
var asDate:Date = new Date(jsDate.getMilliseconds());
Por exemplo, o seguinte código ActionScript converte o objeto RegExp de JavaScript chamado jsRegExp em um
objeto RegExp do ActionScript:
var flags:String = "";
if (jsRegExp.dotAll) flags += "s";
if (jsRegExp.extended) flags += "x";
if (jsRegExp.global) flags += "g";
if (jsRegExp.ignoreCase) flags += "i";
if (jsRegExp.multiline) flags += "m";
var asRegExp:RegExp = new RegExp(jsRegExp.source, flags);
Manipulação de folha de estilos HTML do ActionScript
Depois que o objeto HTMLLoader tiver despachado o evento complete, você poderá examinar e manipular estilos
CSS na página.
Por exemplo, considere o seguinte documento HTML simples:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 247
Programação em HTML e JavaScript
<html>
<style>
.style1A { font-family:Arial; font-size:12px }
.style1B { font-family:Arial; font-size:24px }
</style>
<style>
.style2 { font-family:Arial; font-size:12px }
</style>
<body>
<p class="style1A">
Style 1A
</p>
<p class="style1B">
Style 1B
</p>
<p class="style2">
Style 2
</p>
</body>
</html>
Depois que o objeto HTMLLoader carregar esse conteúdo, você poderá manipular os estilos CSS da página, através da
matriz cssRules da matriz window.document.styleSheets, como mostrado a seguir:
var html:HTMLLoader = new HTMLLoader( );
var urlReq:URLRequest = new URLRequest("test.html");
html.load(urlReq);
html.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void {
var styleSheet0:Object = html.window.document.styleSheets[0];
styleSheet0.cssRules[0].style.fontSize = "32px";
styleSheet0.cssRules[1].style.color = "#FF0000";
var styleSheet1:Object = html.window.document.styleSheets[1];
styleSheet1.cssRules[0].style.color = "blue";
styleSheet1.cssRules[0].style.font-family = "Monaco";
}
Esse código ajusta os estilos CSS para que o documento HTML resultante tenha a seguinte aparência:
Lembre-se de que esse código pode adicionar estilos à página após o objeto HTMLLoader despachar o evento
complete.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 248
Programação em HTML e JavaScript
Conteúdo entre scripts em caixas de proteção de
segurança distintas
O modelo de segurança de tempo de execução isola o código de origens distintas. Cruzando scripts de conteúdo em
caixas de proteção de segurança distintas, você pode permitir que o conteúdo de uma caixa de proteção de segurança
acesse as propriedades e os métodos selecionados em outra caixa de proteção.
Caixas de proteção de segurança do AIR e código JavaScript
O AIR aplica a política de mesma origem, que impede a interação de código de um domínio com o conteúdo de outro
domínio. Todos os arquivos são colocados em uma caixa de proteção com base nas respectivas origens. Normalmente,
o conteúdo na caixa de proteção do aplicativo não pode violar o princípio de mesma origem e o conteúdo entre scripts,
carregado de fora do diretório de instalação do aplicativo. No entanto, o AIR oferece algumas técnicas que permitem
o cruzamento de scripts em conteúdo "não aplicativo".
Uma das técnicas usa frames ou iframes para mapear conteúdo de aplicativo em uma caixa de proteção de segurança
distinta. Qualquer página carregada da área com caixa de proteção do aplicativo se comporta como se tivesse sido
carregada do domínio remoto. Por exemplo, mapeando o conteúdo do aplicativo para o domínio example.com, esse
conteúdo pode fazer o cruzamento entre scripts das páginas carregadas desse domínio.
Como essa técnica coloca o conteúdo do aplicativo em uma caixa de proteção distinta, o código nesse conteúdo
também não estará mais sujeito às restrições na execução de código em strings avaliadas. Você pode usar essa técnica
de mapeamento de caixa de proteção para para atenuar essas restrições, mesmo quando não for necessário fazer o
cruzamento de scripts de conteúdo remoto. Mapear conteúdo dessa maneira pode ser muito útil ao trabalhar com uma
das várias estruturas JavaScript ou com código existente que dependa das strings de avaliação. No entanto, você deve
considerar e se proteger contra o risco adicional de que algum conteúdo não confiável possa ser injetado e executado
quando o conteúdo for executado fora da caixa de proteção do aplicativo.
Ao mesmo tempo, o conteúdo de aplicativo mapeado para uma outra caixa de proteção perde o acesso às APIs do AIR,
portanto, a técnica de mapeamento de caixa de proteção não pode ser usada para expor a funcionalidade do AIR ao
código executado fora da caixa de proteção do aplicativo.
Outra técnica de cruzamento de scripts permite criar uma interface chamada ponte de caixa de proteção entre o
conteúdo de uma caixa de proteção "não aplicativo" e seu documento pai na caixa de proteção do aplicativo. A ponte
permite que o conteúdo filho acesse as propriedades e os métodos definidos pelo pai e o pai acesse as propriedades e
os métodos definidos pelo filho, ou ambos.
Por fim, você também pode executar XMLHttpRequests entre domínios da caixa de proteção do aplicativo e,
opcionalmente, de outras caixas de proteção.
Para obter mais informações, consulte “Elementos HTML frame e iframe” na página 227, “segurança HTML” na
página 30 e “O objeto XMLHttpRequest” na página 221.
Carregamento de conteúdo do aplicativo em uma caixa de proteção "não
aplicativo"
Para permitir que o conteúdo do aplicativo faça cruzamento de script de conteúdo carregado de fora do diretório de
instalação do aplicativo, você pode usar os elementos frame ou iframe para carregar conteúdo do aplicativo na
mesma caixa de proteção de segurança do conteúdo externo. Se você não precisa fazer cruzamento de script de
conteúdo remoto, mas ainda assim deseja carregar uma página do seu aplicativo fora da respectiva caixa de proteção,
pode usar a mesma técnica, especificando http://localhost/ ou algum outro valor inócuo, como o domínio de
origem.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 249
Programação em HTML e JavaScript
O AIR adiciona os novos atributos sandboxRoot e documentRoot ao elemento frame que permite especificar se o
arquivo do aplicativo carregado no frame deve ser mapeado para uma caixa de proteção "não aplicativo". Arquivos que
estão sendo resolvidos em um caminho abaixo da URL sandboxRoot são carregados, em vez do diretório
documentRoot. Para fins de segurança, o conteúdo do aplicativo carregado dessa maneira é tratado como se na
verdade tivesse sido carregado da URL sandboxRoot.
A propriedade sandboxRoot especifica a URL que deve ser usada para determinar a caixa de proteção e o domínio em
que o conteúdo do quadro deve ser colocado. Os esquemas de URL file:, http: ou https: devem ser usados. Se
você especificar uma URL relativa, o conteúdo permanecerá na caixa de proteção do aplicativo.
A propriedade documentRoot especifica o diretório do qual o conteúdo do quadro deve ser carregado. Os esquemas
de URL file:, app: ou app-storage: devem ser usados.
O exemplo a seguir mapeia o conteúdo instalado no subdiretório sandbox do aplicativo a ser executado na caixa de
proteção remota e o domínio www.example.com:
<iframe
src="http://www.example.com/local/ui.html"
sandboxRoot="http://www.example.com/local/"
documentRoot="app:/sandbox/">
</iframe>
A página ui.html pode carregar um arquivo javascript da pasta sandbox local, usando a seguinte tag de script:
<script src="http://www.example.com/local/ui.js"></script>
Ele também pode carregar conteúdo de um diretório no servidor remoto usando uma tag de script como a que segue:
<script src="http://www.example.com/remote/remote.js"></script>
A URL sandboxRoot irá mascarar todo conteúdo na mesma URL do servidor remoto. No exemplo anterior, você não
podia acessar nenhum conteúdo remoto em www.example.com/local/ (ou qualquer um de seus subdiretórios), pois
o AIR remapeia a solicitação para o diretório local do aplicativo. As solicitações são remapeadas, sejam elas derivadas
de navegação de página, de uma XMLHttpRequest ou de qualquer outro meio de carregamento de conteúdo.
Configuração de interface de ponte de caixa de proteção
Você pode usar uma ponte de caixa de proteção quando o conteúdo da caixa de proteção do aplicativo tiver que acessar
propriedades ou métodos definidos pelo conteúdo em uma caixa de proteção "não aplicativo" , ou quando o conteúdo
"não aplicativo" tiver que acessar propriedades e métodos definidos pelo conteúdo na caixa de proteção do aplicativo.
Crie uma ponte com as propriedades childSandboxBridge e parentSandboxBridge do objeto window de algum
documento filho.
Estabelecimento de uma ponte de caixa de proteção filha
A propriedade childSandboxBridge permite que o documento filho exponha uma interface para o conteúdo do
documento pai. Para expor uma interface, você define a propriedade childSandbox como função ou objeto no
documento filho. Em seguida, você pode acessar o objeto ou função do conteúdo no documento pai. O exemplo a
seguir mostra como um script que está sendo executado em um documento filho pode expor um objeto contendo uma
função e uma propriedade para o respectivo pai:
var interface = {};
interface.calculatePrice = function(){
return ".45 cents";
}
interface.storeID = "abc"
window.childSandboxBridge = interface;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 250
Programação em HTML e JavaScript
Se esse filho foi carregado em um iframe com id "filho" atribuída, você poderá acessar a interface do conteúdo pai,
lendo a propriedade childSandboxBridge do quadro:
var childInterface = document.getElementById("child").contentWindow.childSandboxBridge;
air.trace(childInterface.calculatePrice()); //traces ".45 cents"
air.trace(childInterface.storeID)); //traces "abc"
Estabelecimento de uma ponte de caixa de proteção pai
A propriedade parentSandboxBridge permite que o documento pai exponha uma interface para o conteúdo do
documento filho. Para expor uma interface, o documento pai define a propriedade parentSandbox do documento
filho como uma função ou objeto definido no documento pai. Em seguida, você pode acessar o objeto ou função do
conteúdo no filho. O exemplo a seguir mostra como um script que está sendo executado em um quadro pai pode expor
um objeto contendo uma função para um documento filho:
var interface = {};
interface.save = function(text){
var saveFile = air.File("app-storage:/save.txt");
//write text to file
}
document.getElementById("child").contentWindow.parentSandboxBridge = interface;
Ao usar essa interface, o conteúdo do quadro filho poderá salvar texto em um arquivo chamado save.txt, mas não
terá nenhum outro acesso ao sistema de arquivos. O conteúdo filho poderá chamar a função save da seguinte maneira:
var textToSave = "A string.";
window.parentSandboxBridge.save(textToSave);
O conteúdo do aplicativo deverá expor a interface mais estreita possível para as outras caixas de proteção. O conteúdo
"não aplicativo" deve ser considerado não confiável inerentemente, já que ele pode estar sujeito à injeção de código
acidental ou mal-intencionado. Você deve colocar as proteções apropriadas no local para impedir o uso inadequado
da interface exposta através da ponte da caixa de proteção pai.
Acesso à ponte de caixa de proteção pai durante o carregamento de página
Para que o script de um documento filho acesse uma ponte de caixa de proteção pai, a ponte deve ser configurada antes
que o script seja executado. Os objetos window, frame e iframe despacham o evento dominitialize quando uma
nova página DOM tiver sido criada, mas antes que qualquer script tenha sido analisado ou que elementos DOM
tenham sido adicionados. Você pode usar o evento dominitialize para estabelecer a ponte na seqüência de
construção de página, cedo o bastante para que todos os scripts no documento filho possam acessá-la.
O exemplo a seguir ilustra como criar uma ponte de caixa de proteção pai em resposta ao evento dominitialize
despachado do quadro filho:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 251
Programação em HTML e JavaScript
<html>
<head>
<script>
var bridgeInterface = {};
bridgeInterface.testProperty = "Bridge engaged";
function engageBridge(){
document.getElementById("sandbox").contentWindow.parentSandboxBridge = bridgeInterface;
}
</script>
</head>
<body>
<iframe id="sandbox"
src="http://www.example.com/air/child.html"
documentRoot="app:/"
sandboxRoot="http://www.example.com/air/"
ondominitialize="engageBridge()"/>
</body>
</html>
O seguinte documento child.html ilustra como o conteúdo filho pode acessar a ponte de caixa de proteção pai:
<html>
<head>
<script>
document.write(window.parentSandboxBridge.testProperty);
</script>
</head>
<body></body>
</html>
Para ouvir o evento dominitialize em uma janela filha, em vez de um quadro, você deve adicionar o ouvinte ao novo
objeto window filho criado pela função window.open():
var childWindow = window.open();
childWindow.addEventListener("dominitialize", engageBridge());
childWindow.document.location = "http://www.example.com/air/child.html";
Nesse caso, não há como mapear o conteúdo do aplicativo para uma caixa de proteção "não aplicativo". Essa técnica
só é útil quando child.html é carregado de fora do diretório do aplicativo. Você pode ainda mapear conteúdo do
aplicativo na janela para uma caixa de proteção "não aplicativo", mas primeiramente, é preciso carregar uma página
intermediária que use ela mesma quadros para carregar o documento filho e mapeá-lo para a caixa de proteção
desejada.
Se você usar a função createRootWindow() da classe HTMLLoader para criar uma janela, a nova janela não será filha
do documento do qual createRootWindow() será chamado. Portanto, você não pode criar uma ponte de caixa de
proteção da janela que faz a chamada para um conteúdo "não aplicativo" carregado na nova janela. Em vez disso, você
deve carregar uma página intermediária na nova janela que use ela mesma quadros para carregar o documento filho.
Em seguida, você pode estabelecer a ponte do documento pai da nova janela para o documento filho carregado no
quadro.
252
Capítulo 22: Tratamento de eventos
relacionados a HTML
O sistema de tratamento de eventos permite que programadores respondam às entradas de usuários e eventos do
sistema de forma conveniente. O modelo de evento do Adobe® AIR™ não é apenas conveniente, mas também
compatível com os padrões. Com base na Especificação de eventos DOM (Modelo de objeto de documento) de Nível
3, uma arquitetura de tratamento de eventos padrão do segmento, o modelo de evento oferece uma ferramenta de
tratamento de eventos eficiente e intuitiva para programadores.
eventos HTMLLoader
O objeto HTMLLoader despacha os seguintes eventos do Adobe® ActionScript®3.0:
Evento
Descrição
htmlDOMInitialize
Despachado quando o documento HTML é criado, mas antes que qualquer script seja
analisado ou que os nós DOM sejam adicionados à página.
complete
Despachado quando o HTML DOM tiver sido criado em resposta à operação de
carregamento, logo após o evento onload na página HTML.
htmlBoundsChanged
Despachado quando uma ou as duas propriedades contentWidth e
contentHeight são alteradas.
locationChange
Despachado quando a propriedade location do HTMLLoader foi alterada.
scroll
Despachado a sempre que o mecanismo HTML altera a posição de rolagem. Eventos
de rolagem podem ocorrer devido à navegação para ancorar links (nº de links) na
página ou devido às chamadas do métodowindow.scrollTo(). Inserir texto em
uma entrada de texto ou área de texto também pode gerar um evento de rolagem.
uncaughtScriptException
Despachado quando ocorre uma exceção JavaScript no HTMLLoader e a exceção não
é capturada no código JavaScript.
Você também pode registrar uma função ActionScript para o evento JavaScript (como onClick). Para obter detalhes,
consulte “Tratamento de eventos DOM com o ActionScript” na página 252.
Tratamento de eventos DOM com o ActionScript
Você pode registrar as funções do ActionScript para que respondam a eventos JavaScript. Por exemplo, considere o
seguinte conteúdo HTML:
<html>
<body>
<a href="#" id="testLink">Click me.</a>
</html>
Você pode registrar uma função do ActionScript como manipulador de qualquer evento na página. Por exemplo, o
código a seguir adiciona a função clickHandler() como o ouvinte do evento onclick do elemento testLink na
página HTML:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 253
Tratamento de eventos relacionados a HTML
var html:HTMLLoader = new HTMLLoader( );
var urlReq:URLRequest = new URLRequest("test.html");
html.load(urlReq);
html.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void {
html.window.document.getElementById("testLink").onclick = clickHandler;
}
function clickHandler():void {
trace("You clicked it!");
}
Você também pode usar o método addEventListener() para se registrar para esses eventos. Por exemplo, você pode
substituir o método completeHandler() no exemplo anterior pelo seguinte código:
function completeHandler(event:Event):void {
var testLink:Object = html.window.document.getElementById("testLink");
testLink.addEventListener("click", clickHandler);
}
Quando um ouvinte se refere a um elemento DOM específico, é bom aguardar que o HTMLLoader pai despache o
evento complete antes de adicionar os ouvintes de evento. As páginas HTML com freqüência carregam vários
arquivos e o HTML DOM não é criado totalmente até que todos os arquivos sejam carregados e analisados. O
HTMLLoader despacha o evento complete quando todos os elementos tiverem sido criados.
Resposta a exceções JavaScript não capturadas
Considere o seguinte HTML:
<html>
<head>
<script>
function throwError() {
var x = 400 * melbaToast;
}
</script>
</head>
<body>
<a href="#" onclick="throwError()">Click me.</a>
</html>
Ele contém uma função JavaScript, throwError(), que faz referência a uma variável desconhecida, melbaToast:
var x = 400 * melbaToast;
Quando a operação de JavaScript encontra uma operação ilegal não capturada no código JavaScript com uma estrutura
try/catch, o objeto HTMLLoader que contém a página despacha um evento HTMLUncaughtScriptExceptionEvent.
Você pode registrar um manipulador para esse evento, como no código a seguir:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 254
Tratamento de eventos relacionados a HTML
var html:HTMLLoader = new HTMLLoader();
var urlReq:URLRequest = new URLRequest("test.html");
html.load(urlReq);
html.width = container.width;
html.height = container.height;
container.addChild(html);
html.addEventListener(HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION,
htmlErrorHandler);
function htmlErrorHandler(event:HTMLUncaughtJavaScriptExceptionEvent):void
{
event.preventDefault();
trace("exceptionValue:", event.exceptionValue)
for (var i:int = 0; i < event.stackTrace.length; i++)
{
trace("sourceURL:", event.stackTrace[i].sourceURL);
trace("line:", event.stackTrace[i].line);
trace("function:", event.stackTrace[i].functionName);
}
}
No JavaScript, você pode tratar o mesmo evento usando a propriedade window.htmlLoader:
<html>
<head>
<script language="javascript" type="text/javascript" src="AIRAliases.js"></script>
<script>
function throwError() {
var x = 400 * melbaToast;
}
function htmlErrorHandler(event) {
event.preventDefault();
var message = "exceptionValue:" + event.exceptionValue + "\n";
for (var i = 0; i < event.stackTrace.length; i++){
message += "sourceURL:" + event.stackTrace[i].sourceURL +"\n";
message += "line:" + event.stackTrace[i].line +"\n";
message += "function:" + event.stackTrace[i].functionName + "\n";
}
alert(message);
}
window.htmlLoader.addEventListener("uncaughtScriptException", htmlErrorHandler);
</script>
</head>
<body>
<a href="#" onclick="throwError()">Click me.</a>
</html>
O manipulador de eventos htmlErrorHandler() cancela o comportamento padrão do evento (que é enviar a
mensagem de erro de JavaScript para a saída trace do AIR) e gera sua própria mensagem de saída. Ele produz o valor
do exceptionValue do objeto HTMLUncaughtScriptExceptionEvent. Ele produz as propriedades de cada objeto na
matriz stackTrace:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 255
Tratamento de eventos relacionados a HTML
exceptionValue: ReferenceError: Can't find variable: melbaToast
sourceURL: app:/test.html
line: 5
function: throwError
sourceURL: app:/test.html
line: 10
function: onclick
Tratamento de eventos de tempo de execução com
JavaScript
As classes de tempo de execução oferecem suporte à adição de manipuladores de eventos com o método
addEventListener(). Para adicionar uma função do manipulador a um evento, chame o método
addEventListener() do objeto que despacha o evento, fornecendo o tipo de evento e a função de tratamento. Por
exemplo, para ouvir o evento closing despachado quando o usuário clica no botão Fechar da janela na barra de título,
use a seguinte instrução:
window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing);
Criação de função do manipulador de eventos
O código a seguir cria um arquivo HTML simples que exibe informações sobre a posição da janela principal. A função
do manipulador, chamada de moveHandler(), ouve o evento move (definido pela classe
NativeWindowBoundsEvent) da janela principal.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 256
Tratamento de eventos relacionados a HTML
<html>
<script src="AIRAliases.js" />
<script>
function init() {
writeValues();
window.nativeWindow.addEventListener(air.NativeWindowBoundsEvent.MOVE,
moveHandler);
}
function writeValues() {
document.getElementById("xText").value = window.nativeWindow.x;
document.getElementById("yText").value = window.nativeWindow.y;
}
function moveHandler(event) {
air.trace(event.type); // move
writeValues();
}
</script>
<body onload="init()" />
<table>
<tr>
<td>Window X:</td>
<td><textarea id="xText"></textarea></td>
</tr>
<tr>
<td>Window Y:</td>
<td><textarea id="yText"></textarea></td>
</tr>
</table>
</body>
</html>
Quando o usuário move a janela, os elementos da área de texto exibem as posições X e Y atualizadas da janela:
Observe que o objeto de evento é passado como argumento para o método moveHandler(). O parâmetro event
permite que a função do manipulador examine o objeto de evento. Neste exemplo, você usa a propriedade type do
objeto de evento para informar que o evento é um evento move.
Remoção de ouvintes de eventos
Você pode usar o método removeEventListener() para remover um ouvinte de evento que não seja mais necessário.
É uma boa idéia remover o ouvinte que não será mais usado. Entre os parâmetros obrigatórios estão eventName e
listener, que são os mesmos parâmetros obrigatórios no método addEventListener().
Remoção de ouvintes de eventos nas páginas HTML que navegam
Quando o conteúdo HTML é navegado ou quando é descartado porque a janela que o contém é fechada, os ouvintes
de eventos que fazem referência a objetos na página não carregada não são removidos automaticamente. Quando o
objeto despacha um evento para um manipulador que já foi descarregado, você obtém a seguinte mensagem de erro:
"O aplicativo tentou fazer referência a um objeto JavaScript em uma página HTML que não é mais carregada".
Para evitar esse tipo de erro, remova os ouvintes de eventos JavaScript da página HTML antes que ele parta. No caso
de navegação de página (em um objeto HTMLLoader), remova o ouvinte de evento durante o evento unload do objeto
window.
Por exemplo, o código JavaScript a seguir remove um ouvinte de evento de um evento uncaughtScriptException:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 257
Tratamento de eventos relacionados a HTML
window.onunload = cleanup;
window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException);
function cleanup()
{
window.htmlLoader.removeEventListener('uncaughtScriptException',
uncaughtScriptExceptionHandler);
}
Para impedir que o erro ocorra ao fechar janelas que contêm esse conteúdo HTML, chame uma função de limpeza em
resposta ao evento closing do objeto NativeWindow (window.nativeWindow). Por exemplo, o código JavaScript a
seguir remove um ouvinte de evento de um evento uncaughtScriptException:
window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup);
function cleanup()
{
window.htmlLoader.removeEventListener('uncaughtScriptException',
uncaughtScriptExceptionHandler);
}
Você também pode impedir que esse erro ocorra removendo o ouvinte de evento assim que ele for executado. Por
exemplo, o código JavaScript a seguir cria uma janela html chamando o método createRootWindow() da classe
HTMLLoader e adiciona um ouvinte de evento ao evento complete. Quando o manipulador de eventos complete é
chamado, ele remove o próprio ouvinte de evento usando a função removeEventListener():
var html = runtime.flash.html.HTMLLoader.createRootWindow(true);
html.addEventListener('complete', htmlCompleteListener);
function htmlCompleteListener()
{
html.removeEventListener(complete, arguments.callee)
// handler code..
}
html.load(new runtime.flash.net.URLRequest("second.html"));
Remover ouvintes de evento desnecessários também permite que o coletor de lixo do sistema recupere qualquer
memória associada a esses ouvintes.
Verificação de ouvintes de eventos existentes
O método hasEventListener() permite verificar a existência de um ouvinte de evento em um objeto.
258
Capítulo 23: Gravação de script de
contêiner HTML
A classe HTMLLoader funciona como o contêiner de conteúdo HTML no Adobe® AIR™. A classe oferece várias
propriedades e métodos, herdados da classe Sprite, para controlar o comportamento e a aparência do objeto na lista
de exibição do ActionScript® 3.0. Além disso, a classe define propriedades e métodos de tarefas, como carregamento
e interação com conteúdo HTML e gerenciamento de histórico.
A classe HTMLHost define um conjunto de comportamentos padrão de um HTMLLoader. Quando você cria um
objeto HTMLLoader, nenhuma implementação HTMLHost é fornecida. Portanto, quando o conteúdo HTML aciona
um dos comportamentos padrão, como alteração de localização da janela ou do título da janela, não acontece nada.
Você pode estender a classe HTMLHost para definir os comportamentos desejados para o aplicativo.
Uma implementação padrão do HTMLHost é fornecida para janelas HTML criadas pelo AIR. Você pode atribuir a
implementação HTMLHost padrão a outro objeto HTMLLoader definindo a propriedade htmlHost do objeto,
usando um novo objeto HTMLHost criado com o parâmetro defaultBehavior definido como true.
Exibição de propriedades de objetos HTMLLoader
O objeto HTMLLoader herda as propriedades de exibição da classe Sprite do Adobe® Flash® Player. Você pode
redimensionar, mover, ocultar e alterar a cor do plano de fundo, por exemplo. Ou, pode aplicar efeitos avançadas,
como filtros, máscaras, dimensionamento e rotação. Ao aplicar efeitos, considere o impacto sobre a legibilidade. O
conteúdo SWF e PDF carregado em uma página HTML não pode ser exibido quando alguns efeitos são aplicados.
As janelas HTML contêm um objeto HTMLLoader que processa conteúdo HTML. Esse objeto fica restrito dentro da
área da janela, portanto, alterar dimensões, posição, rotação ou fato de dimensionamento nem sempre produz os
resultados desejados.
Propriedades básicas de exibição
As propriedades básicas de exibição do HTMLLoader permitem posicionar o controle no respectivo objeto de exibição
pai para definir o tamanho e mostrar ou ocultar o controle. Você não deve alterar essas propriedades do objeto
HTMLLoader de uma janela HTML.
As propriedades básicas incluem:
Propriedade
Observações
x, y
Posiciona o objeto em seu contêiner pai.
width, height
Altera as dimensões da área de exibição.
visible
Controla a visibilidade do objeto e todo seu conteúdo.
Fora da janela HTML, as propriedades width e height do objeto HTMLLoader assumem o padrão 0. Você deve
definir a largura e a altura para que o conteúdo HTML carregado possa ser visualizado. O conteúdo HTML é
desenhado no tamanho do HTMLLoader, disposto de acordo com as propriedades HTML e CSS do conteúdo. Alterar
o tamanho do HTMLLoader redireciona o conteúdo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 259
Gravação de script de contêiner HTML
Ao carregar conteúdo em um novo objeto HTMLLoader (com width ainda definido como 0), pode ser tentador
definir width e height de exibição do HTMLLoader usando as propriedades contentWidth e contentHeight. Essa
técnica funciona em páginas com largura mínima razoável quando disposta de acordo com as regras de fluxo de
HTML e CSS. No entanto, algumas páginas resultam em um layout longo e estreito na ausência de uma largura
razoável fornecida pelo HTMLLoader.
Nota: Quando você altera a largura e a altura do objeto HTMLLoader, os valores scaleX e scaleY não são alterados, como
ocorreria com a maioria dos demais tipos de objetos de exibição.
Transparência de conteúdo HTMLLoader
A propriedade paintsDefaultBackground do objeto HTMLLoader, que é true por padrão, determina se o objeto
HTMLLoader desenha um plano de fundo opaco. Quando paintsDefaultBackground for false, o plano de fundo
ficará claro. O contêiner do objeto de exibição ou outros objetos de exibição abaixo do objeto HTMLLoader ficam
visíveis por trás dos elementos de primeiro plano do conteúdo HTML.
Se o elemento body ou qualquer outro elemento do documento HTML especificar uma cor de plano de fundo (usando
style="background-color:gray", por exemplo), o plano de fundo dessa parte do HTML ficará opaco e será
processado com a cor de plano de fundo especificada. Se você definir a propriedade opaqueBackground do objeto
HTMLLoader e paintsDefaultBackground for false, a cor definida para opaqueBackground ficará visível.
Nota: Você pode usar um gráfico com formato PNG transparente para dar ao elemento no documento HTML um plano
de fundo de mesclagem de alfa. Não há suporte para a configuração de estilo de opacidade de elemento HTML.
Dimensionamento de conteúdo HTMLLoader
Evite o dimensionamento do objeto HTMLLoader além do fator de dimensionamento de 1.0. O texto no conteúdo
HTMLLoader é processado em uma resolução específica e aparecerá pixelizado se o objeto HTMLLoader for
dimensionado. Para evitar que o HTMLLoader, bem como o respectivo conteúdo, sejam dimensionados quando a
janela for redimensionada, defina a propriedade scaleMode do Palco como StageScaleMode.NO_SCALE.
Considerações ao carregar conteúdo SWF ou PDF em uma página HTML
O conteúdo SWF e PDF carregado em um objeto HTMLLoader desaparece nas seguintes condições:
• Se você dimensionar o objeto HTMLLoader em um outro fator que não 1.0.
• Se você definir a propriedade alfa do objeto HTMLLoader em um outro valor que não 1.0.
• Se você girar o conteúdo HTMLLoader.
O conteúdo reaparecerá se você remover a configuração da propriedade ofensiva e os filtros ativos.
Nota: O tempo de execução não pode exibir conteúdo SWF ou PDF em janelas transparentes.
Para obter mais informações sobre o carregamento desses tipos de mídia no HTMLLoader, consulte “Incorporação de
conteúdo SWF em HTML” na página 244 e “Adição de conteúdo em PDF” na página 272.
Propriedades avançadas de exibição
A classe HTMLLoader herda vários métodos que podem ser usados em efeitos especiais. Em geral, esses efeitos têm
limitações quando usados com a exibição HTMLLoader, mas podem ser úteis em transições ou outros efeitos
temporários. Por exemplo, se você exibe uma janela de diálogo para coletar entradas de usuário, é possível desfocar a
exibição da janela principal até que o usuário feche a caixa de diálogo. Da mesma forma, você pode fazer a exibição
desaparecer gradualmente ao fechar uma janela.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 260
Gravação de script de contêiner HTML
As propriedades avançadas de exibição incluem:
Propriedade
Limitações
alpha
Pode reduzir a legibilidade do conteúdo HTML.
filters
Em uma Janela HTML, os efeitos exteriores são recortados pela borda da
janela.
graphics
As formas desenhadas com comandos gráficos aparecem abaixo do conteúdo
HTML, incluindo o plano de fundo padrão. A propriedade
paintsDefaultBackground deve ser false para que as formas do desenho
estejam visíveis.
opaqueBackground
Não altera a cor do plano de fundo padrão. A propriedade
paintsDefaultBackground deve ser false para que essa camada de cor esteja
visível.
rotation
Os cantos da área retangular do HTMLLoader podem ser recortados pela
borda da janela. O conteúdo SWF e PDF carregado no conteúdo HTML não é
exibido.
scaleX e scaleY
A exibição processada pode aparecer pixelizada em fatores de
dimensionamento maiores que 1. O conteúdo SWF e PDF carregado no
conteúdo HTML não é exibido.
transform
Pode reduzir a legibilidade do conteúdo HTML. A exibição HTML pode ser
recortada pela borda da janela. O conteúdo SWF e PDF carregado no
conteúdo HTML não será exibido se a transformação envolver rotação,
dimensionamento ou inclinação.
O exemplo a seguir ilustra como definir a matriz filters para desfocar a exibição HTML inteira:
var html:HTMLLoader = new HTMLLoader();
var urlReq:URLRequest = new URLRequest("http://www.adobe.com/");
html.load(urlReq);
html.width = 800;
html.height = 600;
var blur:BlurFilter = new BlurFilter(8);
var filters:Array = [blur];
html.filters = filters;
Rolagem de conteúdo HTML
A classe HTMLLoader inclui as seguintes propriedades que permitem controlar a rolagem de conteúdo HTML:
Propriedade
Descrição
contentHeight
A altura, em pixels, do conteúdo HTML.
contentWidth
A largura, em pixels, do conteúdo HTML.
scrollH
A posição da barra de rolagem horizontal do conteúdo HTML no objeto HTMLLoader.
scrollV
A posição da barra de rolagem vertical do conteúdo HTML no objeto HTMLLoader.
O código a seguir define a propriedade scrollV, de modo que o conteúdo HTML seja rolado para a parte inferior da
página:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 261
Gravação de script de contêiner HTML
var html:HTMLLoader = new HTMLLoader();
html.addEventListener(Event.HTML_BOUNDS_CHANGE, scrollHTML);
const SIZE:Number = 600;
html.width = SIZE;
html.height = SIZE;
var urlReq:URLRequest = new URLRequest("http://www.adobe.com");
html.load(urlReq);
this.addChild(html);
function scrollHTML(event:Event):void
{
html.scrollV = html.contentHeight - SIZE;
}
O HTMLLoader não inclui barras de rolagem horizontal e vertical. Você pode implementar barras de rolagem no
ActionScript. Você também pode usar o método HTMLLoader.createRootWindow() para criar uma janela contendo
um objeto HTMLLoader com barras de rolagem (consulte “Criação de janelas com conteúdo HTML de rolagem” na
página 270).
Acesso à lista de histórico de HTML
À medida que novas páginas são carregadas no objeto HTMLLoader, o tempo de execução mantém uma lista de
histórico do objeto. A lista de histórico corresponde ao objeto window.history na página HTML. A classe
HTMLLoader inclui as seguintes propriedades e métodos que permitem trabalhar com a lista de histórico de HTML:
Membro de classe
Descrição
historyLength
O comprimento geral da lista de histórico, incluindo entradas dianteiras e traseiras.
historyPosition
A posição atual na lista de histórico. Os itens de histórico antes dessa posição representam navegação "para
trás" e itens após essa posição representam navegação “para frente”.
getHistoryAt()
Retorna o objeto URLRequest correspondente à entrada de histórico na posição especificada na lista de
histórico.
historyBack()
Navega para trás na lista de histórico, se possível.
historyForward()
Navega para frente na lista de histórico, se possível.
historyGo()
Navega o número indicado de etapas no histórico do navegador. Navega para frente, se for positivo, e para
trás, se for negativo. Navegar para zero recarrega a página. Especificar uma posição além do final, navega para
o final da lista.
Os itens da lista de histórico são armazenados como objetos do tipo HistoryListItem. A classe HistoryListItem tem as
seguintes propriedades:
Propriedade
Descrição
isPost
Defina como true se a página HTML incluir dados POST.
originalUrl
A URL original da página HTML antes de qualquer redirecionamento.
título
O título da página HTML.
url
A URL da página HTML.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 262
Gravação de script de contêiner HTML
Definição do agente do usuário usado ao carregar
conteúdo HTML
A classe HTMLLoader tem a propriedade userAgent, que permite definir a seqüência de agente do usuário usada pelo
HTMLLoader. Defina a propriedade userAgent do objeto HTMLLoader antes de chamar o método load(). Se você
definir esta propriedade na ocorrência HTMLLoader, a propriedade userAgent do URLRequest passada para o
método load()não será usada.
Você pode definir a string de agente do usuário padrão usada por todos os objetos HTMLLoader em um domínio de
aplicativo, configurando a propriedade URLRequestDefaults.userAgent. As propriedades URLRequestDefaults
estáticas são aplicadas como padrão a todos os objetos URLRequest, não apenas aos URLRequests usados com o
método load() dos objetos HTMLLoader. Configurar a propriedade userAgent do HTMLLoader substitui a
configuração URLRequestDefaults.userAgent padrão.
Se você não definir um valor de agente do usuário para a propriedade userAgent do objeto HTMLLoader ou para
URLRequestDefaults.userAgent, o valor de agente do usuário AIR padrão será usado. Esse valor padrão varia em
função do sistema operacional do tempo de execução (tal como Mac OS ou Windows), do idioma do tempo de
execução e da versão, como nos dois exemplos a seguir:
•
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/420+ (KHTML, como Gecko)
AdobeAIR/1.0"
•
"Mozilla/5.0 (Windows; U; en) AppleWebKit/420+ (KHTML, como Gecko) AdobeAIR/1.0"
Configuração de codificação de caractere para uso de
conteúdo HTML.
A página HTML pode especificar a codificação de caractere por ela usado, incluindo a tag meta, como a seguir:
meta http-equiv="content-type" content="text/html" charset="ISO-8859-1";
Substitua a configuração da página para assegurar que a codificação de caractere específica seja usada, configurando a
propriedade textEncodingOverride do objeto HTMLLoader:
var html:HTMLLoader = new HTMLLoader();
html.textEncodingOverride = "ISO-8859-1";
Especifique a codificação de caractere do conteúdo HTMLLoader que deverá ser usada quando a página HTML não
especificar uma configuração com a propriedade textEncodingFallback do objeto HTMLLoader:
var html:HTMLLoader = new HTMLLoader();
html.textEncodingFallback = "ISO-8859-1";
A propriedade textEncodingOverride substitui a configuração da página HTML. E a propriedade
textEncodingOverride e a configuração da página HTML substituem a propriedade textEncodingFallback.
Defina a propriedade textEncodingOverride ou a propriedade textEncodingFallback antes de carregar conteúdo
HTML.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 263
Gravação de script de contêiner HTML
Definição de interfaces do usuário como navegadores
para conteúdo HTML
O JavaScript oferece diversas APIs para controlar a janela que exibe o conteúdo HTML. No AIR, essas APIs podem ser
substituídas implementando uma classe HTMLHost personalizada.
Sobre estender a classe HTMLHost
Se, por exemplo, o aplicativo apresentar vários objetos HTMLLoader em uma interface com abas, talvez você deseje
que as alterações feitas pelas páginas HTML carregadas alterem o rótulo da aba e não o título da janela principal. Da
mesma forma, o código pode responder a uma chamada window.moveTo() reposicionando o objeto HTMLLoader no
respectivo contêiner do objeto de exibição pai, movendo a janela que contém o objeto HTMLLoader, não fazendo
exatamente nada ou fazendo alguma outra coisa por completo.
A classe HTMLHost do AIR controla as seguintes propriedades e métodos JavaScript:
•
window.status
•
window.document.title
•
window.location
•
window.blur()
•
window.close()
•
window.focus()
•
window.moveBy()
•
window.moveTo()
•
window.open()
•
window.resizeBy()
•
window.resizeTo()
Quando você cria um objeto HTMLLoader usando new HTMLLoader(), as propriedades ou métodos JavaScript
listados não são ativados. A classe HTMLHost oferece uma implementação padrão como navegador dessas APIs
JavaScript. Você também pode estender a classe HTMLHost para personalizar o comportamento. Para criar um objeto
HTMLHost que ofereça suporte ao comportamento padrão, defina o parâmetro defaultBehaviors como true no
construtor HTMLHost:
var defaultHost:HTMLHost = new HTMLHost(true);
Quando você cria uma janela HTML no AIR com o método createRootWindow() da classe HTMLLoader, uma
ocorrência HTMLHost com suporte aos comportamentos padrão é atribuída automaticamente. Você pode alterar o
comportamento do objeto host atribuindo uma implementação HTMLHost diferente à propriedade htmlHost do
HTMLLoader ou, pode atribuir null para desativar os recursos completamente.
Nota: O AIR atribui um objeto HTMLHost padrão à janela inicial criada para o aplicativo AIR baseado em HTML e
qualquer janela criada pela implementação padrão do método window.open() de JavaScript.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 264
Gravação de script de contêiner HTML
Exemplo: Extensão da classe HTMLHost
O exemplo a seguir mostra como personalizar a maneira como o objeto HTMLLoader afeta a interface do usuário,
estendendo a classe HTMLHost:
1 Crie um arquivo Flash para o AIR. Defina a classe do documento como CustomHostExample e, em seguida, salve
o arquivo como CustomHostExample.fla.
2 Crie um arquivo ActionScript chamado CustomHost.as contendo uma classe que estenda a classe HTMLHost
(uma subclasse). Essa classe substitui certos métodos da nova classe para tratar alterações nas configurações
relacionadas à interface do usuário. Por exemplo, a classe a seguir, CustomHost, define comportamentos de
chamadas parawindow.open() e altera para window.document.title. As chamadas para o método
window.open() abrem a página HTML em uma nova janela e alterações na propriedade
window.document.title (incluindo a configuração do elemento <title> da página HTML) definem o título
dessa janela.
package
{
import
import
import
import
import
import
import
import
import
import
flash.display.StageScaleMode;
flash.display.NativeWindow;
flash.display.NativeWindowInitOptions;
flash.events.Event;
flash.events.NativeWindowBoundsEvent;
flash.geom.Rectangle;
flash.html.HTMLLoader;
flash.html.HTMLHost;
flash.html.HTMLWindowCreateOptions;
flash.text.TextField;
public class CustomHost extends HTMLHost
{
public var statusField:TextField;
public function CustomHost(defaultBehaviors:Boolean=true)
{
super(defaultBehaviors);
}
override public function windowClose():void
{
htmlLoader.stage.nativeWindow.close();
}
override public function createWindow(
windowCreateOptions:HTMLWindowCreateOptions ):HTMLLoader
{
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(windowCreateOptions.x,
windowCreateOptions.y,
windowCreateOptions.width,
windowCreateOptions.height);
var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions,
windowCreateOptions.scrollBarsVisible, bounds);
htmlControl.htmlHost = new HTMLHostImplementation();
if(windowCreateOptions.fullscreen){
htmlControl.stage.displayState =
StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
return htmlControl;
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 265
Gravação de script de contêiner HTML
}
override public function updateLocation(locationURL:String):void
{
trace(locationURL);
}
override public function set windowRect(value:Rectangle):void
{
htmlLoader.stage.nativeWindow.bounds = value;
}
override public function updateStatus(status:String):void
{
statusField.text = status;
trace(status);
}
override public function updateTitle(title:String):void
{
htmlLoader.stage.nativeWindow.title = title + "- Example Application";
}
override public function windowBlur():void
{
htmlLoader.alpha = 0.5;
}
override public function windowFocus():void
{
htmlLoader.alpha = 1;
}
}
}
3 Crie outro arquivo ActionScript chamado CustomHostExample.as para conter a classe de documento do
aplicativo. Essa classe cria um objeto HTMLLoader e define a respectiva propriedade host como uma ocorrência da
classe CustomHost definida na etapa anterior:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 266
Gravação de script de contêiner HTML
package
{
import
import
import
import
flash.display.Sprite;
flash.html.HTMLLoader;
flash.net.URLRequest;
flash.text.TextField;
public class CustomHostExample extends Sprite
{
function CustomHostExample():void
{
var html:HTMLLoader = new HTMLLoader();
html.width = 550;
html.height = 380;
var host:CustomHost = new CustomHost();
html.htmlHost = host;
var urlReq:URLRequest = new URLRequest("Test.html");
html.load(urlReq);
addChild(html);
var statusTxt:TextField = new TextField();
statusTxt.y = 380;
statusTxt.height = 20;
statusTxt.width = 550;
statusTxt.background = true;
statusTxt.backgroundColor = 0xEEEEEEEE;
addChild(statusTxt);
host.statusField = statusTxt;
}
}
}
Para testar o código descrito aqui, inclua um arquivo HTML com o seguinte conteúdo no diretório do aplicativo:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 267
Gravação de script de contêiner HTML
<html>
<head>
<title>Test</title>
<script>
function openWindow()
{
document.title = "Test"
window.open('Test.html');
}
</script>
</head>
<body bgColor="#EEEEEE">
<a href="#" onclick="window.open('Test.html')">window.open('Test.html')</a>
<br/><a href="#" onclick="window.document.location='http://www.adobe.com'">
window.document.location = 'http://www.adobe.com'</a>
<br/><a href="#" onclick="window.moveBy(6, 12)">moveBy(6, 12)</a>
<br/><a href="#" onclick="window.close()">window.close()</a>
<br/><a href="#" onclick="window.blur()">window.blur()</a>
<br/><a href="#" onclick="window.focus()">window.focus()</a>
<br/><a href="#" onclick="window.status = new Date().toString()">window.status=new
Date().toString()</a>
</body>
</html>
Tratamento de alterações na propriedade window.location
Substitua o método locationChange() para tratar alterações da URL da página HTML. O método
locationChange() é chamado quando o JavaScript em uma página altera o valor de window.location. O exemplo
a seguir simplesmente carrega a URL solicitada:
override public function updateLocation(locationURL:String):void
{
htmlLoader.load(new URLRequest(locationURL));
}
Nota: Você pode usar a propriedade htmlLoader do objeto HTMLHost para fazer referência ao objeto HTMLLoader
atual.
Tratamento de chamadas de JavaScript de window.moveBy(),
window.moveTo(), window.resizeTo() e window.resizeBy()
Substitua o método set windowRect() para tratar alterações nos limites do conteúdo HTML. O método set
windowRect() é chamado quando o JavaScript em uma página chama window.moveBy(), window.moveTo(),
window.resizeTo() ou window.resizeBy(). O exemplo a seguir simplesmente atualiza os limites da janela da área
de trabalho:
override public function set windowRect(value:Rectangle):void
{
htmlLoader.stage.nativeWindow.bounds = value;
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 268
Gravação de script de contêiner HTML
Tratamento de chamadas JavaScript de window.open()
Substitui o método createWindow() para tratar chamadas JavaScript de window.open(). As implementações do
método createWindow() são responsáveis pela criação e retorno de um novo objeto HTMLLoader. Normalmente
você exibe o HTMLLoader em uma nova janela, mas não é necessário criar uma nova janela.
O exemplo a seguir ilustra como implementar a função createWindow() usando
HTMLLoader.createRootWindow() para criar a janela e o objeto HTMLLoader. Você também pode criar o objeto
NativeWindow separadamente e adicionar o HTMLLoader ao palco da janela.
override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader{
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(windowCreateOptions.x, windowCreateOptions.y,
windowCreateOptions.width, windowCreateOptions.height);
var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions,
windowCreateOptions.scrollBarsVisible, bounds);
htmlControl.htmlHost = new HTMLHostImplementation();
if(windowCreateOptions.fullscreen){
htmlControl.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
return htmlControl;
}
Nota: Esse exemplo atribui a implementação HTMLHost personalizada a qualquer janela nova criada com
window.open(). Você também pode usar uma implementação diferente ou definir a propriedade htmlHost como null
em novas janelas, se desejar.
O objeto passado como parâmetro para o método createWindow() é o objeto HTMLWindowCreateOptions. A classe
HTMLWindowCreateOptions inclui propriedades que informam os valores definidos na seqüência de parâmetro
features na chamada de window.open():
propriedade
HTMLWindowCreateOptions
Configuração correspondente na
string de recursos na chamada
JavaScript para window.open()
fullscreen
fullscreen
height
height
locationBarVisible
location
menuBarVisible
menubar
resizeable
resizable
scrollBarsVisible
scrollbars
statusBarVisible
status
toolBarVisible
toolbar
width
width
x
left ou screenX
y
top ou screenY
A classe HTMLLoader não implementa todos os recursos que podem ser especificados na string de recursos. O
aplicativo deve fornecer barras de rolagem, barras de localização, barras de menu, barras de status e barras de
ferramentas, quando apropriado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 269
Gravação de script de contêiner HTML
Os outros argumentos para o método window.open() de JavaScript são tratados pelo sistema. A implementação
createWindow() não deve carregar conteúdo no objeto HTMLLoader nem definir o título da janela.
Tratamento de chamadas JavaScript de window.close()
Substitui o método windowClose() para tratar chamadas JavaScript do método window.close(). O exemplo a seguir
fecha a janela da área de trabalho quando o método window.close() é chamado:
override public function windowClose():void
{
htmlLoader.stage.nativeWindow.close();
}
As chamadas JavaScript de window.close() não têm que fechar as janelas que as contêm. Você pode, por exemplo,
remover o HTMLLoader da lista de exibição, deixando a janela (que pode ter outro conteúdo) aberta, conforme o
código a seguir:
override public function windowClose():void
{
htmlLoader.parent.removeChild(htmlLoader);
}
Tratamento de alterações da propriedade windows.status
Substitua o método updateStatus() para tratar alterações JavaScript no valor de window.status. O exemplo a
seguir rastreia o valor do status:
override public function updateStatus(status:String):void
{
trace(status);
}
O status solicitado é passado como string para o método updateStatus().
O objeto HTMLLoader não oferece uma barra de status.
Tratamento de alterações da propriedade window.document.title
Substitua o método updateTitle() para tratar alterações JavaScript no valor de window.document.title. O
exemplo a seguir altera o título da janela e acrescenta a seqüência, "Sample", ao título:
override public function updateTitle(title:String):void
{
htmlLoader.stage.nativeWindow.title = title + " - Sample";
}
Quando document.title estiver definido em uma página HTML, o título solicitado será passado como string para o
método updateTitle().
As alterações em document.title não devem alterar o título da janela que contém o objeto HTMLLoader. Você pode,
por exemplo, alterar outro elemento de interface, como campo de texto.
Tratamento de chamadas JavaScript de window.blur() e window.focus()
Substitua os métodos windowBlur() e windowFocus() para tratar chamadas JavaScript dewindow.blur() e
window.focus(), conforme mostrado o exemplo a seguir:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 270
Gravação de script de contêiner HTML
override public function windowBlur():void
{
htmlLoader.alpha = 0.5;
}
override public function windowFocus():void
{
htmlLoader.alpha = 1.0;
NativeApplication.nativeApplication.activate(htmlLoader.stage.nativeWindow);
}
Nota: O AIR não fornece nenhuma API para desativar janela nem aplicativo.
Criação de janelas com conteúdo HTML de rolagem
A classe HTMLLoader inclui um método estático, HTMLLoader.createRootWindow(), que permite abrir uma nova
janela (representada por um objeto NativeWindow) que contém um objeto HTMLLoader e define algumas
configurações da interface do usuário para essa janela. O método tem quatro parâmetros que permitem definir a
interface do usuário:
Parâmetro
Descrição
visible
Um valor booleano que especifica se a janela ficará inicialmente visível (true) ou não (false).
windowInitOptions
Um objeto NativeWindowInitOptions. A classe NativeWindowInitOptions define as opções de inicialização do
objeto NativeWindow, incluindo o seguinte: se a janela é minimizável, maximizável ou redimensionável, se a
janela tem cromo do sistema ou cromo personalizado, se a janela é transparente ou não (para janelas que não
usam o cromo do sistema) e o tipo de janela.
scrollBarsVisible
Se há barras de rolagem (true) ou não (false).
bounds
Um objeto Rectangle definindo a posição e o tamanho da nova janela.
Por exemplo, o código a seguir usa o método HTMLLoader.createRootWindow() para criar uma janela com conteúdo
HTMLLoader que usa barras de rolagem:
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(10, 10, 600, 400);
var html2:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, true, bounds);
var urlReq2:URLRequest = new URLRequest("http://www.example.com");
html2.load(urlReq2);
html2.stage.nativeWindow.activate();
Nota: Janelas criadas chamando createRootWindow() diretamente em JavaScript permanecem independentes da
janela HTML aberta. As propriedades opener e parent da janela JavaScript, por exemplo, são null. No entanto, se você
chamar createRootWindow() indiretamente substituindo o método createWindow() do HTMLHost para chamar
createRootWindow(), opener e parent farão referência à janela HTML aberta.
Criação de subclasses da classe HTMLLoader
Você pode criar uma subclasse da classe HTMLLoader para criar novos comportamentos. Por exemplo, você pode
criar uma subclasse que defina ouvintes de evento padrão de eventos HTMLLoader (como os eventos despachados
quando o HTML é processado ou quando um usuário clica em um link).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 271
Gravação de script de contêiner HTML
O exemplo a seguir estende a classe HTMLHost para apresentar comportamento normal quando o método
window.open() de JavaScript for chamado. O exemplo a seguir define uma subclasse do HTMLLoader que usa a classe
personalizada de implementação HTMLHost:
package
{
import flash.html.HTMLLoader;
public class MyHTMLHost extends HTMLHost
{
public function MyHTMLHost()
{
super(false);
}
override public function createWindow(opts:HTMLWindowCreateOptions):void
{
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(opts.x, opts.y, opts.width, opts.height);
var html:HTMLLoader = HTMLLoader.createRootWindow(true,
initOptions,
opts.scrollBarsVisible,
bounds);
html.stage.nativeWindow.orderToFront();
return html
}
}
O seguinte define uma subclasse da classe HTMLLoader que atribui um objeto MyHTMLHost à respectiva
propriedade htmlHost:
package
{
import flash.html.HTMLLoader;
import MyHTMLHost;
import HTMLLoader;
public class MyHTML extends HTMLLoader
{
public function MyHTML()
{
super();
htmlHost = new MyHTMLHost();
}
}
}
Para obter detalhes sobre a classe HTMLHost e o método HTMLLoader.createRootWindow() usado nesse exemplo,
consulte “Definição de interfaces do usuário como navegadores para conteúdo HTML” na página 263.
272
Capítulo 24: Adição de conteúdo em PDF
Aplicativos em execução no Adobe® AIR™ podem produzir não só conteúdo SWF e HTML, mas também em PDF.
Aplicativos AIR processam aplicativos em PDF usando a classe HTMLLoader, o mecanismo WebKit e o plug-in para
navegador Adobe® Reader®. Em um aplicativo AIR, o conteúdo em PDF pode alongar-se pela atura e largura inteiras
de seu aplicativo ou, como alternativa, como uma parte da interface. O plug-in para navegador do Adobe Reader
controla a exibição de arquivos em PDF em um aplicativo AIR, portanto, modificações na interface da barra de
ferramentas do Reader (como as relacionadas à posição, ancoragem e visibilidade) persistem na visualização
subseqüente de arquivos em PDF tanto nos aplicativos AIR como no navegador.
Importante: Para processar conteúdo em PDF no AIR, o usuário deve ter o Adobe Reader ou Adobe® Acrobat® versão 8.1
ou posterior instalada.
Detecção de recurso de PDF
Se o usuário não tiver uma versão instalada do Adobe Reader ou do Adobe Acrobat 8.1 ou posterior, o conteúdo PDF
não será exibido no aplicativo AIR. Para detectar se o usuário pode processar conteúdo em PDF, verifique
primeiramente a propriedade HTMLLoader.pdfCapability. Essa propriedade está definida como uma das seguintes
constantes da classe HTMLPDFCapability:
Constante
Descrição
HTMLPDFCapability.STATUS_OK
Uma versão suficiente (8.1 ou posterior) do Adobe Reader é
detectada e o conteúdo em PDF pode ser carregado em um objeto
HTMLLoader.
HTMLPDFCapability.ERROR_INSTALLED_READER_NOT_FOUND
Não foi detectada nenhuma versão do Adobe Reader. Um objeto
HTMLLoader não pode exibir conteúdo em PDF.
HTMLPDFCapability.ERROR_INSTALLED_READER_TOO_OLD
O Adobe Reader foi detectado, mas a versão é muito antiga. Um
objeto HTMLLoader não pode exibir conteúdo em PDF.
HTMLPDFCapability.ERROR_PREFERRED_READER_TOO_OLD
Uma versão suficiente (8.1 ou posterior) do Adobe Reader foi
detectada, mas a versão do aplicativo configurada para lidar com
conteúdo em PDF é anterior ao Reader 8.1. Um objeto HTMLLoader
não pode exibir conteúdo em PDF.
No Windows, se o Adobe Acrobat ou o Acrobat Reader versão 7.x ou posterior estiver em execução no sistema do
usuário, essa versão será usada, mesmo se houver instalada uma versão posterior que ofereça suporte a PDF carregado.
Nesse caso, se o valor da propriedade pdfCampability for HTMLPDFCapability.STATUS_OK, quando um aplicativo
AIR tentar carregar o conteúdo em PDF, a versão antiga do Acrobat ou do Reader exibirá um alerta (e nenhuma
exceção será lançada no aplicativo AIR). Se isso for uma possibilidade para os usuários finais, considere fornecer a eles
instruções sobre como fechar o Acrobat enquanto o aplicativo é executado. Pode ser conveniente exibir essas
instruções se o conteúdo em PDF não for carregado em um intervalo de tempo aceitável.
No Linux, o AIR procura o Adobe Reader no CAMINHO exportado pelo usuário (se ele contiver o comando acroread)
e no diretório /opt/Adobe/Reader.
O código seguinte detecta se o usuário pode exibir conteúdo em PDF em um aplicativo AIR, e, caso não possa, rastreia
o código de erro que corresponde ao objeto de erro HTMLPDFCapability:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 273
Adição de conteúdo em PDF
if(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK)
{
trace("PDF content can be displayed");
}
else
{
trace("PDF cannot be displayed. Error code:", HTMLLoader.pdfCapability);
}
Carregamento de conteúdo em PDF
Você pode adicionar um PDF a um aplicativo AIR criando uma ocorrência HTMLLoader, definindo as dimensões e
carregando o caminho de um PDF.
O exemplo a seguir carrega um PDF de um site externo. Substitua a URLRequest com o caminho para um PDF externo
disponível.
var request:URLRequest = new URLRequest("http://www.example.com/test.pdf");
pdf = new HTMLLoader();
pdf.height = 800;
pdf.width = 600;
pdf.load(request);
container.addChild(pdf);
Você também pode carregar conteúdo de URLs de arquivos e esquemas de URL específicos do AIR, como app e appstorage. Por exemplo, o código seguinte carrega o arquivo test.pdf no subdiretório PDFs do diretório do aplicativo:
app:/js_api_reference.pdf
Para obter mais informações sobre esquemas de URL do AIR, consulte “Uso de esquemas de URL do AIR em URLs”
na página 306.
Gravando em script o conteúdo em PDF
Você pode usar o JavaScript para controlar o conteúdo em PDF, do mesmo modo que em um página da Web no
navegador.
As extensões JavaScript para o Acrobat oferecem alguns recursos, entre eles:
• Controle de ampliação e navegação de página
• Processamento de formulários no documento
• Controle de eventos multimídia
Detalhes completos sobre extensões JavaScript para o Adobe Acrobat são fornecidos na Conexão de desenvolvedores
do Adobe Acrobat, em http://www.adobe.com/devnet/acrobat/javascript.html.
Noções básicas de comunicação HTML-PDF
O JavaScript em uma página HTML pode enviar uma mensagem para o JavaScript no conteúdo em PDF, chamando
o método postMessage() do objeto DOM representando o conteúdo em PDF. Por exemplo, considere o seguinte
conteúdo em PDF incorporado:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 274
Adição de conteúdo em PDF
<object id="PDFObj" data="test.pdf" type="application/pdf" width="100%" height="100%"/>
o código JavaScript seguinte, no conteúdo HTML contido envia uma mensagem para o JavaScript no arquivo em PDF:
pdfObject = document.getElementById("PDFObj");
pdfObject.postMessage(["testMsg", "hello"]);
O arquivo em PDF pode incluirJavaScript para receber essa mensagem. Você pode adicionar o código JavaScript a
arquivos em PDF em alguns contextos, incluindo os contextos em nível de documento, pasta, página, campo e lote.
Apenas o contexto em nível de documento, que define scripts que são avaliados quando o documento em PDF é aberto,
é discutido aqui.
Um arquivo em PDF pode adicionar uma propriedade messageHandler ao objeto hostContainer. A propriedade
messageHandler é um objeto que define funções do manipulador para responder a mensagens. Por exemplo, o código
seguinte define a função para tratar mensagens recebidas pelo arquivo em PDF a partir do contêiner host (que é o
conteúdo HTML incorporando o arquivo em PDF):
this.hostContainer.messageHandler = {onMessage: myOnMessage};
function myOnMessage(aMessage)
{
if(aMessage[0] == "testMsg")
{
app.alert("Test message: " + aMessage[1]);
}
else
{
app.alert("Error");
}
}
O código JavaScript na página HTML pode chamar o método postMessage() do objeto PDF contido na página.
Chamar esse método envia uma mensagem ("Hello from HTML") para o JavaScript em nível de documento no
arquivo em PDF:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 275
Adição de conteúdo em PDF
<html>
<head>
<title>PDF Test</title>
<script>
function init()
{
pdfObject = document.getElementById("PDFObj");
try {
pdfObject.postMessage(["alert", "Hello from HTML"]);
}
catch (e)
{
alert( "Error: \n name = " + e.name + "\n message = " + e.message );
}
}
</script>
</head>
<body onload='init()'>
<object
id="PDFObj"
data="test.pdf"
type="application/pdf"
width="100%" height="100%"/>
</body>
</html>
Para obter um exemplo mais avançado e obter informações sobre como usar o Acrobat 8 para adicionar JavaScript a
um arquivo em PDF, consulte Conteúdo em PDF entre scripts no Adobe AIR.
Gravação em script de conteúdo em PDF do ActionScript
O código do ActionScript (no conteúdo SWF) não pode se comunicar diretamente com o JavaScript no conteúdo em
PDF. Entretanto, o ActionScript pode se comunicar com o JavaScript na página HTML carregada em um objeto
HTMLLoader que carrega conteúdo em PDF, e o código JavaScript pode se comunicar com o JavaScript no arquivo
em PDF carregado. Para obter mais informações, consulte “Programação em HTML e JavaScript” na página 233.
Limitações conhecidas do conteúdo em PDF no AIR
O conteúdo em PDF no Adobe AIR tem as seguintes limitações:
• O conteúdo em PDF não é exibido em uma janela (um objeto NativeWindow) que seja transparente (na qual a
propriedade transparent esteja definida como true).
• A ordem de exibição de um arquivo em PDF funciona de forma diferente de outros objetos de exibição em um
aplicativo AIR. Embora o conteúdo em PDF se afixe corretamente de acordo com a ordem de exibição de HTML,
ele sempre ficará por cima do conteúdo na ordem de exibição do aplicativo AIR.
• O conteúdo em PDF não é exibido em uma janela que esteja no modo tela cheia (quando a propriedade
displayState do Palco está definida como StageDisplayState.FULL_SCREEN ou
StageDisplayState.FULL_SCREEN_INTERACTIVE).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 276
Adição de conteúdo em PDF
• Se determinadas propriedades visuais de um objeto HTMLLoader que contenha um documento PDF forem
alteradas, o documento PDF se tornará invisível. Essas propriedades incluem filters, alpha, rotation e
scaling. Alterá-las torna o arquivo PDF invisível até a redefinição das propriedades. Isso também vale se você
alterar essas propriedades de contêineres de objeto de exibição que contêm o objeto HTMLLoader.
• O conteúdo PDF fica visível somente quando a propriedade scaleMode do objeto Stage do objeto NativeWindow
contendo o conteúdo PDF é definida como StageScaleMode.NO_SCALE. Quando ela é definida com outro valor,
o conteúdo PDF não fica visível.
• Clicar em links para conteúdo dentro do arquivo em PDF atualiza a posição de rolagem do conteúdo em PDF.
Clicar em links para conteúdo fora do arquivo em PDF redireciona o objeto HTMLLoader que contém o PDF
(mesmo que o destino de um link seja uma nova janela).
• Fluxos de trabalho de comentário de PDF não funcionam no AIR.
277
Capítulo 25: Utilização de gerenciamento
de direitos digitais
O FMRMS (Servidor de gerenciamento de direitos do Adobe® Flash® Media) fornece aos editores de mídia a
capacidade de distribuir conteúdo, especificamente arquivos FLV e MP4, e recuperar custos de produção por meio de
compensação direta (paga pelo usuário) ou indireta (paga por propaganda) por seus consumidores. Os editores
distribuem mídia como FLVs criptografados que podem ser baixados e reproduzidos no Adobe® Media Player™ ou em
qualquer aplicativo do AIR que use a API de DRM (gerenciamento de direitos digitais).
Com o FMRMS, os provedores de conteúdo podem usar licenciamento baseado em identidade para proteger seu
conteúdo com credenciais de usuários. Por exemplo, um consumidor deseja exibir um programa de televisão, mas não
deseja assistir às propagandas que o acompanham. Para evitar assistir às propagandas, o consumidor registra e paga
ao editor de conteúdo um prêmio. O usuário pode usar sua credencial de autenticação para obter acesso e assistir ao
programa sem os comerciais. Outro consumidor pode querer exibir o conteúdo offline ao viajar sem acesso à Internet.
Após se registrar e pagar ao editor de conteúdo pelo serviço premium, a credencial de autenticação do usuário permite
a eles acessarem e baixarem o programa do site do editor. O usuário pode então exibir o conteúdo offline durante o
período permitido. O conteúdo também é protegido pelas credenciais do usuário e não pode ser compartilhado com
outros usuários.
Quando um usuário tenta reproduzir um arquivo criptografado por DRM, o aplicativo entra em contato com o
FMRMS que, por sua vez, entra em contato com o sistema do editor de conteúdo por sua SPI (interface de provedor
de serviços) para autenticar o usuário e recuperar a licença, um comprovante que determina se o usuário pode acessar
o conteúdo e, se sim, por quanto tempo. O comprovante também determina se o usuário pode acessar o conteúdo
offline e, se sim, por quanto tempo. Como tal, as credenciais do usuário são necessárias para determinar o acesso ao
conteúdo criptografado.
O licenciamento baseado em identidade também suporta o acesso anônimo. Por exemplo, o acesso anônimo pode ser
usado pelo provedor para distribuir conteúdo suportado por propaganda ou para permitir acesso livre ao conteúdo
atual por um número de dias especificado. O material de arquivo pode ser considerado conteúdo premium que deve
ser pago e requer credenciais do usuário. O provedor de conteúdo também pode especificar e restringir o tipo e a
versão do player necessário para seu conteúdo.
É descrito aqui como habilitar seu aplicativo do AIR para reproduzir conteúdo protegido com criptografia de
gerenciamento de direitos digitais. Não é necessário entender como criptografar conteúdo usando DRM, mas supõese que você tenha acesso a conteúdo criptografado por DRM e esteja se comunicando com o FMRMS para autenticar
o usuário e recuperar o comprovante.
Para uma visão geral do FMRMS, incluindo a criação de diretivas, consulte a documentação incluída com o FMRMS.
Para obter informações sobre o Adobe Media Player, consulte a Ajuda do Adobe Media Player disponível no Adobe
Media Player.
Informações online adicionais sobre o gerenciamento
de direitos digitais
Você pode encontrar mais informações sobre o gerenciamento de direitos digitais nestas fontes:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 278
Utilização de gerenciamento de direitos digitais
Referência de Linguagem
• AuthenticationMethod
• DRMAuthenticationCompleteEvent
• DRMAuthenticationErrorEvent
• DRMAuthenticateEvent
• DRMContentData
• DRMErrorEvent
• DRMManager
• DRMPlaybackTimeWindow
• DRMStatusEvent
• DRMVoucher
• LoadVoucherSetting
• NetStream
Artigos e amostras do Adobe Developer Connection
• Conexão de desenvolvedores do Adobe AIR para Flash (procure "gerenciamento de direitos digitais" ou "drm")
Compreensão do fluxo de trabalho FLV criptografado
Existem quatro tipos de eventos: StatusEvent, DRMAuthenticateEvent, DRMErrorEvent e DRMStatusEvent, que
podem ser despachados quando um aplicativo do AIR tenta reproduzir um arquivo criptografado por DRM. Para
suportar esses arquivos, o aplicativo deve adicionar ouvintes de eventos para manipular os eventos DRM.
A seguir, está o fluxo de trabalho de como o aplicativo do AIR pode recuperar e reproduzir o conteúdo protegido com
criptografia DRM:
1 O aplicativo, usando um objeto NetStream, tenta reproduzir um arquivo FLV ou MP4. Se o conteúdo for
criptografado, um evento events.StatusEvent é despachado com o código, DRM.encryptedFLV, indicando que
o FLV está criptografado.
Nota: Se um aplicativo não quiser reproduzir o arquivo criptografado por DRM, ele poderá ouvir o evento de status
despachado quando encontrar um conteúdo criptografado e, em seguida, permitir que o usuário saiba que o arquivo
não é suportado e fechar a conexão.
2 Se o arquivo for criptografado de modo anônimo, o que significa que todos os usuários podem exibir o conteúdo
sem inserir credenciais de autenticação, o aplicativo do AIR continuará com a última etapa desse fluxo de trabalho.
No entanto, se o arquivo exigir uma licença baseada em identidade, o que significa que a credencial do usuário é
exigida, o objeto NetStream despachará um objeto DRMAuthenticateEvent. O usuário deve fornecer suas
credenciais de autenticação antes que a reprodução seja iniciada.
3 O aplicativo do AIR deve fornecer algum mecanismo para coletar as credenciais de autenticação necessárias. As
propriedades usernamePrompt, passwordPrompt e urlPrompt da classe DRMAuthenticationEvent, fornecidas
pelo servidor de conteúdo, podem ser usadas para instruir o usuário final com informações sobre os dados
necessários. Você pode usar essas propriedades de construir uma interface de usuário para recuperar as credenciais
de usuário necessárias. Por exemplo, a seqüência de caracteres de valor usernamePrompt pode afirmar que o nome
de usuário deve estar na forma de um endereço de e-mail.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 279
Utilização de gerenciamento de direitos digitais
Nota: O AIR não fornece uma interface de usuário padrão para coletar credenciais de autenticação. O desenvolvedor
do aplicativo deve escrever a interface de usuário e manipular os eventos DRMAuthenticateEvent. Se o aplicativo não
fornecer um ouvinte de eventos para objetos DRMAuthenticateEvent, o objeto criptografado por DRM permanecerá
em um estado “aguardando credenciais” e o conteúdo não está, portanto, disponível.
4 Depois que o aplicativo obtiver as credenciais do usuário, ele as transmitirá com o método
setDRMAuthenticationCredentials() ao objeto NetStream. Isso sinaliza ao objeto NetStream que ele deve
tentar autenticar o usuário na próxima oportunidade disponível. O AIR então transmite a credencial ao FMRMS
para autenticação. Se o usuário foi autenticado, o aplicativo continuará com a etapa seguinte.
Se a autenticação falhar, o objeto NetStream despachará um novo objeto DRMAuthenticateEvent e o aplicativo
retornará à etapa 3. Esse processo é repetido indefinidamente. O aplicativo deve fornecer um mecanismo para
manipular e limitar as tentativas de autenticação repetidas. Por exemplo, o aplicativo poderia permitir ao usuário
cancelar a tentativa que pode fechar a conexão do NetStream.
5 Depois que o usuário estiver autenticado, ou se a criptografia anônima for usada, o subsistema DRM recupera o
comprovante. O comprovante é usado para verificar se o usuário está autorizado a exibir o conteúdo. As
informações no comprovante podem ser aplicadas aos usuários autenticados e anônimos. Por exemplo, os usuários
autenticados e anônimos podem ter acesso ao conteúdo por um período de tempo especificado antes que o
conteúdo expire ou podem não ter acesso ao conteúdo porque o provedor de conteúdo pode não suportar a versão
do aplicativo de exibição.
Se não tiver ocorrido nenhum erro e o usuário foi autorizado com êxito a exibir o conteúdo, o objeto NetStream
despachará um objeto DRMStatusEvent e o aplicativo do AIR começará a reprodução. O objeto DRMStatusEvent
guarda as informações do comprovante relacionadas, que identifica a diretiva e as permissões do usuário. Por exemplo,
ele contém informações com relação a se o conteúdo pode ser disponibilizado offline ou quando o comprovante expira
e o conteúdo não pode mais se exibido. O aplicativo pode usar esses dados para informar ao usuário sobre o status de
sua diretiva. Por exemplo, o aplicativo pode exibir o número de dias restantes que o usuário possui para exibir o
conteúdo em uma barra de status.
Se ao usuário for permitido acesso offline, o comprovante será armazenado em cache e o conteúdo criptografado será
baixado na máquina do usuário e estará acessível pela duração definida no período offline. A propriedade detail no
evento contém "DRM.voucherObtained". O aplicativo decide onde armazenar o conteúdo localmente para que ele
esteja disponível off-line. No AIR 1.5, você também pode pré-carregar comprovantes usando a classe DRMManager.
Todos os erros relacionados a DRM resultam em o aplicativo despachar um objeto de evento DRMErrorEvent. O AIR
manipula as falhas de autenticação encontradas usando o método setDRMAuthenticationCredentials()do
NetStream, despachando novamente o objeto DRMAuthenticationEvent. Todos os outros eventos de erro devem ser
explicitamente manipulados pelo aplicativo. Isso inclui casos nos quais o usuário insere credenciais válidas, mas o
comprovante que protege o conteúdo criptografado restringe o acesso ao conteúdo. Por exemplo, um usuário
autenticado pode ainda não ter acesso ao conteúdo porque os direitos não foram pagos. Isso poderia ocorrer também
onde dois usuários, ambos membros registrados com o mesmo editor de mídia, estão tentando compartilhar conteúdo
pelo qual apenas um dos membros pagou. O aplicativo deve informar o usuário sobre o erro, como as restrições para
o conteúdo, bem como fornecer uma alternativa, como instruções sobre como registrar e pagar pelos direitos para
exibir o conteúdo.
Pré-carregar comprovantes para reprodução offline
Você pode pré-carregar os comprovantes necessários para reproduzir conteúdo protegido por DRM. Comprovantes
pré-carregados permitem que os usuários vejam o conteúdo com ou sem conexão à Internet. (O processo de précarregamento propriamente dito obviamente requer conexão com Internet.) Use o método
preloadEmbeddedMetadata() da classe NetStream e a classe 1.5 DRMManager do AIR 1.5 para pré-carregar
comprovantes.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 280
Utilização de gerenciamento de direitos digitais
As etapas a seguir descrevem o fluxo de trabalho para pré-carregar o comprovante de um arquivo de mídia protegido
por DRM:
1 Baixe e armazene o arquivo de mídia. (Metadados DRM só podem ser pré-carregados de arquivos armazenados
localmente.)
2 Crie os objetos NetConnection e NetStream, fornecendo implementações para as funções de retorno de chamada
onDRMContentData() e onPlayStatus() do objeto cliente NetStream.
3 Crie um objeto NetStreamPlayOptions e defina a propriedade stream para a URL do arquivo de mídia local.
4 Chame o NetStream preloadEmbeddedMetadata(), passando no objeto NetStreamPlayOptions que identifica o
arquivo de mídia que será analisado.
5 Se o arquivo de mídia contiver metadados DRM, a função de retorno de chamada onDRMContentData() será
chamada. Os metadados são transmitidos a essa função como objeto DRMContentData.
6 Use o objeto DRMContentData para obter o comprovante usando o método loadVoucher() do DRMManager.
Se o valor da propriedade authenticationMethod do objeto DRMContentData for userNameAndPassword, você
deverá autenticar o usuário no servidor de direitos de mídia antes de carregar o comprovante. As propriedades
serverURL e domain do objeto DRMContentData podem ser passadas para o método authenticate() do
DRMManager, juntamente com as credenciais do usuário.
7 A função de retorno de chamada onPlayStatus() é chamada após a conclusão da análise do arquivo. Se a função
onDRMContentData() não tiver sido chamada, o arquivo não conterá os metadados necessários para obter um
comprovante (e pode não estar protegido por DRM).
O exemplo de código a seguir ilustra como pré-carregar um comprovante DRM para um arquivo de mídia local:
package
{
import flash.display.Sprite;
import flash.events.DRMAuthenticationCompleteEvent;
import flash.events.DRMAuthenticationErrorEvent;
import flash.events.DRMErrorEvent;
import flash.ev ents.DRMStatusEvent;
import flash.events.NetStatusEvent;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamPlayOptions;
import flash.net.drm.AuthenticationMethod;
import flash.net.drm.DRMContentData;
import flash.net.drm.DRMManager;
import flash.net.drm.LoadVoucherSetting;
public class DRMPreloader extends Sprite
{
private var videoURL:String = "app-storage:/video.flv";
private var userName:String = "user";
private var password:String = "password";
private var preloadConnection:NetConnection;
private var preloadStream:NetStream;
private var drmManager:DRMManager = DRMManager.getDRMManager();
private var drmContentData:DRMContentData;
public function DRMPreloader():void {
drmManager.addEventListener( DRMAuthenticationCompleteEvent.AUTHENTICATION_COMPLETE,
onAuthenticationComplete );
drmManager.addEventListener(
DRMAuthenticationErrorEvent.AUTHENTICATION_ERROR,onAuthenticationError );
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 281
Utilização de gerenciamento de direitos digitais
drmManager.addEventListener(DRMStatusEvent.DRM_STATUS, onDRMStatus);
drmManager.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMError);
preloadConnection = new NetConnection();
preloadConnection.addEventListener(NetStatusEvent.NET_STATUS, onConnect);
preloadConnection.connect(null);
}
private function onConnect( event:NetStatusEvent ):void
{
preloadMetadata();
}
private function preloadMetadata():void
{
preloadStream = new NetStream( preloadConnection );
preloadStream.client = this;
var options:NetStreamPlayOptions = new NetStreamPlayOptions();
options.streamName = videoURL;
preloadStream.preloadEmbeddedData( options );
}
public function onDRMContentData( drmMetadata:DRMContentData ):void
{
drmContentData = drmMetadata;
if ( drmMetadata.authenticationMethod == AuthenticationMethod.USERNAME_AND_PASSWORD )
{
authenticateUser();
}
else
{
getVoucher();
}
}
private function getVoucher():void
{
drmManager.loadVoucher( drmContentData, LoadVoucherSetting.ALLOW_SERVER );
}
private function authenticateUser():void
{
drmManager.authenticate( drmContentData.serverURL, drmContentData.domain, userName,
password );
}
private function onAuthenticationError( event:DRMAuthenticationErrorEvent ):void
{
trace( "Authentication error: " + event.errorID + ", " + event.subErrorID );
}
private function onAuthenticationComplete( event:DRMAuthenticationCompleteEvent ):void
{
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 282
Utilização de gerenciamento de direitos digitais
trace( "Authenticated to: " + event.serverURL + ", domain: " + event.domain );
getVoucher();
}
private function onDRMStatus( event:DRMStatusEvent ):void
{
trace( "DRM Status: " + event.detail);
trace("--Voucher allows offline playback = " + event.isAvailableOffline );
trace("--Voucher already cached
= " + event.isLocal );
trace("--Voucher required authentication = " + !event.isAnonymous );
}
private function onDRMError( event:DRMErrorEvent ):void
{
trace( "DRM error event: " + event.errorID + ", " + event.subErrorID + ", " + event.text );
}
public function onPlayStatus( info:Object ):void
{
preloadStream.close();
}
}
}
Membros e eventos relacionados a DRM da classe
NetStream
A classe NetStream fornece uma conexão de streaming unidirecional entre o Flash Player ou um aplicativo do AIR e
o Flash Media Server ou o sistema de arquivos local. (A classe NetStream também suporta o download progressivo.)
Um objeto NetStream é um canal em um objeto NetConnection. Em um aplicativo AIR, a classe NetStream despacha
quatro eventos relacionados a DRM:
Evento
Descrição
drmAuthenticate
Definido na classe DRMAuthenticateEvent, esse evento é despachado quando um objeto NetStream tenta
reproduzir conteúdo criptografado por DRM que exija uma credencial de usuário para a autenticação antes da
reprodução.
As propriedades desse evento incluem as propriedades header, usernamePrompt, passwordPrompt e
urlPrompt que podem ser usadas para obter e definir as credenciais do usuário. Esse evento ocorre
repetidamente até que o objeto NetStream receba credenciais de usuário válidas.
drmError
Definido na classe DRMErrorEvent e despachado quando um objeto NetStream encontra um erro relacionado
ao DRM ao tentar reproduzir um arquivo criptografado por DRM. Por exemplo, um objeto de evento de erro
DRM é despachado quando a autorização do usuário falha. Talvez seja porque o usuário não adquiriu os
direitos de visualização do conteúdo ou porque o provedor de conteúdo não oferece suporte ao aplicativo de
visualização.
drmStatus
Definido na classe DRMStatusEvent, é despachado quando o conteúdo criptografado por DRM inicia a
reprodução (quando o usuário for autenticado e autorizado a reproduzir o conteúdo). O objeto
DRMStatusEvent contém informações relacionadas ao comprovante, tais como se o conteúdo pode ser
disponibilizado offline ou quando o comprovante vencerá e o conteúdo não poderá mais ser visualizado.
status
Definido em events.StatusEvent e apenas despachado quando o aplicativo tenta reproduzir o conteúdo
criptografado com DRM, invocando o método NetStream.play(). O valor da propriedade do código de status
será "DRM.encryptedFLV".
A classe NetStream inclui os seguintes métodos específicos de DRM:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 283
Utilização de gerenciamento de direitos digitais
Método
Descrição
resetDRMVouchers()
Exclui todos os dados de comprovação de gerenciamento de direitos digitais armazenados
localmente em cache. O aplicativo deve baixar o comprovante novamente para que o usuário
possa acessar o conteúdo criptografado.
Por exemplo, o código a seguir remove todos os comprovantes do cache:
NetStream.resetDRMVouchers();
setDRMAuthenticationCredentials()
Transmite um conjunto de credenciais de autenticação, a saber, nome de usuário, senha e tipo de
autenticação, ao objeto NetStream para autenticação. Os tipos de autenticação válidos são "drm"
e "proxy" . Com o tipo de autenticação "drm" , as credenciais fornecidas são autenticadas em
relação ao FMRMS. Com o tipo de autenticação "proxy", as credenciais são autenticadas em
comparação ao servidor proxy e devem ser compatíveis àquelas solicitadas por ele. Por exemplo,
a opção "proxy" permite que o aplicativo autentique em comparação a um servidor proxy se uma
empresa solicitar essa etapa antes que o usuário possa acessar a Internet. A menos que seja usada
a autenticação anônima, depois da autenticação proxy, o usuário ainda precisará ser autenticado
comparando ao FMRMS para obter o comprovante e reproduzir o conteúdo. Você pode usar
setDRMAuthenticationcredentials() uma segunda vez, com a opção "drm" para
autenticar em comparação ao FMRMS.
preloadEmbeddedMetadata()
Analisa se um arquivo de mídia local contém metadados incorporados. Quando metadados
relacionados a DRM são encontrados, o AIR chama a função de retorno de chamada
onDRMContentData() .
Além disso, um objeto NetStream chama as funções de retorno de chamada onDRMContentData() e onPlayStatus()
como resultado de uma chamada para o método preloadEmbeddedMetaData(). A função onDRMContentData() é
chamada quando os metadados DRM são encontrados em um arquivo de mídia. A função onPlayStatus() é
chamada quando o arquivo é totalmente analisado. As funções onDRMContentData() e onPlayStatus() devem ser
definidas no objeto client atribuído à ocorrência do NetStream. Se você usar o mesmo objeto NetStream para précarregar comprovantes e reproduzir conteúdo, deverá aguardar pela chamada onPlayStatus() gerada pelo
preloadEmbeddedMetaData() antes de iniciar a reprodução.
No seguinte código, nome de usuário (“administrator”), senha (“password”) e o tipo de autenticação “drm” são
definidos para autenticar o usuário. O método setDRMAuthenticationCredentials() deve fornecer credenciais
correspondentes a credenciais conhecidas e aceitas pelo provedor de conteúdo (as mesmas credenciais de usuário que
forneciam permissão para exibir o conteúdo). O código para reproduzir o vídeo e certificar-se de que foi feita uma
conexão bem-sucedida ao streaming de vídeo não está incluída aqui.
var connection:NetConnection = new NetConnection();
connection.connect(null);
var videoStream:NetStream = new NetStream(connection);
videoStream.addEventListener(DRMAuthenticateEvent.DRM_AUTHENTICATE,
drmAuthenticateEventHandler)
private function drmAuthenticateEventHandler(event:DRMAuthenticateEvent):void
{
videoStream.setDRMAuthenticationCredentials("administrator", "password", "drm");
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 284
Utilização de gerenciamento de direitos digitais
Uso da classe DRMStatusEvent
Um objeto NetStream despacha um objeto DRMStatusEvent quando o conteúdo protegido, que usa DRM, começa a
ser reproduzido com êxito (quando o comprovante é verificado e quando o usuário é autenticado e autorizado a exibir
o conteúdo). DRMStatusEvent também é despachado para usuários anônimos se for permitido acesso a eles. O
comprovante é consultado para verificar se usuários anônimos, que não precisam de autenticação, podem acessar e
reproduzir o conteúdo. Pode ser negado o acesso a usuários anônimos por várias razões. Por exemplo, um usuário
anônimo pode não ter acesso ao conteúdo porque ele expirou.
O objeto DRMStatusEvent contém informações relacionadas ao comprovante, tais como se o conteúdo pode ser
disponibilizado offline ou quando o comprovante vencerá e o conteúdo não poderá mais ser visualizado. O aplicativo
pode usar esses dados para transmitir suas permissões e o status da diretiva do usuário.
Propriedades DRMStatusEvent
A classe DRMStatusEvent inclui as seguintes propriedades:
Propriedade
Descrição
contentData
Um objeto DRMContentData contendo os metadados DRM incorporados no conteúdo.
detail
Uma seqüência de caracteres que explica o contexto do evento de status. No DRM 1.0, o único valor válido é
DRM.voucherObtained.
isAnonymous
Indica se o conteúdo, protegido com criptografia por DRM, está disponível sem exigir que um usuário forneça
credenciais de autenticação (true) ou não (false). Um valor false significa que os usuários devem fornecer um
nome de usuário e uma senha que corresponda aos conhecidos e esperados pelo provedor de conteúdo.
isAvailableOffline
Indica se o conteúdo, protegido com criptografia por DRM, pode ser disponibilizado offline (true) ou não
(false). Para que o conteúdo protegido digitalmente seja disponibilizado offline, seu comprovante deve ser
armazenado em cache na máquina local do usuário.
isLocal
Indica se o comprovante necessário para reproduzir o conteúdo está armazenado em cache localmente.
offlineLeasePeriod
O número restante de dias que o conteúdo pode ser exibido offline.
diretivas
Um objeto personalizado que pode conter propriedades DRM personalizadas.
comprovante
O DRMVoucher.
voucherEndDate
A data absoluta na qual o comprovante expira e o conteúdo não pode mais ser exibido.
Criação de um manipulador DRMStatusEvent
O exemplo a seguir cria um manipulador de eventos que fornece as informações de status de conteúdo DRM para o
objeto NetStream que originou o evento. Adicione esse manipulador de eventos a um objeto NetStream que aponta
para o conteúdo criptografado por DRM.
function drmStatusEventHandler(event:DRMStatusEvent):void
{
trace(event);
}
function drmStatusEventHandler(event:DRMStatusEvent):void
{
trace(event);
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 285
Utilização de gerenciamento de direitos digitais
Uso da classe DRMAuthenticateEvent
O objeto DRMAuthenticateEvent é despachado quando um objeto NetStream tenta reproduzir conteúdo
criptografado por DRM que exija uma credencial de usuário para a autenticação antes da reprodução.
O manipulador DRMAuthenticateEvent é responsável pela coleta das credenciais necessárias (nome de usuário, senha
e tipo) e pela transmissão dos valores ao método NetStream.setDRMAuthenticationCredentials() para
validação. Cada aplicativo do AIR deve fornecer algum mecanismo para obter credenciais do usuário. Por exemplo, o
aplicativo poderia fornecer um usuário com uma interface de usuário simples para digitar valores de nome de usuário
e senha e, opcionalmente, o valor de tipo também. O aplicativo do AIR também deve fornecer um mecanismo para
manipular e limitar as tentativas de autenticação repetidas.
Propriedades DRMAuthenticateEvent
A classe DRMAuthenticateEvent inclui as seguintes propriedades:
Propriedade
Descrição
authenticationType
Indica se as credenciais fornecidas são para autenticação em comparação ao FMRMS (“drm”) ou um servidor
proxy (“proxy”). Por exemplo, a opção "proxy" permite que o aplicativo autentique em comparação a um
servidor proxy se uma empresa solicitar essa etapa antes que o usuário possa acessar a Internet. A menos que
seja usada a autenticação anônima, depois da autenticação proxy, o usuário ainda precisará ser autenticado
comparando ao FMRMS para obter o comprovante e reproduzir o conteúdo. Você pode usar
setDRMAuthenticationcredentials() uma segunda vez, com a opção "drm" para autenticar em comparação ao
FMRMS.
header
O cabeçalho do arquivo de conteúdo criptografado fornecido pelo servidor. Ele contém informações sobre o
contexto do conteúdo criptografado.
netstream
O objeto NetStream que iniciou esse evento.
passwordPrompt
Um prompt para uma credencial de senha, fornecida pelo servidor. A seqüência de caracteres pode incluir
instruções para o tipo de senha necessária.
urlPrompt
Um prompt para uma seqüência de caracteres de URL, fornecida pelo servidor. A seqüência de caracteres
pode fornecer o local para onde o nome de usuário e a senha são enviados.
usernamePrompt
Um prompt para uma credencial de nome de usuário, fornecida pelo servidor. A seqüência de caracteres pode
incluir instruções para o tipo de nome de usuário necessário. Por exemplo, um provedor de conteúdo pode
exigir um endereço de e-mail como o nome de usuário.
Criação de um manipulador DRMAuthenticateEvent
O exemplo a seguir cria um manipulador de eventos que transmite um conjunto de credenciais de autenticação
codificadas ao objeto NetStream que originou o evento. (O código para reproduzir o vídeo e certificar-se de que foi
feita uma conexão bem-sucedida ao streaming de vídeo não está incluída aqui.)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 286
Utilização de gerenciamento de direitos digitais
var connection:NetConnection = new NetConnection();
connection.connect(null);
var videoStream:NetStream = new NetStream(connection);
videoStream.addEventListener(DRMAuthenticateEvent.DRM_AUTHENTICATE,
drmAuthenticateEventHandler)
private function drmAuthenticateEventHandler(event:DRMAuthenticateEvent):void
{
videoStream.setDRMAuthenticationCredentials("administrator", "password", "drm");
}
Criação de uma interface para recuperar credenciais do usuário
No caso em que o conteúdo DRM requer autenticação do usuário, o aplicativo do AIR normalmente precisa recuperar
as credenciais de autenticação do usuário por uma interface de usuário.
Uso da classe DRMErrorEvent
O AIR despacha um objeto DRMErrorEvent quando um objeto NetStream, tentando reproduzir um arquivo
criptografado por DRM, encontra um erro relacionado a DRM. No caso de credenciais de usuário inválidas, o objeto
DRMAuthenticateEvent manipula o erro despachando-o repetidamente até que o usuário insira credenciais válidas ou
o aplicativo do AIR negue tentativas futuras. O aplicativo deve ouvir qualquer evento de erro do DRM para detectar,
identificar e manipular os erros relacionados a DRM.
Se um usuário inserir credenciais válidas, ele ainda pode não exibir o conteúdo criptografado, dependendo dos termos
do comprovante do DRM. Por exemplo, se o usuário estiver tentando exibir o conteúdo em um aplicativo não
autorizado, isto é, um aplicativo não validado pelo editor do conteúdo criptografado. Neste caso, um objeto
DRMErrorEvent é despachado. Os eventos de erro também podem ser disparados se o conteúdo estiver corrompido
ou se a versão do aplicativo não corresponder ao que é especificado pelo comprovante. O aplicativo deve fornecer um
mecanismo apropriado para manipular erros.
Propriedades DRMErrorEvent
A tabela a seguir lista os erros relatados pelo objeto DRMErrorEvent:
Código de erro
principal
Código de erro
secundário
Detalhes do erro
1001
não usado
Falha na autenticação do usuário.
1002
não usado
O FMRMS não suporta SSL (Secure Sockets Layer).
1003
não usado
O conteúdo expirou e não está mais disponível
para exibição.
1004
não usado
Falha na autorização do usuário. Isso pode
ocorrer, por exemplo, se o usuário não tiver
adquirido o conteúdo e, portanto, não possuir os
direitos de exibi-lo.
1005
não usado
Server URL
Descrição
Não é possível conectar ao servidor.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 287
Utilização de gerenciamento de direitos digitais
Código de erro
principal
Código de erro
secundário
Detalhes do erro
1006
não usado
Uma atualização de cliente é necessária, isto é, o
FMRMS requer um novo mecanismo DRM.
1007
não usado
Falha interna genérica.
1008
Código de erro de
descriptografia
detalhada
Chave de licença incorreta.
1009
não usado
O conteúdo FLV está corrompido.
1010
não usado
1011
não usado
A versão do aplicativo não corresponde ao que
está especificado na diretiva.
1012
não usado
Falha na verificação do comprovante associado
ao conteúdo criptografado, indicando que o
conteúdo pode estar corrompido.
1013
não usado
Não foi possível salvar o comprovante associado
ao conteúdo criptografado.
1014
não usado
Falha na verificação da integridade do cabeçalho
FLV, indicando que o conteúdo pode estar
corrompido.
Código de erro
principal
ID de erro
secundária
3300
Código de erro do
servidor de diretivas
da Adobe
O aplicativo detectou um comprovante inválido
associado ao conteúdo.
3301
não usado
Falha na autenticação do usuário.
3302
não usado
SSL não suportado pelo FMRMS.
3303
não usado
O conteúdo expirou e não está mais disponível
para exibição.
3304
não usado
Falha na autorização do usuário. Isso pode
ocorrer mesmo se o usuário estiver autenticado,
por exemplo, se o usuário não tiver adquirido os
direitos para exibir o conteúdo.
3305
não usado
3306
não usado
Uma atualização de cliente é necessária, isto é, o
FMRMS requer um novo mecanismo de cliente
DRM.
3307
não usado
Falha genérica no DRM interno.
3308
Código de erro de
descriptografia
detalhada
Chave de licença incorreta.
3309
não usado
O conteúdo de vídeo do Flash está corrompido.
publisherID:applicationID
Detalhes do erro
Server URL
Descrição
A ID do aplicativo de exibição não corresponde a
uma ID válida suportada pelo editor de
conteúdo.
Descrição
Não é possível conectar ao servidor.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 288
Utilização de gerenciamento de direitos digitais
Código de erro
principal
ID de erro
secundária
Detalhes do erro
Descrição
3310
não usado
publisherID:applicationID
A ID do aplicativo de exibição não corresponde a
uma ID válida suportada pelo editor de
conteúdo. Em outras palavras, o aplicativo de
exibição não é suportado pelo provedor de
conteúdo.
3311
não usado
mín=x:máx=y
A versão do aplicativo não corresponde ao que
está especificado no comprovante.
3312
não usado
Falha na verificação do comprovante associado
ao conteúdo criptografado, indicando que o
conteúdo pode estar corrompido.
3313
não usado
Não foi possível salvar o comprovante associado
ao conteúdo criptografado no Microsafe.
3314
não usado
Falha na verificação da integridade do cabeçalho
FLV, indicando que o conteúdo pode estar
corrompido.
3315
não usado
A reprodução remota do conteúdo protegido por
DRM não é permitida.
3316
não usado
Módulo AdobeCP faltando.
3317
não usado
Falha no carregamento do módulo AdobeCP.
3318
não usado
Versão incompatível do AdobeCP encontrada.
3319
não usado
Ponto de entrada de API do AdobeCP faltando.
3320
não usado
Módulo AdobeCP não autenticado.
Criação de um manipulador DRMErrorEvent
O exemplo a seguir cria um manipulador de eventos para o objeto NetStream que originou o evento. Ele é chamado
quando o NetStream encontra um erro ao tentar reproduzir o conteúdo criptografado por DRM. Normalmente,
quando um aplicativo encontra um erro, ele executa várias tarefas de limpeza, informa o usuário do erro e fornece
opções para resolver o problema.
private function drmErrorEventHandler(event:DRMErrorEvent):void
{
trace(event.toString());
}
Uso da classe DRMManager
Use a classe DRMManager para gerenciar comprovantes e sessões do servidor de direitos de mídia em um aplicativo
AIR. A classe DRMManager está disponível na versão 1.5 ou superior do AIR.
Gerenciamento de comprovante
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 289
Utilização de gerenciamento de direitos digitais
Sempre que um usuário reproduz um arquivo de mídia protegido por DRM, o AIR obtém e armazena em cache o
comprovante da licença necessário para exibir o conteúdo. Se o aplicativo salvar o arquivo localmente e o comprovante
permitir a reprodução offline, o usuário poderá exibir o conteúdo mesmo se não houver conexão ao servidor de
direitos de mídia disponível. Usando o DRMManager e o método preloadEmbeddedMetadata() do NetStream, você
pode pré-armazenar o comprovante em cache, de forma que o aplicativo não precise iniciar a reprodução para obter
a licença necessária para exibir o conteúdo. Por exemplo, seu aplicativo pode baixar o arquivo de mídia e obter o
comprovante enquanto o usuário ainda está online.
Para pré-carregar um comprovante, use o método preloadEmbeddedMetadata() do NetStream para obter um
conteúdo do objeto DRMContentData. O objeto DRMContentData contém a URL e o domínio do servidor dos
direitos de mídia que pode fornecer a licença e descreve se a autenticação é necessária. Com essas informações, você
pode chamar o método loadVoucher() do DRMManager para obter o comprovante e armazená-lo em cache. O fluxo
de trabalho para pré-carregar comprovantes é descrito com mais detalhes em “Pré-carregar comprovantes para
reprodução offline” na página 279.
Gerenciamento de sessão
Você também pode usar o DRMManager para autenticar o usuário para um servidor de direitos de mídia e gerenciar
sessões persistentes.
Chame o método authenticate() do DRMManager para estabelecer uma sessão com o servidor de direitos de mídia.
Quando a autenticação for concluída com êxito, o DRMManager despachará um objeto
DRMAuthenticationCompleteEvent. Esse objeto contém um token de sessão. Você pode salvar esse token para
estabelecer sessões futuras, de forma que o usuário não precise fornecer suas credenciais de conta. Envie o token para
o método setAuthenticationToken() a fim de estabelecer uma nova sessão autenticada. (A expiração de token e outros
atributos são determinados pelas configurações do servidor que o gera. A estrutura de dados do token não deve ser
interpretada pelo código do aplicativo do AIR e pode ser alterada em atualizações futuras do AIR).
É possível transferir tokens de autenticação para outros computadores. Para proteger os tokens, armazene-os no
depósito local criptografado do AIR. Consulte “Armazenamento de dados criptografados” na página 215 para obter
mais informações.
Eventos do DRMStatus
O DRMManager despacha um objeto DRMStatusEvent após uma chamada bem-sucedida para o método
loadVoucher().
Se um comprovante for obtido, a propriedade de detalhes do objeto do evento terá o valor: "DRM.voucherObtained",
e a propriedade voucher conterá o objeto DRMVoucher.
Se um comprovante não for obtido, a propriedade detail ainda terá o valor: "DRM.voucherObtained"; no entanto, a
propriedade voucher será null. Você pode deixar de obter um comprovante se, por exemplo, usar
LoadVoucherSetting de localOnly e não existir um comprovante armazenado em cache localmente.
Se a chamada loadVoucher() não for concluída com êxito, talvez por causa de um erro de autenticação ou
comunicação, o DRMManager despachará um objeto DRMErrorEvent em vez disso.
Eventos DRMAuthenticationComplete
O DRMManager despacha um objeto DRMAuthenticationCompleteEvent quando um usuário é autenticado com
êxito por meio de uma chamada para o método authenticate().
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 290
Utilização de gerenciamento de direitos digitais
No AIR 1.5, o objeto DRMAuthenticationCompleteEvent contém um token reutilizável que pode ser usado para
persistir em autenticações do usuário em sessões do aplicativo. Passe esse token para o método
setAuthenticationToken() do DRMManager, a fim de estabelecer novamente a sessão. (Atributos de token, como
expiração, são definidos pelo criador do token. O AIR não fornece uma API para a examinar atributos de token).
Eventos DRMAuthenticationError
O DRMManager despacha um objeto DRMAuthenticationErrorEvent quando um usuário não pode ser autenticado
com êxito por meio de uma chamada para os métodos authenticate() ou setAuthenticationToken().
Uso da classe DRMContentData
O objeto DRMContentData contém as propriedades de metadados de um arquivo de mídia protegido por DRM. As
propriedades DRMContentData contêm as informações necessárias para obter um comprovante de licença para exibir
o conteúdo.
291
Capítulo 26: Inicialização do aplicativo e
opções de saída
Esta seção discute opções e considerações para inicializar um aplicativo instalado do Adobe® AIR™, bem como opções
e considerações para fechar um aplicativo em execução.
Invocação do aplicativo
Um aplicativo do AIR é invocado quando o usuário (ou o sistema operacional):
• Inicia o aplicativo do shell da área de trabalho.
• Usa o aplicativo como um comando em um shell de linha de comando.
• Abre um tipo de arquivo para o qual o aplicativo é o aplicativo de abertura padrão.
• (Mac OS X) clica no ícone do aplicativo na barra de tarefas do encaixe (esteja o aplicativo em execução ou não no
momento).
• Opta por inicializar o aplicativo do instalador (na extremidade de um novo processo de instalação ou após clicar
duas vezes no arquivo do AIR para um aplicativo já instalado).
• Começa uma atualização de um aplicativo do AIR quando a versão instalada tiver assinalado que está lidando
sozinha com atualizações do aplicativo (incluindo uma declaração <customUpdateUI>true</customUpdateUI>
no arquivo do descritor do aplicativo).
• Visita uma página da Web que hospeda um crachá ou aplicativo do Flash que chama o método
com.adobe.air.AIR launchApplication() especificando as informações de identificação para o aplicativo do
AIR. (O descritor do aplicativo deve incluir também uma declaração
<allowBrowserInvocation>true</allowBrowserInvocation> para que a invocação do navegador seja bemsucedida.) Consulte “Inicialização de um aplicativo do AIR instalado do navegador” na página 320.
Sempre que um aplicativo do AIR for invocado, o AIR despacha um objeto de tipo InvokeEvent invoke pelo objeto
singleton NativeApplication. Para permitir que o tempo de um aplicativo se inicialize e registre um ouvinte de evento,
eventos invoke são enfileirados em vez de descartados. Assim que um ouvinte é registrado, todos os eventos
enfileirados são entregues.
Nota: Quando um aplicativo é invocado usando o recurso de invocação do navegador, o objeto NativeApplication
despacha apenas um evento invoke se o aplicativo ainda não estiver em execução. Consulte “Inicialização de um
aplicativo do AIR instalado do navegador” na página 320.
Para receber eventos invoke, chame o método addEventListener() do objeto NativeApplication
(NativeApplication.nativeApplication). Quando um ouvinte de evento registra um evento invoke, ele também
recebe todos os eventos invoke que ocorreram antes do registro. Eventos invoke enfileirados são despachados um de
cada vez em um curto intervalo após a chamada para addEventListener() ser retornada. Se um novo evento invoke
ocorrer durante esse processo, ele poderá ser despachado antes de um ou mais dos eventos enfileirados. Esse
enfileiramento de eventos permite que você manipule qualquer evento invoke que tenha ocorrido antes de seu código
de inicialização ser executado. Tenha em mente que, se você adicionar um ouvinte de evento depois na execução
(depois da inicialização do aplicativo), ele ainda receberá todos os eventos invoke que ocorreram desde que o
aplicativo foi iniciado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 292
Inicialização do aplicativo e opções de saída
Apenas uma instância de um aplicativo do AIR é iniciada. Quando um aplicativo já em execução é invocado
novamente, o AIR despacha um novo evento invoke para a instância em execução. É de responsabilidade de um
aplicativo do AIR responder a um evento invoke e executar a ação apropriada (como abrir uma janela de um novo
documento).
Um objeto InvokeEvent contém qualquer argumento transmitido ao aplicativo, bem como o diretório a partir do qual
o aplicativo foi invocado. Se o aplicativo foi invocado devido a uma associação de tipo de arquivo, todo o caminho para
o arquivo será incluído nos argumentos de linha de comando. Da mesma forma, se o aplicativo foi invocado devido a
uma atualização de aplicativo, todo o caminho para o arquivo do AIR atualizado será fornecido.
Quando vários arquivos são abertos em uma operação, um único objeto InvokeEvent é despachado no Mac OS X.
Cada arquivo é incluído na matriz arguments. No Windows e no Linux, um objeto InvokeEvent distinto é despachado
para cada arquivo.
Seu aplicativo pode manipular eventos invoke registrando um ouvinte com seu objeto NativeApplication:
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvokeEvent);
air.NativeApplication.nativeApplication.addEventListener(air.InvokeEvent.INVOKE,
onInvokeEvent);
E definindo um ouvinte de evento:
var arguments:Array;
var currentDir:File;
public function onInvokeEvent(invocation:InvokeEvent):void {
arguments = invocation.arguments;
currentDir = invocation.currentDirectory;
}
Captura de argumentos de linha de comando
Os argumentos de linha de comando associados à invocação de um aplicativo do AIR são entregues no evento invoke
despachado pelo objeto NativeApplication. A propriedade InvokeEvent.arguments contém uma matriz dos
argumentos transmitidos pelo sistema operacional quando um aplicativo do AIR é invocado. Se os argumentos
contêm caminhos de arquivos relativos, você pode normalmente resolver os caminhos usando a propriedade
currentDirectory.
Os argumentos transmitidos a um programa do AIR são tratados como seqüências delimitadas de espaço em branco,
a menos que estejam entre aspas duplas:
Argumentos
Matriz
tick tock
{tick,tock}
tick "tick tock"
{tick,tick tock}
"tick" “tock”
{tick,tock}
\"tick\" \"tock\"
{"tick","tock"}
A propriedade InvokeEvent.currentDirectory contém um objeto File que representa o diretório a partir do qual
o aplicativo foi iniciado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 293
Inicialização do aplicativo e opções de saída
Quando um aplicativo é invocado porque um arquivo de um tipo registrado pelo aplicativo é aberto, o caminho nativo
para o arquivo é incluído nos argumentos de linha de comando como uma seqüência de caracteres. (Seu aplicativo é
responsável por abrir ou executar a operação pretendida no arquivo.) Da mesma forma, quando um aplicativo é
programado para se atualizar (em vez de confiar na interface de usuário de atualização do AIR padrão), o caminho
nativo para o arquivo do AIR é incluído quando um usuário clica duas vezes em um arquivo do AIR que contém um
aplicativo com uma ID correspondente do aplicativo.
Você pode acessar o arquivo usando o método resolve() do objeto File currentDirectory:
if((invokeEvent.currentDirectory != null)&&(invokeEvent.arguments.length > 0)){
dir = invokeEvent.currentDirectory;
fileToOpen = dir.resolvePath(invokeEvent.arguments[0]);
}
Você também deve validar se um argumento é realmente um caminho para um arquivo.
Exemplo: log de eventos de invocação
O exemplo a seguir demonstra como registrar ouvintes para e manipular o evento invoke. O exemplo registra todos
os eventos de invocação recebidos e exibe o diretório atual e os argumentos de linha de comando.
Nota: Para criar o seguinte exemplo usando o Adobe® Flash® CS3 Professional ou o Adobe® Flash® CS4 Professional, crie
primeiro um arquivo do Flash (Adobe AIR). No painel de configurações do ActionScript 3.0 (Arquivo > Configurações
de publicação... > botão Configurações), digite o nome InvokeEventLogExample no campo de classe Document. Salve o
arquivo FLA com o nome InvokeEventLogExample.fla. Em seguida, crie um arquivo do ActionScript na mesma pasta.
Digite o seguinte código no arquivo do ActionScript e, em seguida, salve o arquivo com o nome
InvokeEventLogExample.as.
package
{
import
import
import
import
flash.display.Sprite;
flash.events.InvokeEvent;
flash.desktop.NativeApplication;
flash.text.TextField;
public class InvokeEventLogExample extends Sprite
{
public var log:TextField;
public function InvokeEventLogExample()
{
log = new TextField();
log.x = 15;
log.y = 15;
log.width = 520;
log.height = 370;
log.background = true;
addChild(log);
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
}
public function onInvoke(invokeEvent:InvokeEvent):void
{
var now:String = new Date().toTimeString();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 294
Inicialização do aplicativo e opções de saída
logEvent("Invoke event received: " + now);
if (invokeEvent.currentDirectory != null)
{
logEvent("Current directory=" + invokeEvent.currentDirectory.nativePath);
}
else
{
logEvent("--no directory information available--");
}
if (invokeEvent.arguments.length > 0)
{
logEvent("Arguments: " + invokeEvent.arguments.toString());
}
else
{
logEvent("--no arguments--");
}
}
public function logEvent(entry:String):void
{
log.appendText(entry + "\n");
trace(entry);
}
}
}
Inicialização no login
Um aplicativo do AIR pode ser definido para ser inicializado automaticamente quando o usuário atual faz login
definindo NativeApplication.nativeApplication.startAtLogin=true. Depois de definido, o aplicativo é
iniciado automaticamente sempre que o usuário fizer login. Ele continua a ser aberto na inicialização até que a
configuração seja alterada para false, o usuário altera manualmente a configuração pelo sistema operacional ou o
aplicativo é desinstalado. A inicialização no login é uma configuração de tempo de execução.
Nota: O aplicativo não é iniciado quando o sistema do computador é iniciado. Ele é iniciado quando o usuário faz login.
A configuração se aplica apenas ao usuário atual. Além disso, o aplicativo deve ser instalado para definir com êxito a
propriedade startAtLogin como true. Um erro é lançado se a propriedade é definida quando um aplicativo não é
instalado (como quando ele é inicializado com o ADL).
Invocação do navegador
Usando o recurso de invocação do navegador, um site da Web pode inicializar um aplicativo instalado do AIR do
navegador. A invocação do navegador é permitida apenas se o arquivo do descritor do aplicativo define
allowBrowserInvocation como true:
<allowBrowserInvocation>true</allowBrowserInvocation>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 295
Inicialização do aplicativo e opções de saída
Para obter mais informações sobre o arquivo do descritor do aplicativo, consulte “Configuração de propriedades do
aplicativo do AIR” na página 44.
Quando o aplicativo é invocado pelo navegador, o objeto NativeApplication do aplicativo despacha um objeto
BrowserInvokeEvent.
Para receber eventos BrowserInvokeEvent, chame o método addEventListener() do objeto NativeApplication
(NativeApplication.nativeApplication) no aplicativo do AIR. Quando um ouvinte de evento registra um evento
BrowserInvokeEvent, ele também recebe todos os eventos BrowserInvokeEvent que ocorreram antes do registro. Esses
eventos são despachados depois que a chamada a addEventListener() retorna, mas não necessariamente antes de
outros eventos BrowserInvokeEvent, que podem ser recebidos depois do registro. Isso permite que você manipule os
eventos BrowserInvokeEvent ocorridos antes que seu código de inicialização fosse executado (por exemplo, quando o
aplicativo foi inicialmente invocado do navegador). Tenha em mente que, se você adicionar um ouvinte de evento
depois na execução (depois da inicialização do aplicativo), ele ainda receberá todos os eventos BrowserInvokeEvent
ocorridos desde que o aplicativo foi iniciado.
O objeto BrowserInvokeEvent inclui as seguintes propriedades:
Propriedade
Descrição
argumentos
Uma matriz de argumentos (seqüências de caracteres) para transmitir ao aplicativo.
isHTTPS
Se o conteúdo do navegador usa o esquema de URL https (true) ou não (false).
isUserEvent
Se a invocação do navegador resultou em um evento de usuário (como clique do mouse). No AIR 1.0, este
ajuste é sempre true; o AIR exige um evento de usuário para o recurso de invocação do navegador.
sandboxType
O tipo de caixa de proteção para o conteúdo do navegador. Valores válidos são definidos como aqueles que
podem ser usados na propriedade Security.sandboxType e podem ser um dos seguintes:
•
•
Security.APPLICATION – O conteúdo está na caixa de proteção de segurança do aplicativo.
Security.LOCAL_TRUSTED – O conteúdo está na caixa de proteção de segurança local com sistema de
arquivos.
•
Security.LOCAL_WITH_FILE – O conteúdo está na caixa de proteção de segurança local com sistema
de arquivos.
securityDomain
•
Security.LOCAL_WITH_NETWORK – O conteúdo está na caixa de proteção de segurança local com rede.
•
Security.REMOTE — O conteúdo está em um domínio remoto (de rede).
O domínio de segurança para o conteúdo do navegador, como "www.adobe.com" ou
"www.example.org". Essa propriedade é definida apenas para conteúdo na caixa de proteção de segurança
remota (para conteúdo de um domínio de rede). Ele não é definido para conteúdo em uma caixa de proteção
de segurança local ou do aplicativo.
Se você usa o recurso de invocação do navegador, certifique-se de considerar implicações de segurança. Quando um
site da Web inicia um aplicativo do AIR, ele pode enviar dados pela propriedade arguments do objeto
BrowserInvokeEvent. Cuidado ao usar esses dados em qualquer operação confidencial, como carregar código ou
arquivo de APIs. Esse nível de risco depende do que o aplicativo está fazendo com os dados. Se você espera apenas um
site da Web específico para invocar o aplicativo, o aplicativo deve verificar a propriedade securityDomain do objeto
BrowserInvokeEvent. Você também pode exigir que o site invoque o aplicativo para usar HTTPs, o que você pode
verificar marcando a propriedade isHTTPS do objeto BrowserInvokeEvent.
O aplicativo deve validar os dados transmitidos. Por exemplo, se um aplicativo espera para transmitir URLs a um
domínio específico, ele deve validar se as URLs realmente apontam para aquele domínio. Isso pode impedir que um
invasor engane o aplicativo para lhe enviar dados confidenciais.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 296
Inicialização do aplicativo e opções de saída
Nenhum aplicativo deve usar argumentos BrowserInvokeEvent que possam apontar para recursos locais. Por
exemplo, um aplicativo não deve criar objetos File com base em um caminho transmitido do navegador. Se espera-se
que caminhos remotos sejam transmitidos do navegador, o aplicativo deve garantir que os caminhos não usem o
protocolo file:// em vez de um protocolo remoto.
Para obter detalhes sobre como invocar um aplicativo do navegador, consulte “Inicialização de um aplicativo do AIR
instalado do navegador” na página 320.
Encerramento do aplicativo
A maneira mais rápida de encerrar um aplicativo é acionar NativeApplication.nativeApplication.exit(), o
que funciona bem quando seu aplicativo não tem dados para salvar ou recursos externos para limpar. Chamar exit()
fecha todas as janelas e, em seguida, encerra o aplicativo. No entanto, para permitir que janelas ou outros componentes
do seu aplicativo interrompam o processo de encerramento, talvez para salvar dados vitais, despache os eventos de
aviso adequados antes de chamar exit().
Outra consideração sobre como fechar um aplicativo graciosamente é fornecer um único caminho de execução, sem
importar como o processo de encerramento é iniciado. O usuário (ou sistema operacional) pode disparar o
encerramento do aplicativo das seguintes maneiras:
• Fechando a última janela do aplicativo quando NativeApplication.nativeApplication.autoExit for true.
• Selecionando o comando de saída do aplicativo do sistema operacional; por exemplo, quando o usuário escolhe o
comando de sair do aplicativo do menu padrão. Isso só ocorre com o Mac OS. O Windows e o Linux não fornecem
um comando de saída do aplicativo por meio do cromo de sistema.
• Desligando o computador.
Quando um comando de saída é mediado pelo sistema operacional por uma dessas rotas, o NativeApplication
despacha um evento exiting. Se nenhum ouvinte cancelar o evento exiting, qualquer janela aberta será fechada.
Cada janela despacha um evento closing e, em seguida, um close. Se alguma das janelas cancelar o evento closing,
o processo de encerramento será interrompido.
Se a ordem do fechamento das janelas for um problema para o seu aplicativo, ouça o evento exiting do
NativeApplication e feche você mesmo as janelas na ordem adequada. Isso pode ocorrer, por exemplo, se você possuir
uma janela de documento com paletas de ferramentas. Pode ser inconveniente, ou pior, se o sistema fechou as paletas,
mas o usuário decidiu cancelar o comando de sair para salvar alguns dados. No Windows, o único momento que você
obterá o evento exiting é depois de fechar a última janela (quando a propriedade autoExit do objeto
NativeApplication for definida como true).
Para fornecer um comportamento consistente em todas as plataformas, seja a seqüência de saída iniciada pelo cromo
do sistema operacional, por comandos de menu ou pela lógica do aplicativo, observe as seguintes práticas
recomendadas para sair do aplicativo:
1 Sempre despache um evento exiting pelo objeto NativeApplication antes de chamar exit() no código do
aplicativo e verifique se outro componente do seu aplicativo não cancela o evento.
public function applicationExit():void {
var exitingEvent:Event = new Event(Event.EXITING, false, true);
NativeApplication.nativeApplication.dispatchEvent(exitingEvent);
if (!exitingEvent.isDefaultPrevented()) {
NativeApplication.nativeApplication.exit();
}
}
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 297
Inicialização do aplicativo e opções de saída
2 Ouça o evento exiting do aplicativo do objeto NativeApplication.nativeApplication e, no manipulador,
feche qualquer janela (despachando um evento closing primeiro). Execute qualquer tarefa de limpeza necessária,
como salvar dados de aplicativo ou excluir arquivos temporários, após todas as janelas terem sido fechadas. Apenas
use métodos síncronos durante a limpeza para garantir que eles sejam concluídos antes que o aplicativo seja
encerrado.
Se a ordem na qual suas janelas forem fechadas não importar, você pode efetuar um loop pela matriz
NativeApplication.nativeApplication.openedWindows e fechar cada janela sucessivamente. Se a ordem
importar, forneça um modo de fechar as janelas na seqüência correta.
private function onExiting(exitingEvent:Event):void {
var winClosingEvent:Event;
for each (var win:NativeWindow in NativeApplication.nativeApplication.openedWindows) {
winClosingEvent = new Event(Event.CLOSING,false,true);
win.dispatchEvent(winClosingEvent);
if (!winClosingEvent.isDefaultPrevented()) {
win.close();
} else {
exitingEvent.preventDefault();
}
}
if (!exitingEvent.isDefaultPrevented()) {
//perform cleanup
}
}
3 As janelas devem sempre manipular sua própria limpeza ouvindo seus próprios eventos closing.
4 Use apenas um ouvinte exiting no seu aplicativo uma vez que manipuladores chamados anteriormente não
podem saber se os manipuladores subseqüentes irão cancelar o evento exiting (e não seria inteligente confiar na
ordem de execução).
Consulte também
“Configuração de propriedades do aplicativo do AIR” na página 44
“Apresentação de uma interface de usuário de atualização do aplicativo personalizado” na página 330
298
Capítulo 27: Leitura de configurações do
aplicativo
No tempo de execução, você pode obter propriedades do arquivo descritor do aplicativo, bem como a ID do editor do
aplicativo. Elas são definidas nas propriedades applicationDescriptor e publisherID do objeto
NativeApplication.
Leitura do arquivo do descritor do aplicativo.
Você pode ler o arquivo descritor do aplicativo em execução no momento, como um objeto XML, obtendo a
propriedade applicationDescriptor do objeto NativeApplication, conforme segue:
var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor;
Em seguida, você pode acessar dados do descritor do aplicativo, como um objeto XML (E4X), como no seguinte:
var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = appXml.namespace();
var appId = appXml.ns::id[0];
var appVersion = appXml.ns::version[0];
var appName = appXml.ns::filename[0];
air.trace("appId:", appId);
air.trace("version:", appVersion);
air.trace("filename:", appName);
var xmlString = air.NativeApplication.nativeApplication.applicationDescriptor;
Para obter mais informações, consulte “A estrutura do arquivo do descritor do aplicativo” na página 44.
Como obter os identificadores de aplicativo e editor
As IDs de aplicativo e editor juntas, identificam exclusivamente um aplicativo do AIR. Você especifica a ID do
aplicativo no elemento <id> do descritor do aplicativo. A ID de editor é derivada do certificado usado para assinar o
pacote de instalação do AIR.
A ID do aplicativo pode ser lida da propriedade id do objeto NativeApplication, conforme ilustrado no seguinte
código:
trace(NativeApplication.nativeApplication.applicationID);
A ID do editor pode ser lida da propriedade publisherID do NativeApplication:
trace(NativeApplication.nativeApplication.publisherID);
Nota: Quando um aplicativo AIR está sendo executado com ADL, ele não tem uma ID de editor, a menos que uma ID
seja atribuída temporariamente usando o sinalizador -pubID na linha de comando do ADL.
A ID do editor de um aplicativo instalado também pode ser encontrada no arquivo META-INF/AIR/publisherid no
diretório de instalação do aplicativo.
Para obter mais informações, consulte “Sobre identificadores do editor do AIR” na página 322.
299
Capítulo 28: Trabalho com tempo de
execução e informações do sistema
operacional
Esta seção discute os modos pelos quais um aplicativo AIR pode gerenciar associações de arquivo do sistema
operacional, detectar atividade do usuário e obter informações sobre o tempo de execução do Adobe® AIR™.
Gerenciamento de associações de arquivos
Associações entre seu aplicativo e um tipo de arquivo devem ser declaradas no descritor do aplicativo. Durante o
processo de instalação, o instalador do aplicativo AIR associa o aplicativo AIR como o aplicativo de abertura padrão
para cada um dos tipos de arquivo declarados, a menos que outro aplicativo já seja o padrão. O processo de instalação
do aplicativo AIR não substitui uma associação de tipo de arquivo existente. Para se apoderar da associação de outro
aplicativo, chame o método NativeApplication.setAsDefaultApplication() no tempo de execução.
Constitui boa prática verificar se as associações de arquivos esperadas estão em vigor quando seu aplicativo inicializar
Isso porque o instalador do aplicativo AIR não sobrescreve associações de arquivo existentes e porque associações de
arquivo em um sistema de usuário podem mudar a qualquer momento. Quando outro aplicativo tem a associação de
arquivo atual, também é boa prática solicitar ao usuário antes de se apoderar de uma associação existente.
Os métodos seguintes da classe NativeApplication permitem que um aplicativo gerencie associações de arquivos. Cada
um dos métodos toma a extensão de tipo de arquivo como um parâmetro:
Método
Descrição
isSetAsDefaultApplication()
Retorna true se o aplicativo AIR está associado atualmente ao tipo de arquivo especificado.
setAsDefaultApplication()
Cria a associação entre o aplicativo AIR e a ação aberta do tipo de arquivo.
removeAsDefaultApplication()
Remove a associação entre o aplicativo AIR e o tipo de arquivo.
getDefaultApplication()
Reporta o caminho do aplicativo que está associado atualmente ao tipo de arquivo.
O AIR só pode gerenciar associações para os tipos de arquivo originalmente declarados no descritor do aplicativo.
Você não pode obter informações sobre as associações de um tipo de arquivo não declarado, mesmo que um usuário
tenha criado manualmente a associação entre esse tipo de arquivo e seu aplicativo. Chamar algum dos métodos de
gerenciamento de associação de arquivo com a extensão de um tipo de arquivo não declarado no descritor do
aplicativo faz com que o aplicativo lance uma exceção de tempo de execução.
Para obter informações sobre declarar tipos de arquivos no descritor do aplicativo, consulte “Declaração de
associações de tipo de arquivo” na página 52.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 300
Trabalho com tempo de execução e informações do sistema operacional
Obtenção da versão do tempo de execução e do nível de
patch
O objeto NativeApplication tem uma propriedade runtimeVersion, que é a versão do tempo de execução em que o
aplicativo está sendo executado (uma string, como "1.0.5"). O objeto NativeApplication também tem uma
propriedade runtimePatchLevel, que é o nível de patch do tempo de execução (um número, como 2960). O código
seguinte usa estas propriedades:
trace(NativeApplication.nativeApplication.runtimeVersion);
trace(NativeApplication.nativeApplication.runtimePatchLevel);
Detecção de recursos do AIR
Para um arquivo que esteja reunido com o aplicativo Adobe AIR, a propriedade Security.sandboxType está definida
como o valor definido pela constante Security.APPLICATION. Você pode carregar o conteúdo (que pode ou não
conter APIs específicas ao AIR) baseado em um arquivo estar na caixa de proteção de segurança do Adobe AIR, como
ilustrado no código seguinte:
if (Security.sandboxType == Security.APPLICATION)
{
// Load SWF that contains AIR APIs
}
else
{
// Load SWF that does not contain AIR APIs
}
Todos os recursos não instalado com o aplicativo AIR são atribuídos às mesmas caixas de proteção de segurança como
seriam atribuídos pelo Adobe® Flash® em um navegador da Web. Recursos remotos são colocados em caixas de
proteção, de acordo com seus domínios de origem, e recursos locais são colocados na caixa de proteção local com rede,
local com sistema de arquivos ou local confiável.
Você pode verificar se a propriedade estática Capabilities.playerType está definida como "Desktop" para ver se
o conteúdo está sendo executado no tempo de execução (e não em execução no Flash Player em execução em um
navegador).
Para obter mais informações, consulte “Segurança do AIR” na página 23.
Rastreamento de presença do usuário
O objeto NativeApplication despacha dois eventos que o ajudam a detectar quando o usuário está usando o
computador ativamente. Se não for detectada nenhuma atividade do mouse nem do teclado no intervalo de tempo
determinado pela propriedade NativeApplication.idleThreshold, o NativeApplication despacha um evento
userIdle. Quando ocorrer a próxima entrada de mouse ou teclado, o objeto NativeApplication despachará um evento
userPresent. O intervalo idleThreshold é medido em segundos e tem um valor padrão de 300 (5 minutos). Você
também ode obter o número de segundos desde a última entrada de usuário da propriedade
NativeApplication.nativeApplication.lastUserInput.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 301
Trabalho com tempo de execução e informações do sistema operacional
As linhas seguintes de código definem o limite de ociosidade para 2 minutos e ouvem tanto eventos userIdle como
userPresent:
NativeApplication.nativeApplication.idleThreshold = 120;
NativeApplication.nativeApplication.addEventListener(Event.USER_IDLE, function(event:Event) {
trace("Idle");
});
NativeApplication.nativeApplication.addEventListener(Event.USER_PRESENT,
function(event:Event) {
trace("Present");
});
Nota: Apenas um único evento userIdle é despachado entre quaisquer dois eventos userPresent.
302
Capítulo 29: Monitoramento de
conectividade de rede
O Adobe® AIR™ oferece os meios para verificar alterações na conectividade de rede do computador em que um
aplicativo AIR esteja instalado. Essa informação é útil caso um aplicativo utilize dados obtidos da rede. Além disso, o
aplicativo pode verificar a disponibilidade de um serviço de rede.
Detecção de alterações na conectividade de rede
Seu aplicativo AIR pode ser executado em ambientes com conectividade de rede incerta e em mudança. Para ajudar
um aplicativo a gerenciar conexões em recursos on-line, o Adobe AIR envia um evento de mudança de rede sempre
que uma conexão de rede se torna disponível ou indisponível. O objeto NativeApplication do aplicativo despacha o
evento de mudança de rede. Para reagir a esse evento, adicione um ouvinte:
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange);
E defina uma função do manipulador de eventos:
function onNetworkChange(event:Event)
{
//Check resource availability
}
O evento Event.NETWORK_CHANGE não indica uma mudança em toda a atividade de rede, mas apenas que uma
conexão de rede sofreu mudança. O AIR não tenta interpretar o significado da mudança de rede. Um computador em
rede pode ter várias conexões reais e virtuais, portanto, perder uma conexão não significa necessariamente perder um
recurso. Por outro lado, novas conexões também não garantem melhor disponibilidade de recursos. Às vezes uma
nova conexão pode até bloquear o acesso a recursos anteriormente disponíveis (por exemplo, ao se conectar a uma
VPN).
Em geral, a única maneira de um aplicativo determinar se ele pode se conectar a um recurso remoto é por tentativa.
Para essa finalidade, as estruturas de monitoramento de serviço do pacote air.net fornecem aplicativos AIR com um
meio baseado em evento de responder às mudanças na conectividade de rede para um host especificado.
Nota: A estrutura de monitoramento de serviço detecta se um servidor responde de maneira aceitável a uma solicitação.
Isso não garante conectividade total. Serviços dimensionáveis da Web geralmente usam aparatos de cache e
balanceamento de carga para redirecionar o tráfego para um cluster de servidores Web. Nessa situação, provedores de
serviço só oferecem um diagnóstico parcial de conectividade de rede.
Noções básicas de monitoramento de serviço
A estrutura de monitor de serviço, separada da estrutura do AIR, reside no arquivo servicemonitor.swc. Para usar a
estrutura, o arquivo servicemonitor.swc deve ser incluído em seu processo de construção.
Importante: Para usar essas classes no Adobe® Flash® CS3 Professional, arraste o componente ServiceMonitorShim do
painel Componentes para a Biblioteca e, em seguida, adicione a seguinte declaração import ao código do ActionScript 3.0:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 303
Monitoramento de conectividade de rede
import air.net.*;
Para usar essas classes no Adobe® Flash® CS4 Professional:
1 Selecione o comando Arquivo > Configurações de publicação.
2 Clique no botão Configurações do ActionScript 3.0. Selecione Caminho da biblioteca.
3 Clique no botão Procurar SWC e procure por Adobe Flash CS4/AIK1.1/frameworks/libs/air/servicemoniter.swc.
4 Clique no botão OK.
5 Adicione a seguinte instrução de importação ao código do ActionScript 3.0:
import air.net.*;
A classe ServiceMonitor implementa a estrutura para monitorar serviços de rede e oferece uma funcionalidade básica
para monitores de serviço. Por padrão, uma ocorrência da classe ServiceMonitor despacha eventos relacionados à
conectividade de rede. O objeto ServiceMonitor despacha esses eventos quando a ocorrência é criada e sempre que
uma mudança de rede é detectada pelo Adobe AIR. Além disso, você pode definir a propriedade pollInterval de
uma ocorrência ServiceMonitor para verificar a conectividade em um intervalo especificado em milissegundos,
independentemente de eventos gerais de conectividade de rede. Um objeto ServiceMonitor não verifica a
conectividade de rede até que o método start() seja chamado.
A classe URLMonitor, uma subclasse da classe ServiceMonitor, detecta mudanças na conectividade HTTP para um
URLRequest especificado.
A classe SocketMonitor, também uma subclasse da classe ServiceMonitor, detecta mudanças na conectividade em um
host especificado de uma porta especificada.
Detecção de conectividade HTTP
A classe URLMonitor determina se podem ser feitas solicitações HTTP a um endereço especificado na porta 80 (a
porta típica para comunicação HTTP). O código seguinte usa uma instância da classe URLMonitor para detectar
mudanças de conectividade no site da Adobe:
import air.net.URLMonitor;
import flash.net.URLRequest;
import flash.events.StatusEvent;
var monitor:URLMonitor;
monitor = new URLMonitor(new URLRequest('http://www.adobe.com'));
monitor.addEventListener(StatusEvent.STATUS, announceStatus);
monitor.start();
function announceStatus(e:StatusEvent):void {
trace("Status change. Current status: " + monitor.available);
}
Detecção de conectividade de soquete
Aplicativos AIR também podem usar conexões de soquete para conectividade modelo empurrar. Firewalls e
roteadores de rede geralmente restringem a comunicação em rede em portas não autorizadas, por questões de
segurança. Por esse motivo, os desenvolvedores devem considerar que usuários podem não ter recursos para fazer
conexões de rede.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 304
Monitoramento de conectividade de rede
Semelhante ao exemplo URLMonitor, o código seguinte usa uma ocorrência da classe SocketMonitor para detectar
mudanças na conectividade em uma conexão de soquete em 6667, uma porta comum do IRC:
import air.net.ServiceMonitor;
import flash.events.StatusEvent;
socketMonitor = new SocketMonitor('www.adobe.com',6667);
socketMonitor.addEventListener(StatusEvent.STATUS, socketStatusChange);
socketMonitor.start();
function announceStatus(e:StatusEvent):void {
trace("Status change. Current status: " + socketMonitor.available);
}
305
Capítulo 30: Solicitações de URL e rede
A nova funcionalidade do Adobe AIR relacionada à especificação de solicitações de URL não está disponível para
conteúdo SWF executado no navegador. Essa funcionalidade só está disponível para conteúdo na caixa de proteção de
segurança do aplicativo. Esta seção descreve os recursos de URLRequest no tempo de execução e analisa como a API
de rede altera o conteúdo do AIR.
Para obter outras informações sobre o uso dos recursos de rede e comunicação do Adobe® ActionScript® 3.0, consulte
Programação do Adobe ActionScript 3.0.
Uso da classe URLRequest
Com a classe URLRequest, você pode definir mais do que simplesmente a string da URL. O AIR adicionou algumas
novas propriedades à classe URLRequest, que só estão disponíveis para conteúdo do AIR executado na caixa de
proteção de segurança do aplicativo. O conteúdo no tempo de execução pode definir URLs usando novos esquemas
de URL (além de esquemas padrão, como file e http).
Propriedades de URLRequest
A classe URLRequest inclui as seguintes propriedades, que estão disponíveis para conteúdo somente na caixa de
proteção de segurança de aplicativos do AIR:
Propriedade
Descrição
followRedirects
Especifica se os redirecionamentos devem ser seguidos (true, o valor padrão) ou não (false). Esta
propriedade só é suportada no tempo de execução.
manageCookies
Especifica se a pilha de protocolo HTTP deve gerenciar cookies (true, o valor padrão) ou não (false) desta
solicitação. Esta propriedade só é suportada no tempo de execução.
authenticate
Especifica se as solicitações de autenticação relativas a esta solicitação devem ser manipuladas (true). Esta
propriedade só é suportada no tempo de execução. O padrão é autenticar as solicitações, o que pode fazer
com que seja exibida uma caixa de diálogo de autenticação se o servidor exigir a apresentação das credenciais.
Também é possível definir o nome de usuário e a senha (consulte “Configuração de padrões de URLRequest”
na página 306.
cacheResponse
Especifica se os dados de respostas bem-sucedidas relacionados a esta solicitação devem ser armazenados em
cache. Esta propriedade só é suportada no tempo de execução. O padrão é armazenar a resposta em cache
(true).
useCache
Especifica se o cache local deve ser consultado antes que URLRequest saia em busca dos dados. Esta
propriedade só é suportada no tempo de execução. O padrão (true) é usar a versão armazenada no cache
local, se disponível.
userAgent
Especifica a string user-agent a ser usada na solicitação HTTP.
As seguintes propriedades de um objeto URLRequest podem ser definidas por conteúdo em qualquer caixa de
proteção (e não somente na caixa de proteção de segurança de aplicativos do AIR):
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 306
Solicitações de URL e rede
Propriedade
Descrição
contentType
O tipo de conteúdo MIME de qualquer dado enviado com a solicitação de URL.
data
Um objeto contendo dados a serem transmitidos com a solicitação de URL.
digest
Uma "compilação" segura em um arquivo em cache que monitora o cache do Adobe® Flash® Player.
method
Controla o método de solicitação HTTP, como uma operação GET ou POST. (O conteúdo em execução no
domínio de segurança do aplicativo do AIR pode especificar strings diferentes de "GET" ou "POST" como a
propriedade method. É permitido qualquer verbo HTTP, e "GET" é o método padrão. Consulte “Segurança do
AIR” na página 23.)
requestHeaders
A matriz de cabeçalhos de solicitação HTTP a ser acrescentada à solicitação HTTP.
url
Especifica a URL a ser solicitada.
Nota: A classe HTMLLoader tem propriedades relacionadas para configurações que pertencem ao conteúdo carregado
por um objeto HTMLLoader. Para obter detalhes, consulte “Sobre a classe HTMLLoader” na página 233 .
Configuração de padrões de URLRequest
A classe URLRequestDefaults permite definir configurações padrão para objetos URLRequest. Por exemplo, o código
abaixo define os valores padrão para as propriedades manageCookies e useCache:
URLRequestDefaults.manageCookies = false;
URLRequestDefaults.useCache = false;
air.URLRequestDefaults.manageCookies = false;
air.URLRequestDefaults.useCache = false;
A classe URLRequestDefaults inclui um método setLoginCredentialsForHost() que permite especificar um nome
de usuário e uma senha padrão para uso em um determinado host. O host, definido no parâmetro hostname do
método, pode ser um domínio, como "www.example.com", ou um domínio e um número de porta, como
"www.example.com:80". Observe que "example.com", "www.example.com" e "sales.example.com" são todos
considerados hosts únicos.
Essas credenciais só serão utilizadas se exigidas pelo servidor. Se o usuário já foi autenticado (por exemplo, usando a
caixa de diálogo de autenticação), você não poderá alterar o usuário autenticado chamando o método
setLoginCredentialsForHost().
Por exemplo, o seguinte código define o nome de usuário e a senha padrão que devem ser utilizados em
www.example.com:
URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X");
air.URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X");
Cada propriedade de configurações URLRequestDefaults aplica-se somente ao domínio de aplicativo do conteúdo que
define a propriedade. No entanto, o método setLoginCredentialsForHost() aplica-se ao conteúdo em todos os
domínios de aplicativo dentro de um aplicativo do AIR. Dessa maneira, um aplicativo pode fazer logon em um host e
ter todo o conteúdo no aplicativo conectado com as credenciais especificadas.
Para obter mais informações, consulte a classe URLRequestDefaults na Referência dos componentes e da linguagem
do ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_br).
Uso de esquemas de URL do AIR em URLs
Os esquemas de URL padrão, como os seguintes, estão disponíveis quando são definidas URLs em qualquer caixa de
proteção de segurança do AIR:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 307
Solicitações de URL e rede
http: e https:
Use-os da mesma forma que você os utilizaria em um navegador da Web.
file:
Use para especificar um caminho relativo à raiz do sistema de arquivos. Por exemplo:
file:///c:/AIR Test/test.txt
Também é possível utilizar os seguintes esquemas ao definir uma URL para conteúdo em execução na caixa de
proteção de segurança do aplicativo:
app:
Use para especificar um caminho relativo ao diretório raiz do aplicativo instalado (o diretório que contém o arquivo
de descrição do aplicativo instalado). Por exemplo, o seguinte caminho aponta para um subdiretório de recursos do
diretório do aplicativo instalado:
app:/resources
Quando executado no aplicativo ADL, o diretório de recursos do aplicativo é definido como o diretório que contém o
arquivo de descrição do aplicativo.
app-storage:
Use para especificar um caminho relativo ao diretório de armazenamento do aplicativo. Para cada aplicativo instalado,
o AIR define um diretório de armazenamento do aplicativo exclusivo para cada usuário, que é um local útil para
armazenar dados específicos desse aplicativo. Por exemplo, o caminho a seguir aponta para o arquivo prefs.xml em
um subdiretório de configurações do diretório de armazenamento do aplicativo:
app-storage:/settings/prefs.xml
A localização do diretório de armazenamento do aplicativo baseia-se no nome do usuário, na ID do aplicativo e na ID
do editor:
• No Mac OS, em:
/Users/user name/Library/Preferences/applicationID.publisherID/Local Store/
Por exemplo:
/Users/babbage/Library/Preferences/com.example.TestApp.02D88EEED35F84C264A183921344EEA353
A629FD.1/Local Store
• No Windows: no diretório Documents and Settings, em:
user name/Application Data/applicationID.publisherID/Local Store/
Por exemplo:
C:\Documents and Settings\babbage\Application
Data\com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Local Store
• No Linux - In:
/home/user name/.appdata/applicationID.publisherID/Local Store/
Por exemplo:
/home/babbage/.appdata/com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Loc
al Store
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 308
Solicitações de URL e rede
A URL (e a propriedade url) de um objeto File criado com File.applicationStorageDirectory usa o esquema de
URL app-storage, como abaixo:
var dir:File = File.applicationStorageDirectory;
dir = dir.resolvePath("preferences");
trace(dir.url); // app-storage:/preferences
var dir = air.File.applicationStorageDirectory;
dir = dir.resolvePath("prefs.xml");
air.trace(dir.url); // app-storage:/preferences
mailto:
Você pode usar o esquema mailto em objetos URLRequests enviados para a função navigateToURL(). Consulte
“Abertura de uma URL no navegador da Web padrão do sistema” na página 308.
Uso de esquemas de URL no AIR
Você pode usar um objeto URLRequest que utilize qualquer um desses esquemas de URL para definir a solicitação de
URL para inúmeros objetos diferentes, como FileStream ou Sound. Também é possível usar esses esquemas em um
conteúdo HTML em execução no AIR; por exemplo, você pode usá-los no atributo src de uma tag img.
Porém, você só pode usar estes esquemas de URL específicos do AIR (app: e app-storage:) no conteúdo localizado
na caixa de proteção de segurança do aplicativo. Para obter mais informações, consulte “Segurança do AIR” na
página 23.
Esquemas de URL proibidos
Algumas APIs permitem iniciar conteúdo em um navegador da Web. Por motivo de segurança, alguns esquemas de
URL são proibidos quando essas APIs são utilizadas no AIR. A lista de esquemas proibidos depende da caixa de
proteção de segurança do código que usa a API. Para obter detalhes, consulte “Abertura de uma URL no navegador da
Web padrão do sistema” na página 308 .
Alterações feitas na classe URLStream
A classe URLStream fornece acesso de baixo nível para download de dados de URLs. No tempo de execução, a classe
URLStream inclui um novo evento: httpResponseStatus. Diferentemente do evento httpStatus, o evento
httpResponseStatus é fornecido antes de qualquer dado de resposta. O evento httpResponseStatus (definido na
classe HTTPStatusEvent) inclui uma propriedade responseURL, que é a URL da qual a resposta foi retornada, e uma
propriedade responseHeaders, que é uma matriz de objetos URLRequestHeader representando os cabeçalhos de
resposta retornados pela resposta.
Abertura de uma URL no navegador da Web padrão do
sistema
Você pode usar a função navigateToURL() para abrir uma URL no navegador da Web padrão do sistema. Para o
objeto URLRequest que você passar como o parâmetro request desta função, só é usada a propriedade url.
var url = "http://www.adobe.com";
var urlReq = new air.URLRequest(url);
air.navigateToURL(urlReq);
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 309
Solicitações de URL e rede
Nota: Na utilização da função navigateToURL(), o tempo de execução trata um objeto URLRequest que usa o método
POST (um que tenha a propriedade method definida como URLRequestMethod.POST)
Quando é usada a função navigateToURL(), são permitidos esquemas de URL baseados na caixa de proteção de
segurança do código chamando-se a função navigateToURL().
Algumas APIs permitem iniciar conteúdo em um navegador da Web. Por motivo de segurança, alguns esquemas de
URL são proibidos quando essas APIs são utilizadas no AIR. A lista de esquemas proibidos depende da caixa de
proteção de segurança do código que usa a API. (Para obter detalhes sobre caixas de proteção de segurança, consulte
“Segurança do AIR” na página 23.)
Caixa de proteção do aplicativo
Os esquemas abaixo são permitidos. Use-os da mesma forma que você os utilizaria em um navegador da Web.
•
http:
•
https:
•
file:
•
mailto: — O AIR direciona essas solicitações para o aplicativo de email do sistema registrado
•
app:
•
app-storage:
Todos os demais esquemas de URL são proibidos.
Caixa de proteção remota
Os esquemas abaixo são permitidos. Use-os da mesma forma que você os utilizaria em um navegador da Web.
•
http:
•
https:
•
mailto: — O AIR direciona essas solicitações para o aplicativo de email do sistema registrado
Todos os demais esquemas de URL são proibidos.
Caixa de proteção Local com arquivo
Os esquemas abaixo são permitidos. Use-os da mesma forma que você os utilizaria em um navegador da Web.
•
file:
•
mailto: — O AIR direciona essas solicitações para o aplicativo de email do sistema registrado
Todos os demais esquemas de URL são proibidos.
Caixa de proteção Local com rede
Os esquemas abaixo são permitidos. Use-os da mesma forma que você os utilizaria em um navegador da Web.
•
http:
• https:
•
mailto: — O AIR direciona essas solicitações para o aplicativo de email do sistema registrado
Todos os demais esquemas de URL são proibidos.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 310
Solicitações de URL e rede
Caixa de proteção Local confiável
Os esquemas abaixo são permitidos. Use-os da mesma forma que você os utilizaria em um navegador da Web.
•
file:
•
http:
• https:
•
mailto: — O AIR direciona essas solicitações para o aplicativo de email do sistema registrado
Todos os demais esquemas de URL são proibidos.
311
Capítulo 31: Comunicação entre
aplicativos
A classe LocalConnection permite comunicações entre aplicativos Adobe® AIR™, bem como entre aplicativos AIR e
conteúdo SWF em execução no navegador.
O método connect() da classe LocalConnection usa um parâmetro connectionName para identificar aplicativos. No
conteúdo em execução na caixa de proteção de segurança do aplicativo AIR (conteúdo instalado com o aplicativo
AIR), o AIR usa a string app# seguida pela ID do aplicativo, seguida por um caractere de ponto (.), seguido pela ID do
editor para o aplicativo AIR (definido no arquivo do descritor do aplicativo) no lugar do domínio usado pelo conteúdo
SWF em execução no navegador. Por exemplo, um connectionName para um aplicativo com a ID de aplicativo
com.example.air.MyApp, o connectionName e a ID do editor B146A943FBD637B68C334022D304CEA226D129B4
é resolvido
para"app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4:connectionName". (Para
obter mais informações, consulte Definição das informações básicas do aplicativo e “Como obter os identificadores de
aplicativo e editor” na página 298.)
Quando você permite que outro aplicativo AIR se comunique com seu aplicativo pela conexão local, é preciso chamar
o allowDomain() do objeto LocalConnection, passando o nome de domínio da conexão local. Para um aplicativo
AIR, esse nome de domínio é formado a partir das IDs do aplicativo e do editor, da mesma forma que na string de
conexão. Por exemplo, se o aplicativo AIR de envio tem uma ID de aplicativo de com.example.air.FriendlyApp e
uma ID de editor de 214649436BD677B62C33D02233043EA236D13934, a string de domínio a usar para permitir que
esse aplicativo se conecte é:
app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.
Nota: Ao executar seu aplicativo com ADL (ou outra ferramenta de desenvolvimento, como o Flash CS3, Flex Builder
ou Dreamweaver), a ID do editor será nula e deverá ser omitida da string do domínio. Ao instalar e executar seu
aplicativo, a ID do editor deverá ser incluída na string do domínio. Você pode atribuir uma ID do editor temporária
usando os argumentos de linha de comando do ADL. Use uma ID do editor temporária para testar se a string de conexão
e o nome de domínio estão formatados corretamente.
312
Capítulo 32: Distribuição, instalação e
execução de aplicativos do AIR
Os aplicativos do AIR são distribuídos como um único arquivo de instalação do AIR, que contém o código do
aplicativo e todos os ativos. Você pode distribuir esse arquivo por qualquer um dos meios típicos, como por download,
e-mail ou mídia física, como CD-ROM. Os usuários podem instalar o aplicativo clicando duas vezes no arquivo do
AIR. Você pode usar o recurso de instalação direta, que permite aos usuários instalar seu aplicativo do AIR (e o Adobe®
AIR™, se necessário) clicando em um único link em uma página da Web.
Antes que ele possa ser distribuído, um arquivo de instalação do AIR deve ser empacotado e assinado com um
certificado de assinatura de código e uma chave privada. Assinar digitalmente o arquivo de instalação fornece a
garantia de que o seu aplicativo não foi alterado desde que ele foi assinado. Além disso, se uma autoridade de
certificação confiável emitiu o certificado digital, seus usuários podem confirmar sua identidade como o editor e
signatário. O arquivo do AIR é assinado quando o aplicativo é empacotado com a ferramenta para desenvolvedores do
AIR (ADT).
Para obter informações sobre como empacotar um aplicativo em um arquivo do AIR usando a atualização do AIR para
Flash, consulte “Criação de arquivos do aplicativo AIR e do instalador” na página 15.
Para obter informações sobre como empacotar um aplicativo em um arquivo do AIR usando o SDK do Adobe® AIR™,
consulte “Empacotamento de um arquivo de instalação do AIR usando o ADT (ferramenta para desenvolvedores do
AIR)” na página 357.
Instalação e execução de um aplicativo do AIR da área de
trabalho
Você pode simplesmente enviar o arquivo do AIR ao destinatário. Por exemplo, você pode enviar o arquivo do AIR
como um anexo de e-mail ou um link em uma página da Web.
Depois que o usuário baixar o aplicativo do AIR, ele deverá seguir estas instruções para instalá-lo:
1 Clique duas vezes no arquivo do AIR.
O Adobe AIR já deve estar instalado no computador.
2 Na janela de instalação, deixe as configurações padrão selecionadas e clique em Continuar.
No Windows, o AIR faz automaticamente o seguinte:
• Instala o aplicativo no diretório Arquivos de Programas
• Cria um atalho na área de trabalho para o aplicativo
• Cria um atalho no menu Iniciar
• Adiciona uma entrada para o aplicativo no Painel de Controle Adicionar ou Remover Programas
No Mac OS, por padrão, o aplicativo é adicionado ao diretório Aplicativos.
Se o aplicativo já estiver instalado, o instalador oferece ao usuário a opção de abrir a versão existente do aplicativo
ou atualizar para a versão no arquivo do AIR obtido por download. O instalador identifica o aplicativo usando a ID
do aplicativo e a ID do editor no arquivo do AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 313
Distribuição, instalação e execução de aplicativos do AIR
3 Quando a instalação estiver concluída, clique em Concluir.
No Mac OS, para instalar uma versão atualizada de um aplicativo, o usuário precisa de privilégios adequados do
sistema para instalar no diretório do aplicativo. No Windows e no Linux, um usuário precisa de privilégios
administrativos.
Um aplicativo também pode instalar uma versão nova via ActionScript ou JavaScript. Para obter mais informações,
consulte “Atualização de aplicativos do AIR” na página 328.
Depois que o aplicativo do AIR está instalado, um usuário simplesmente clica duas vezes no ícone do aplicativo para
executá-lo, como qualquer outro aplicativo de área de trabalho.
• No Windows, clique duas vezes no ícone do aplicativo (que está instalado na área de trabalho ou em uma pasta) ou
selecione o aplicativo no menu Iniciar.
• No Linux, clique duas vezes no ícone do aplicativo (que está instalado na área de trabalho ou em uma pasta) ou
selecione o aplicativo no menu aplicativos.
• No Mac OS, clique duas vezes no aplicativo na pasta em que ele foi instalado. O diretório de instalação padrão é o
diretório /Aplicativos.
O recurso de instalação direta do AIR permite que um usuário instale um aplicativo do AIR clicando em um link em
uma página da Web. O recurso de invocação do navegador do AIR permite que um usuário execute um aplicativo do
AIR instalado clicando em um link em uma página da Web. Esses recursos são descritos na seção a seguir.
Instalação e execução de aplicativos do AIR de uma
página da Web
O recurso de instalação direta permite que você incorpore um arquivo SWF em uma página da Web que permite ao
usuário instalar um aplicativo do AIR do navegador. Se o tempo de execução não for instalado, o recurso de instalação
direta instalará o tempo de execução. O recurso de instalação direta permite que usuários instalem o aplicativo do AIR
sem salvar o arquivo do AIR em seus computadores. Incluído no SDK do AIR está um arquivo badge.swf, que permite
a você usar facilmente o recurso de instalação direta. Para obter detalhes, consulte “Usando o arquivo badge.swf para
instalar um aplicativo do AIR” na página 314.
Para obter uma demonstração de como usar o recurso de instalação direta, consulte o artigo de amostra de início
rápido Distribuição de um aplicativo do AIR pela Web
(http://www.adobe.com/go/learn_air_qs_seamless_install_en).
Sobre a personalização de badge.swf para instalação direta
Além de usar o arquivo badge.swf fornecido com o SDK, você pode criar seu próprio arquivo SWF para usar em uma
página do navegador. Seu arquivo SWF personalizado pode interagir com o tempo de execução das seguintes
maneiras:
• Ele pode instalar um aplicativo do AIR. Consulte “Instalação de um aplicativo do AIR do navegador” na página 319.
• Ele pode verificar se um aplicativo do AIR específico está instalado. Consulte “Verificar por uma página da Web se
um aplicativo do AIR está instalado” na página 318.
• Ele pode verificar se o tempo de execução está instalado. Consulte “Verificar se o tempo de execução está instalado”
na página 317.
• Ele pode iniciar um aplicativo do AIR instalado no sistema do usuário. Consulte “Inicialização de um aplicativo do
AIR instalado do navegador” na página 320.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 314
Distribuição, instalação e execução de aplicativos do AIR
Esses recursos são todos fornecidos ao chamar as APIs em um arquivo SWF hospedado em adobe.com: air.swf. Esta seção
descreve como usar e personalizar o arquivo badge.swf e como chamar as APIs do air.swf do seu próprio arquivo SWF.
Além disso, um arquivo SWF em execução no navegador pode se comunicar com um aplicativo do AIR em execução
usando a classe LocalConnection. Para obter mais informações, consulte “Comunicação entre aplicativos” na
página 311.
Importante: Os recursos descritos nesta seção (e as APIs no arquivo air.swf) exigem que o usuário final tenha a
atualização 3 do Adobe® Flash® Player 9 instalada no navegador da Web no Windows ou Mac OS. No Linux, o recurso
de instalação contínua requer o Flash Player 10 (versão 10,0,12,36 ou posterior). Você pode escrever códigos para verificar
a versão instalada do Flash Player e fornecer uma interface alternativa ao usuário se a versão exigida do Flash Player
não for instalada. Por exemplo, se uma versão mais antiga do Flash Player for instalada, você poderia fornecer um link
para a versão de download do arquivo do AIR (em vez de usar o arquivo badge.swf ou a API do air.swf para instalar um
aplicativo).
Usando o arquivo badge.swf para instalar um aplicativo do AIR
Incluído no SDK do AIR está um arquivo badge.swf, que permite a você usar facilmente o recurso de instalação direta.
O badge.swf pode instalar o tempo de execução e um aplicativo do AIR de um link em uma página da Web. O arquivo
badge.swf e seu código-fonte são fornecidos a você para distribuição no seu site da Web.
As instruções nesta seção fornecem informações sobre a definição de parâmetros do arquivo badge.swf fornecido pela
Adobe. Também fornecemos o código-fonte para o arquivo badge.swf, que você pode personalizar.
Incorporação do arquivo badge.swf em uma página da Web
1 Localize os arquivos a seguir, fornecidos no diretório de exemplos/crachás do SDK do AIR, e adicione-os ao seu
servidor Web.
• badge.swf
• default_badge.html
• AC_RunActiveContent.js
2 Abra a página default_badge.html em um editor de texto.
3 Na página default_badge.html, na função JavaScript AC_FL_RunContent(), ajuste as definições do parâmetro
FlashVars para as seguintes:
Parâmetro
Descrição
appname
O nome do aplicativo, exibido pelo arquivo SWF quando o tempo de execução não está instalado.
appurl
(Obrigatório). A URL do arquivo do AIR a ser obtido por download. Você deve usar uma URL absoluta, e
não relativa.
airversion
(Obrigatório). Para a versão 1.0 do tempo de execução, defina isso para 1.0.
imageurl
A URL da imagem (opcional) para exibir no crachá.
buttoncolor
A cor do botão de download (especificada como um valor hexadecimal, como FFCC00).
messagecolor
A cor da mensagem de texto exibida abaixo do botão quando o tempo de execução não está instalado
(especificada como um valor hexadecimal, como FFCC00).
4 O tamanho mínimo do arquivo badge.swf é de 217 pixels de largura por 180 pixels de altura. Ajuste os valores dos
parâmetros width e height da função AC_FL_RunContent() para se adequar às suas necessidades.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 315
Distribuição, instalação e execução de aplicativos do AIR
5 Renomeie o arquivo default_badge.html e ajuste seu código (ou inclua-o em outra página HTML) para se adequar
às suas necessidades.
Você também pode editar e recompilar o arquivo badge.swf. Para obter detalhes, consulte “Modificação do arquivo
badge.swf” na página 315.
Instalação do aplicativo do AIR de um link de instalação direta em uma página da Web
Depois de ter adicionado o link de instalação direta a uma página, o usuário pode instalar o aplicativo do AIR clicando
no link no arquivo SWF.
1 Navegue até a página HTML em um navegador da Web que tenha Flash Player (versão 9 atualização 3 ou posterior
no Windows e Mac OS ou versão 10 no Linux) instalada.
2 Na página da Web, clique no link no arquivo badge.swf.
• Se tiver instalado o tempo de execução, passe para a próxima etapa.
• Se não tiver instalado o tempo de execução, uma caixa de diálogo será exibida perguntando se você gostaria de
instalá-lo. Instale o tempo de execução (consulte “Instalação do Adobe AIR” na página 1) e continue com a etapa
seguinte.
3 Na janela de instalação, deixe as configurações padrão selecionadas e clique em Continuar.
Em um computador Windows, o AIR faz automaticamente o seguinte:
• Instala o aplicativo em c:\Arquivos de Programas\
• Cria um atalho na área de trabalho para o aplicativo
• Cria um atalho no menu Iniciar
• Adiciona uma entrada para o aplicativo no Painel de Controle Adicionar ou Remover Programas
No Mac OS, o instalador adiciona o aplicativo ao diretório Aplicativos (por exemplo, no diretório /Aplicativos no
Mac OS).
Em um computador Linux, o AIR faz automaticamente o seguinte:
• Instala o aplicativo na /saída.
• Cria um atalho na área de trabalho para o aplicativo
• Cria um atalho no menu Iniciar
• Adicione uma entrada para o aplicativo no gerenciador de pacotes do sistema
4 Selecione as opções desejadas e clique no botão Instalar.
5 Quando a instalação estiver concluída, clique em Concluir.
Modificação do arquivo badge.swf
O SDK do AIR fornece os arquivos de origem para o arquivo badge.swf. Esses arquivos estão incluídos na pasta
samples/badge do SDK:
Arquivos de origem
Descrição
badge.fla
O arquivo de origem do Flash usado para compilar o arquivo badge.swf. O arquivo badge.fla é compilado em
um arquivo do SWF 9 (que pode ser carregado no Flash Player).
AIRBadge.as
Uma classe do ActionScript 3.0 que define a classe base usada no arquivo basdge.fla.
Você pode usar o Flash CS3 ou o Flash CS4 para reprojetar a interface visual do arquivo badge.fla.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 316
Distribuição, instalação e execução de aplicativos do AIR
A função de construtor AIRBadge(), definida na classe AIRBadge, carrega o arquivo air.swf hospedado em
http://airdownload.adobe.com/air/browserapi/air.swf. O arquivo air.swf inclui código para usar o recurso de
instalação direta.
O método onInit() (na classe AIRBadge) é invocado quando o arquivo air.swf é carregado com sucesso:
private function onInit(e:Event):void {
_air = e.target.content;
switch (_air.getStatus()) {
case "installed" :
root.statusMessage.text = "";
break;
case "available" :
if (_appName && _appName.length > 0) {
root.statusMessage.htmlText = "<p align='center'><font color='#"
+ _messageColor + "'>In order to run " + _appName +
", this installer will also set up Adobe® AIR™.</font></p>";
} else {
root.statusMessage.htmlText = "<p align='center'><font color='#"
+ _messageColor + "'>In order to run this application, "
+ "this installer will also set up Adobe® AIR™.</font></p>";
}
break;
case "unavailable" :
root.statusMessage.htmlText = "<p align='center'><font color='#"
+ _messageColor
+ "'>Adobe® AIR™ is not available for your system.</font></p>";
root.buttonBg_mc.enabled = false;
break;
}
}
O código define a variável global _air para a classe principal do arquivo air.swf carregado. Essa classe inclui os
seguintes métodos públicos, que o arquivo badge.swf acessa para chamar a funcionalidade de instalação direta:
Método
Descrição
getStatus()
Determina se o tempo de execução é instalado (ou pode ser instalado) no computador. Para obter detalhes,
consulte “Verificar se o tempo de execução está instalado” na página 317.
installApplication() Instala o aplicativo especificado na máquina do usuário. Para obter detalhes, consulte “Instalação de um
aplicativo do AIR do navegador” na página 319.
•
url — Uma seqüência de caracteres que define a URL. Você deve usar um caminho de URL absoluta, e não
relativa.
•
runtimeVersion — Uma string que indica a versão do tempo de execução (como "1.0.M6") exigida
pelo aplicativo a ser instalado.
•
arguments — Argumentos a serem transmitidos ao aplicativo se ele for iniciado na instalação. O aplicativo
é iniciado na instalação se o elemento allowBrowserInvocation é definido como true no arquivo do
descritor do aplicativo. (Para obter mais informações sobre o arquivo do descritor do aplicativo, consulte
“Configuração de propriedades do aplicativo do AIR” na página 44.) Se o aplicativo for iniciado como
resultado de uma instalação direta do navegador (com o usuário optando por iniciar na instalação), o objeto
NativeApplication do aplicativo despacha um objeto BrowserInvokeEvent apenas se argumentos forem
transmitidos. Considere as implicações de segurança de dados que você transmite ao aplicativo. Para obter
detalhes, consulte “Inicialização de um aplicativo do AIR instalado do navegador” na página 320.
As configurações para url e runtimeVersion são transmitidas no arquivo SWF pelas configurações do FlashVars na
página HTML do contêiner.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 317
Distribuição, instalação e execução de aplicativos do AIR
Se o aplicativo for iniciado automaticamente na instalação, você poderá usar a comunicação LocalConnection para ter
o aplicativo instalado. Entre em contato com o arquivo badge.swf na invocação. Para obter detalhes, consulte
“Comunicação entre aplicativos” na página 311.
Você também pode chamar o método getApplicationVersion() do arquivo air.swf para verificar se um aplicativo
está instalado. Você pode chamar esse método antes do processo de instalação do aplicativo ou após a instalação ser
iniciada. Para obter detalhes, consulte “Verificar por uma página da Web se um aplicativo do AIR está instalado” na
página 318.
Carregar o arquivo air.swf
Você pode criar seu próprio arquivo do SWF que usa as APIs no arquivo air.swf para interagir com o tempo de
execução e aplicativos do AIR de uma página da Web em um navegador. O arquivo air.swf é hospedado em
http://airdownload.adobe.com/air/browserapi/air.swf. Para se referir às APIs do air.swf do seu arquivo SWF, carregue
o arquivo air.swf no mesmo domínio de aplicativo do seu arquivo SWF. O código a seguir mostra um exemplo de como
carregar o arquivo air.swf no domínio do aplicativo do arquivo SWF que está sendo carregado:
var airSWF:Object; // This is the reference to the main class of air.swf
var airSWFLoader:Loader = new Loader(); // Used to load the SWF
var loaderContext:LoaderContext = new LoaderContext();
// Used to set the application domain
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
airSWFLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit);
airSWFLoader.load(new URLRequest("http://airdownload.adobe.com/air/browserapi/air.swf"),
loaderContext);
function onInit(e:Event):void
{
airSWF = e.target.content;
}
Depois que o arquivo air.swf for carregado (quando o objeto contentLoaderInfo do objeto Loader despachar o
evento init), você poderá chamar qualquer uma das APIs do air.swf. Essas APIs são descritas nestas seções:
• “Verificar se o tempo de execução está instalado” na página 317
• “Verificar por uma página da Web se um aplicativo do AIR está instalado” na página 318
• “Instalação de um aplicativo do AIR do navegador” na página 319
• “Inicialização de um aplicativo do AIR instalado do navegador” na página 320
Nota: O arquivo badge.swf, fornecido com o SDK do AIR, carrega automaticamente o arquivo air.swf. Consulte “Usando
o arquivo badge.swf para instalar um aplicativo do AIR” na página 314. As instruções desta seção se aplicam à criação
do seu próprio arquivo do SWF que carrega o arquivo air.swf.
Verificar se o tempo de execução está instalado
Um arquivo SWF pode verificar se o tempo de execução está instalado chamando o método getStatus() no arquivo
air.swf carregado de http://airdownload.adobe.com/air/browserapi/air.swf. Para obter detalhes, consulte “Carregar o
arquivo air.swf” na página 317.
Depois que o arquivo air.swf for carregado, o arquivo SWF poderá chamar o método getStatus() do arquivo air.swf
como a seguir:
var status:String = airSWF.getStatus();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 318
Distribuição, instalação e execução de aplicativos do AIR
O método getStatus() retorna um dos seguintes valores de seqüências de caracteres, com base no status do tempo
de execução no computador:
Valor de string
Descrição
"available"
O tempo de execução pode ser instalado nesse computador, mas não está instalado no momento.
"unavailable"
O tempo de execução não pode ser instalado neste computador.
"installed"
O tempo de execução está instalado nesse computador.
O método getStatus() lança um erro se a versão necessária do Flash Player (versão 9 atualização 3 ou posterior no
Windows e Mac OS ou versão 10 no Linux) não estiver instalada no navegador.
Verificar por uma página da Web se um aplicativo do AIR está instalado
Um arquivo SWF pode verificar se um aplicativo do AIR (com uma ID de aplicativo e uma ID de editor
correspondentes) está instalado chamando o método getApplicationVersion() no arquivo air.swf carregado de
http://airdownload.adobe.com/air/browserapi/air.swf. Para obter detalhes, consulte “Carregar o arquivo air.swf” na
página 317.
Depois que o arquivo air.swf for carregado, o arquivo SWF poderá chamar o método getApplicationVersion() do
arquivo air.swf como a seguir:
var appID:String = "com.example.air.myTestApplication";
var pubID:String = "02D88EEED35F84C264A183921344EEA353A629FD.1";
airSWF.getApplicationVersion(appID, pubID, versionDetectCallback);
function versionDetectCallback(version:String):void
{
if (version == null)
{
trace("Not installed.");
// Take appropriate actions. For instance, present the user with
// an option to install the application.
}
else
{
trace("Version", version, "installed.");
// Take appropriate actions. For instance, enable the
// user interface to launch the application.
}
}
O método getApplicationVersion() possui os seguintes parâmetros:
Parâmetros
Descrição
appID
A ID desse aplicativo. Para obter detalhes, consulte “Definição de identidade do aplicativo” na página 47.
pubID
A ID do editor do aplicativo. Para obter detalhes, consulte “Sobre identificadores do editor do AIR” na
página 322.
retorno de chamada
Uma função de retorno de chamada para servir como a função do manipulador. O método
getApplicationVersion() opera de modo assíncrono e ao detectar essa versão instalada (ou a falta de uma
versão instalada), esse método de retorno de chamada é invocado. A definição do método de retorno de
chamada deve incluir um parâmetro, uma seqüência de caracteres, definida para a seqüência de caracteres da
versão do aplicativo instalado. Se o aplicativo não for instalado, um valor de nulo será transmitido à função,
como ilustrado no exemplo de código anterior.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 319
Distribuição, instalação e execução de aplicativos do AIR
O método getApplicationVersion() lança um erro se a versão necessária do Flash Player (versão 9 atualização 3
ou posterior no Windows e Mac OS ou versão 10 no Linux) não estiver instalada no navegador.
Instalação de um aplicativo do AIR do navegador
Um arquivo SWF pode instalar um aplicativo do AIR chamando o método installApplication() no arquivo air.swf
carregado de http://airdownload.adobe.com/air/browserapi/air.swf. Para obter detalhes, consulte
“Carregar o arquivo air.swf” na página 317.
Depois que o arquivo air.swf for carregado, o arquivo SWF poderá chamar o método installApplication() do
arquivo air.swf como no código a seguir:
var url:String = "http://www.example.com/myApplication.air";
var runtimeVersion:String = "1.0";
var arguments:Array = ["launchFromBrowser"]; // Optional
airSWF.installApplication(url, runtimeVersion, arguments);
O método installApplication() instala o aplicativo especificado na máquina do usuário. Esse método possui os
seguintes parâmetros:
Parâmetro
Descrição
url
Uma seqüência de caracteres que define a URL do arquivo do AIR a instalar. Você deve usar um caminho de
URL absoluta, e não relativa.
runtimeVersion
Uma seqüência de caracteres que indica a versão do tempo de execução (como "1.0") exigida pelo aplicativo
a ser instalado.
arguments
Uma matriz de argumentos a serem transmitidos ao aplicativo se ele for iniciado na instalação. Somente
caracteres alfanuméricos são reconhecidos nos argumentos. Se for necessário passar outros valores, considere
o uso de um esquema de codificação.
O aplicativo é iniciado na instalação se o elemento allowBrowserInvocation é definido como true no
arquivo do descritor do aplicativo. (Para obter mais informações sobre o arquivo do descritor do aplicativo,
consulte “Configuração de propriedades do aplicativo do AIR” na página 44.) Se o aplicativo for iniciado como
resultado de uma instalação direta do navegador (com o usuário optando por iniciar na instalação), o objeto
NativeApplication do aplicativo despacha um objeto BrowserInvokeEvent apenas se argumentos tiverem sido
transmitidos. Para obter detalhes, consulte “Inicialização de um aplicativo do AIR instalado do navegador” na
página 320.
O método installApplication() pode operar apenas quando chamado no manipulador de eventos para um evento
do usuário, como um clique do mouse.
O método installApplication() lança um erro se a versão necessária do Flash Player (versão 9 atualização 3 ou
posterior no Windows e Mac OS ou versão 10 no Linux) não estiver instalada no navegador.
No Mac OS, para instalar uma versão atualizada de um aplicativo, o usuário precisa ter privilégios adequados do
sistema para instalar no diretório do aplicativo (e privilégios administrativos se o aplicativo atualizar o tempo de
execução). No Windows, o usuário deve ter privilégios administrativos.
Você também pode chamar o método getApplicationVersion() do arquivo air.swf para verificar se um aplicativo
já está instalado. Você pode chamar esse método antes que o processo de instalação do aplicativo seja iniciado ou após
a instalação ser iniciada. Para obter detalhes, consulte “Verificar por uma página da Web se um aplicativo do AIR está
instalado” na página 318. Depois que o aplicativo estiver em execução, ele pode se comunicar com o conteúdo do SWF
no navegador usando a classe LocalConnection. Para obter detalhes, consulte “Comunicação entre aplicativos” na
página 311.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 320
Distribuição, instalação e execução de aplicativos do AIR
Inicialização de um aplicativo do AIR instalado do navegador
Para usar o recurso de invocação do navegador (permitindo que ele seja iniciado do navegador), o arquivo do descritor
do aplicativo de destino deve incluir a seguinte configuração:
<allowBrowserInvocation>true</allowBrowserInvocation>
Para obter mais informações sobre o arquivo do descritor do aplicativo, consulte “Configuração de propriedades do
aplicativo do AIR” na página 44.
Um arquivo SWF no navegador pode iniciar um aplicativo do AIR chamando o método launchApplication() no
arquivo air.swf carregado de http://airdownload.adobe.com/air/browserapi/air.swf. Para obter detalhes, consulte
“Carregar o arquivo air.swf” na página 317.
Depois que o arquivo air.swf for carregado, o arquivo SWF poderá chamar o método launchApplication() do
arquivo air.swf como no código a seguir:
var appID:String = "com.example.air.myTestApplication";
var pubID:String = "02D88EEED35F84C264A183921344EEA353A629FD.1";
var arguments:Array = ["launchFromBrowser"]; // Optional
airSWF.launchApplication(appID, pubID, arguments);
O método launchApplication() é definido no nível superior do arquivo air.swf (carregado no domínio do aplicativo
do arquivo SWF da interface do usuário). Chamar esse método faz com que o AIR inicie o aplicativo especificado (se
ele for instalado e a invocação do navegador for permitida, pela configuração allowBrowserInvocation no arquivo
do descritor do aplicativo). O método tem os seguintes parâmetros:
Parâmetro
Descrição
appID
A ID do aplicativo a ser iniciado. Para obter detalhes, consulte “Definição de identidade do aplicativo” na
página 47.
pubID
A ID do editor do aplicativo a ser iniciado. Para obter detalhes, consulte “Sobre identificadores do editor do
AIR” na página 322.
arguments
Uma matriz de argumentos para transmitir ao aplicativo. O objeto NativeApplication do aplicativo despacha
um evento BrowserInvokeEvent que possui uma propriedade de argumentos definida para essa matriz.
Somente caracteres alfanuméricos são reconhecidos nos argumentos. Se for necessário passar outros valores,
considere o uso de um esquema de codificação.
O método launchApplication() pode operar apenas quando chamado no manipulador de eventos para um evento
do usuário, como um clique do mouse.
O método launchApplication() lança um erro se a versão necessária do Flash Player (versão 9 atualização 3 ou
posterior no Windows e Mac OS ou versão 10 no Linux) não estiver instalada no navegador.
Se o elemento allowBrowserInvocation for definido como false no arquivo do descritor do aplicativo, chamar o
método launchApplication() não terá efeito.
Antes de apresentar a interface do usuário para iniciar o aplicativo, você pode desejar chamar o método
getApplicationVersion() no arquivo air.swf. Para obter detalhes, consulte “Verificar por uma página da Web se
um aplicativo do AIR está instalado” na página 318.
Quando o aplicativo é invocado pelo recurso de invocação do navegador, o objeto NativeApplication do aplicativo
despacha um objeto BrowserInvokeEvent. Para obter detalhes, consulte “Invocação do navegador” na página 294.
Se você usa o recurso de invocação do navegador, certifique-se de considerar implicações de segurança, descritas em
“Invocação do navegador” na página 294.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 321
Distribuição, instalação e execução de aplicativos do AIR
Depois que o aplicativo estiver em execução, ele pode se comunicar com o conteúdo do SWF no navegador usando a
classe LocalConnection. Para obter detalhes, consulte “Comunicação entre aplicativos” na página 311.
Implantação empresarial
Os administradores de TI podem instalar o tempo de execução do Adobe AIR e aplicativos do AIR de modo silencioso
usando ferramentas de implantação de área de trabalho padrão. Os administradores de TI podem fazer o seguinte:
• Instalar silenciosamente o tempo de execução do Adobe AIR usando ferramentas como Microsoft SMS, IBM Tivoli,
ou qualquer ferramenta de implantação que permita instalações silenciosas que usem um inicializador
• Instalar silenciosamente o aplicativo do AIR usando as mesmas ferramentas usadas para implantar o tempo de
execução
Para obter mais informações, consulte o Guia do administrador do Adobe AIR
(http://www.adobe.com/go/learn_air_admin_guide_en).
Assinatura digital de um arquivo do AIR
Assinar digitalmente seus arquivos de instalação do AIR com um certificado emitido por uma autoridade de
certificação reconhecida (CA) fornece uma garantia significativa aos seus usuários de que o aplicativo que estão
instalando não foi alterado de modo acidental ou mal-intencionado e o identifica como o signatário (editor). O AIR
exibe o nome do editor durante a instalação quando o aplicativo do AIR tiver sido assinado com um certificado
confiável ou que esteja vinculado a um certificado confiável no computador de instalação. Caso contrário, o nome do
editor será exibido como “Desconhecido”.
Importante: Uma entidade mal-intencionada poderia falsificar um arquivo do AIR com sua identidade se ela, de alguma
forma, obtiver seu arquivo de armazenamento de chaves de assinatura ou descobrir sua chave privada.
Informações sobre certificados de assinatura de código
As garantias de segurança, limitações e obrigações legais que envolvem o uso de certificados de assinatura de código
são descritas nas Declarações de Práticas de Certificação (CPS) e nos contratos de assinatura publicados pela
autoridade de certificação emissora. Para obter mais informações sobre os contratos das autoridades de certificação
que emitem atualmente certificados de assinatura de código do AIR, consulte:
ChosenSecurity (http://www.chosensecurity.com/products/tc_publisher_id_adobe_air.htm)
http://www.chosensecurity.com/resource_center/repository.htm
(http://www.chosensecurity.com/resource_center/repository.htm)
GlobalSign (http://www.globalsign.com/developer/code-signing-certificate/index.htm)
CPS da GlobalSign (http://www.globalsign.com/repository/index.htm)
CPS da Thawte (http://www.thawte.com/cps/index.html)
Contrato de desenvolvedor de assinatura de código da Thawte (http://www.thawte.com/ssl-digital-certificates/freeguides-whitepapers/pdf/develcertsign.pdf)
VeriSign CPS (http://www.verisign.com/repository/CPS/)
Contrato de assinante do VeriSign (https://www.verisign.com/repository/subscriber/SUBAGR.html)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 322
Distribuição, instalação e execução de aplicativos do AIR
Sobre a assinatura de código do AIR
Quando um arquivo do AIR é assinado, uma assinatura digital é incluída no arquivo de instalação. A assinatura inclui
uma compilação do pacote, usada para verificar se o arquivo do AIR não foi alterado desde que foi assinado e se ele
inclui informações sobre o certificado de assinatura, usado para verificar a identidade do editor.
O AIR usa a infra-estrutura de chave pública (PKI) suportada pelo armazenamento de certificados do sistema
operacional para estabelecer se um certificado pode ser confiável. O computador no qual um aplicativo do AIR está
instalado deve confiar diretamente no certificado usado para assinar o aplicativo do AIR ou deve confiar em uma
cadeia de certificados que vincula o certificado a uma autoridade de certificação confiável para que as informações do
editor sejam verificadas.
Se um arquivo do AIR for assinado com um certificado que não vincula a nenhum dos certificados raiz confiáveis (e
normalmente isso inclui todos os certificados auto-assinados), as informações do editor não podem ser verificadas.
Embora o AIR possa determinar que o pacote do AIR não foi alterado desde que ele foi assinado, não há como saber
quem realmente criou e assinou o arquivo.
Nota: Um usuário pode optar por confiar em um certificado auto-assinado e, em seguida, qualquer aplicativo do AIR
assinado com o certificado exibirá o valor do campo de nome comum no certificado como o nome do editor. O AIR não
fornece nenhum meio de um usuário designar um certificado como confiável. O certificado (não incluindo a chave
privada) deve ser fornecido ao usuário separadamente e o usuário deve usar um dos mecanismos fornecidos pelo sistema
operacional ou uma ferramenta apropriada para importar o certificado no local apropriado no armazenamento de
certificados do sistema.
Sobre identificadores do editor do AIR
Como parte do processo de criar um arquivo do AIR, a ferramenta para desenvolvedores do AIR (ADT) gera uma ID
do editor. Esse é um identificador único para o certificado usado para criar o arquivo do AIR. Se você reutilizar o
mesmo certificado para vários aplicativos do AIR, eles terão a mesma ID do editor. A ID do editor é usada para
identificar o aplicativo do AIR em comunicação LocalConnection (consulte “Comunicação entre aplicativos” na
página 311). Você pode identificar a ID do editor de um aplicativo instalado lendo a propriedade
NativeApplication.nativeApplication.publisherID.
Os campos a seguir são usados para computar a ID do editor: Name, CommonName, Surname, GivenName, Initials,
GenerationQualifier, DNQualifier, CountryName, localityName, StateOrProvinceName, OrganizationName,
OrganizationalUnitName, Title, Email, SerialNumber, DomainComponent, Pseudonym, BusinessCategory,
StreetAddress, PostalCode, PostalAddress, DateOfBirth, PlaceOfBirth, Gender, CountryOfCitizenship,
CountryOfResidence e NameAtBirth. Se você renovar um certificado emitido por uma autoridade de certificação ou
gerar novamente um certificado auto-assinado, esses campos deverão ser iguais para a ID do editor permanecer a
mesma. Além disso, o certificado raiz de um certificado emitido por uma CA e a chave pública de um certificado autoassinado devem ser os mesmos.
Sobre formatos de certificados
As ferramentas de assinatura do AIR aceitam qualquer armazenamento de chave acessível pela JCA (arquitetura de
criptografia Java). Isso inclui armazenamentos de chaves baseados em arquivos como arquivos de formatos PKCS12
(que normalmente usam uma extensão de arquivo .pfx ou .p12), arquivos .keystore Java, armazenamentos de chaves
de hardware PKCS11 e armazenamentos de chaves de sistema. Os formatos de armazenamento de chave que o ADT
pode acessar dependem da versão e configuração do tempo de execução Java usado para executar o ADT. Acessar
alguns tipos de armazenamento de chave, como tokens de hardware PKCS11, pode exigir a instalação e configuração
de drivers de software adicionais e plug-ins de JCA.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 323
Distribuição, instalação e execução de aplicativos do AIR
Para assinar arquivos do AIR, você pode usar a maioria dos certificados de assinatura de código existentes ou obter um
novo, emitido expressamente para assinar aplicativos do AIR. Por exemplo, qualquer um dos seguintes tipos de
certificado da VeriSign, Thawte, GlobalSign ou ChosenSecurity podem ser usados:
• ChosenSecurity
• ID de Editor TC para Adobe AIR
• GlobalSign
• Certificado de assinatura de código ObjectSign
• Thawte:
• Certificado do desenvolvedor do AIR
• Certificado do desenvolvedor Apple
• Certificado do desenvolvedor JavaSoft
• Certificado Microsoft Authenticode
• VeriSign:
• ID digital do Adobe AIR
• ID digital Microsoft Authenticode
• ID digital de assinatura Sun Java
Nota: O certificado deve ser criado para assinatura de código. Você não pode usar um SSL ou outro tipo de certificado
para assinar arquivos do AIR.
Carimbos de data/hora
Quando você assina um arquivo do AIR, a ferramenta de empacotamento consulta o servidor de uma autoridade de
carimbo de data/hora para obter uma data e hora da assinatura independentemente verificáveis. O carimbo de
data/hora está incorporado no arquivo do AIR. Desde que o certificado de assinatura seja válido no momento da
assinatura, o arquivo do AIR poderá ser instalado, mesmo depois que o certificado expirar. Por outro lado, se nenhum
carimbo de data/hora for obtido, o arquivo do AIR não poderá mais ser instalado quando o certificado expirar ou for
revogado.
Por padrão, as ferramentas de empacotamento do AIR obtêm um carimbo de data/hora. No entanto, para permitir que
aplicativos sejam empacotados quando o serviço de carimbo de data/hora estiver indisponível, você pode desativar o
recurso de carimbo de data/hora. A Adobe recomenda que todos os arquivos do AIR distribuídos publicamente
incluam um carimbo de data/hora.
A autoridade padrão de carimbo de data/hora usada pelas ferramentas de empacotamento do AIR é Geotrust.
Obtenção de um certificado
Para obter um certificado, você normalmente visitaria o site da autoridade de certificação na Web e completaria o
processo de obtenção da empresa. As ferramentas usadas para produzir o arquivo de armazenamento de chave
necessário pelas ferramentas do AIR dependem do tipo de certificado adquirido, de como o certificado é armazenado
no computador recebedor e, em alguns casos, o navegador usado para obter o certificado. Por exemplo, para obter e
exportar um certificado do Adobe Developer do Thawte, você deve usar o Mozilla Firefox. O certificado pode então
ser exportado como um arquivo .12 diretamente da interface do usuário do Firefox.
Você pode gerar um certificado auto-assinado usando a ferramenta para desenvolvedores do AIR (ADT) usada para
empacotar arquivos de instalação do AIR. Algumas ferramentas de terceiros também podem ser usadas.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 324
Distribuição, instalação e execução de aplicativos do AIR
Para obter instruções como gerar um certificado auto-assinado, bem como instruções sobre como assinar um arquivo
do AIR, consulte “Empacotamento de um arquivo de instalação do AIR usando o ADT (ferramenta para
desenvolvedores do AIR)” na página 357. Você também pode exportar e assinar arquivos do AIR usando o Flex
Builder, Dreamweaver e a atualização do AIR para o Flash.
O exemplo a seguir descreve como obter um Certificado de desenvolvedor do AIR da autoridade de certificação
Thawte e prepará-lo para o uso com o ADT.
Exemplo: Obtenção de um certificado do desenvolvedor do AIR da Thawte
Nota: Este exemplo ilustra apenas uma das várias maneiras de se obter e preparar um certificado de assinatura do código
para o uso. Cada autoridade de certificação tem suas próprias políticas e procedimentos.
Para adquirir um certificado do desenvolvedor do AIR, o site da Thawte na Web requer que você use o navegador
Mozilla Firefox. A chave privada para o certificado é armazenada no armazenamento de chave do navegador.
Verifique se o armazenamento de chave do Firefox é protegido por uma senha mestre e se o computador em si é
fisicamente seguro. (Você pode exportar e remover o certificado e a chave privada do armazenamento de chave do
navegador quando o processo de obtenção estiver concluído.)
Como parte do processo de inscrição do certificado, é gerado um par de chave privada/pública. A chave privada é
armazenada automaticamente no armazenamento de chave do Firefox. Você deve usar o mesmo computador e
navegador para solicitar e recuperar o certificado do site da Thawte na Web.
1 Visite o site da Thawte na Web e navegue até Página de produtos para certificados de assinatura de código.
2 Da lista de certificados de assinatura de código, selecione o certificado do desenvolvedor do Adobe AIR.
3 Complete o processo de inscrição de três etapas. Você precisa fornecer informações organizacionais e de contato.
A Thawte executa então seu processo de verificação de identidade e pode solicitar informações adicionais. Após a
conclusão da verificação, a Thawte enviará um e-mail com instruções sobre como recuperar o certificado.
Nota: informações adicionais sobre o tipo de documentação necessária podem ser encontradas aqui:
https://www.thawte.com/ssl-digital-certificates/free-guides-whitepapers/pdf/enroll_codesign_eng.pdf.
4 Recupere o certificado emitido do site da Thawte. O certificado é salvo automaticamente no armazenamento de
chave do Firefox.
5 Exporte um arquivo de armazenamento de chave contendo a chave privada e o certificado do armazenamento de
chave do Firefox usando as seguintes etapas:
Nota: Ao exportar a chave privada/certificado do Firefox, ele é exportado em um formato de .p12 (pfx) que o ADT,
Flex, Flash e o Dreamweaver podem usar.
a Abra a caixa de diálogo do gerenciador de certificados do Firefox:
b No Windows: abra Tools (Ferramentas) -> Options (Opções) -> Advanced (Avançadas) -> Encryption
(Criptografia) -> View Certificates (Exibir certificados)
c No Mac OS: abra Firefox (Firefox) -> Preferences (Preferências) -> Advanced (Avançadas) -> Encryption
(Criptografia) -> View Certificates (Exibir certificados)
d No Linux: abra Edit (Editar) -> Preferences (Preferências) -> Advanced (Avançadas) -> Encryption
(Criptografia) -> View Certificates (Exibir certificados)
e Selecione o certificado de assinatura do código do Adobe AIR da lista de certificados e clique no botão Backup.
f
Digite um nome de arquivo e a localização para a qual exportar o arquivo de armazenamento de chave e clique
em Save (Salvar).
g Se estiver usando a senha mestre do Firefox, será solicitado que você digite sua senha para o dispositivo de
segurança do software para exportar o arquivo. (Essa senha é usada apenas pelo Firefox.)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 325
Distribuição, instalação e execução de aplicativos do AIR
h Na caixa de diálogo Choose a Certificate Backup Password (Escolha uma senha de backup de certificado), crie
uma senha para o arquivo de armazenamento de chave.
Importante: Essa senha protege o arquivo de armazenamento de chave e é necessária quando o arquivo é usado
para assinar aplicativos do AIR. Uma senha segura deve ser escolhida.
i
Clique em OK. Você deve receber uma mensagem de senha de backup bem-sucedida. O arquivo de
armazenamento de chave contendo a chave privada e o certificado é salvo com uma extensão de arquivo .p12
(no formato PKCS12)
6 Use o arquivo de armazenamento de chave exportado com o ADT, Flex Builder, Flash ou Dreamweaver. A senha
criada para o arquivo é necessária sempre que um aplicativo do AIR é assinado.
Importante: A chave privada e o certificado ainda são armazenados no armazenamento de chave do Firefox. Enquanto
isso permite que você exporte uma cópia adicional do arquivo de certificado, também fornece outro ponto de acesso que
deve ser protegido para manter a segurança do seu certificado e da chave privada.
Alteração de certificados
Em algumas circunstâncias, você pode precisar alterar o certificado usado para assinar seu aplicativo do AIR. Tais
circunstâncias incluem:
• Atualização de um certificado auto-assinado para um certificado emitido por uma autoridade de certificação
• Alteração de um certificado auto-assinado prestes a expirar para outro
• Alterar um certificado comercial para outro, por exemplo, quando sua identidade corporativa for alterada
Como o certificado de assinatura é um dos elementos que determina a identidade de um aplicativo do AIR, você não
pode simplesmente assinar uma atualização para o seu aplicativo com um certificado diferente. Para que o AIR
reconheça um arquivo do AIR como uma atualização, você deve assinar o arquivo original e qualquer arquivo
atualizado do AIR com o mesmo certificado. Caso contrário, o AIR instala o novo arquivo do AIR como um aplicativo
separado em vez de atualizar a instalação existente.
No AIR 1.1, você pode alterar o certificado de assinatura de um aplicativo usando uma assinatura de migração. Uma
assinatura de migração é uma segunda assinatura aplicada ao arquivo de atualização do AIR. A assinatura de migração
usa o certificado original, que estabelece que o signatário é o editor original do aplicativo.
Importante: O certificado deve ser alterado antes que o certificado original expire ou seja revogado. Se você não criar
uma atualização assinada com uma assinatura de migração antes que seu certificado expire, os usuários terão que
desinstalar sua versão existente do seu aplicativo antes de instalar qualquer atualização. Certificados emitidos
comercialmente podem normalmente ser renovados para evitar a expiração. Certificados auto-assinados não podem ser
renovados.
Para alterar os certificados:
1 Crie uma atualização para o seu aplicativo
2 Empacote e assine o arquivo de atualização do AIR com o novo certificado
3 Assine o arquivo do AIR novamente com o certificado original (usando o comando -migrate do ADT)
O procedimento para aplicar uma assinatura de migração é descrito em “Assinatura de um arquivo do AIR para alterar
o certificado do aplicativo” na página 367.
Quando o arquivo do AIR atualizado é instalado, a identidade do aplicativo é alterada. Essa alteração de identidade
possui as seguintes repercussões:
• A ID do editor do aplicativo é alterada para corresponder ao novo certificado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 326
Distribuição, instalação e execução de aplicativos do AIR
• A nova versão do aplicativo não pode acessar dados no armazenamento local criptografado existente.
• O local do diretório de armazenamento do aplicativo é alterado. Os dados no local antigo não são copiados para o
novo diretório. (Mas o novo aplicativo pode localizar o diretório original com base na ID do editor antigo).
• O aplicativo não pode mais abrir conexões locais usando a ID do editor antigo.
• Se um usuário reinstalar um arquivo do AIR de pré-migração, o AIR o instalará como um aplicativo separado
usando a ID do editor original.
É de responsabilidade do seu aplicativo migrar qualquer dado entre a versão original e a nova do aplicativo. Para
migrar dados no ELS (Armazenamento de local criptografado), você deve exportar os dados antes que a alteração no
certificado ocorra. É impossível para a nova versão do seu aplicativo ler o ELS da versão antiga. (Muitas vezes, é mais
fácil apenas recriar os dados do que migrá-lo.)
Você deve continuar aplicando a assinatura de migração a quantas atualizações subseqüentes forem possíveis. Caso
contrário, os usuários que ainda não atualizaram do original devem instalar uma versão de migração intermediária ou
desinstalar sua versão atual antes que possam instalar sua atualização mais recente. Finalmente, é claro, o certificado
original irá expirar e você não poderá mais aplicar uma assinatura de migração. (No entanto, a menos que você
desabilite o carimbo de data/hora, os arquivos do AIR assinados anteriormente com uma assinatura de migração
permanecerão válidos. A assinatura de migração é carimbada com data e hora para permitir que o AIR aceite a
assinatura mesmo depois que o certificado expirar.)
Um arquivo do AIR com uma assinatura de migração é, em outros aspectos, um arquivo do AIR normal. Se o aplicativo
é instalado em um sistema sem a versão original, o AIR instala a nova versão da maneira normal.
Nota: Você não precisa normalmente migrar o certificado quando renovar um certificado emitido comercialmente. Um
certificado renovado retém a mesma identidade do editor do original, a menos que o nome distinto tenha sido alterado.
Para obter uma lista completa dos atributos do certificado usados para determinar o nome distinto, consulte “Sobre
identificadores do editor do AIR” na página 322.
Terminologia
Esta seção fornece um glossário de um pouco da terminologia principal que você deve entender ao tomar decisões
sobre como assinar seu aplicativo para distribuição pública.
Termo
Descrição
Autoridade de certificação (CA)
Uma entidade em uma rede de infra-estrutura de chave pública que serve como um terceiro
confiável e, por último, certifica a identidade do proprietário de uma chave pública. Uma CA
normalmente emite certificados digitais, assinados por sua própria chave privada, para atestar que
ela verificou a identidade do proprietário do certificado.
Declaração de Prática de Certificação
(CPS)
Apresenta as práticas e políticas da autoridade de certificação em emitir e verificar certificados. A
CPS é parte do contrato entre a CA e seus assinantes e terceiros. Ela também resume as políticas
para verificação de identidade e o nível de garantias oferecidas pelos certificados que elas
fornecem.
Lista de revogação de certificado (CRL) Uma lista de certificados emitidos que foram revogados e nos quais não se deve mais confiar. O
AIR verifica o CRL no momento em que um aplicativo do AIR é assinado e, se nenhum carimbo de
data/hora estiver presente, novamente quando o aplicativo for instalado.
Cadeia de certificados
Uma cadeia de certificados é uma seqüência de certificados na qual cada certificado da cadeia foi
assinado pelo certificado seguinte.
Certificado digital
Um documento digital que contém informações sobre a identidade do proprietário, a chave
pública do proprietário e a identidade do certificado em si. Um certificado emitido por uma
autoridade de certificação é em si assinado por um certificado que pertence à CA emissora.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 327
Distribuição, instalação e execução de aplicativos do AIR
Termo
Descrição
Assinatura digital
Uma mensagem criptografada ou uma compilação que pode apenas ser descriptografada com
metade da chave pública de um par de chave pública-privada. Em uma PKI, uma assinatura digital
contém um ou mais certificados digitais rastreáveis, por último, para a autoridade de certificação.
Uma assinatura digital pode ser usada para validar que uma mensagem (ou arquivo do
computador) não foi alterada desde que ela foi assinada (nos limites da garantia fornecida pelo
algoritmo criptográfico usado) e, supondo que alguém confia na autoridade de certificação
emissora, a identidade do signatário.
Armazenamento de chave
Um banco de dados contendo certificados digitais e, em alguns casos, as chaves privadas
relacionadas.
JCA (arquitetura de criptografia Java)
Uma arquitetura extensível para gerenciar e acessar armazenamentos de chaves. Consulte o Guia
de referência da arquitetura de criptografia Java para obter mais informações.
PKCS n º 11
O padrão de interface de token criptográfico da RSA Laboratories. Um armazenamento de chave
baseado em token de hardware.
PKCS n º 12
O padrão de sintaxe do Exchange de informações pessoais da RSA Laboratories. Um
armazenamento de chave baseado em arquivo que normalmente contém uma chave privada e
seu certificado digital associado.
Chave privada
A metade privada de um sistema criptográfico assimétrico de chave pública-privada de duas
partes. A chave privada deve ser mantida em segredo e nunca deve ser transmitida pela rede.
Mensagens assinadas digitalmente são criptografadas com a chave privada pelo signatário.
Chave pública
A metade pública de um sistema criptográfico assimétrico de chave pública-privada de duas
partes. A chave pública está abertamente disponível e é usada para descriptografar mensagens
criptografadas com a chave privada.
Infra-estrutura de chave pública (PKI)
Um sistema de confiança no qual as autoridades de certificação atestam para a identidade dos
proprietários de chaves públicas. Clientes da rede confiam nos certificados digitais emitidos por
uma CA confiável para verificar a identidade do signatário de uma mensagem digital (ou arquivo).
Carimbo de data/hora
Um dado assinado digitalmente contendo a data e hora em que um evento ocorreu. O ADT pode
incluir um carimbo de data/hora de um servidor compatível com hora RFC 3161 em um pacote do
AIR. Quando presente, o AIR usa o carimbo de data/hora para estabelecer a validade de um
certificado no momento da assinatura. Isso permite que um aplicativo do AIR seja instalado após
seu certificado de assinatura ter expirado.
Autoridade de carimbo de data/hora
Uma autoridade que emite carimbos de data/hora. Para ser reconhecido pelo AIR, o carimbo de
data/hora deve estar em conformidade com RFC 3161 e a assinatura de carimbo de data/hora deve
ser vinculada a um certificado raiz confiável na máquina de instalação.
328
Capítulo 33: Atualização de aplicativos do
AIR
Os usuários podem instalar ou atualizar um aplicativo do AIR clicando duas vezes no arquivo AIR no computador ou
a partir do navegador (usando o recurso de instalação direta). O aplicativo instalador do Adobe® AIR™ gerencia a
instalação, alertando o usuário se ele estiver atualizando um aplicativo já existente. (Consulte “Distribuição, instalação
e execução de aplicativos do AIR” na página 312.)
No entanto, também é possível que um aplicativo instalado se atualize automaticamente para uma nova versão usando
a classe Updater. (Um aplicativo instalado pode detectar que uma nova versão está disponível para download e
instalação.) A classe Updater inclui um método update() que permite apontar para um arquivo do AIR no
computador do usuário e atualizar para essa versão.
As IDs do aplicativo e do editor de um arquivo do AIR de atualização devem corresponder às do aplicativo a ser
atualizado. A ID do editor é derivada do certificado de autenticação, o que significa que a atualização e o aplicativo a
ser atualizado devem ser assinados com o mesmo certificado.
A partir do AIR 1.1, é possível migrar um aplicativo para usar um novo certificado de autenticação de código. A
migração de um aplicativo para usar uma nova assinatura envolve assinar o arquivo do AIR de atualização com os
certificados novo e original. A migração de certificado é um processo unidirecional. Após a migração, somente os
arquivos do AIR assinados com o novo certificado (ou com ambos) serão reconhecidos como atualizações de uma
instalação existente.
Gerenciar a atualização de aplicativos pode ser complicado. O AIR 1.5 inclui a nova estrutura de atualização para
aplicativos do Adobe® AIR™. Essa estrutura fornece APIs para auxiliar os desenvolvedores a fornecer bons recursos de
atualização em aplicativos do AIR.
Você pode usar a migração de certificado para mudar de um certificado auto-assinado para um certificado comercial
de autenticação de código ou de um certificado auto-assinado ou comercial para outro. Caso você não migre o
certificado, os usuários existentes deverão remover a versão atual do seu aplicativo antes de instalar a nova. Para obter
mais informações, consulte “Alteração de certificados” na página 325.
Sobre atualização de aplicativos
A classe Updater (no pacote flash.desktop) inclui um método, update(), que você pode usar para atualizar o aplicativo
que está sendo executado com outra versão. Por exemplo, se o usuário tem uma versão do arquivo do AIR
("Sample_App_v2.air") localizada na área de trabalho, o seguinte código atualiza o aplicativo:
var updater:Updater = new Updater();
var airFile:File = File.desktopDirectory.resolvePath("Sample_App_v2.air");
var version:String = "2.01";
updater.update(airFile, version);
Antes de um aplicativo usar a classe Updater, o usuário ou o aplicativo deve baixar a versão atualizada do arquivo do
AIR no computador. Para obter mais informações, consulte “Download de um arquivo do AIR no computador do
usuário” na página 330.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 329
Atualização de aplicativos do AIR
Resultados de chamar o método Updater.update()
Quando um aplicativo no tempo de execução chama o método update(), o tempo de execução fecha o aplicativo e
tenta instalar a nova versão do arquivo do AIR. O tempo de execução verifica se a ID do aplicativo e a ID do editor
especificadas no arquivo do AIR correspondem às IDs do aplicativo e do editor do aplicativo que está chamando o
método update(). (Para obter informações sobre a ID do aplicativo e a ID do editor, consulte “Configuração de
propriedades do aplicativo do AIR” na página 44.) Ele também verifica se a string de versão corresponde à string
version passada para o método update(). Se a instalação for concluída com êxito, o tempo de execução abrirá a nova
versão do aplicativo. Do contrário (se a instalação não for concluída), ele reabrirá a versão existente (pré-instalação)
do aplicativo.
No Mac OS, para instalar uma versão atualizada de um aplicativo, o usuário deve ter privilégios adequados do sistema
para instalar no diretório do aplicativo. No Windows e no Linux, um usuário precisa de privilégios administrativos.
Se a versão atualizada do aplicativo exigir uma versão atualizada do tempo de execução, a nova versão do tempo de
execução será instalada. Para atualizar o tempo de execução, o usuário deve ter privilégios administrativos no
computador.
Durante o teste de um aplicativo usando o ADL, se o método update() for chamado, será gerada uma exceção do
tempo de execução.
Sobre a string de versão
A string especificada como o parâmetro version do método update() deve corresponder à string no atributo
version do principal elemento application do arquivo de descrição do aplicativo referente ao arquivo do AIR a ser
instalado. É necessário especificar o parâmetro version por motivo de segurança. Ao exigir que o aplicativo verifique
o número da versão no arquivo do AIR, o aplicativo não instalará inadvertidamente uma versão mais antiga, que pode
conter uma vulnerabilidade de segurança corrigida no aplicativo que está instalado. O aplicativo também deve verificar
a string de versão no arquivo do AIR com a string de versão no aplicativo instalado para impedir ataques de
downgrade.
A string de versão pode ter qualquer formato. Por exemplo, pode ser "2.01" ou "versão 2". A decisão quanto ao formato
dessa string fica a seu critério, que é o desenvolvedor do aplicativo. O tempo de execução não valida a string de versão;
o código do aplicativo deve fazer isso antes de atualizar o aplicativo.
Se um aplicativo do Adobe AIR baixa um arquivo do AIR pela web, é recomendável ter um mecanismo através do qual
o serviço da web possa notificar o aplicativo sobre a versão que está sendo baixada. O aplicativo poderá então usar essa
string como o parâmetro version do método update(). Se o arquivo do AIR for obtido por algum outro meio, no
qual a versão do arquivo é desconhecida, o aplicativo do AIR poderá examiná-lo para determinar a informação de
versão. (Um arquivo do AIR consiste em um arquivo compactado no formato ZIP, e o arquivo de descrição do
aplicativo é o segundo registro no arquivo.)
Para obter detalhes sobre o arquivo de descrição do aplicativo, consulte “Configuração de propriedades do aplicativo
do AIR” na página 44.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 330
Atualização de aplicativos do AIR
Apresentação de uma interface de usuário de
atualização do aplicativo personalizado
O AIR vem com uma interface de atualização padrão:
Essa interface sempre é usada quando o usuário instala uma versão de um aplicativo em uma máquina pela primeira
vez. No entanto, você pode definir sua própria interface para usá-la em ocorrências subseqüentes. Se seu aplicativo
definir uma interface de atualização personalizada, especifique um elemento customUpdateUI no arquivo de descritor
do aplicativo para o aplicativo instalado no momento:
<customUpdateUI>true</customUpdateUI>
Quando o aplicativo é instalado e o usuário abre um arquivo do AIR com uma ID de aplicativo e uma ID de editor que
correspondem às do aplicativo instalado, o tempo de execução abre o aplicativo em vez no instalador de aplicativo
padrão do AIR. Para obter mais informações, consulte “Fornecer uma interface de usuário personalizada para
atualizações de aplicativos” na página 52.
O aplicativo pode decidir, quando executado (quando o objeto NativeApplication.nativeApplication despacha
um evento load), se o aplicativo deve ser atualizado (usando a classe Updater). Se ele optar pela atualização, poderá
apresentar ao usuário sua própria interface de instalação (que é diferente da interface padrão que está sendo
executada).
Download de um arquivo do AIR no computador do
usuário
Para utilizar a classe Updater, primeiro o usuário ou o aplicativo deve salvar um arquivo do AIR localmente no
computador do usuário.
Nota: O AIR 1.5 inclui uma estrutura de atualização, que auxilia desenvolvedores no fornecimento de bons recursos de
atualização em aplicativos do AIR. Usar essa estrutura pode ser bem mais fácil que usar o método update() da classe
Update diretamente. Para obter detalhes, consulte “Uso da estrutura de atualização” na página 332.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 331
Atualização de aplicativos do AIR
O código abaixo lê um arquivo do AIR a partir de uma URL (http://example.com/air/updates/Sample_App_v2.air) e
salva o arquivo no diretório de armazenamento do aplicativo:
var urlString:String = "http://example.com/air/updates/Sample_App_v2.air";
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
var fileData:ByteArray = new ByteArray();
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load(urlReq);
function loaded(event:Event):void {
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
writeAirFile();
}
function writeAirFile():void {
var file:File = File.applicationStorageDirectory.resolvePath("My App v2.air");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(fileData, 0, fileData.length);
fileStream.close();
trace("The AIR file is written.");
}
Para obter mais informações, consulte “Fluxo de trabalho de leitura e gravação de arquivos” na página 121.
Verificar se um aplicativo está sendo executado pela
primeira vez
Depois que você atualizar um aplicativo, convém exibir para o usuário uma mensagem de "introdução" ou "boasvindas". Após a inicialização, o aplicativo verifica se está sendo executado pela primeira vez para determinar se deve
exibir a mensagem.
Nota: O AIR 1.5 inclui uma estrutura de atualização, que auxilia desenvolvedores no fornecimento de bons recursos de
atualização em aplicativos do AIR. Essa estrutura fornece métodos fáceis para verificar se uma versão de um aplicativo
está sendo executada pela primeira vez. Para obter detalhes, consulte “Uso da estrutura de atualização” na página 332.
Uma forma de fazer isso é salvar um arquivo no diretório de armazenamento do aplicativo depois de inicializá-lo.
Sempre que o aplicativo é inicializado, deve averiguar se esse arquivo existe. Se o arquivo não existir, isso indica que o
aplicativo está sendo executado pela primeira vez para o usuário atual. Se o arquivo existir, o aplicativo já foi executado
pelo menos uma vez. Se o arquivo existir e contiver um número de versão mais antigo que o atual, você saberá que o
usuário está executando a nova versão pela primeira vez.
Se o seu aplicativo salva dados localmente (como no diretório de armazenamento do aplicativo), convém verificar se
existem dados já salvos (de versões anteriores) após a primeira execução.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 332
Atualização de aplicativos do AIR
Uso da estrutura de atualização
Gerenciar a atualização de aplicativos pode ser complicado. A estrutura de atualização para aplicativos AdobeAIR
fornece APIs para auxiliar desenvolvedores no fornecimento de bons recursos de atualização em aplicativos do AIR.
A funcionalidade na estrutura de atualização do AIR auxilia desenvolvedores a:
• Verificar periodicamente atualizações com base em um intervalo ou na solicitação do usuário
• Baixar arquivos do AIR (atualizações) de uma fonte da Web
• Alertar o usuário na primeira execução da versão recém-instalada
• Confirmar se o usuário deseja verificar atualizações
• Exibir informações sobre a nova versão de atualização para o usuário
• Exibir o andamento do download e as informações de erro para o usuário
A estrutura de atualização do AIR fornece um exemplo de interface de usuário que seu aplicativo pode usar. Ela fornece
ao usuário informações básicas e opções relacionadas às atualizações do aplicativo. Seu aplicativo também pode definir
a própria interface de usuário personalizada para uso com a estrutura de atualização.
A estrutura de atualização do AIR permite armazenar informações sobre a versão de atualização de um aplicativo AIR
em arquivos de configuração XML simples. Para a maioria dos aplicativos, definir esses arquivos de configuração e
incluir alguns códigos básicos fornece uma boa funcionalidade de atualização para o usuário final.
Mesmo sem usar a estrutura de atualização, o Adobe AIR inclui uma classe Updater que os aplicativos do AIR podem
usar para atualizar para novas versões. Essa classe permite que um aplicativo seja atualizado para uma versão contida
em um arquivo do AIR no computador do usuário. No entanto, o gerenciamento de atualização pode envolver mais
que simplesmente atualizar o aplicativo com base em um arquivo do AIR armazenado localmente.
Arquivos na estrutura de atualização do AIR
A estrutura de atualização do AIR inclui os seguintes diretórios:
• doc — A documentação (que você está lendo agora) da estrutura de atualização do AIR.
• estruturas – Esse diretório inclui arquivos SWC, para desenvolvimento em Flex – e arquivos SWF, para
desenvolvimento em HTML. Para obter mais informações, consulte estas seções (imediatamente na seqüência):
• “Configuração do ambiente de desenvolvimento em Flex” na página 332
• “Inclusão de arquivos de estrutura em um aplicativo do AIR baseado em HTML” na página 333
• amostras – Este diretório inclui exemplos baseados em HTML e Flex mostrando como usar a estrutura de
atualização de aplicativo. Compile e teste esses arquivos, como faria em qualquer aplicativo do AIR.
• modelos – Este diretório contém arquivos de exemplo do descritor de atualização (simples e localizados) e arquivos
de configuração. (Para obter mais informações sobre esses arquivos, consulte Configuração do ambiente de
desenvolvimento em Flex e “Exemplo básico: Uso da versão ApplicationUpdaterUI” na página 333).
Configuração do ambiente de desenvolvimento em Flex
O diretório frameworks/flex da estrutura de atualização inclui estes arquivos:
• ApplicationUpdater.swc — Define a funcionalidade básica da biblioteca de atualização, sem qualquer interface do
usuário
• ApplicationUpdater_UI.swc — Define a funcionalidade básica da biblioteca de atualização, incluindo uma
interface de usuário que seu aplicativo usa para exibir opções de atualização
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 333
Atualização de aplicativos do AIR
Os arquivos SWC definem classes que você pode usar no desenvolvimento de Flex.
Para usar a estrutura de atualização ao compilar com o Flex SDK, inclua o arquivo ApplicationUpdater.swc ou o
ApplicationUpdater_UI.swc na chamada do compilador amxmlc. No exemplo a seguir, o compilador carrega o
arquivo ApplicationUpdater.swc no subdiretório lib do diretório Flex SDK:
amxmlc -library-path+=lib/ApplicationUpdater.swc
-- myApp.mxml
No exemplo a seguir, o compilador carrega o arquivo ApplicationUpdater_UI.swc no subdiretório lib do diretório Flex SDK:
amxmlc -library-path+=lib/ApplicationUpdater_UI.swc
-- myApp.mxml
Ao desenvolver usando o construtor Flex, adicione o arquivo SWC à guia Caminho da biblioteca das configurações do
caminho de criação de Flex na caixa de diálogo Propriedades.
Assegure-se de copiar os arquivos SWC no diretório que você usará como referência no compilador amxmlc (usando
o Flex SDK) ou Flex Builder.
Inclusão de arquivos de estrutura em um aplicativo do AIR baseado em HTML
O diretório frameworks/html da estrutura de atualização inclui estes arquivos:
• ApplicationUpdater.swf — Define a funcionalidade básica da biblioteca de atualização, sem qualquer interface do
usuário
• ApplicationUpdater_UI.swf — Define a funcionalidade básica da biblioteca de atualização, incluindo uma interface
de usuário que seu aplicativo usa para exibir opções de atualização
O código JavaScript nos aplicativos do AIT podem usar classes definidas nos arquivos SWF.
Para usar a estrutura de atualização, inclua o arquivo ApplicationUpdater.swf ou o ApplicationUpdater_UI.swf no
diretório do aplicativo (ou um subdiretório). Em seguida, no arquivo HTML que usará a estrutura (em código
JavaScript), inclua uma tag script que carregue o arquivo:
<script src="applicationUpdater.swf" type="application/x-shockwave-flash"/>
Ou use essa tag script para carregar o arquivo ApplicationUpdater_UI.swf:
<script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/>
A API definida nesses dois arquivos é descrita no restante deste documento.
Exemplo básico: Uso da versão ApplicationUpdaterUI
A versão ApplicationUpdaterUI da estrutura de atualização fornece uma interface básica que pode ser facilmente
usada no seu aplicativo. A seguir há um exemplo básico:
Primeiro, crie um aplicativo do AIR que chame a estrutura de atualização:
1 Se seu aplicativo for um aplicativo do AIR baseado em HTML, carregue o arquivo ApplicationUpdaterUI.js:
<script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/>
2 Na lógica de programação do aplicativo do AIR, instancie um objeto do ApplicationUpdaterUI.
No ActionScript, use o seguinte código:
var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();
No JavaScript, use o seguinte código:
var appUpdater = new runtime.air.update.ApplicationUpdaterUI();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 334
Atualização de aplicativos do AIR
Você pode adicionar esse código a uma função de inicialização executada quando o aplicativo é carregado.
3 Crie um arquivo de texto updateConfig.xml e adicione o seguinte a ele:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0">
<url>http://example.com/updates/update.xml</url>
<delay>1</delay>
</configuration>
Edite o elemento URL do arquivo updateConfig.xml para que corresponda à localização eventual do arquivo de
descritor de atualização do seu servidor da Web (veja o próximo procedimento).
O delay é o número de dias que o aplicativo aguarda entre as verificações de atualizações.
4 Adicione o arquivo updateConfig.xml ao diretório do projeto do seu aplicativo do AIR.
5 Faça com que o objeto updater referencie o arquivo updateConfig.xml e chame o método initialize() do
objeto.
No ActionScript, use o seguinte código:
appUpdater.configurationFile = new File("app:/updateConfig.xml");
appUpdater.initialize();
No JavaScript, use o seguinte código:
appUpdater.configurationFile = new air.File("app:/updateConfig.xml");
appUpdater.initialize();
6 Crie uma segunda versão do aplicativo AIR que tenha uma versão diferente do primeiro aplicativo. (A versão é
especificada no arquivo de descritor do aplicativo, no elemento version.)
Em seguida, adicione a versão de atualização do aplicativo do AIR ao servidor da Web:
1 Coloque a versão de atualização do arquivo AIR no servidor da Web.
2 Crie um arquivo de texto updateDescriptor.xml e adicione o seguinte conteúdo a ele:
<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.1</version>
<url>http://example.com/updates/sample_1.1.air</url>
<description>This is the latest version of the Sample application.</description>
</update>
Edite version, URL e description do arquivo updateDescriptor.xml para que corresponda ao seu arquivo do AIR.
3 Adicione o arquivo updateDescriptor.xml ao mesmo diretório do servidor da Web que contém o arquivo do AIR
atualizado.
Esse é um exemplo básico, mas fornece a funcionalidade de atualização suficiente para vários aplicativos. O restante
deste documento descreve como usar a estrutura de atualização para atender melhor suas necessidades.
Para obter outro exemplo de uso da estrutura de atualização, consulte o seguinte aplicativo de amostra no Centro de
desenvolvedores do Adobe AIR: Estrutura de atualização em um aplicativo com base no
Flash(http://www.adobe.com/go/learn_air_qs_update_framework_flash_en).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 335
Atualização de aplicativos do AIR
Definição do arquivo de descritor de atualização a acréscimo do arquivo do
AIR ao servidor da Web.
Quando você usa a estrutura de atualização do AIR, define informações básicas sobre a atualização disponível em um
arquivo de descritor de atualização, armazenado no servidor da Web. O arquivo de descritor de atualização é um
arquivo XML simples. A estrutura de atualização incluída no aplicativo verifica esse arquivo para ver se uma nova
versão foi carregada.
O arquivo de descritor de atualização contém os seguintes dados:
•
version— A nova versão do aplicativo do air. Deve ser a mesma seqüência de caracteres usada no novo arquivo
de descritor do aplicativo air da versão. Se a versão do arquivo de descritor de atualização não corresponder à versão
do arquivo do AIR, a estrutura de atualização lançará uma exceção.
•
url – O local do arquivo do AIR de atualização. Esse arquivo contém a versão de atualização do aplicativo AIR.
•
description — Detalhes relativos à nova versão. Essas informações podem ser exibidas para o usuário durante o
processo de atualização.
Os elementos version e url são obrigatórios. O elemento description é opcional.
Este é um exemplo de arquivo de descritor de atualização:
<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.1a1</version>
<url>http://example.com/updates/sample_1.1a1.air</url>
<description>This is the latest version of the Sample application.</description>
</update>
Se desejar definir a tag description usando vários idiomas, use vários elementos text que definam o atributo lang:
<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.1a1</version>
<url>http://example.com/updates/sample_1.1a1.air</url>
<description>
<text xml:lang="en">English description</text>
<text xml:lang="fr">French description</text>
<text xml:lang="ro">Romanian description</text>
</description>
</update>
Coloque o arquivo de descritor de atualização no servidor da Web, juntamente com o arquivo de atualização do AIR.
O diretório modelo incluído com o descritor de atualização inclui exemplos dos arquivos descritores de atualização.
Eles incluem versões com um idioma ou vários idiomas.
Instanciação de um objeto atualizador
Depois de carregar a estrutura de atualização do AIR em seu código (consulte “Configuração do ambiente de
desenvolvimento em Flex” na página 332 e “Inclusão de arquivos de estrutura em um aplicativo do AIR baseado em
HTML” na página 333), você deverá instanciar um objeto atualizador, como no exemplo a seguir:
var appUpdater:ApplicationUpdater = new ApplicationUpdater();
O código anterior usa a classe ApplicationUpdater (que não fornece interface de usuário). Se você deseja usar a classe
ApplicationUpdaterUI (que fornece uma interface de usuário), use o seguinte:
var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 336
Atualização de aplicativos do AIR
Os exemplos de código restantes neste documento supõem que você tenha instanciado um objeto atualizador
appUpdater.
Definição das configurações de atualização
O ApplicationUpdater e o ApplicationUpdaterUI podem ser configurados por meio de um arquivo de configuração
fornecido com o aplicativo ou por meio de ActionScript ou JavaScript no aplicativo.
Definição das configurações de atualização em um arquivo de configuração XML
O arquivo de configuração de atualização é um arquivo XML. Ele pode conter os seguintes elementos:
•
updateURL— Uma seqüência de caracteres. Representa a localização do descritor de atualização no servidor
remoto. Qualquer localização de URLRequest válida é permitida. Você deve definir a propriedade updateURL pelo
arquivo de configuração ou por script (consulte “Definição do arquivo de descritor de atualização a acréscimo do
arquivo do AIR ao servidor da Web.” na página 335). Defina essa propriedade antes de usar o atualizador (antes de
chamar o método initialize() do objeto atualizador, descrito em “Inicialização da estrutura de atualização” na
página 338).
•
delay— Um número. Representa um intervalo de tempo fornecido em dias (valores como 0,25 são permitidos)
para verificação de atualizações. Um valor de 0 (que é o valor padrão) especifica que o atualizador não realiza uma
verificação automática periódica.
O arquivo de configuração do ApplicationUpdaterUI pode conter o seguinte elemento, além dos elementos
updateURL e delay:
•
defaultUI: Uma lista de elementos dialog. Cada elemento dialog tem um atributo name que corresponde à caixa
de diálogo na interface do usuário. Cada elemento dialog tem um atributo visible que define se a caixa de
diálogo está visível. O valor padrão é true. Valores possíveis para o atributo name são:
•
"checkForUpdate" – Corresponde às caixas de diálogo Verificar atualizações, Nenhuma atualização e Erro de
atualização.
•
"downloadUpdate"— Corresponde à caixa de diálogo Fazendo download de atualização.
•
"downloadProgress"—Corresponde às caixas de diálogo Download em andamento e Erro de download.
•
"installUpdate"— Corresponde à caixa de diálogo Instalar atualização.
•
"fileUpdate"— Corresponde às caixas de diálogo Atualização de arquivo, Não atualização de arquivo e Erro
de arquivo
•
"unexpectedError"— Corresponde à caixa de diálogo Erro inesperado
Quando definida como false, a caixa de diálogo correspondente não aparece como parte do procedimento de
atualização.
Este é um exemplo do arquivo de configuração para a estrutura ApplicationUpdater:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0">
<url>http://example.com/updates/update.xml</url>
<delay>1</delay>
</configuration>
Este é um exemplo do arquivo de configuração para a estrutura ApplicationUpdaterUI, que inclui uma definição para
o elemento defaultUI:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 337
Atualização de aplicativos do AIR
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0">
<url>http://example.com/updates/update.xml</url>
<delay>1</delay>
<defaultUI>
<dialog name="checkForUpdate" visible="false" />
<dialog name="downloadUpdate" visible="false" />
<dialog name="downloadProgress" visible="false" />
</defaultUI>
</configuration>
Aponte a propriedade configurationFile para o local desse arquivo: como no seguinte
• ActionScript:
appUpdater.configurationFile = new File("app:/cfg/updateConfig.xml");
• JavaScript:
appUpdater.configurationFile = new air.File("app:/cfg/updateConfig.xml");
O diretório modelo da estrutura de atualização inclui um exemplo de arquivo de configuração, o config-template.xml.
Definição das configurações de atualização do código ActionScript ou JavaScript
Esses parâmetros de configuração também podem ser definidos usando código no aplicativo, como a seguir:
appUpdater.updateURL = " http://example.com/updates/update.xml";
appUpdater.delay = 1;
As propriedades do objeto atualizador são updateURL e delay. Essas propriedades definem as mesmas configurações
dos elementos updateURL e delay no arquivo de configuração: o URL e o arquivo de descritor de atualização e o
intervalo de verificação de atualizações. Se você especificar as configurações and de um arquivo de configuração no
código, todas as propriedades definidas usando o código terão precedência sobre as configurações correspondentes no
arquivo de configuração.
Você deve definir a propriedade updateURL por meio do arquivo de configuração ou por meio de script (consulte
“Definição do arquivo de descritor de atualização a acréscimo do arquivo do AIR ao servidor da Web.” na página 335)
antes de usar o atualizador (antes de chamar o método initialize() do objeto atualizador, descrito em “Inicialização
da estrutura de atualização” na página 338).
A estrutura ApplicationUpdaterUI define essas propriedades adicionais do objeto atualizador:
•
isCheckForUpdateVisible – Corresponde às caixas de diálogo Verificar atualizações, Nenhuma atualização e
Erro de atualização.
•
isDownloadUpdateVisible— Corresponde à caixa de diálogo Fazendo download de atualização.
•
isDownloadProgressVisible —Corresponde às caixas de diálogo Download em andamento e Erro de download.
•
isInstallUpdateVisible — Corresponde à caixa de diálogo Instalar atualização.
•
isFileUpdateVisible — Corresponde às caixas de diálogo Atualização de arquivo, Não atualização de arquivo e
Erro de arquivo
•
isUnexpectedErrorVisible — Corresponde à caixa de diálogo Erro inesperado
Cada propriedade corresponde a uma ou mais caixa de diálogo da interface de usuário ApplicationUpdaterUI. Cada
propriedade é um valor booleano com um valor padrão true. Quando definida como false, a caixa de diálogo
correspondente não aparece como parte do procedimento de atualização.
Essas propriedades de caixa de diálogo substituem as configurações no arquivo de configuração de atualização.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 338
Atualização de aplicativos do AIR
O processo de atualização
A estrutura de atualização do AIR completa o processo de atualização nas seguintes etapas:
1 A inicialização do atualizador verifica se foi realizada uma verificação de atualização no intervalo de tempo definido
(consulte “Definição das configurações de atualização” na página 336). Se estiver faltando uma verificação de
atualização, o processo de atualização continuará.
2 O atualizador baixa e interpreta o arquivo de descritor de atualização.
3 O atualizador baixa o arquivo AIR de atualização.
4 O atualizador instala a versão atualizada do aplicativo.
O objeto atualizador despacha eventos na conclusão de cada uma das etapas. Na versão do ApplicationUpdater, você
pode cancelar os eventos que indicam a conclusão bem-sucedida de uma etapa no processo. Se você cancelar um desses
eventos, a próxima etapa do processo será cancelada. Na versão do ApplicationUpdaterUI, o atualizador apresenta
uma caixa de diálogo permitindo que o usuário cancele ou continue para a próxima etapa do processo.
Se você cancelar o evento, poderá chamar métodos do objeto atualizador para retomar o processo.
Conforme a versão do ApplicationUpdater do atualizador progride pelo processo de atualização, ela registra seu estado
atual em uma propriedade currentState. Essa propriedade é definida como uma seqüência de caracteres com os
seguintes valores possíveis:
•
"UNINITIALIZED" — O atualizador não foi inicializado.
•
"INITIALIZING" — O atualizador está sendo inicializado.
•
"READY" — O atualizador foi inicializado
•
"BEFORE_CHECKING" — O atualizador ainda não verificou se existe um arquivo de descritor de atualização.
•
"CHECKING" — O atualizador está verificando se existe um arquivo de descritor de atualização.
•
"AVAILABLE" — O arquivo de descritor de atualização está disponível.
•
"DOWNLOADING" — O atualizador está baixando o arquivo do AIR.
•
"DOWNLOADED" — O atualizador baixou o arquivo do AIR.
•
"INSTALLING" — O atualizador está instalando o arquivo do AIR.
•
"PENDING_INSTALLING" — O atualizador foi inicializado e não há atualizações pendentes.
Alguns métodos do objeto atualizador só serão executados se o atualizador estiver em determinado estado.
Inicialização da estrutura de atualização
Depois de definir as propriedades de configuração (consulte “Exemplo básico: Uso da versão ApplicationUpdaterUI”
na página 333), chame o método initialize() para inicializar a atualização:
appUpdater.initialize();
Esse método faz o seguinte:
• Ele inicializa a estrutura de atualização, instalando de forma silenciosa e síncrona todas as atualizações pendentes.
É necessário para chamar esse método durante a inicialização do aplicativo, pois ele pode reiniciar o aplicativo
quando chamado.
• Ele verifica se existe uma atualização adiada e a instala;
• Se houver um erro durante o processo de atualização, ele limpa o arquivo de atualização e as informações de versão
da área de armazenamento do aplicativo.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 339
Atualização de aplicativos do AIR
• Se o tempo limite tiver expirado, o processo de atualização e iniciado. Caso contrário, ele inicia o timer.
Chamar esse método pode resultar no despacho dos seguintes eventos pelo objeto atualizador:
•
UpdateEvent.INITIALIZED — Despachado quando a inicialização é concluída.
•
ErrorEvent.ERROR — Despachado quando há um erro na inicialização.
No despacho do evento UpdateEvent.INITIALIZED, o processo de atualização é concluído.
Quando você chama o método initialize(), o atualizador inicia o processo de atualização e conclui todas as etapas
com base na configuração de tempo do timer. No entanto, você também pode iniciar o processo de atualização a
qualquer momento chamando o método checkNow() do objeto atualizador:
appUpdater.checkNow();
Esse método não faz nada se o processo de atualização já estiver em execução. Caso contrário, ele começa o processo
de atualização.
O objeto atualizador pode despachar o seguinte evento como resultado de chamar o método checkNow():
• Evento UpdateEvent.CHECK_FOR_UPDATE, antes de ele tentar baixar o arquivo de descritor de atualização.
Se você cancelar o evento checkForUpdate, poderá chamar o método checkForUpdate() do objeto atualizador.
(Consulte a próxima seção.) Se você não cancelar o evento, o processo de atualização continuará para verificar se há
arquivo de descritor de atualização.
Gerenciamento do processo de atualização na versão ApplicationUpdaterUI
Na versão ApplicationUpdaterUI, o usuário pode cancelar o processo pelos botões Cancelar das caixas de diálogo da
interface de usuário. Além disso, você pode cancelar de forma programática o processo de atualização chamando o
método cancelUpdate() do objeto ApplicationUpdaterUI.
Você pode definir as propriedades do objeto ApplicationUpdaterUI ou definir elementos no arquivo de configuração
de atualização para especificar quais confirmações de caixa de diálogo o atualizador exibe. Para obter detalhes, consulte
“Definição das configurações de atualização” na página 336.
Gerenciamento do processo de atualização na versão ApplicationUpdater
Você pode chamar o método preventDefault() dos objetos de evento despachados pelo objeto ApplicationUpdater
para cancelar etapas do processo de atualização (consulte “O processo de atualização” na página 338). Cancelar o
comportamento padrão fornece ao seu aplicativo uma chance de exibir uma mensagem ao usuário perguntando se ele
deseja continuar.
As seções a seguir descrevem como continuar o processo de atualização quando uma etapa do processo é cancelada.
Download e interpretação do arquivo de descritor de atualização
O objeto ApplicationUpdater despacha o evento checkForUpdate antes do processo de atualização ser iniciado, logo
antes de o atualizador tentar baixar o arquivo de descritor de atualização. Se você cancelar o comportamento padrão
do evento checkForUpdate, o atualizador não baixará o arquivo de descritor de atualização. Você pode chamar o
método checkForUpdate() para retomar o processo de atualização:
appUpdater.checkForUpdate();
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 340
Atualização de aplicativos do AIR
Chamar o método checkForUpdate() faz com que o atualizador baixe de forma assíncrona e interprete o arquivo de
descritor de atualização. Como resultado de chamar o método checkForUpdate(), o objeto atualizador poderá
despachar os seguintes eventos:
•
StatusUpdateEvent.UPDATE_STATUS — O atualizador baixou e interpretou o arquivo de descritor de atualização
com êxito. Esse evento tem estas propriedades:
•
available — Um valor booleano. Defina como true se houver uma versão disponível diferente da versão do
aplicativo atual; false, para o contrário (a versão é a mesma).
•
version — Uma seqüência de caracteres. A versão do arquivo de descritor de aplicativo do arquivo de
atualização
•
details — Uma matriz. Se não houver versões localizadas da descrição, essa matriz retornará uma seqüência
de caracteres vazia ("") como primeiro elemento e a descrição como segundo elemento.
Se houver várias versões da descrição (no arquivo de descritor de atualização), a matriz conterá várias
submatrizes. Cada matriz tem dois elementos: o primeiro é um código de idiomas (como "en") e o segundo é a
descrição correspondente (uma seqüência de caracteres) para o idioma. Consulte “Definição do arquivo de
descritor de atualização a acréscimo do arquivo do AIR ao servidor da Web.” na página 335.
•
StatusUpdateErrorEvent.UPDATE_ERROR — Ocorreu e o atualizador não pôde baixar ou interpretar o arquivo
de descritor de eventos.
Download do arquivo de atualização do AIR
O objeto ApplicationUpdater despacha o evento updateStatus depois que o atualizador baixa e interpreta com êxito
o arquivo de descritor de atualização. O comportamento padrão é começar a baixar o arquivo de atualização, se ele
estiver disponível. Se você cancelar o comportamento padrão, poderá chamar o método downloadUpdate() para
retomar o processo de atualização.
appUpdater.downloadUpdate();
Chamar esse método faz com que o atualizador baixe de forma assíncrona a versão de atualização do arquivo do AIR.
O método downloadUpdate() pode despachar os seguintes eventos:
•
UpdateEvent.DOWNLOAD_START — Foi estabelecida a conexão com o servidor. Quando você usa a biblioteca
ApplicationUpdaterUI, esse evento exibe uma caixa de diálogo com uma barra de progresso para controlar o
andamento do download.
•
ProgressEvent.PROGRESS — Despachado periodicamente conforme o download do arquivo progride.
•
DownloadErrorEvent.DOWNLOAD_ERROR — Despachado se houver um erro na conexão ou no download do
arquivo de atualização. Também é despachado para status de HTTP inválidos (como " 404 - Arquivo não
encontrado"). Esse evento tem uma propriedade errorID, um inteiro que define informações de erro adicionais.
Uma propriedade subErrorID adicional pode conter mais informações de erro.
•
UpdateEvent.DOWNLOAD_COMPLETE — O atualizador baixou e interpretou o arquivo de descritor de atualização
com êxito. Se você não cancelar esse evento, a versão do ApplicationUpdater continuará a instalar a versão de
atualização. Na versão do ApplicationUpdaterUI, o usuário visualiza uma caixa de diálogo que fornece a opção de
continuar.
Atualização do aplicativo
O objeto ApplicationUpdater despacha o evento downloadComplete quando o download do arquivo de atualização é
concluído. Se você cancelar o comportamento padrão, poderá chamar o método installUpdate() para retomar o
processo de atualização.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 341
Atualização de aplicativos do AIR
appUpdater.installUpdate(file);
Chamar esse método faz com que o atualizador instale uma versão de atualização do arquivo do AIR. O método inclui
um parâmetro, file, que é um objeto File que referencia o arquivo do AIR a ser usado como atualização.
O objeto ApplicationUpdater pode despachar e evento beforeInstall como resultado de chamar o método
installUpdate():
•
UpdateEvent.BEFORE_INSTALL — Despachado antes de instalar a atualização. Às vezes, é útil impedir a instalação
da atualização nesse momento, para que o usuário possa concluir o trabalho atual antes de a atualização continuar.
Chamar o método preventDefault() do objeto Event adia a instalação até o próximo reinício, e nenhum processo
de atualização adicional pode ser iniciado. (Isso inclui atualizações que resultariam de chamar o método
checkNow() ou de verificações periódicas.)
Instalação de um arquivo do AIR arbitrário
Você pode chamar o método installFromAIRFile() para instalar a versão de atualização para instalar de um
arquivo do AIR no computador do usuário.
appUpdater.installFromAIRFile();
Esse método faz com que o atualizador instale uma versão de atualização do aplicativo a partir do arquivo do AIR.
O método installFromAIRFile() pode despachar os seguintes eventos:
•
StatusFileUpdateEvent.FILE_UPDATE_STATUS — Despachado depois que ApplicationUpdater valida com
êxito o arquivo envaido usando o método installFromAIRFile(). Esse evento tem as seguintes propriedades:
•
available — Definida como true se houver uma versão diferente da versão do aplicativo atual; false caso
contrário (as versões são as mesmas).
•
version — A string que representa a nova versão disponível.
•
path — Representa o caminho nativo do arquivo de atualização.
Você pode cancelar esse evento se a propriedade disponível do objeto StatusFileUpdateEvent estiver definida como
true. O cancelamento do evento impede a continuidade da atualização. Chame o método installUpdate() para
continuar a atualização cancelada.
•
StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR — Ocorreu um erro e o atualizador não pôde instalar o
aplicativo AIR.
Cancelamento do processo de atualização
Você pode chamar o método cancelUpdate() para cancelar o processo de atualização:
appUpdater.cancelUpdate();
Esse método cancela os downloads pendentes, excluindo arquivos baixados incompletos, e reinicia o timer de
verificação periódica.
O método não faz nada se o objeto atualizador estiver sendo inicializado.
Localização da interface ApplicationUpdaterUI
A classe ApplicationUpdaterUI fornece uma interface de usuário padrão para o processo de atualização. Isso inclui
caixas de diálogo que permitem que o usuário inicie o processo, cancele o processo e realize outras ações relacionadas.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 342
Atualização de aplicativos do AIR
O elemento description do arquivo de descritor de atualização permite definir a descrição do aplicativo em vários
idiomas. Use vários elementos text que definem atributos lang, como a seguir:
<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.1a1</version>
<url>http://example.com/updates/sample_1.1a1.air</url>
<description>
<text xml:lang="en">English description</text>
<text xml:lang="fr">French description</text>
<text xml:lang="ro">Romanian description</text>
</description>
</update>
A estrutura de atualização usa a descrição mais adequada para a cadeia de localização do usuário. Para obter mais
informações, consulte Definição do arquivo de descritor de atualização a acréscimo do arquivo do AIR ao servidor da Web.
Desenvolvedores de Flex podem adicionar diretamente um novo idioma ao grupo "ApplicationUpdaterDialogs".
Desenvolvedores de JavaScript podem chamar o método addResources() do objeto atualizador. Esse método
adiciona dinamicamente um novo conjunto de recursos para um idioma. O conjunto de recursos define seqüências de
caracteres localizadas para um idioma. Essas seqüências de caracteres são usadas em vários campos de texto de caixa
de diálogo.
Desenvolvedores de JavaScript podem usar a propriedade localeChain da classe ApplicationUpdaterUI para definir
a cadeia de localização usada pela interface do usuário. Geralmente, somente desenvolvedores de JavaScript (HTML)
usam essa propriedade. Desenvolvedores de Flex usam o ResourceManager para gerenciar a cadeia de localização.
Por exemplo, o código de JavaScript a seguir define grupos de recursos para romano e húngaro.
appUpdater.addResources("ro_RO",
{titleCheck: "Titlu", msgCheck: "Mesaj", btnCheck: "Buton"});
appUpdater.addResources("hu", {titleCheck: "Cím", msgCheck: "Üzenet"});
var languages = ["ro", "hu"];
languages = languages.concat(air.Capabilities.languages);
var sortedLanguages = air.Localizer.sortLanguagesByPreference(languages,
air.Capabilities.language,
"en-US");
sortedLanguages.push("en-US");
appUpdater.localeChain = sortedLanguages;
Para obter detalhes, consulte a descrição do método addResources() da classe ApplicationUpdaterUI na referência
de idiomas.
343
Capítulo 34: Localização de aplicativos
AIR
O Adobe® AIR™ 1.1 inclui suporte para vários idiomas.
Introdução à localização
Localização é o processo de inclusão de recursos para oferecer suporte a vários códigos de idiomas. Código de idiomas
é a combinação de um idioma e um código de um país. Por exemplo, en_US se refere ao idioma inglês falado nos
Estados Unidos e fr_FR se refere ao idioma francês falado na França. Para localizar um aplicativo para esses códigos
de idiomas, você fornece dois conjuntos de recursos: um para o código de idioma en_US e um para o código de idiomas
fr_FR.
Os códigos de idiomas podem compartilhar idiomas. Por exemplo, en_US e en_GB (Grã-Bretanha) são códigos de
idiomas diferentes. Nesse caso, os dois códigos de idiomas usam o idioma inglês, mas o código do país indica que são
códigos de idiomas diferentes e podem, portanto, usar recursos diferentes. Por exemplo, um aplicativo no código de
idioma sen_US pode escrever a palavra "color", ao passo que ela seria "colour" no código de idiomas en_GB. Além
disso, unidades monetárias seriam representadas em dólares ou em libras, dependendo do código de idiomas, e o
formato de data e hora também pode ser diferente.
Você também podem fornecer um conjunto de recursos para um idioma sem especificar o código do país. Por
exemplo, você pode fornecer recursos en para o idioma Inglês e fornecer recursos adicionais do código de idiomas
en_US, específicos para inglês dos EUA.
O AIR SDK oferece uma estrutura de localização HTML (contida no arquivo AIRLocalizer.js). Essa estrutura inclui
APIs que auxiliam no trabalho com vários códigos de idiomas. Para obter detalhes, consulte “Localização de conteúdo
HTML” na página 344.
A localização vai além de só traduzir as seqüências usadas no aplicativo. Ela também pode incluir qualquer tipo de
recurso, como arquivos de áudio, imagens e vídeos.
Localização do nome e da descrição do aplicativo no
instalador do aplicativo
Você pode especificar vários idiomas para os elementos name e description no arquivo do descritor do aplicativo.
Por exemplo, o seguinte especifica o nome do aplicativo em três idiomas (inglês, francês e alemão):
<name>
<text xml:lang="en">Sample 1.0</text>
<text xml:lang="fr">Échantillon 1.0</text>
<text xml:lang="de">Stichprobe 1.0</text>
</name>
O atributo xml:lang de cada elemento de texto especifica um código de idioma, como definido por RFC4646
(http://www.ietf.org/rfc/rfc4646.txt).
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 344
Localização de aplicativos AIR
O elemento name define o nome do aplicativo que o instalador de aplicativo do AIR exibe. O instalador de aplicativo
do AIR usa o valor localizado que melhor corresponda aos idiomas da interface do usuário definidos pelas
configurações do sistema operacional.
De modo semelhante, você pode especificar várias versões de idioma do elemento description no arquivo do
descritor do aplicativo. Esse elemento define o texto de descrição que instalador de aplicativo do AIR exibe.
Essas configurações só se aplicam aos idiomas disponíveis no instalador de aplicativo do AIR. Elas não definem os
códigos de idiomas disponíveis para a execução do aplicativo instalado. Os aplicativo do AIR pode oferecer interfaces
do usuário que oferecem suporte a vários idiomas, incluindo e além daquelas disponíveis no instalador de aplicativo
do AIR.
Para obter mais informações, consulte “Definição de propriedades no arquivo do descritor do aplicativo” na página 45.
Seleção de código de idiomas
Para determinar que código de idiomas o aplicativo usa, você pode usar um dos seguintes métodos:
• Prompt de usuário: você pode iniciar o aplicativo em algum código de idiomas padrão e, então, solicitar ao usuário
que selecione o código de idiomas preferido.
•
Capabilities.languages: a propriedade Capabilities.languages lista uma matriz de idiomas disponíveis
nos idiomas de preferência do usuário, conforme definido pelo sistema operacional. As seqüências contêm tags de
idioma (e informações de script e região, quando aplicável) definidas por RFC4646
(http://www.ietf.org/rfc/rfc4646.txt). As seqüências usam hífens como delimitadores (por exemplo, "en-US" ou
"ja-JP"). A primeira entrada na matriz retornada tem a mesma ID de idioma principal da propriedade language.
Por exemplo, se languages[0] for definido como "en-US", a propriedade language será definida como "en".
Entretanto, se a propriedade language for definida como "xu" (especificando um idioma desconhecido), o
primeiro elemento na matriz languages será diferente.
•
Capabilities.language: a propriedade Capabilities.language oferece o código de idioma da interface do
usuário do sistema operacional. No entanto, essa propriedade está limitada a 20 idiomas conhecidos. E, nos
sistemas em inglês, essa propriedade retorna somente o código do idioma, não o código do país. Por esses motivos,
é melhor usar o primeiro elemento na matriz Capabilities.languages.
Localização de conteúdo Flash
O Flash CS3 e Flash CS4 incluem a classe Locale nos componentes do ActionScript 3.0. A classe Locale permite
controlar como o arquivo SWF exibe o texto multilíngüe. O painel Strings do Flash permite usar IDs de string em vez
de literais de string nos campos de texto dinâmicos. Isso permite criar um arquivo SWF que exibe o texto carregado
de um arquivo XML específico do idioma. Para obter informações sobre o uso da classe Locale, consulte a Referência
dos componentes e da linguagem do ActionScript 3.0 do Flash.
Localização de conteúdo HTML
O AIR 1.1 SDK inclui uma estrutura de localização HTML. O arquivo de JavaScript AIRLocalizer.js define a estrutura.
O diretório de estruturas do AIR SDK contém o arquivo AIRLocalizer.js. Esse arquivo inclui a classe Localizer, que
oferece funcionalidade para auxiliar na criação de aplicativos que ofereçam suporte a várias versões localizadas.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 345
Localização de aplicativos AIR
Carregamento do código de estrutura de localização HTML do AIR.
Para usar a estrutura de localização, copie o arquivo AIRLocalizer.js em seu projeto. Em seguida, inclua-a no arquivo
HTML principal do aplicativo, usando uma tag de script:
<script src="AIRLocalizer.js" type="text/javascript" charset="utf-8"></script>
Em seguida, o JavaScript pode chamar o objeto air.Localizer.localizer:
<script>
var localizer = air.Localizer.localizer;
</script>
O objeto air.Localizer.localizer é um objeto singleton que define métodos e propriedades para usar e gerenciar
recursos de localização. A classe Localizer inclui os seguintes métodos:
Método
Descrição
getFile()
Obtém o texto de um grupo de recursos especificados para um código de idiomas especificado. Consulte
“Obtenção de recursos para um código de idiomas específico.” na página 351.
getLocaleChain()
Retorna os idiomas na cadeia de código de idiomas. Consulte “Definição da cadeia de código de idiomas” na
página 350.
getResourceBundle()
Retorna as chaves do grupo e os valores correspondentes como um objeto. Consulte “Obtenção de recursos
para um código de idiomas específico.” na página 351.
getString()
Obtém a seqüência definida para um recurso. Consulte “Obtenção de recursos para um código de idiomas
específico.” na página 351.
setBundlesDirectory(
)
Define o local do diretório de compactados. Consulte “Personalização de configurações HTML Localizer do
AIR” na página 349.
setLocalAttributePre
fix()
Define o prefixo usado pelos atributos do localizer usados nos elementos HTML DOM. Consulte
“Personalização de configurações HTML Localizer do AIR” na página 349
setLocaleChain()
Define a ordem de idiomas na cadeia de código de idiomas. Consulte “Definição da cadeia de código de
idiomas” na página 350.
sortLanguagesByPrefe
rence()
Classifica os códigos de idiomas na cadeia de código de idiomas com base na ordem de códigos de idiomas
nas configurações do sistema operacional. Consulte “Definição da cadeia de código de idiomas” na
página 350.
update()
Atualiza o HTML DOM (ou um elemento DOM) com seqüências localizadas da cadeia de código de idiomas
atual. Para obter uma discussão sobre cadeias de códigos de idiomas, consulte “Gerenciamento de cadeias de
códigos de idiomas” na página 347. Para obter mais informações sobre o método update(), consulte
“Atualização de elementos DOM para uso de código de idiomas atual” na página 348.
A classe Localizer inclui as seguintes propriedades estáticas:
Propriedade
Descrição
localizer
Retorna uma referência para o objeto singleton Localizer do aplicativo.
ultimateFallbackLocale
Código de idiomas usado quando o aplicativo não oferece suporte a nenhuma
preferência de usuário. Consulte “Definição da cadeia de código de idiomas” na
página 350.
Definição de grupos de recursos
A estrutura de localização HTML faz a leitura de versões localizadas de seqüências de arquivos de localização. O
arquivo de localização é um conjunto de valores baseados em chaves, serializados em um arquivo de texto. O arquivo
de localização é algumas vezes tratado como um compactado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 346
Localização de aplicativos AIR
Crie um subdiretório do diretório de projeto do aplicativo, chamado código de idiomas. (Você também pode usar um
nome diferente; consulte “Personalização de configurações HTML Localizer do AIR” na página 349.) Esse diretório
incluirá os arquivos de localização. Esse diretório é conhecido como o diretório de compactações.
Para cada código de idiomas a que seu aplicativo oferece suporte, crie um subdiretório do diretório de compactações.
Nomeie cada subdiretório para corresponder ao código de idiomas. Por exemplo, nomeie o diretório French como "fr"
e o diretório English como "en". Você pode usar o caractere sublinhado (_) para definir o código de idiomas que tenha
um código de país e idioma. Por exemplo, nomeie o diretório U.S. English como “en_us”. (Como alternativa, você
pode usar um hífen, em vez de um sublinhado, como em “en-us.” A estrutura de localização HTML oferece suporte às
duas opções).
Você pode adicionar qualquer número de arquivos de recursos a um subdiretório código de idiomas. Normalmente,
você cria um arquivo de localização para cada idioma (e coloca o arquivo no diretório desse idioma). A estrutura de
localização HTML inclui o método getFile() que permite ler o conteúdo de um arquivo (consulte “Obtenção de
recursos para um código de idiomas específico.” na página 351.
Arquivos com a extensão de arquivo .properties são conhecidos como arquivos de propriedades de localização. Você
pode usá-los para definir pares de valores chave para um código de idiomas. O arquivo de propriedade define um valor
de seqüência em cada linha. Por exemplo, o seguinte define o valor de seqüência "Oi em inglês". para uma chave
de nome greeting:
greeting=Hello in English.
O arquivo de propriedades contendo o texto a seguir define seis pares de valores chave:
title=Sample Application
greeting=Hello in English.
exitMessage=Thank you for using the application.
color1=Red
color2=Green
color3=Blue
Este exemplo mostra uma versão em inglês do arquivo de propriedades que deve ser armazenado no diretório en.
A versão francesa desse arquivo de propriedades é colocada no diretório fr:
title=Application Example
greeting=Bonjour en français.
exitMessage=Merci d'avoir utilisé cette application.
color1=Rouge
color2=Vert
color3=Bleu
Você pode definir vários arquivos de recursos para tipos diferentes de informações. Por exemplo, o arquivo
legal.properties pode conter texto de padrão legal (como informações de direitos autorais). Talvez você deseje
reutilizar esse recurso em vários aplicativos. De modo semelhante, você pode definir arquivos distintos que definem
conteúdo localizado de diferentes partes da interface do usuário.
Use a codificação UTF-8 para esses arquivos, para oferecer suporte a vários idiomas.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 347
Localização de aplicativos AIR
Gerenciamento de cadeias de códigos de idiomas
Quando o aplicativo carrega o arquivo AIRLocalizer.js, ele examina os códigos de idiomas definidos no aplicativo.
Esses códigos de idiomas correspondem aos subdiretórios do diretório de compactações (consulte “Definição de
grupos de recursos” na página 345). Essa lista de códigos de idiomas disponíveis é conhecida como a cadeia de código
de idiomas. O arquivo AIRLocalizer.js classifica automaticamente a cadeia de código de idiomas com base na ordem
de preferência definida pelas configurações do sistema operacional. (A propriedade Capabilities.languages lista
os idiomas da interface do usuário do sistema operacional, por ordem de preferência).
Portanto, se um aplicativo define recursos para os códigos de idiomas "en", "en_US" e "en_UK", a estrutura HTML
Localizer do AIR classifica a cadeia de código de idiomas de maneira apropriada. Quando o aplicativo é iniciado em
um sistema que informa "en" como código de idiomas principal, a cadeia de código de idiomas é classificada como
["en", "en_US", "en_UK"]. Nesse caso o aplicativo procura primeiramente por recursos no grupo "en" e, em
seguida, no grupo "en_US".
No entanto, se o sistema informar "en-US" como código de idiomas principal, a classificação usará ["en_US", "en",
en_UK"]. Nesse caso, o aplicativo procura primeiramente recursos no grupo "en_US" e, em seguida, no grupo "en".
Por padrão, o aplicativo define o primeiro código de idiomas na cadeia de código de idiomas como o código de idiomas
padrão para usar. Você pode solicitar que o usuário selecione um código de idiomas na primeira execução do
aplicativo. Em seguida, você pode optar por armazenar a seleção em um arquivo de preferências e usar esse código de
idiomas na inicialização subseqüente do aplicativo.
O aplicativo pode usar as seqüências de recursos em qualquer código de idiomas da cadeia de código de idiomas. Se
um código de idiomas específico não definir uma seqüência de recursos, o aplicativo usará a próxima seqüência de
recursos correspondente em outros códigos de idiomas definidos na cadeia de código de idiomas.
Você pode personalizar a cadeia de código de idiomas chamando o método setLocaleChain() do objeto Localizer.
Consulte “Definição da cadeia de código de idiomas” na página 350.
Atualização de elementos DOM com conteúdo localizado
O elemento no aplicativo pode fazer referência a um valor chave em um arquivo de propriedades de localização. Por
exemplo, o elemento title no exemplo a seguir especifica um atributo local_innerHTML. A estrutura de localização
usa esse atributo para pesquisar um valor localizado. Por padrão, a estrutura pesquisa nomes de atributos que iniciam
com "local_". A estrutura atualiza os atributos com nomes que correspondem ao texto em seguida a "local_".
Nesse caso, a estrutura define o atributo innerHTML do elemento title. O atributo innerHTML usa o valor definido
para a chave mainWindowTitle no arquivo de propriedades padrão (default.properties):
<title local_innerHTML="default.mainWindowTitle"/>
Se o código de idiomas atual não definir nenhum valor correspondente, a estrutura do localizador procura o restante
da cadeia de códigos de idiomas. Ele usa o próximo código de idiomas na cadeia de código de idiomas para o qual um
valor está definido.
No exemplo a seguir, o texto (atributo innerHTML) do elemento p usa o valor da chave greeting definido no arquivo
de propriedades padrão:
<p local_innerHTML="default.greeting" />
No exemplo a seguir, o atributo de valor (e texto exibido) do elemento input usa o valor da chave btnBlue definido
no arquivo de propriedades padrão:
<input type="button" local_value="default.btnBlue" />
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 348
Localização de aplicativos AIR
Para atualizar o HTML DOM para usar as seqüências definidas na cadeia de código de idiomas atual, chame o método
update() do objeto Localizer. Chamar o método update() faz com que o objeto Localizer analise o DOM e aplique
manipulações onde encontrar atributos de localização "local_..."):
air.Localizer.localizer.update();
Você pode definir valores tanto para um atributo (como "innerHTML") quanto para o respectivo atributo de
localização correspondente (como "local_innerHTML"). Nesse caso, a estrutura de localização só sobrescreve o valor
de atributo se ela encontrar um valor correspondente na cadeia de localização. Por exemplo, o elemento a seguir define
os atributos value e local_value:
<input type="text" value="Blue" local_value="default.btnBlue"/>
Você também pode atualizar apenas um elemento DOM específico Consulte a próxima seção, “Atualização de
elementos DOM para uso de código de idiomas atual” na página 348.
Por padrão, o HTML Localizer do AIR usa "local_" como o prefixo de atributos que definem as configurações de
localização do elemento. Por exemplo, por padrão, o atributo local_innerHTML define o nome do grupo e recurso
usados no valor innerHTML do elemento. Além disso, por padrão, o atributo local_value define o nome do grupo e
recurso usados no atributo value do elemento. Você pode configurar o Localizer para usar um prefixo de atributo
além de "local_". Consulte “Personalização de configurações HTML Localizer do AIR” na página 349.
Atualização de elementos DOM para uso de código de idiomas atual
Quando o objeto Localizer atualiza o HTML DOM, isso faz com que elementos marcados usem valores de atributos
com base nas seqüências definidas na cadeia de código de idiomas atual. Para fazer com que o localizador HTML
atualize o HTML DOM, chame o método update() do objeto Localizer:
air.Localizer.localizer.update();
Para atualizar apenas um elemento DOM especificado, passe-o como parâmetro para o método update(). O método
update() só tem um parâmetro, parentNode, que é opcional. Quando especificado, o parâmetro parentNode define
o elemento DOM para ser localizado. Chamar o método update() e especificar o parâmetro parentNode define os
valores localizados de todos os elementos filhos que especificam atributos de localização.
Por exemplo, considere o seguinte elemento div:
<div id="colorsDiv">
<h1 local_innerHTML="default.lblColors" ></h1>
<p><input type="button" local_value="default.btnBlue" /></p>
<p><input type="button" local_value="default.btnRed" /></p>
<p><input type="button" local_value="default.btnGreen" /></p>
</div>
Para atualizar esse elemento para usar as seqüências localizadas definidas na cadeia de código de idiomas atual, use o
seguinte código JavaScript:
var divElement = window.document.getElementById("colorsDiv");
air.Localizer.localizer.update(divElement);
Se o valor chave não for encontrado na cadeia de código de idiomas, a estrutura de localização definirá o valor de
atributo como o valor do atributo "local_". Por exemplo, no exemplo anterior, suponhamos que a estrutura de
localização não possa encontrar o valor da chave lblColors (em qualquer um dos arquivos default.properties na
cadeia de código de idiomas). Nesse caso, ela usará "default.lblColors" como valor innerHTML. Usar esse valor
indica (para o desenvolvedor) ausência de recursos.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 349
Localização de aplicativos AIR
O método update() despacha o evento resourceNotFound quando não consegue encontrar um recurso na cadeia de
código de idiomas. A constante air.Localizer.RESOURCE_NOT_FOUND define a seqüência "resourceNotFound". O
evento tem três propriedades: bundleName, resourceName e locale. A propriedade bundleName é o nome do grupo
em que o recurso não foi encontrado. A propriedade resourceName é o nome do grupo em que o recurso não foi
encontrado. A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado.
O método update() despacha o evento bundleNotFound quando não consegue encontrar o grupo especificado. A
constante air.Localizer.BUNDLE_NOT_FOUND define a seqüência "bundleNotFound". O evento tem duas
propriedades: bundleName e locale. A propriedade bundleName é o nome do grupo em que o recurso não foi
encontrado. A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado.
O método update() funciona de forma assíncrona (e despacha os eventos resourceNotFound e bundleNotFound de
forma assíncrona). O código a seguir define ouvintes de evento dos eventos resourceNotFound e bundleNotFound:
air.Localizer.localizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler);
air.Localizer.localizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, rnfHandler);
air.Localizer.localizer.update();
function rnfHandler(event)
{
alert(event.bundleName + ": " + event.resourceName + ":." + event.locale);
}
function bnfHandler(event)
{
alert(event.bundleName + ":." + event.locale);
}
Personalização de configurações HTML Localizer do AIR
O método setBundlesDirectory() do objeto Localizer permite personalizar o caminho do diretório de
compactações. O método setLocalAttributePrefix() do objeto Localizer permite personalizar o caminho do
diretório de compactações e personalizar o valor de atributo usado pelo Localizer.
O diretório de compactações padrão é definido como o subdiretório código de idiomas do diretório do aplicativo.
Você pode especificar outro diretório chamando o método setBundlesDirectory() do objeto Localizer. Esse
método usa o parâmetro path, que é o caminho para o diretório de compactações desejado, como uma seqüência. O
valor do parâmetro path pode ser algum dos seguintes:
• Uma seqüência que define o caminho relativo para o diretório do aplicativo, como "locales"
• Uma seqüência que define a URL válida que usa os esquemas de URL app, app-storage ou file, como
"app://languages" (não usa o esquema de URL http)
• O objeto File
Para obter informações sobre caminhos de diretórios e URLs, consulte “Caminhos de objetos File” na página 107.
Por exemplo, o código a seguir define o diretório de compactações como subdiretório de idiomas do diretório de
armazenamento do aplicativo (não o diretório de aplicativo):
air.Localizer.localizer.setBundlesDirectory("languages");
Passe um caminho válido como o parâmetro path. Do contrário, o método emitirá uma exceção
BundlePathNotFoundError. Esse erro tem "BundlePathNotFoundError" como sua propriedade name e a respectiva
propriedade message especifica o caminho inválido.
Por padrão, o HTML Localizer do AIR usa "local_" como o prefixo de atributos que definem as configurações de
localização do elemento. Por exemplo, o atributo local_innerHTML define o nome do grupo e recurso usado no valor
innerHTML do seguinte elemento input:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 350
Localização de aplicativos AIR
<p local_innerHTML="default.greeting" />
O método setLocalAttributePrefix() do objeto Localizer permite usar outro prefixo de atributo que não seja
"local_". Esse método estático usa um parâmetro, que é a seqüência que você deseja usar como prefixo de atributo.
Por exemplo, o código a seguir define que a estrutura de localização use "loc_" como o prefixo de atributo:
air.Localizer.localizer.setLocalAttributePrefix("loc_");
Você pode personalizar o prefixo de atributo que a estrutura de localização utiliza. Talvez você deseje personalizar o
prefixo, caso o valor padrão ("local_") entre em conflito com o nome de outro atributo usado por seu código.
Certifique-se de usar caracteres válidos em atributos HTML quando chamar esse método. (Por exemplo, o valor não
pode conter um caractere de espaço em branco).
Para obter mais informações sobre como usar os atributos de localização em elementos HTML, consulte “Atualização
de elementos DOM com conteúdo localizado” na página 347.
As configurações do diretório de compactações e prefixo de atributo não persistem entre sessões de aplicativos
diferentes. Se você usar uma configuração personalizada de diretório de compactações ou de prefixo de atributo,
certifique-se de defini-las sempre que iniciar o aplicativo.
Definição da cadeia de código de idiomas
Por padrão, quando você carrega o código AIRLocalizer.js, ele define a cadeia de código de idiomas padrão. Os códigos
de idiomas disponíveis nas configurações de diretório de compactações e de idioma do sistema operacional definem
essa cadeia de código de idiomas. (Para obter detalhes, consulte “Gerenciamento de cadeias de códigos de idiomas”
na página 347).
Você pode modificar a cadeia de código de idiomas chamando o método estático setLocaleChain() do objeto
Localizer. Por exemplo, talvez você deseje chamar esse método se o usuário indicar a preferência por um idioma
específico. O método setLocaleChain() usa um parâmetro, chain, que é uma matriz de códigos de idiomas, como
["fr_FR","fr","fr_CA"]. A ordem dos códigos de idiomas na matriz define a ordem em que a estrutura pesquisa
recursos (em operações subseqüentes). Se o recurso não for encontrado para o primeiro código de idiomas na cadeia,
ele continua pesquisando em outros recursos de códigos de idiomas. Se o argumento chain estiver ausente, se não for
uma matriz ou for uma matriz vazia, a função falhará e emitirá uma exceção IllegalArgumentsError.
O método estático getLocaleChain() do objeto Localizer retorna uma matriz que lista os códigos de idiomas na
cadeia de código de idiomas atual.
O código a seguir faz a leitura da cadeia de código de idiomas atual e adiciona dois códigos de idiomas franceses ao
cabeçalho da cadeia:
var currentChain = air.Localizer.localizer.getLocaleChain();
newLocales = ["fr_FR", "fr"];
air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain));
O método setLocaleChain() despacha o evento "change" quando atualiza a cadeia de código de idiomas. A
constante air.Localizer.LOCALE_CHANGE define a seqüência "change". O evento tem uma propriedade,
localeChain, uma matriz de códigos de idiomas na nova cadeia de código de idiomas. O código a seguir define um
ouvinte de evento para esse evento:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 351
Localização de aplicativos AIR
var currentChain = air.Localizer.localizer.getLocaleChain();
newLocales = ["fr_FR", "fr"];
localizer.addEventListener(air.Localizer.LOCALE_CHANGE, changeHandler);
air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain));
function changeHandler(event)
{
alert(event.localeChain);
}
A propriedade estática air.Localizer.ultimateFallbackLocale representa o código de idiomas usado quando o
aplicativo não oferece suporte a nenhuma preferência do usuário. O valor padrão é "en". Você pode defini-lo como
outro código de idiomas, como mostrado no código a seguir:
air.Localizer.ultimateFallbackLocale = "fr";
Obtenção de recursos para um código de idiomas específico.
O método getString() do objeto Localizer retorna a seqüência definida para um recurso em um código de idiomas
específico. Não é necessário especificar o valor locale ao chamar o método. Nesse caso, o método procura em toda a
cadeia de código de idiomas e retorna a seqüência no primeiro código de idiomas que fornece o nome de recurso
determinado. O método tem os seguintes parâmetros:
Parâmetro
Descrição
bundleName
O grupo que contém o recurso. Esse é o nome de arquivo do arquivo de
propriedades sem a extensão .properties. (Por exemplo, se esse parâmetro for
definido como "alerts", o código Localizer pesquisará nos arquivos de
localização chamados alerts.properties.
resourceName
O nome do recurso.
templateArgs
Opcional. A matriz de seqüência para substituir as tags numeradas na seqüência
de substituição. Por exemplo, considere uma chamada para a função em que o
parâmetro templateArgs seja ["Raúl", "4"] e a seqüência de recursos
correspondente seja "Hello, {0}. Você tem {1} mensagens novas.".
Nesse caso, a função retorna "Hello, Raúl. Você tem 4 mensagens
novas".. Para ignorar essa configuração, passe o valor null.
locale
Opcional. O código de idiomas (como "en", "en_us" ou "fr") que deve ser
usado. Se o código de idiomas for fornecido e nenhum valor correspondente for
encontrado, o método não continuará a busca por valores em outros códigos de
idiomas na cadeia de código de idiomas. Se nenhum código de idiomas for
especificado, a função retornará a seqüência no primeiro código de idiomas na
cadeia de código de idiomas que ofereça o valor para o nome de recurso
determinado.
A estrutura de localização pode atualizar atributos HTML DOM marcados. No entanto, você pode usar seqüências
localizadas de outras maneiras. Por exemplo, você pode usar uma seqüência em HTMLs gerados dinamicamente ou
como valor de parâmetro em uma chamada de função. Por exemplo, o código a seguir chama a função alert() com
a seqüência definida no recurso error114 no arquivo de propriedades padrão do código de idiomas fr_FR:
alert(air.Localizer.localizer.getString("default", "error114", null, "fr_FR"));
O método getString() despacha o evento resourceNotFound quando não consegue encontrar o recurso no grupo
especificado. A constante air.Localizer.RESOURCE_NOT_FOUND define a seqüência "resourceNotFound". O
evento tem três propriedades: bundleName, resourceName e locale. A propriedade bundleName é o nome do grupo
em que o recurso não foi encontrado. A propriedade resourceName é o nome do grupo em que o recurso não foi
encontrado. A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 352
Localização de aplicativos AIR
O método getString() despacha o evento bundleNotFound quando não consegue encontrar o grupo especificado.
A constante air.Localizer.BUNDLE_NOT_FOUND define a seqüência "bundleNotFound". O evento tem duas
propriedades: bundleName e locale. A propriedade bundleName é o nome do grupo em que o recurso não foi
encontrado. A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado.
O método getString() opera de forma assíncrona (e despacha os eventos resourceNotFound e resourceNotFound
de forma assíncrona). O código a seguir define ouvintes de evento dos eventos resourceNotFound e
bundleNotFound:
air.Localizerlocalizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler);
air.Localizerlocalizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, bnfHandler);
var str = air.Localizer.localizer.getString("default", "error114", null, "fr_FR");
function rnfHandler(event)
{
alert(event.bundleName + ": " + event.resourceName + ":." + event.locale);
}
function bnfHandler(event)
{
alert(event.bundleName + ":." + event.locale);
}
O método getResourceBundle() do objeto Localizador retorna um grupo especificado para um determinado local.
O valor de retorno do método é um objeto com propriedades correspondentes às chaves do grupo. (Se o aplicativo não
puder localizar o grupo especificado, o método retornará null.)
O método assume dois parâmetros - locale e bundleName.
Parâmetro
Descrição
locale
O local (como "fr").
bundleName
O nome do grupo.
Por exemplo, o código a seguir chama o método document.write() para carregar o grupo padrão para o local fr. Em
seguida, ele chama o método document.write() com valores das chaves str1 e str2 do grupo:
var aboutWin = window.open();
var bundle = localizer.getResourceBundle("fr", "default");
aboutWin.document.write(bundle.str1);
aboutWin.document.write("<br/>");
aboutWin.document.write(bundle.str2);
aboutWin.document.write("<br/>");
O método getResourceBundle() despacha o evento bundleNotFound quando não consegue encontrar o grupo
especificado. A constante air.Localizer.BUNDLE_NOT_FOUND define a seqüência "bundleNotFound". O evento
tem duas propriedades: bundleName e locale. A propriedade bundleName é o nome do grupo em que o recurso não
foi encontrado. A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado.
O método getFile() do objeto Localizer retorna o conteúdo de um grupo, como uma seqüência, para um código de
idiomas determinado. O arquivo de compactação é interpretado como arquivo UTF-8. O método inclui os seguintes
parâmetros:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 353
Localização de aplicativos AIR
Parâmetro
Descrição
resourceFileName
Nome de arquivo do arquivo de recurso (como "about.html").
templateArgs
Opcional. A matriz de seqüência para substituir as tags numeradas na seqüência
de substituição. Por exemplo, considere uma chamada para a função em que o
parâmetro templateArgs seja ["Raúl", "4"] e o arquivo de recursos
correspondente contenha duas linhas:
<html>
<body>Hello, {0}. You have {1} new messages.</body>
</html>
Nesse caso, a função retorna uma seqüência com duas linhas:
<html>
<body>Hello, Raúl. You have 4 new messages. </body>
</html>
locale
O código de idiomas, como "en_GB", que deve ser usado. Se o código de idiomas
for fornecido e nenhum arquivo correspondente for encontrado, o método não
continuará a busca em outros códigos de idiomas na cadeia de código de
idiomas. Se o código de idiomas no for especificado, a função retornará o texto no
primeiro código de idiomas na cadeia de código de idiomas com um arquivo que
corresponda a resourceFileName.
Por exemplo, o código a seguir chama o método document.write() usando o conteúdo do arquivo about.html do
código de idiomas fr:
var aboutWin = window.open();
var aboutHtml = localizer.getFile("about.html", null, "fr");
aboutWin.document.close();
aboutWin.document.write(aboutHtml);
O método getFile() despacha o evento fileNotFound quando não consegue encontrar um recurso na cadeia de
código de idiomas. A constante air.Localizer.FILE_NOT_FOUND define a seqüência "resourceNotFound". O
método getFile() funciona de forma assíncrona (e despacha o evento fileNotFound de forma assíncrona). O
evento tem duas propriedades: fileName e locale. A propriedade fileName é o nome do arquivo não encontrado.
A propriedade locale é o nome do código de idiomas em que o recurso não foi encontrado. O código a seguir define
um ouvinte de evento para esse evento:
air.Localizer.localizer.addEventListener(air.Localizer.FILE_NOT_FOUND, fnfHandler);
air.Localizer.localizer.getFile("missing.html", null, "fr");
function fnfHandler(event)
{
alert(event.fileName + ": " + event.locale);
}
Localização de datas, horas e moedas
A maneira como os aplicativos apresentam dados, horas e moedas varia consideravelmente em cada código de
idiomas. Por exemplo, o padrão dos EUA para representação de datas é mês/dia/ano, enquanto o padrão europeu para
representação de datas é dia/mês/ano.
Você pode gravar um código para formatar datas, horas e moedas. Por exemplo, o código a seguir converte o objeto
Date no formato mês/dia/ano ou no formato dia/mês/ano. Se a variável locale (representando o código de idiomas)
for definida como "en_US", a função retornará o formato mês/dia/ano. O exemplo converte o objeto Date no formato
dia/mês/ano de todos os outros códigos de idiomas:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 354
Localização de aplicativos AIR
function convertDate(date)
{
if (locale == "en_US")
{
return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
}
else
{
return date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear();
}
}
355
Capítulo 35: Criação de um aplicativo do
AIR usando as ferramentas de linha de
comando
As ferramentas de linha de comando do Adobe® AIR™ permitem que você teste e empacote aplicativos do Adobe AIR.
Você também pode usar essas ferramentas em processos de criação automatizados. As ferramentas de linha de
comando do AIR estão incluídas no SDK do AIR (http://www.adobe.com/go/learn_air_download_AIRSDK_en).
Uso do ADL (AIR Debug Launcher)
Use o ADL (AIR Debug Launcher) para executar aplicativos com base em SWF e HTML durante o desenvolvimento.
Usando o ADL, você pode executar um aplicativo sem compactá-lo e instalá-lo primeiro. Por padrão, o ADL usa um
tempo de execução incluído com o SDK, o que significa que você não precisa instalar o tempo de execução
separadamente para usar o ADL.
O ADL imprime instruções de rastreamento e erros de tempo de execução para a saída padrão, mas não suporta pontos
de interrupção ou outros recursos de depuração. Se estiver desenvolvendo um aplicativo baseado em SWF, use o Flash
Debugger (ou Flash CS) para problemas de depuração complexos. É possível conectar-se ao Flash Debugger iniciando
o programa depurador antes de executar o aplicativo com ADL.
Inicialização de um aplicativo com ADL
Use a seguinte sintaxe:
adl [-runtime runtime-directory] [-pubid publisher-id] [-nodebug] application.xml [rootdirectory] [-- arguments]
-runtime runtime-directory Especifica o diretório que contém o tempo de execução a ser usado. Se não especificado,
o diretório do tempo de execução no mesmo SDK do programa ADL é usado. Se você mover o ADL para fora de sua
pasta do SDK, deverá especificar o diretório de tempo de execução. No Windows e no Linux, especifique o diretório que
contém o diretório do Adobe AIR . No Mac OS X, especifique o diretório que contém a estrutura do Adobe AIR.
-pubid publisher-id Atribui o valor especificado como a ID do editor do aplicativo do AIR para essa execução.
Especificar uma ID de editor temporária permite que você teste recursos de um aplicativo do AIR, como comunicação
por uma conexão local, que usa a ID do editor para ajudar a identificar unicamente um aplicativo. A ID do editor final
é determinada pelo certificado digital usado para assinar o arquivo de instalação do AIR.
-nodebug Desativa o suporte para depuração. Se usado, o processo de aplicativo não poderá se conectar ao depurador
do Flash e as caixas de diálogo para exceções não manipuladas são suprimidas. (No entanto, instruções de
rastreamento ainda serão impressas na janela do console.) Desativar a depuração permite que o seu aplicativo seja
executado um pouco mais rapidamente e também emula mais rigorosamente o modo de execução de um aplicativo
instalado.
application.xml O arquivo do descritor do aplicativo. Consulte “Configuração de propriedades do aplicativo do AIR”
na página 44.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 356
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
root-directory Especifica o diretório raiz do aplicativo a ser executado. Se não especificado, o diretório que contém o
arquivo do descritor do aplicativo será usado.
-- arguments Qualquer seqüência de caracteres que apareça após "--" é transmitida ao aplicativo como argumentos de
linha de comando.
Nota: Quando você inicia um aplicativo do AIR já em execução, uma nova instância desse aplicativo não é iniciada. Em
vez disso, um evento invoke é despachado para a instância em execução.
Impressão de instruções de rastreamento
Para imprimir instruções de rastreamento para o console usado para executar o ADL, adicione instruções de
rastreamento ao seu código com a função trace():
trace("debug message");
air.trace("debug message");
Exemplos de ADL
Execute um aplicativo no diretório atual:
adl myApp-app.xml
Execute um aplicativo em um subdiretório do diretório atual:
adl source/myApp-app.xml release
Execute um aplicativo e transmita dois argumentos de linha de comando, "tick" e "tock":
adl myApp-app.xml -- tick tock
Execute um aplicativo usando um tempo de execução específico:
adl -runtime /AIRSDK/runtime myApp-app.xml
Execute um aplicativo sem o suporte de depuração:
adl myApp-app.xml -nodebug
Conexão ao FDB (depurador do Flash)
Para depurar um aplicativo do AIR baseado em SWF com o depurador do Flash, inicie uma sessão do FDB e inicie
uma versão de depuração do seu aplicativo. Um aplicativo AIR contendo uma versão de depuração de um arquivo
SWF se conecta automaticamente a uma sessão de escuta do FDB.
Nota: Na versão de depuração de um aplicativo AIR, o arquivo SWF é compilado com o sinalizador -debug.
1 Inicie o FDB. O programa FDB pode ser encontrado no diretório bin do Flex SDK.
O console exibe o prompt do FDB: <fdb>
2 Execute o comando run. <fdb>run [Enter]
3 Em um comando diferente ou console do shell, inicie uma versão de depuração do seu aplicativo:
adl myApp.xml
4 Usando os comandos do FDB, defina pontos de interrupção como desejado.
5 Digite: continue [Enter]
Se um aplicativo AIR for baseado em SWF, o depurador só controlará a execução do código ActionScript. Se o
aplicativo do AIR for baseado em HTML, o depurador só controlará a execução do código JavaScript.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 357
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Para executar ADL sem conectar-se ao depurador, inclua a opção -nodebug.
adl myApp.xml -nodebug
Para obter informações básicas sobre comandos do FDB, execute o comando help:
<fdb>help [Enter]
Para obter detalhes sobre comandos FDB, consulte Usando os comandos do depurador de linha de comando na
documentação do Flex na documentação do Flex.
Códigos de erro e saída do ADL
A tabela a seguir descreve os códigos de saída impressos pelo ADL:
Código de
saída
Descrição
0
Inicialização bem-sucedida. O ADL é encerrado após o aplicativo do AIR ser encerrado.
1
Invocação bem-sucedida de um aplicativo do AIR já em execução. O ADL é encerrado imediatamente.
2
Erro de uso. Os argumentos fornecidos ao ADL estão incorretos.
3
O tempo de execução não pode ser encontrado.
4
O tempo de execução não pode ser iniciado. Muitas vezes, isso ocorre porque a versão do nível de patch
especificado no aplicativo não corresponde à versão ou nível de patch do tempo de execução.
5
Ocorreu um erro de causa desconhecida.
6
O arquivo do descritor do aplicativo não pode ser encontrado.
7
O conteúdo do descritor do aplicativo não é válido. Esse erro normalmente indica que o XML não é bem
formado.
8
O principal arquivo de conteúdo do aplicativo (especificado no elemento <content> do arquivo do
descritor do aplicativo) não pode ser encontrado.
9
O principal arquivo de conteúdo do aplicativo não é um arquivo SWF ou HTML válido.
Empacotamento de um arquivo de instalação do AIR
usando o ADT (ferramenta para desenvolvedores do
AIR)
Você cria um arquivo de instalação do AIR para seus aplicativos do AIR baseados em SWF e em HTML usando o ADT
(ferramenta para desenvolvedores do AIR). (Se estiver usando o Adobe Flash CS3 para criar seu aplicativo, também
poderá usar o comando Criar arquivo do AIR no menu Comandos para criar o pacote do AIR. Para obter mais
informações, consulte “Atualização do Adobe AIR para Flash CS3 Professional” na página 13. Para obter informações
sobre o uso do Flash CS4 para criar aplicativos AIR, consulte Publicação no Adobe AIR em Como usar o Flash.)
O ADT é um programa Java que você pode executar da linha de comando ou de uma ferramenta de criação como Ant.
Os SDKs do AIR e do Flex incluem scripts de linha de comando que executam o programa Java para você.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 358
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Empacotamento de um arquivo de instalação do AIR
Cada aplicativo do AIR deve, no mínimo, possuir um arquivo do descritor do aplicativo e um arquivo principal do
SWF ou HTML. Qualquer outro ativo de aplicativo instalado deve ser empacotado no arquivo AIR também.
Todos os arquivos do instalador do AIR devem ser assinados usando um certificado digital. O instalador do AIR usa
a assinatura para verificar que seu arquivo de aplicativo não foi alterado desde que você o assinou. Você pode usar um
certificado de assinatura de código de uma autoridade de certificação ou um certificado auto-assinado. Um certificado
emitido por uma autoridade de certificação confiável fornece aos usuários do seu aplicativo alguma garantia da sua
identidade como editor. Um certificado auto-assinado não pode ser usado para verificar sua identidade como o
assinante. Essa desvantagem também enfraquece a garantia de que o pacote não tenha sido alterado, porque um
arquivo de instalação legítimo poderia ser substituído por um falsificado antes de ele chegar ao usuário).
Você pode empacotar e assinar um arquivo do AIR em uma única etapa usando o comando -package do ADT. Você
também pode criar um pacote intermediário, não assinado com o comando -prepare e assinar o pacote intermediário
com o comando -sign em uma etapa separada.
Ao assinar o pacote de instalação, o ADT automaticamente entra em contato com um servidor de autoridade com
carimbo de data/hora para verificar a hora. As informações de carimbo de data/hora estão incluídas no arquivo do
AIR. Um arquivo do AIR que inclui um carimbo de data/hora verificado pode ser instalado em qualquer momento do
futuro. Se o ADT não puder se conectar ao servidor de carimbo de data/hora, o empacotamento será cancelado. Você
pode substituir a opção de carimbo de data/hora, mas sem um carimbo de data/hora, um aplicativo do AIR deixa de
poder ser instalado após o certificado usado para assinar o arquivo de instalação expirar.
Se estiver criando um pacote If para atualizar um aplicativo do AIR existente, o pacote deverá ser assinado com o
mesmo certificado do aplicativo original ou com um certificado que possua a mesma identidade. Para ter a mesma
identidade, dois certificados precisam ter o mesmo nome distinto (todos os campos de informações correspondem) e
a mesma cadeia de certificados para o certificado raiz. Portanto, você pode usar um certificado renovado de uma
autoridade de certificação desde que não altere nenhuma das informações de identificação.
No AIR 1.1, você pode migrar um aplicativo para usar um novo certificado usando o comando -migrate. Migrar o
certificado requer a assinatura do arquivo do AIR com o novo e o antigo certificado. A migração de certificados
permite que você mude de um auto-assinado para um certificado de comercial de assinatura de código ou de um
certificado auto-assinado ou comercial para outro. Ao migrar um certificado, seus usuários existentes não precisam
desinstalar seu aplicativo existente antes de instalar sua nova versão. Assinaturas de migração possuem carimbo de
data/hora, por padrão.
Nota: As configurações no arquivo do descritor do aplicativo determinam a identidade de um aplicativo do AIR e seu
caminho de instalação padrão. Consulte “A estrutura do arquivo do descritor do aplicativo” na página 44.
Empacotamento e assinatura de um arquivo do AIR em uma etapa
❖ Use o comando -package com a seguinte sintaxe (em uma única linha de comando):
adt -package SIGNING_OPTIONS air_file app_xml [file_or_dir | -C dir file_or_dir | -e file
dir ...] ...
SIGNING_OPTIONS As opções de assinatura identificam o armazenamento de chaves que contém a chave
privada e o certificado usado para assinar o arquivo do AIR. Para assinar um aplicativo do AIR com um certificado
auto-assinado gerado pelo ADT, as opções são:
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 359
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
-storetype pkcs12 -keystore certificate.p12
Neste exemplo, certificate.p12 é o nome do arquivo de armazenamento de chaves. (O ADT solicita a você a senha
uma vez que ela não é fornecida na linha de comando.) As opções de assinatura são totalmente descritas em
“Opções de assinatura de linha de comando do ADT” na página 363.
air_file O nome do arquivo do AIR criado.
app_xml O caminho para o arquivo do descritor do aplicativo. O caminho pode ser especificado em relação ao
diretório atual ou como um caminho absoluto. (O arquivo do descritor do aplicativo é renomeado como
“application.xml” no arquivo do AIR.)
file_or_dir Os arquivos e diretórios a empacotar no arquivo do AIR. Qualquer número de arquivos e diretórios
pode ser especificado, delimitado por um espaço em branco. Se você listar um diretório, todos os arquivos e
subdiretórios dentro dele, exceto arquivos ocultos, serão adicionados ao pacote. (Além disso, se o arquivo do
descritor do aplicativo for especificado, diretamente ou por caractere curinga ou expansão de diretório, ele será
ignorado e não adicionado ao pacote uma segunda vez.) Arquivos e diretórios especificados devem estar no
diretório atual ou em um de seus subdiretórios. Use a opção -C para alterar o diretório atual.
Importante: Caracteres curinga não podem ser usados nos argumentos file_or_dir depois da opção –C. (Shells de
comando expandem os caracteres curinga antes de transmitir os argumentos para o ADT, o que faz com que o ADT
procure arquivos no lugar errado.) Você pode, no entanto, usar ainda o caractere de ponto, ".", para representar o
diretório atual. Por exemplo, "-C assets ." copia tudo no diretório de ativos, incluindo qualquer subdiretório, para
o nível raiz do pacote do aplicativo.
-C dir Altera o diretório de trabalho para o valor de dir antes de processar arquivos e diretórios subseqüentes
adicionados ao pacote do aplicativo. Os arquivos ou diretórios são adicionados à raiz do pacote do aplicativo. A
opção –C pode ser usada quantas vezes for preciso para incluir arquivos de vários pontos no sistema de arquivos.
Se um caminho relativo for especificado para dir, o caminho sempre é resolvido do diretório de trabalho original.
À medida que o ADT processa os arquivos e diretórios incluídos no pacote, os caminhos relativos entre o diretório
atual e os arquivos de destino são armazenados. Esses caminhos são expandidos na estrutura do diretório do
aplicativo quando o pacote é instalado. Portanto, especificar -C release/bin lib/feature.swf coloca o arquivo
release/bin/lib/feature.swf no subdiretório lib da pasta do aplicativo raiz.
-e file dir Coloca o arquivo especificado no diretório do pacote especificado.
Nota: O elemento <content> do arquivo do descritor do aplicativo deve especificar o local final do arquivo do
aplicativo principal na árvore do diretório do pacote do aplicativo.
Exemplos do ADT
Arquivos do aplicativo específicos do pacote no diretório atual:
adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf components.swc
Empacote todos os arquivos e subdiretórios no diretório de trabalho atual:
adt –package -storetype pkcs12 -keystore ../cert.p12 myApp.air myApp.xml .
Nota: O arquivo de armazenamento de chaves contém a chave privada usada para assinar seu aplicativo. Nunca inclua
o certificado de assinatura no pacote do AIR! Se você usar caracteres curinga no comando do ADT, coloque o arquivo de
armazenamento de chaves em um local diferente para que ele não seja incluído no pacote. Neste exemplo, o arquivo de
armazenamento de chaves, cert.p12, reside no diretório pai.
Empacote apenas os arquivos principais e um subdiretório de imagens:
adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf images
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 360
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Empacote o arquivo application.xml e o SWF principal localizados em um diretório de trabalho (release/bin):
adt –package -storetype pkcs12 -keystore cert.p12 myApp.air release/bin/myApp.xml –C
release/bin myApp.swf
Empacote ativos de mais de um lugar no seu sistema de arquivo de criação. Neste exemplo, os ativos do aplicativo são
localizados nas seguintes pastas antes do empacotamento:
/devRoot
/myApp
/release
/bin
myApp.xml
myApp.swf
/artwork
/myApp
/images
image-1.png
...
image-n.png
/libraries
/release
/libs
lib-1.swf
...
lib-n.swf
AIRAliases.js
Executar o seguinte comando do ADT do diretório /devRoot/myApp:
adt –package -storetype pkcs12 -keystore cert.p12 myApp.air release/bin/myApp.xml
–C release/bin myApp.swf
–C ../artwork/myApp images
–C ../libraries/release libs
Resulta na seguinte estrutura de pacote:
/myAppRoot
/META-INF
/AIR
application.xml
hash
myApp.swf
mimetype
/images
image-1.png
...
image-n.png
/libs
lib-1.swf
...
lib-n.swf
AIRAliases.js
Execute o ADT como um programa Java (sem definir o caminho da classe):
java –jar {AIRSDK}/lib/ADT.jar –package -storetype pkcs12 -keystore cert.p12 myApp.air
myApp.xml myApp.swf
Execute o ADT como um programa Java (com o caminho da classe Java definido para incluir o pacote ADT.jar):
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 361
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
java com.adobe.air.ADT –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml
myApp.swf
Mensagens de erro do ADT
As tabelas a seguir listam os erros que o programa ADT pode reportar e suas possíveis causas:
Erros de validação do descritor do aplicativo
Código do erro
Descrição
Observações
100
Não é possível analisar o descritor do
aplicativo
Verifique o arquivo do descritor do
aplicativo para obter os erros de sintaxe
XML, como tags abertas.
101
Espaço para nomes ausente
Adicione o espaço para nomes ausente.
102
Espaço para nomes inválido
Verifique a ortografia do espaço para
nomes.
103
Elemento ou atributo inesperado
Remova os elementos e atributos
incorretos. Valores personalizados não são
permitidos no arquivo de descritor.
Verifique a ortografia dos nomes do
elemento e dos atributos.
Verifique se os elementos estão inseridos
no elemento pai correto e se os atributos
são usados com os elementos corretos.
104
Elemento ou atributo ausente
Adicione o elemento ou atributo
necessário.
105
Elemento ou atributo contém um valor
inválido
Corrija o valor incorreto.
106
Combinação de atributos de janela ilegal
Não é possível usar algumas configurações
de janela, como transparency = true
e systemChrome = standard juntas.
Altere uma das configurações
incompatíveis.
107
O tamanho mínimo da janela é maior que o Altere a configuração do tamanho mínimo
tamanho máximo da janela
ou do máximo.
Consulte “Configuração de propriedades do aplicativo do AIR” na página 44 para obter informações sobre espaços
para nomes, elementos, atributos e seus valores válidos.
Erros do ícone do aplicativo
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 362
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Código do erro
Descrição
Observações
200
Não é possível abrir o arquivo de ícone
Verifique se o arquivo existe no caminho
especificado.
Use outro aplicativo para garantir que o
arquivo possa ser aberto.
201
Ícone no tamanho errado
O tamanho do ícone (em pixels) deve
corresponder à tag XML. Por exemplo,
dado o elemento do descritor do aplicativo:
<image32x32>icon.png</image32x3
2>
A imagem em icon.png deve ser
exatamente de 32x32 pixels.
202
O arquivo do ícone contém um formato de Somente o formato PNG tem suporte.
imagem sem suporte
Converta imagens em outros formatos
antes de empacotar o aplicativo.
Erros de arquivo no aplicativo
Código do erro
Descrição
Observações
300
Arquivo ausente ou não é possível abrir
arquivo
Não é possível encontrar ou abrir um
arquivo especificado na linha de comando.
301
Arquivo do descritor de aplicativo ausente
ou não é possível abri-lo
O arquivo do descritor de aplicativo não foi
encontrado no caminho especificado ou
não é possível abri-lo.
302
Arquivo do conteúdo raiz ausente do
pacote
É necessário adicionar o arquivo SWF ou
HTML referenciado no elemento
<content> do descritor do aplicativo ao
pacote incluindo-o nos arquivos listados na
linha de comando do ADT.
303
Arquivo de ícone ausente do pacote
É necessário adicionar os arquivos de ícone
especificados no descritor do aplicativo ao
pacote incluindo-os entre os arquivos
listados na linha de comando do ADT. Os
arquivos de ícone não são adicionados
automaticamente.
304
Conteúdo da janela inicial inválido
O arquivo referenciado no elemento
<content> do descritor do aplicativo não
é reconhecido como arquivo HTML ou SWF
válido.
305
A versão inicial do SWF de conteúdo da
janela excedeu a versão do espaço para
nomes
Códigos de saída de outros erros
A versão SWF do arquivo referenciado no
elemento <content> do descritor do
aplicativo não tem suporte da versão do
AIR especificado no espaço para nomes do
descritor. Por exemplo, se você tentar
empacotar um arquivo SWF10 (Flash Player
10) como conteúdo inicial de um aplicativo
AIR 1.1, gerará esse erro.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 363
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Código de saída Descrição
Observações
2
Erro de uso
Verifique se há erros nos argumentos da
linha de comando
5
Erro desconhecido
Esse erro indica que não é possível explicar
uma situação com condições de erro
comuns. As possíveis causas raiz incluem
incompatibilidade entre o ADT e o Java
Runtime Environment, instalações de ADT
ou JRE corrompidas e erros de
programação dentro do ADT.
6
Não foi possível gravar no diretório de saída Verifique se o diretório de saída
especificado (ou implícito) está acessível e
se a unidade que o contém tem espaço em
disco suficiente.
7
Não foi possível acessar o certificado
Verifique se o caminho para o
armazenamento de chaves está
especificado corretamente.
Verifique se o certificado do
armazenamento de chaves pode ser
acessado. O utilitário Java 1.6 Keytool pode
ser usado para ajudar a solucionar
problemas de acesso ao certificado.
8
Certificado inválido
O arquivo de certificado foi malformado,
modificado, expirado ou revogado.
9
Não foi possível assinar o arquivo AIR
Verifique as opções de assinaturas enviadas
para o ADT.
10
Não foi possível criar um carimbo de data e O ADT não estabeleceu uma conexão com
hora
o servidor do carimbo de data e hora. Se
você se conecta à Internet por meio de um
servidor proxy, pode precisar definir as
configurações de proxy do JRE.
11
Erro de criação do certificado
Verifique os argumentos da linha de
comando usados para criar assinaturas.
12
Entrada inválida
Verifique os caminhos e outros argumentos
enviados para o ADT na linha de comando.
Opções de assinatura de linha de comando do ADT
O ADT usa JCA (arquitetura de criptografia Java) para acessar chaves privadas e certificados para assinar aplicativos
do AIR. As opções de assinatura identificam o armazenamento de chaves e a chave privada e o certificado dentro desse
armazenamento de chaves.
O armazenamento de chaves deve incluir a chave privada e a cadeia de certificado associada. A cadeia de certificado é
usada para estabelecer a ID do editor do aplicativo. Se o certificado de assinatura estiver vinculado a um certificado
confiável em um computador, o nome comum do certificado será exibido como o nome do editor na caixa de diálogo
de instalação do AIR.
O ADT requer que o certificado esteja em conformidade com o padrão x509v3 (RFC3280) e inclua a extensão de uso
de chave estendida com os valores adequados para assinatura do código. As restrições no certificado são respeitadas e
poderiam impedir o uso de alguns certificados para assinar aplicativos do AIR.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 364
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Nota: O ADT usa as configurações de proxy do ambiente de tempo de execução Java, quando apropriado, para conectar
aos recursos de Internet para verificar listas de revogação de certificado e obter carimbos de data/hora. Se encontrar
problemas para se conectar a recursos da Internet ao usar o ADT e sua rede exigir configurações de proxy específicas, você
pode precisar configurar as configurações de proxy do JRE.
Especificação de opções de assinatura do AIR
❖ Para especificar as opções de assinatura do ADT para os comandos -package e -prepare, use a seguinte sintaxe:
[-alias aliasName] [-storetype type] [-keystore path] [-storepass password1] [-keypass
password2] [-providerName className] [-tsa url]
-alias aliasName —O alias de uma chave no armazenamento de chaves. Especificar um alias não é necessário
quando um armazenamento de chaves contém apenas um único certificado. Se nenhum alias for especificado, o
ADT usará a primeira chave do armazenamento de chaves.
Nem todos os aplicativos de gerenciamento do armazenamento de chaves permitem que um alias seja atribuído a
certificados. Ao usar o armazenamento de chaves do sistema Windows, por exemplo, use o nome distinto do
certificado como o alias. Você pode usar o utilitário Java Keytool para listar os certificados disponíveis para que
possa determinar o alias. Por exemplo, executar o comando:
keytool -list -storetype Windows-MY
produz uma saída como a seguinte para um certificado:
CN=TestingCert,OU=QE,O=Adobe,C=US, PrivateKeyEntry,
Certificate fingerprint (MD5): 73:D5:21:E9:8A:28:0A:AB:FD:1D:11:EA:BB:A7:55:88
Para se referir a esse certificado na linha de comando do ADT, defina o alias como:
CN=TestingCert,OU=QE,O=Adobe,C=US
No Mac OS X, o alias de um certificado no Keychain é o nome exibido no aplicativo Keychain Access.
-storetype type —O tipo de armazenamento de chaves, determinado pela implementação de armazenamento de
chaves. A implementação de armazenamento de chaves padrão incluída na maioria das instalações de Java suporta
os tipos JKS e PKCS12. O Java 5.0 inclui suporte para o tipo PKCS11, para acessar armazenamentos de chaves em
tokens de hardware e para o tipo Keychain, para acessar o chaveiro do Mac OS X. O Java 6.0 inclui suporte para o
tipo MSCAPI (no Windows). Se outros provedores de JCA tiverem sido instalados e configurados, tipos adicionais
de armazenamentos de chaves podem estar disponíveis. Se nenhum tipo de armazenamento de chave for
especificado, o tipo padrão para o provedor de JCA padrão será usado.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 365
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Tipo de
armazenament
o
Formato de
armazenamento de chave
Versão mínima de
Java
JKS
Arquivo de
armazenamento de chave
Java (.keystore)
1.2
PKCS12
Arquivo PKCS12 (.p12 ou
.pfx)
1.4
PKCS11
Token de hardware
1.5
KeychainStore
Chaveiro do Mac OS X
1.5
Windows-MY ou
Windows-ROOT
MSCAPI
1.6
-keystore path —O caminho para o arquivo de armazenamento de chaves para tipos de armazenamento baseado
em arquivo.
-storepass password1 —A senha necessária para acessar o armazenamento de chaves. Se não especificada, o ADT
solicita a senha.
-keypass password2 —A senha necessária para acessar a chave privada usada para assinar o aplicativo do AIR. Se
não especificada, o ADT solicita a senha.
-providerName className —O provedor de JCA para o tipo de armazenamento de chave especificado. Se não
especificado, o ADT usa o provedor padrão para esse tipo de armazenamento de chave.
-tsa url —Especifica a URL de um servidor com carimbo de data/hora compatível com RFC3161 para carimbar
com data/hora a assinatura digital. Se nenhuma URL for especificada, um servidor padrão com carimbo de
data/hora fornecido pela Geotrust será usado. Quando a assinatura de um aplicativo do AIR for carimbada com
data/hora, o aplicativo poderá ainda ser instalado depois que o certificado de assinatura expirar, porque o carimbo
de data/hora verifica se o certificado era válido no momento da assinatura.
Se o ADT não puder se conectar ao servidor de carimbo de data/hora, a assinatura será cancelada e nenhum
empacotamento será produzido. Especifique -tsa none para desabilitar o carimbo de data/hora. No entanto, um
aplicativo do AIR empacotado sem um carimbo de data/hora deixa de poder ser instalado depois que o certificado
de assinatura expira.
Nota: As opções de assinatura são como as opções equivalentes do utilitário Java Keytool. Você pode usar o utilitário
Keytool para examinar e gerenciar armazenamentos de chaves no Windows. O utilitário de segurança da Apple®
também pode ser usado para esse fim no Mac OS X.
Exemplos de opção de assinatura
Assinatura com um arquivo .p12:
-storetype pkcs12 -keystore cert.p12
Assinatura com o armazenamento de chaves Java padrão:
-alias AIRcert -storetype jks
Assinatura com o armazenamento de chaves Java específico:
-alias AIRcert -storetype jks -keystore certStore.keystore
Assinatura com o chaveiro do Mac OS X:
-alias AIRcert -storetype KeychainStore -providerName Apple
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 366
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Assinatura com o armazenamento de chaves do sistema Windows:
-alias cn=AIRCert -storeype Windows-MY
Assinatura com um token de hardware (consulte as instruções do fabricante do token sobre como configurar Java para
usar o token e para o valor correto de providerName):
-alias AIRCert -storetype pkcs11 -providerName tokenProviderName
Assinatura sem incorporar um carimbo de data/hora:
-storetype pkcs12 -keystore cert.p12 -tsa none
Criação de um arquivo intermediário do AIR não assinado com o ADT
Use o comando -prepare para criar um arquivo intermediário do AIR não assinado. Um arquivo intermediário do
AIR deve ser assinado com o comando do ADT -sign para produzir um arquivo de instalação do AIR válido.
O comando -prepare emprega os mesmos sinalizadores e parâmetros do comando -package (exceto para as opções
de assinatura). A única diferença é que o arquivo de saída não é assinado. O arquivo intermediário é gerado com a
extensão de nome de arquivo: airi.
Para assinar um arquivo intermediário do AIR, use o comando do ADT -sign. (Consulte Assinatura de um arquivo
intermediário do AIR com o ADT.)
Exemplo do ADT
adt –prepare unsignedMyApp.airi myApp.xml myApp.swf components.swc
Assinatura de um arquivo intermediário do AIR com o ADT
Para assinar um arquivo intermediário do AIR com o ADT, use o comando -sign. O comando sign funciona apenas
com arquivos intermediários do AIR (extensão airi). Um arquivo do AIR não pode ser assinado uma segunda vez.
Para criar um arquivo intermediário do AIR, use o comando do ADT -prepare. (Consulte “Criação de um arquivo
intermediário do AIR não assinado com o ADT” na página 366.)
Assinatura de um arquivo AIRI
❖ Use o comando do ADT -sign com a seguinte sintaxe:
adt -sign SIGNING_OPTIONSairi_fileair_file
SIGNING_OPTIONS As opções de assinatura identificam a chave privada e o certificado com o qual o arquivo do
AIR será assinado. Essas opções são descritas em “Opções de assinatura de linha de comando do ADT” na
página 363.
airi_file O caminho para o arquivo intermediário não assinado do AIR a ser assinado.
air_file O nome do arquivo do AIR a ser criado.
Exemplo do ADT
adt –sign -storetype pkcs12 -keystore cert.p12 unsignedMyApp.airi myApp.air
Para obter mais informações, consulte “Assinatura digital de um arquivo do AIR” na página 321.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 367
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Assinatura de um arquivo do AIR para alterar o
certificado do aplicativo
Para atualizar um aplicativo do AIR existente para usar um novo certificado de assinatura, use o comando do ADT migrate.
A migração de certificados pode ser útil nas seguintes situações:
• Atualização de um certificado auto-assinado para um emitido por uma autoridade de certificação
• Alteração de um certificado auto-assinado que está prestes a expirar para um novo certificado auto-assinado
• Alterar de um certificado comercial para outro, por exemplo, quando sua identidade corporativa for alterada
Para aplicar uma assinatura de migração, o certificado original ainda deve estar válido. Depois que o certificado tiver
expirado, uma assinatura de migração não poderá ser aplicada. Usuários do seu aplicativo precisarão desinstalar a
versão existente antes que possam instalar a versão atualizada. Observe que a assinatura de migração possui carimbo
de data/hora, por padrão, então as atualizações do AIR assinadas com uma assinatura de migração permanecerão
válidas mesmo depois que o certificado expirar.
Nota: Você não precisa normalmente migrar o certificado quando renovar um certificado emitido comercialmente. Um
certificado renovado retém a mesma identidade do editor do original, a menos que o nome distinto tenha sido alterado.
Para obter uma lista completa dos atributos do certificado usados para determinar o nome distinto, consulte “Sobre
identificadores do editor do AIR” na página 322.
Para migrar o aplicativo a fim de usar um novo certificado:
1 Crie uma atualização para o seu aplicativo
2 Empacote e assine o arquivo de atualização do AIR com o novo certificado
3 Assine o arquivo do AIR novamente com o certificado original usando o comando -migrate
Um arquivo do AIR assinado com o comando -migrate pode ser usado para instalar uma nova versão do aplicativo
e para atualizar versões anteriores, incluindo as assinadas com o certificado antigo.
Migração de um aplicativo do AIR para usar um novo certificado
❖ Use o comando do ADT -migrate com a seguinte sintaxe:
adt -migrate SIGNING_OPTIONS air_file_in air_file_out
SIGNING_OPTIONS As opções de assinatura identificam a chave privada e o certificado com o qual o arquivo do
AIR será assinado. Essas opções devem identificar o certificado de assinatura original e são descritas em “Opções
de assinatura de linha de comando do ADT” na página 363.
air_file_in O arquivo do AIR para a atualização, assinado com o certificado novo.
air_file_out O arquivo do AIR a ser criado.
Exemplo do ADT
adt –migrate -storetype pkcs12 -keystore cert.p12 myApp.air myApp.air
Para obter mais informações, consulte “Assinatura digital de um arquivo do AIR” na página 321.
Nota: O comando -migrate foi adicionado ao ADT na versão AIR 1.1.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 368
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Criação de um certificado auto-assinado com o ADT
Os certificados auto-assinados permitem que você produza um arquivo de instalação do AIR válido, mas apenas
fornecem garantias de segurança limitadas aos seus usuários uma vez que a autenticidade de certificados autoassinados não pode ser verificada. Quando um arquivo do AIR auto-assinado é instalado, as informações do editor são
exibidas para o usuário como Desconhecidas. Um certificado gerado pelo ADT é válido por cinco anos.
Se você criar uma atualização para um aplicativo do AIR assinada com um certificado auto-gerado, deverá usar o
mesmo certificado para assinar os originais e atualizar os arquivos do AIR. Os certificados que o ADT produz são
sempre únicos, mesmo se os mesmos parâmetros são usados. Portanto, se você desejar auto-assinar atualizações com
um certificado gerado pelo ADT, preserve o certificado original em um local seguro. Além disso, você não poderá
produzir um arquivo do AIR atualizado depois que o certificado original gerado pelo ADT expirar. (Você pode
publicar novos aplicativos com um certificado diferente, mas não novas versões do mesmo aplicativo.)
Importante: Devido às limitações de certificados auto-assinados, a Adobe recomenda altamente o uso de um certificado
comercial emitido por uma autoridade de certificação de reputação, para assinar publicamente aplicativos do AIR
lançados.
O certificado e a chave privada associada gerados pelo ADT são armazenados em um arquivo de armazenamento de
chaves do tipo PKCS12. A senha especificada é definida na chave em si, e não no armazenamento de chaves.
Geração de um certificado de ID digital para auto-assinar arquivos do AIR
❖ Use o comando do ADT -certificate (em uma única linha de comando):
adt -certificate -cn name [-ou org_unit][-o org_name][-c country]
key_type pfx_file password
-cn name A seqüência de caracteres atribuída como o nome comum do novo certificado.
-ou org_unit Uma seqüência de caracteres atribuída como a unidade organizacional que emite o certificado.
(Opcional.)
-o org_name Uma seqüência de caracteres atribuída como a organização que emite o certificado. (Opcional.)
-c countryUm código de país de duas letras ISO-3166. Um certificado não é gerado se um código inválido é
fornecido. (Opcional.)
key_typeO tipo de chave a ser usada para o certificado, “1024-RSA” ou “2048-RSA”.
pfx_file O caminho para o arquivo do certificado a ser gerado.
password A senha para o novo certificado. A senha é necessária ao assinar arquivos do AIR com esse certificado.
Exemplos de geração de certificado
adt -certificate -cn SelfSign -ou QE -o "Example, Co" -c US 2048-RSA newcert.p12 39#wnetx3tl
adt -certificate -cn ADigitalID 1024-RSA SigningCert.p12 39#wnetx3tl
Para usar esses certificados para assinar arquivos do AIR, você usa as seguintes opções de assinatura com os comandos
-package ou -prepare do ADT:
-storetype pkcs12 -keystore newcert.p12 -keypass 39#wnetx3tl
-storetype pkcs12 -keystore SigningCert.p12 -keypass 39#wnetx3tl
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 369
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Uso do Apache Ant com as ferramentas do SDK
Esse tópico fornece exemplos de como usar a ferramenta de criação Apache Ant para testar e empacotar aplicativos do AIR.
Nota: Essa discussão não tenta fornecer um resumo abrangente do Apache Ant. Para obter a documentação do Ant,
consulte http://Ant.Apache.org.
Uso do Ant para projetos simples
Esse exemplo ilustra a criação de um aplicativo do AIR usando o Ant e as ferramentas de linha de comando do AIR.
Uma estrutura de projeto simples é usada com todos os arquivos armazenados em um único diretório.
Para facilitar a reutilização do script de criação, esses exemplos usam várias propriedades definidas. Um conjunto de
propriedades identifica os locais instalados das ferramentas de linha de comando:
<property name="SDK_HOME" value="C:/Flex3SDK"/>
<property name="ADL" value="${SDK_HOME}/bin/adl.exe"/>
<property name="ADT.JAR" value="${SDK_HOME}/lib/adt.jar"/>
O segundo conjunto de propriedades é específico do projeto. Essas propriedades supõem uma convenção de
nomenclatura na qual o descritor do aplicativo e os arquivos do AIR são baseados em nome no arquivo de origem raiz.
Outras convenções são facilmente suportadas.
<property
<property
<property
<property
<property
<property
name="APP_NAME" value="ExampleApplication"/>
name="APP_ROOT" value="."/>
name="APP_DESCRIPTOR" value="${APP_ROOT}/${APP_NAME}-app.xml"/>
name="AIR_NAME" value="${APP_NAME}.air"/>
name="STORETYPE" value="pkcs12"/>
name="KEYSTORE" value="ExampleCert.p12"/>
Invocação do ADL para testar um aplicativo
Para executar o aplicativo com o ADL, use uma tarefa exec:
<target name="test" depends="compile">
<target name="test">
<exec executable="${ADL}">
<arg value="${APP_DESCRIPTOR}"/>
</exec>
</target>
Invocação do ADT para empacotar um aplicativo
Para empacotar o aplicativo, use uma tarefa Java para executar a ferramenta adt.jar:
<target name="package">
<java jar="${ADT.JAR}" fork="true" failonerror="true">
<arg value="-package"/>
<arg value="-storetype"/>
<arg value="${STORETYPE}"/>
<arg value="-keystore"/>
<arg value="${KEYSTORE}"/>
<arg value="${AIR_NAME}"/>
<arg value="${APP_DESCRIPTOR}"/>
<arg value="${APP_NAME}.swf"/>
<arg value="*.png"/>
</java>
</target>
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 370
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
Se seu aplicativo tiver mais arquivos para empacotar, você pode adicionar elementos <arg> adicionais.
Uso do Ant para projetos mais complexos
A estrutura do diretório de um aplicativo típico é mais complexa do que um diretório único. O exemplo a seguir ilustra
um arquivo de criação usado para compilar, testar e empacotar um aplicativo do AIR com uma estrutura de diretório
de projeto mais prática.
Esse projeto de exemplo armazena os arquivos de origem do aplicativo e outros ativos como arquivos de ícone em um
diretório src. O script de criação cria os seguintes diretórios de trabalho:
build Armazena as versões de lançamento (não-depuração) de arquivos do SWF compilados.
debug Armazena a versão de depuração não empacotada do aplicativo, incluindo qualquer arquivo de ativo e SWFs
compilados. O utilitário do ADL executa o aplicativo desse diretório.
release Armazena o pacote do AIR final
As ferramentas do AIR requerem o uso de algumas opções adicionais ao operar em arquivos fora do diretório de
trabalho atual:
Teste O segundo argumento transmitido ao ADL especifica o diretório raiz do aplicativo do AIR. Para especificar o
diretório raiz do aplicativo, a seguinte linha é adicionada à tarefa de teste:
<arg value="${debug}"/>
Empacotamento Empacotar arquivos de subdiretórios que não devem ser parte da estrutura do pacote final requer o
uso da diretiva -C para alterar o diretório de trabalho do ADT. Quando você usa a diretiva -C, os arquivos e diretórios
no novo diretório de funcionamento são copiados para o nível raiz do arquivo do pacote do AIR. Portanto, -C build
file.png copia file.png para a raiz do diretório do aplicativo. Da mesma forma, -C assets icons copia a pasta
icon para o nível raiz e copia também todos os arquivos e diretórios dentro da pasta icons. Por exemplo, a seguinte
seqüência de linhas na tarefa do pacote adiciona o diretório icons diretamente ao nível raiz do arquivo do pacote do
aplicativo:
<arg value="-C"/>
<arg value="${assets}"/>
<arg value="icons"/>
Nota: Se você precisar mover vários recursos e ativos para diferentes locais relativos, é normalmente mais fácil dispô-los
em um diretório temporário usando tarefas do Ant do que criar uma lista de argumento complexa para o ADT. Depois
que seus recursos forem organizados, uma simples lista de argumento do ADT poderá ser usada para empacotá-los.
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 371
Criação de um aplicativo do AIR usando as ferramentas de linha de comando
<project>
<!-- SDK properties -->
<property name="SDK_HOME" value="C:/Flex3SDK"/>
<property name="ADL" value="${SDK_HOME}/bin/adl.exe"/>
<property name="ADT.JAR" value="${SDK_HOME}/lib/adt.jar"/>
<!-- Project properties -->
<property name="PROJ_ROOT_DIR" value="."/>
<property name="APP_NAME" value="ExampleApplication"/>
<property name="APP_ROOT_DIR" value="."/>
<property name="APP_ROOT_FILE" value="${APP_NAME}.swf"/>
<property name="APP_DESCRIPTOR" value="${PROJ_ROOT_DIR}/${APP_NAME}-app.xml"/>
<property name="AIR_NAME" value="${APP_NAME}.air"/>
<property name="release" location="${PROJ_ROOT_DIR}/release"/>
<property name="assets" location="${PROJ_ROOT_DIR}/src/assets"/>
<property name="STORETYPE" value="pkcs12"/>
<property name="KEYSTORE" value="ExampleCert.p12"/>
<target name="init" depends="clean">
<mkdir dir="${release}"/>
</target>
<target name="test">
<exec executable="${ADL}">
<arg value="${APP_DESCRIPTOR}"/>
<arg value="${APP_ROOT_DIR}"/>
</exec>
</target>
<target name="package" depends="init">
<java jar="${ADT.JAR}" fork="true" failonerror="true">
<arg value="-package"/>
<arg value="-storetype"/>
<arg value="${STORETYPE}"/>
<arg value="-keystore"/>
<arg value="${KEYSTORE}"/>
<arg value="${release}/${AIR_NAME}"/>
<arg value="${APP_DESCRIPTOR}"/>
<arg value="-C"/>
<arg value="${APP_ROOT_DIR}"/>
<arg value="${APP_ROOT_FILE}"/>
<arg value="-C"/>
<arg value="${assets}"/>
<arg value="icons"/>
</java>
</target>
<target name="clean" description="clean up">
<delete dir="${release}"/>
</target>
</project>
372
Índice
Símbolos
: caractere (dois pontos), em nomes de
parâmetro de instrução SQL 175
distribuição 312
arquivos Info.plist (Mac OS) 49
execução 312, 320
arquivos P12 322
ícones 51
arquivos PFX 322
? (ponto de interrogação) caractere, em
parâmetros SQL sem nome 176
informações de copyright 49
arquivos SWF
Numéricos
1024-RSA 368
2048-RSA 368
inicializar 291
carregamento por tag de script 244
instalação 23, 312
arquivos temporários 121
invocação 291
arrastar e soltar
invocação do navegador 52
classes relacionadas a 133
sair 291
comportamento padrão em HTML 141
versões 47, 300, 329
efeitos de cursor 139, 143
A
AC_RuntimeActiveContent.js 314
AppInstallDisabled (configuração de
Registro do Windows) 26
eventos em HTML 141
Acrobat 219, 272
área de transferência
gestos 133
ActionScript
entre scripts JavaScript 241
copiar e colar 149
formatos de transferência 133
HTML 140, 224
argumentos de linha de comando,
captura 292
para conteúdo de caixa de proteção de
não-aplicativo (em HTML) 147
atualização 23
armazenamentos de chaves 363, 368
suporte a Flex 135
desinstalação 2
arquivo AIRAliases.js 218, 239
instalação 23
Arquivo AIRLocalizer.js 344
assinatura de arquivos do AIR 358
introdução 6
arquivo ApplicationUpdater_UI.swf 333
assinatura de código 43, 321
nova funcionalidade 54
Arquivo ApplicationUpdater.swc 332
assinaturas
Adobe AIR
teclas do modificador 139
Adobe Media Player 277
Arquivo ApplicationUpdater.swf 333
Adobe Reader 219, 272
arquivo ApplicatoinUpdater_UI.swc 332
assinaturas digitais 321, 358, 363
AIR Debug Launcher (ADL)
arquivo de configuração de atualização
(estrutura de atualização) 336
associações de tipo de arquivo 52, 293, 299
códigos de erro e saída 357
Ajax
segurança 33
suporte na caixa de proteção do
aplicativo 33
arquivo de descrição de atualização
(estrutura de atualização) 335
arquivo descritor do aplicativo
leitura 298
migração 325, 367
atalhos do teclado
copiar e colar 151
ativação de janelas 67, 73
atividade (usuário), detecção 300
AMF (Action Message Format) 135, 154,
157
arquivo do descritor do aplicativo 44
atividade de usuário, detecção 300
arquivo publisherid 298
aparência de janelas 62
arquivos
atributo allowCrossDomainXHR
(elementos frame e iframe) 222, 227
API de arquivo 106
banco de dados 165
API de sistema de arquivos 106
cópia 119
aplicativos
exclusão 120
atributo contenteditable (HTML) 145
atributo documentRoot (elementos frame e
iframe) 30, 219, 227, 248
gravação 121
atributo minimumPatchLevel (arquivo do
descritor do aplicativo) 45
aplicativos avançados da Internet (RIAs) 6
leitura 121
Atributo ondominitialize 228
aplicativos de amostra 2
movimentação 119
aplicativos do AIR
referência 110
atributo sandboxRoot (elementos frame e
iframe) 219, 222, 227, 248
Consulte aplicativos do AIR
associações de tipo arquivo 299
associações de tipo de arquivo 52, 293
atualização 23, 52, 328
caminho de instalação 47
configurações 44, 47, 298
desinstalação 26
detecção de instalação de 318
suporte a arrastar e soltar 133
suporte a copiar e colar 149
arquivos AIRI
criação com a ferramenta para
desenvolvedores do AIR (ADT) 366
arquivos do AIR
assinatura 321
empacotamento 358
atributos documentRoot (elementos frame e
iframe) 30
atualização de aplicativos do AIR 52, 328
autoridades de certificação (CAs) 321
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 373
Índice
caixas de proteção que não são de
aplicativo 219
método uncompress() 157
alteração de dados 185
caixas de proteção remotas 27, 220
método writeFloat() 154
arquivos 165
caminhos (arquivo e diretório) 112
método writeInt() 154
campos 166
caminhos relativos (entre arquivos) 113
método writeObject() 154
chaves primárias 184, 185
caminhos, relativo 113
método writeUTFBytes() 154
classes usadas com 167
campo NSHumanReadableCopyright (Mac
OS) 49
propriedade bytesAvailable 155
B
bancos de dados
colunas 166
conexão 172
campos (banco de dados) 166
criação 169
caractere @, em nomes de parâmetro de
instrução SQL 175
desempenho 176
caracteres mnemônicos
digitação de dados 176, 189
itens de menu 90
método writeBytes() 154
propriedade length 155
propriedade position 155
classe Capabilities
propriedade playerType 300
classe Clipboard
erros 186
carimbos de data/hora 323
estrutura 166
Centro de desenvolvedores do Adobe
Acrobat 273
classe CompressionAlgorithm 157
exclusão de dados 185
identificadores de linha 185
certificados
classe ContextMenuEvent
método getData() 135, 139
Classe ContextMenu 89, 92
linhas 166
alteração 325, 367
modo assíncrono 168
assinatura de arquivos do AIR 321
modo síncrono 168
assinatura de código 43
Classe ContextMenuItem 89
na memória 169
autorizações (CAs) 43
classe Dictionary 239
recuperação de dados 177
cadeias 326
classe DRMAuthenticateEvent 278, 285
segurança 176
expiração de 323
classe DRMErrorEvent 278
sobre 165
formatos de 322
tabelas 166, 170
migração 325, 367
usos de 165
opções de linha de comando do ADT 363
vários, trabalhar com 186
bancos de dados locais
Consulte bancos de dados
propriedade contextMenuOwner 92
propriedade mouseTarget 92
códigos de erro 286
propriedade subErrorID 286
classe DRMStatusEvent 278
certificados auto-assinados 43, 321, 368
classe EncryptedLocalStore 215
Certificados ChosenSecurity 321, 323
Classe File 106, 107
Certificados do desenvolvedor Apple 323
getRootDirectories() 107
bancos de dados na memória 169
Certificados do desenvolvedor do AIR 323
método getRootDirectories() 107
bancos de dados relacionais
Certificados do desenvolvedor JavaSoft 323
método resolvePath() 107
Certificados GlobalSign 321, 323
Consulte bancos de dados
barra de ferramentas (Mac OS) 65
Certificados Microsoft Authenticode 323
propriedade
applicationStorageDirectory 107
barras de menu 88
certificados Thawte 321, 323
propriedade desktopDirectory 107
bitmaps
Certificados VeriSign 323
propriedade documentsDirectory 107
suporte a arrastar e soltar 133, 142
certificados Verisign 321, 323
propriedade nativePath 107, 118
suporte a copiar e colar 149
Chaveiro (associação de dados
criptografados com usuários) 215
propriedade spaceAvailable 115
propriedade url 107, 118
propriedade userDirectory 107
C
caixa de proteção confiável local 220
chaves primárias
caixa de proteção do aplicativo 27, 219, 220,
233, 234, 235, 238, 248, 300
chaves privadas 363
classe ApplicationDomain 242
fazendo referência a um banco de dados
local 169
caixa de proteção local com rede 27
classe BrowserInvokeEvent 294
método browseForDirectory() 110
caixa de proteção local com sistema de
arquivos 27, 220
classe ByteArray
método browseForOpen() 111
bancos de dados 184
classe File
construtor 154
método browseForSave() 111
caixa de proteção local confiável 27
método compress() 157
método copyTo() 119
caixas de diálogo seletoras de arquivos 111
método readBytes() 154
método copyToAsync() 119
caixas de diálogo seletoras de diretórios 110
método readFloat() 154
método createDirectory() 116
caixas de proteção 27, 220, 248, 300
método readInt() 154
método createTempDirectory() 116, 121
caixas de proteção "não-aplicativos" 29
método readObject() 154
método createTempFile() 121
caixas de proteção de não-aplicativos 147,
220, 234, 235, 248
método readUTFBytes() 154
método deleteDirectory() 118
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 374
Índice
método deleteDirectoryAsync() 118
classe InvokeEvent 53, 292
método deleteFile() 120
propriedade currentDirectory 292
método deleteFileAsync() 120
propriedade de argumentos 292
propriedade label 152
propriedade mnemonicIndex 90
propriedade submenu 88
método getDirectoryListingAsync() 117
classe Keyboard 89
método load() 129
Classe Loader 68
acesso JavaScript a 218
método moveTo() 119
Classe LoaderContext
construtor 67
método moveToAsync() 119
método moveToTrash() 120
método moveToTrashAsync() 120
propriedade
allowLoadBytesCodeExecution 41
classe LoaderContext
classe NativeWindow 59
eventos 79
instanciação 71
método activate 73
método relativize() 113
propriedade applicationDomain 36
método activate() 73
método save() 129
propriedade securityDomain 36
método addEventListener() 79
propriedade creationDate 118
classe LoaderInfo
método close(). 74
propriedade creator 118
propriedade childSandboxBridge 36
método dispatchEvent() 61
propriedade encoding 115
propriedade parentSandboxBridge 36
método maximize() 75
propriedade exists 118
classe LocalConnection 314, 321
método minimize() 75
propriedade isDirectory 118
classe NativeApplication 227
método orderBehind() 73
propriedade lineEnding 115
método addEventListener() 291
método orderInBackOf() 73
propriedade modificationDate 118
método exit() 296
método orderInFrontOf() 73
propriedade name 118
método getDefaultApplication() 299
método orderToBack() 73
propriedade parent 118
método isSetAsDefaultApplication() 299
método orderToFront() 73
propriedade separator 115
método
removeAsDefaultApplication() 299
método restore() 75
propriedade size 118
propriedade type 118
Classe FileMode 106
classe FileReference
método load() 129
método save() 129
Classe FileStream 106
Classe HTMLLoader 233
classe HTMLLoader
acesso JavaScript a 218
eventos 252
método createRootWindow() 67, 69, 233
método loadString() 35, 233
propriedade height 233
propriedade
paintsDefaultBackground 63, 70
propriedade pdfCapability 272
propriedade
placeLoadStringContentInApplication
Sandbox 35
propriedade
runtimeApplicationDomain 242
propriedade width 233
classe HTMLPDFCapability 272
classe HTMLUncaughtScriptException 253
classe Icon
método bounce() 102
propriedade bitmaps 101
método setAsDefaultApplication() 52
método() copy() 152
propriedade activeWindow 72
propriedade applicationDescriptor 298
propriedade autoExit 296
propriedade icon 101
propriedade id 298
propriedade idleThreshold 300
propriedade lastUserInput 300
propriedade publisherID 298, 322
propriedade runtimePatchLevel 300
propriedade runtimeVersion 300
propriedade startAtLogin 294
propriedade supportsDockIcon 101
propriedade supportsMenu 98
propriedade
supportsSystemTrayIcon 101
classe NativeBoundsEvent 79
classe NativeDragEvent
propriedade clipboard 139
propriedade dropAction 138, 139
classe NativeDragManager
método acceptDragDrop() 134, 139
método doDrag() 134, 136, 139
classe NativeMenu 88, 96
classe NativeMenuItem 88
método startMove() 78
método startResize() 77
método() activate 67
propriedade alwaysInFront 73
propriedade stage 70
propriedade systemChrome 62
propriedade systemMaxSize 67
propriedade systemMinSize 67
propriedade transparent 62, 63
propriedade type 62
propriedade visible 67, 73
classe NativeWindowDisplayStateEvent 80
classe NativeWindowInitOptions 66, 67
Classe NetStream
método
preloadEmbeddedMetadata() 279
classe NetStream
método resetDRMVouchers() 282
método
setDRMAuthenticationCredentials() 2
78, 282
classe Netstream
conteúdo criptografado, reprodução
com 278
classe Responder 174, 184
classe Screen 82
método getScreenForRectangle() 83
propriedade data 90
propriedade mainScreen 83
propriedade keyEquivalent 89
propriedade screens 83
propriedade keyEquivalentModifiers 89
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 375
Índice
classe Security
método allowDomain() 36, 40
códigos de idiomas, seleção para
aplicativo 344
propriedade sandboxType 300
colunas (banco de dados) 166
CSS
acesso a estilos HTML do
ActionScript 246
classe SQLCollationType 167
colunas AUTOINCREMENT (SQL) 185
classe SQLColumnNameStyle 167
colunas INTEGER PRIMARY KEY
(SQL) 185
cursor, efeitos de arrastar e soltar 139, 143
comandos, menu
D
dados binários
classe SQLConnection 167
método attach() 186
método open 169
método open() 169
método openAsync() 169, 172
classe SQLError 167, 174
classe SQLErrorEvent 167, 174
Consulte itens de menu
compactação de dados 157
compactação deflate 157
compactação ZLIB 157
compilador acompc 245
extensões do AIR para 231
Consulte matrizes de bytes
dados criptografados, armazenamento e
recuperação 215
declaração de prática de certificação
(CPS) 326
classe SQLEvent 167
comprovantes, utilização com conteúdo
criptografado por DRM 277
classe SQLIndexSchema 167
conexão com um banco de dados 172
definir a ordem das janelas 73
classe SQLMode 167, 173
classe SQLResult 167, 184
configurações de FlashVars (para usar
badge.swf) 314
delimitador de caminho (sistema de
arquivos) 110
classe SQLSchemaResult 167
Configurações de Registro do Windows 26
depuração
classe SQLStatement 167, 173
Construtores de funções (em JavaScript) 221
método execute 175
conteúdo em PDF
default_badge.html 314
uso de ADL 356
desinstalação
método execute() 177, 184
adição a aplicativos AIR 272
método getResult() 184
carregamento 273
objeto parameters 174
comunicação JavaScript 273
dimensões, janelas 51
limitações conhecidas 275
diretório Arquivos de Programas
(Windows) 312
propriedade parameters 175
propriedade sqlConnection 174
propriedade text 174, 175, 177, 185
classe SQLTableSchema 167
conteúdo SWF
diretório da área de trabalho 108
sobreposição em HTML 69
diretório de armazenamento do
aplicativo 25, 108, 112, 240
cookies 223
classe SQLTriggerSchema 167
cópia de arquivos 119
classe SQLUpdateEvent 167
cópia de diretórios 117
classe SQLViewSchema 167
copiar e colar
atalhos do teclado 151
método addChild() 70
comandos de menu 151
método addChildAt() 70
equivalentes de teclas 153
propriedade displayState 80
HTML 149, 223
propriedade nativeWindow 66, 72
itens de menu padrão (Mac OS) 152
propriedade scaleMode 67, 77
classe StageDisplayState 80
classe StageScaleMode 67, 77
tempo de execução do AIR 2
em HTML 219
classe SQLTransactionLockType 167
classe Stage
aplicativos do AIR 26
credenciais
para conteúdo criptografado por
DRM 286
diretório de documentos 108
diretório do aplicativo 108
diretório inicial 108
diretório My documents (Windows) 108
diretórios 108, 116
cópia 117
criação 116
enumeração 117
exclusão 118, 120
invocação do aplicativo 292
movimentação 117
referência 108
classe StatusEvent 278
credenciais do usuário e segurança 42
classe TextField
criação de diretórios 116
diretórios temporários 116
HTML carregado em 233
criptografia 277
distribuição de aplicativos do AIR 312
tags img 28
criptografia AES-CBC de 128 bits 215
Documentação do ActionScript 9
classe Updater 328
criptografia de conteúdo de vídeo 277
Documentação do Adobe 9
Classe URLStream 222
criptografia de dados 215
Documentação do Flash 9
classe Window 59
cromo do sistema 62
documentação, relacionada 9
classe WindowedApplication 59
Classe XMLList 239
janelas HTML 67
cromo personalizado 62
dois pontos (:) caractere, em nomes de
parâmetro de instrução SQL 175
Clipboard 223
DPAPI (associação de dados criptografados
com usuários) 215
códigos de erro
DRM 277
DRM 286
credenciais 286
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 376
Índice
E
elemento allowBrowserInvocation (arquivo
do descritor do aplicativo) 52, 291, 294
elemento content (arquivo do descritor do
aplicativo) 50
elementos frame 219, 222, 227
evento load 219, 221, 235, 242
elementos iframe 30, 219, 222, 227
evento locationChange 252
empacotamento de arquivos do AIR
evento mouseDown 77, 134
ferramenta para desenvolvedores do AIR
(ADT) 358
evento mouseMove 134
evento move 61, 79
elemento customUpdateUI (arquivo de
descrição do aplicativo) 291, 330
Endian.BIG_ENDIAN 156
evento moving 79
elemento customUpdateUI (arquivo do
descritor do aplicativo) 52
Endian.LITTLE_ENDIAN 156
evento nativeDragComplete 134, 138, 140
entre scripts 35, 241, 248
evento nativeDragDrop 134
elemento description (arquivo do descritor
do aplicativo) 49
enumeração de diretórios 117
evento nativeDragEnter 134, 138, 139, 140
enumeração de telas 83
evento nativeDragExit 134, 140
elemento filename (arquivo de descrição do
aplicativo) 47
equivalentes de tecla de comandos de
menu 89
evento nativeDragOver 134, 138, 139, 140
elemento fileTypes (arquivo do descritor do
aplicativo) 52, 299
equivalentes de teclas
elemento height (arquivo do descritor do
aplicativo) 51
esquema de URL app-storage 25, 39, 42, 112,
273
elemento icon (arquivo do descritor do
aplicativo) 51
esquema de URL app-support 248
evento result 174
esquema de URL de aplicativo 39, 42, 68,
112, 220, 240, 248, 273
evento scroll 252
esquema de URL de arquivo 39, 240
evento uncaughtScriptExcpetion 252
esquema de URL do javascript 227
evento userIdle 300
esquema de URL javascript 33, 237
evento userPresent 300
elemento initialWindow (arquivo do
descritor do aplicativo) 50
esquema URL de arquivo 112
eventos
esquemas de URL 112
classe NativeWindow 79
elemento installFolder (arquivo do descritor
do aplicativo) 49
estrutura de atualização 332
HTML 252
evento active 79
janelas nativas 61
elemento maximizable (arquivo do descritor
do aplicativo) 51
evento browserInvoke 295, 320
manipuladores 255
elemento maxSize (arquivo do descritor do
aplicativo) 51
evento close 79
menu 88, 96
evento closing 74, 79, 255, 296
elemento id (arquivo do descritor do
aplicativo) 47
elemento id (classe NativeApplication) 298
elemento initialWindow (arquivo de
descrição do aplicativo) 60
copiar e colar 153
evento nativeDragStart 134, 140
evento nativeDragUpdate 134, 140
evento resize 61, 79
evento resizing 79
evento select 88, 97, 98
ouvintes 255
elemento minimizable (arquivo do descritor
do aplicativo) 51
Evento complete 242, 252
eventos load 238
evento complete 246
eventos menuItemSelect 89
elemento minSize (arquivo do descritor do
aplicativo) 51
evento contextmenu 93
eventos menuSelect 89
evento da área de transferência 224
eventos unload 225
elemento name (arquivo de descrição do
aplicativo) 48
evento de copiar 150
exclusão de arquivos 120
exclusão de diretórios 118, 120
elemento programMenuFolder (arquivo do
descritor do aplicativo) 50
evento de recortar 150
evento deactivate 79
execução de aplicativos do AIR 312, 320
evento displaying 88, 98
exibições
elemento resizable (arquivo do descritor do
aplicativo) 51
evento displayStateChange 61, 80
elemento title (arquivo do descritor do
aplicativo) 51
evento displayStateChanging 61, 80
elemento transparent (arquivo do descritor
do aplicativo) 51
evento drag 141, 224
elemento version (arquivo do descritor do
aplicativo) 47
evento dragenter 141, 224
elemento visible (arquivo do descritor do
aplicativo) 51
evento dragover 141, 224
evento dominitialize 228
evento dragend 141, 224
evento dragleave 141, 224
Consulte telas
extensões (arquivo), associação com um
aplicativo AIR 299
extensões (arquivo), associação com um
aplicativo do AIR 52, 293
F
FDB (depurador) 356
fechamento de janelas 61, 74, 296
elemento width (arquivo do descritor do
aplicativo) 51
evento dragstart 141, 224
elemento x (arquivo do descritor do
aplicativo) 51
evento enterFrame 70
evento error 174
elemento y (arquivo do descritor do
aplicativo) 51
arquivos AIRI 366
evento htmlBoundsChanged 252
criação de certificados auto-assinados 368
evento drop 141, 224
evento htmlDOMInitialize 252
fechar aplicativos 296
ferramenta para desenvolvedores do AIR
(ADT)
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 377
Índice
empacotamento de um arquivo do
AIR 358
I
ícones
itens de menu 88
ativados 90
opções de assinatura 363
animação 101
caracteres mnemônicos 90
Flash Player 54, 217, 220, 239
aplicativo 51
copiar e colar 152
Flex
bandeja do sistema 101
criação 92
barra de tarefas 73, 101
dados, atribuição a 90
encaixe 101, 102
estados 90
imagens 101
marcados 90
remoção 101
seleção 97
suporte a arrastar e soltar 135
FMRMS (Servidor de gerenciamento de
direitos do Flash Media) 277
formato de arquivo ZIP 159
formato GZIP 157
função AC_FL_RunContent() (em
default_badge.html) 314
ícones de bandeja do sistema 87, 90
ícones de encaixe 102
teclas de aceleração 89
itens de menu ativados 90
função eval() 28, 32, 221, 234, 235
menus 90
itens de menu marcados 90
função setInterval() 33, 226, 237
minimização de janelas e 73
itens de menus
função setTimeout() 33, 226, 237
funções (JavaScript)
construtor 237
definições 33
literais 33
ícones de proxy
ícones do encaixe
suporte 101
ícones na bandeja do sistema
suporte 101
G
geração de código dinâmico 32
gerenciamento de direitos digitais 277
gesto de arrastar para dentro 133, 138
equivalentes de tecla 89
Mac OS 65
J
janela ativa 72, 73
janelas 59
aparência 62
ícones na barra de tarefas 73, 101
ativação 67
ícones na barra de título (Windows) 65
ativas 72, 73
ícones no encaixe
classes para trabalhar com 60
pular 102
comportamento 62
gesto de arrastar para fora 133, 135
identificadores de editor 298
criação 65, 71, 233
gravação de arquivos 121
identificadores do editor 322
cromo 62
idiomas, com suporte no instalador do
aplicativo do AIR 49
cromo do sistema 62
IDs digitais de assinatura Sun Java 323
estilo 62
IDs digitais Microsoft Authenticode 323
eventos 79
IDs do aplicativo 47
fechamento 61, 74, 296
imagens de bitmap, definição para
ícones 101
fluxo de eventos 61
H
HMTL
copiar e colar 149
suporte a arrastar e soltar 133, 142
HTML
caixas de proteção 220
impressão 220
carregamento de conteúdo 233
informações de copyright para aplicativos
do AIR 49
DOM, acesso do ActionScript 242
eventos 252
extensões do AIR para 227
impressão 220
janelas 67
objetos incorporados 219
plug-ins 219
rolagem 252
segurança 30, 219, 248
sobreposição de conteúdo SWF 69
HTMLLoader
propriedade
placeLoadStringContentInApplication
Sandbox 233
cromo personalizado 62
gerenciamento 72
iniciais 60
inicialização 65
inicialização (sistema), inicialização de um
aplicativo do AIR na 294
janelas de utilitário 62
inicialização automática (inicialização de
um aplicativo do AIR no login) 294
leves 62
inicializar aplicativos do AIR 291
minimização 51, 61, 73, 75
instalação de aplicativos do AIR 312
modos de dimensionamento de palco 67
Instrução CREATE TABLE (SQL) 170
mostrar 73
Instrução DELETE (SQL) 185
movimentação 61, 77, 78
Instrução INSERT (SQL) 189
movimento 83
Instrução SELECT (SQL) 177, 189
não retangulares 63
Instrução UPDATE (SQL) 185
ocultar 73
instruções, SQL 173
ordem 73
interface de usuário de atualização
personalizada 330
ordem de exibição 73
invocação de aplicativos do AIR 291
invocar evento 291
janelas normais 62
maximização 51, 61, 75
plano de fundo de 63
posição 51
propriedades 50
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 378
Índice
redimensionamento 51, 61, 77
restauração 61, 75
tamanho 67
tamanho de 51
tamanho máximo 67
tamanho mínimo 67
tipos 62
transparência 51, 63
visibilidade 51
janelas da área de trabalho
Consulte janelas
janelas de utilitário 62
janelas em tela cheia 80
Janelas HTML DOM e nativas 60
janelas leves 62
janelas nativas
Consulte janelas
janelas normais 62
janelas pop-up 73
janelas transparentes 51, 63
JavaScript
acesso às APIs do AIR 239
arquivo AIRAliases.js 218, 239
como evitar erros de segurança 235
entre scripts ActionScript 241
erros 235, 242, 253, 256
eventos de erro 252
eventos, tratamento 255
PDF 273
programação 233
segurança 248
suporte do AIR para 220
tempo de execução do AIR e 217
JCA (arquitetura de criptografia Java) 363
JSON 221
L
leitura de arquivos 121
ligação forte de dados criptografados 215
limpeza de diretórios 118
linhas (banco de dados) 166, 184
linhas separadoras, menu 92
lista de revogação de certificado (CRL) 326
listas de arquivos
suporte a arrastar e soltar 142
literais de objeto (em JavaScript) 32
Livros da Adobe Press 9
lixeira (exclusão de arquivo) 120
localização 343
login do sistema, inicialização de um
aplicativo do AIR no 294
menus de janela 86, 98
login, inicialização de um aplicativo do AIR
no 294
menus nativos
M
Mac OS
barra de ferramentas 65
ícones de proxy 65
criação 90
Consulte menus
menus pop-up 86, 96
criação 90
método acceptDragDrop() (classe
NativeDragManager) 134, 139
manipulador onclick 238
método activate() (classe
NativeWindow) 67, 73
manipulador onload 32
método addChild() (classe Stage) 70
manipulador onmouseover 238
método addChildAt() (classe Stage) 70
matrizes de bytes
ordem de bytes 156
método attach() (classe
SQLConnection) 186
position em 155
método bounce() (classe Icon) 102
tamanho de 155
método browseForDirectory() (classe
File) 110
maximização de janelas 51, 61, 75
menu
aplicativo 98
estrutura 88
eventos 98
menu Iniciar (Windows) 50
menus 86
aplicativo 90
classes de trabalho 87
comandos de copiar e colar 151
método browseForOpen() (classe File) 111
método browseForSave() (classe File) 111
método clearData()
objeto ClipboardData 223
objeto DataTransfer 142, 224
método close()
classe NativeWindow 74
método close() (objeto Window) 60
método compress() (classe ByteArray) 157
criação 90
método copy() (classe
NativeApplication) 152
encaixe 87
método copyTo() (classe File) 119
equivalentes de tecla 89
método copyToAsync() (classe File) 119
estrutura 87
método createDirectory() (classe File) 116
fluxo de evento 88, 96
método createElement() (objeto
Document) 238
ícone de bandeja do sistema 90
ícones de bandeja do sistema 87
item de encaixe 90
itens 88
janela 90, 98
linhas separadoras 92
menus de contexto 92
método createRootWindow() (classe
HTMLLoader) 67, 69, 233
método createTempDirectory() (classe
File) 116, 121
método createTempFile() (classe File) 121
método deleteDirectory() (classe File) 118
personalizados 87
método deleteDirectoryAsync() (classe
File) 118
pop-up 90, 96
método deleteFile() (classe File) 120
sistema padrão 87
método deleteFileAsync() (classe File) 120
submenus 88, 91
tipos de 87
método dispatchEvent() (classe
NativeWindow) 61
XML, definição com 94
método display() (classe NativeMenu) 96
menus de aplicativo 86, 98
criação 90
menus de contexto 86, 92
HTML 93
menus de encaixe 87
Método Document object
wirtelin() 225
método doDrag() (classe
NativeDragManager) 134, 136, 139
método execute() (classe
SQLStatement) 175, 177, 184
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 379
Índice
método openAsync() (classe
SQLConnection) 169, 172
método writeln() (objeto Document) 225,
238
método getApplicationVersion() (arquivo
air.swf) 318
método orderBehind() (classe
NativeWindow) 73
método writeObject() (classe
ByteArray) 154
método getData()
método orderInBackOf() (classe
NativeWindow) 73
método writeUTFBytes() (classe
ByteArray) 154
método orderInFrontOf() (classe
NativeWindow) 73
Microsoft Windows
método orderToBack() (classe
NativeWindow) 73
migração de uma assinatura 325, 367
método orderToFront() (classe
NativeWindow) 73
monitores
método exit()
classe NativeApplication 296
classe Clipboard 139
evento de copiar e colar HTML 150
objeto ClipboardData 223
objeto DataTransfer 145, 224
método getData() (classe Clipboard) 135
método getData() (de uma propriedade
dataTransfer de um evento de arrastar
HTML) 142
método getDefaultApplication() (classe
NativeApplication) 299
método postMessage() (objeto PDF) 274
ícones na barra de título 65
minimização de janelas 51, 61, 73, 75
Consulte telas
método preloadEmbeddedMetadata()
(classe NetStream) 279
mostrar janelas 73
movimentação de arquivos 119
método print() (objeto Window) 220
movimentação de diretórios 117
método getDirectoryListing() (classe
File) 117
método readBytes() (classe ByteArray) 154
movimentação de janelas 61, 77, 78
método getDirectoryListingAsync() (classe
File) 117
método readInt() (classe ByteArray) 154
método getResult() (classe
SQLStatement) 184
método getScreensForRectangle() (classe
Screen) 83
método getStatus() (arquivo air.swf) 317
método hasEventListener() 257
método installApplication() (arquivo
air.swf) 319
método readFloat() (classe ByteArray) 154
método readObject() (classe ByteArray) 154
método readUTFBytes() (classe
ByteArray) 154
método relativize() (classe File) 113
método removeAsDefaultApplication()
(classe NativeApplication) 299
método removeEventListener() 256
método resetDRMVouchers() (classe
NetStream) 282
N
namespace XML (arquivo do descritor do
aplicativo) 45
navegação
para selecionar um arquivo 111
para selecionar um diretório 110
navegadores da Web
detecção de tempo de execução do AIR
de 317
método resolvePath() (classe File) 108
detecção se um aplicativo do AIR está
instalado de 318
método listRootDirectories() (classe
File) 108
método restore() (classe NativeWindow) 75
inicialização de aplicativos do AIR de 320
método load() (classe FileReference) 129
método loadBytes() (classe Loader) 41
método setAsDefaultApplication() (classe
NativeApplication) 52, 299
método Loader.loadBytes() 41
método setData()
método isSetAsDefaultApplication() (classe
NativeApplication) 299
método loadString() (classe
HTMLLoader) 35, 233
método maximize() (classe
NativeWindow) 75
método minimize() (classe
NativeWindow) 75
método moveTo()
classe File 119
objeto Window 60
método moveToAsync() (classe File) 119
método save() (classe FileReference) 129
objeto ClipboadData 223
objeto DataTransfer 142, 144, 224
instalação de aplicativos do AIR de 319
navegadores da web
inicialização de um aplicativo do AIR
de 294
níveis de patch
tempo de execução do AIR 300
método setDragImage() (de uma
propriedade dataTransfer de um
evento de arrastar HTML) 142
níveis de patch, tempo de execução do
AIR 45
método
setDRMAuthenticationCredentials()
(classe NetStream) 278, 282
nome de coluna ROWID (SQL) 185
método startMove() (classe
NativeWindow) 78
nome do editor 321
nome de coluna OID (SQL) 185
nome de coluna _ROWID_ (SQL) 185
nome do editor desconhecido (no instalador
do aplicativo do AIR) 321
método moveToTrash() (classe File) 120
método startResize() (classe
NativeWindow) 77
método moveToTrashAsync() (classe
File) 120
método uncompress() (classe
ByteArray) 157
método
NativeApplication.setAsDefaultApplic
ation() 299
método update() (classe Updater) 328
método open()
método writeBytes() (classe ByteArray) 154
O
objeto Canvas 222, 229
classe SQLConnection 169
método writeFloat() (classe ByteArray) 154
objeto DataTransfer
objeto Window 35, 67, 227
método writeInt() (classe ByteArray) 154
método open() (classe SQLConnection) 169
método write() (objeto Document) 225, 238
nomes de usuário
configuração para conteúdo de mídia
criptografado 277
propriedade types 145
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 380
Índice
objeto DataTransfer (HTML arrastar e
soltar) 142, 143, 144, 145, 224
objeto Document
método write() 33, 225, 238
plug-ins (em HTML) 219
propriedade creator (classe File) 118
pontes de caixa de proteção 31, 35, 219, 220,
235, 248
propriedade CSS -webkit-user-drag 144
propriedade currentDirectory (classe
InvokeEvent) 292
método writeln() 33, 238
ponto de interrogação (?) caractere, em
parâmetros SQL sem nome 176
propriedade designMode 145, 225
posição de janelas 51
propriedade currentDomain (classe
ApplicationDomain) 242
propriedade stylesheets 246
posição do mouse ao arrastar 140
propriedade data
privilégios necessários para atualizar o
tempo de execução do AIR ou de um
aplicativo do AIR 23
propriedade de argumentos
objeto Document object
método createElement() 238
objeto Window
método moveTo() 60
privilégios necessários para atualizar o
tempo de execução do AIR ou um
aplicativo do AIR 313, 319
método open 227
programação assíncrona
método close() 60
método open() 35, 67
bancos de dados 168, 172, 190
método print() 220
sistema-arquivo 106
objeto htmlLoader 218
XMLHttpRequests 238
objeto nativeWindow 218
programação síncrona
propriedade childSandboxBridge 31
bancos de dados 168, 172, 190
propriedade htmlLoader 68, 226, 233
sistema-arquivo 106
propriedade nativeWindow 60, 68, 226
propriedade opener 68
propriedade parent 68
propriedade parentSandboxBridge 31,
226, 249
propriedade runtime 28, 34, 68, 218, 226,
239
XMLHttpRequests 238
propriedade activeWindow (classe
NativeApplication) 72
propriedade air (arquivo AIRAliases.js) 218,
239
propriedade allowLoadBytesCodeExecution
(classe LoaderContext) 41
objeto XMLHttpRequest 34, 221, 227, 238
propriedade alwaysInFront (classe
NativeWindow) 73
objetos Date, conversão entre ActionScript e
JavaScript 246
propriedade applicationDescriptor (classe
NativeApplication) 298
objetos incorporados (em HTML) 219
propriedade applicationStorageDirectory
(classe File) 108
objetos RegExp, conversão entre
ActionScript e JavaScript 246
objetos serializados 135
propriedade autoExit
classe NativeApplication 296
classe NativeMenuItem 90
classe BrowserInvokeEvent 295
classe InvokeEvent 292
propriedade de tipos
evento de arrastar HTML 142
propriedade designMode (objeto
Document) 145, 225
propriedade desktopDirectory (classe
File) 108
propriedade displayState (classe Stage) 80
propriedade documentsDirectory (classe
File) 108
propriedade dropAction (classe
NativeDragEvent) 138, 139
propriedade dropEffect (objeto
DataTransfer) 142, 143, 224
propriedade effectAllowed (objeto
DataTransfer) 142, 143, 144, 224
propriedade encoding (classe File) 115
propriedade exists (classe File) 118
propriedade height (classe
HTMLLoader) 233
propriedade hostContainer (PDF) 274
propriedade htmlLoader (objeto
Window) 68, 218, 226, 233
propriedade icon (classe
NativeApplication) 101
suporte a arrastar e soltar 133
propriedade bitmaps (classe Icon) 101
suporte a copiar e colar 149
ocultar janelas 73
propriedade bytesAvailable (classe
ByteArray) 155
propriedade innerHTML 33, 225, 238
ordem das janelas 73
propriedade childSandboxBridge
propriedade isDirectory (classe File) 118
ordem de bytes 156
classe LoaderInfo 36
ordem de bytes de big-endian 156
objeto Window 31
ordem de bytes de little-endian 156
ordem de exibição, janelas 73
P
parâmetros nomeados (em instruções
SQL) 175
parâmetros sem nome (em instruções
SQL) 176
parâmetros, em instruções SQL 175
PDF
suporte para 219, 272
plano de fundo de janelas 63
propriedade idleThreshold (classe
NativeApplication) 300
propriedade isHTTPS (classe
BrowserInvokeEvent) 295
propriedade clientX (eventos de arrastar
HTML) 142
propriedade keyEquivalent (classe
NativeMenuItem) 89
propriedade clientY (eventos de arrastar
HTML) 142
propriedade keyEquivalentModifiers (classe
NativeMenuItem) 89
propriedade clipboard (classe
NativeDragEvent) 139
propriedade label (classe
NativeMenuItem) 152
propriedade clipboardData (eventos da área
de transferência) 224
propriedade lastInsertRowID (classe
SQLResult) 184
propriedade clipboardData (eventos de
copiar e colar HTML) 150
propriedade lastUserInput (classe
NativeApplication) 300
propriedade contextMenuOwner (classe
ContextMenuEvent) 92
propriedade length (classe ByteArray) 155
propriedade creationDate (classe File) 118
propriedade mainScreen (classe Screen) 83
propriedade lineEnding (classe File) 115
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 381
Índice
propriedade messageHandler (PDF) 274
propriedade mnemonicIndex
classe NativeMenuItem 90
propriedade modificationDate (classe
File) 118
propriedade mouseTarget (classe
ContextMenuEvent) 92
propriedade screenX (eventos de arrastar
HTML) 142
propriedade screenY (eventos de arrastar
HTML) 142
propriedade securityDomain (classe
BrowserInvokeEvent) 295
propriedade separator (classe File) 115
propriedade name (classe File) 118
propriedade size (classe File) 118
propriedade nativePath (classe File) 108, 118
propriedade spaceAvailable (classe File) 115
propriedade nativeWindow
propriedade sqlConnection (classe
SQLStatement) 174
classe Stage 66, 72
objeto Window 218, 226
propriedade nativeWindow (objeto
Window) 60, 68
propriedade opener (objeto Window) 68
propriedade paintsDefaultBackground
(classe HTMLLoader) 63, 70
propriedade parameters (classe
SQLStatement) 174, 175
propriedade parent (classe File) 118
propriedade parent (objeto Window) 68
propriedade parentSandboxBridge
classe LoaderInfo 36
objeto Window 31, 226
Q
quadros 30
R
recurso de invocação do navegador 52, 294
Recursos
propriedade de idioma 344
propriedade de idiomas 344
redimensionamento de janelas 51, 61, 77
referências a objetos
suporte a arrastar e soltar para 133
propriedade stage
classe NativeWindow 70
propriedade startAtLogin (classe
NativeApplication) 294
referências de objetos
suporte a copiar e colar 149
registro de tipos de arquivo 299
propriedade styleSheets (objeto
Document) 246
requisitos
propriedade subErrorID (classe
DRMErrorEvent) 286
restauração de janelas 61, 75
processamento em PDF 272
propriedade submenu
classe NativeMenuItem 88
propriedade supportsDockIcon (classe
NativeApplication) 101
propriedade supportsMenu (classe
NativeApplication) 98
S
sair de aplicativos do AIR 291
sair do evento 296
screens 82
security
propriedade parentSandboxBridge (objeto
Window) 249
propriedade supportsSystemTrayIcon
(classe NativeApplication) 101
propriedade pdfCapability (classe
HTMLLoader) 272
propriedade systemChrome (classe
NativeWindow) 62
ataques de downgrade 42
propriedade
placeLoadStringContentInApplication
Sandbox (classe HTMLLoader) 35, 233
propriedade systemMaxSize (classe
NativeWindow) 67
cache entre domínios 29
XMLHTTPRequest 228
segurança
banco de dados 176
propriedade systemMinSize (classe
NativeWindow) 67
caixa de proteção do aplicativo 27
caixas de proteção de não-aplicativos 29
propriedade position (classe ByteArray) 155
propriedade text (classe SQLStatement) 174,
175, 177, 185
propriedade publisherID (classe
NativeApplication) 298, 322
propriedade transparent (classe
NativeWindow) 62, 63
carregar conteúdo 68
propriedade runtime (objeto Window) 68,
218, 226, 239
propriedade type (classe File) 118
propriedade runtimeApplicationDomain
(classe HTMLLoader) 242
propriedade types
propriedade playerType
classe Capabilities 300
propriedade runtimePatchLevel (classe
NativeApplication) 300
propriedade runtimeVersion (classe
NativeApplication) 300
propriedade sandboxRoot
frame 30
iframe 30
propriedade sandboxType
classe BrowserInvokeEvent 295
classe Security 300
propriedade scaleMode
classe Stage 77
propriedade screens (classe Screen) 83
propriedade type (classe NativeWindow) 62
caixas de proteção 27, 219, 220, 248, 300
campos de texto 28
credenciais do usuário 42
criptografia de dados 215
CSS 29
evento de copiar e colar HTML 150
diretório de armazenamento do
aplicativo 25
objeto DataTransfer 224
entre scripts 35
propriedade types (objeto
DataTransfer) 145
propriedade url
classe File 108, 118
propriedade url (classe File) 108
propriedade userDirectory (classe File) 108
propriedade visible
classe NativeWindow 67, 73
propriedade width (classe
HTMLLoader) 233
propriedades outerHTML 225
protocolo asfunction 29
erros JavaScript 235
estruturas Ajax 33
frames 29, 30
função eval() 32
geração de código dinâmico 32
HTML 30, 32, 217, 219, 234
iframes 29, 30
instalação (aplicativo e tempo de
execução) 23
JavaScript 248
método Loader.loadBytes() 41
DESENVOLVIMENTO DE APLICATIVOS DO ADOBE AIR 1.5 COM O FLASH CS4 PROFESSIONAL 382
Índice
objetos XMLHttpRequest 34
pontes de caixa de proteção 31, 35, 248
práticas recomendadas 41
privilégios de instalação do usuário 23
protocolo asfunction 29
T
tabelas (banco de dados) 166
criação 170
tags de script 221, 225, 238, 240, 244
propriedade src de 33
sistema de arquivos 39
tags img (no conteúdo do objeto
TextField) 28
tags img 28
tamanho de janelas 51
window.open() 35
tamanho, janelas 67
recurso de invocação do navegador 295
V
validação de dados, invocação do
aplicativo 295
versões, aplicativo AIR 300
vídeos FLV, criptografia de 277
visibilidade de janelas 51
volumes de raiz 108
W
WebKit 217, 220, 231
segurança de cache entre domínios 29
Tecla Command 89
Segurança de JavaScript 32
Tecla Control 89
segurança e ataques de downgrade 42
tecla Shift 89
-webkit-border-horizontal-spacing CSS
property 231
senhas
teclas de aceleração de comandos de
menu 89
-webkit-border-vertical-spacing CSS
property 231
teclas do modificador, itens de menu 89
-webkit-line-break CSS property 231
Servidor de gerenciamento de direitos do
Flash Media 277
teclas primárias
-webkit-margin-bottom-collapse CSS
property 231
sistema de arquivos
tela principal 83
configuração para conteúdo de mídia
criptografado 277
segurança 39
itens de menu 89
telas
-webkit-margin-collapse CSS property 231
-webkit-margin-start CSS property 231
Site de suporte da Adobe 9
enumeração 83
-webkit-margin-top-collapse CSS
property 231
SQL
janelas, movimento entre 83
-webkit-nbsp-mode CSS property 231
principal 83
-webkit-padding-start CSS property 231
classes usadas com 167
colunas AUTOINCREMENT 185
tempo de execução do AIR
-webkit-rtl-ordering CSS property 231
colunas INTEGER PRIMARY KEY 185
atualização 23
-webkit-text-fill-color CSS property 232
digitação de dados 176, 189
desinstalação 2
-webkit-text-security CSS property 232
instrução CREATE TABLE 170
detecção 300, 317
propriedade -webkit-user-drag CSS 232
instrução DELETE 185
níveis de patch 45, 300
propriedade CSS -webkit-user-drag 141
instrução INSERT 189
nova funcionalidade 54
-webkit-user-modify CSS property 232
instrução SELECT 177, 189
tempo ocioso (usuário) 300
propriedade -webkit-user-select CSS 232
instrução UPDATE 185
texto
propriedade CSS -webkit-user-select 141,
144
instruções 173
nome de coluna OID 185
suporte a arrastar e soltar 133, 142
suporte a copiar e colar 149
nome de coluna ROWID 185
tipos de dados, banco de dados 189
nome de coluna _ROWID_ 185
tipos MIME
parâmetros em instruções 175
arrastar e soltar HTML 142
parâmetros nomeados (em
instruções) 175
copiar e colar HTML 223
parâmetros sem nome (em
instruções) 176
sobre 167
stylesheets, HTML
manipulação no ActionScript 246
tradução de aplicativos 343
U
UntrustedAppInstallDisabled
(configurações de Registro do
Windows) 26
Suporte para bancos de dados SQLLite 164
UpdateDisabled (configurações de Registro
do Windows) 26
suporte para bancos de dados SQLLite
URLs 240
submenus 88, 91
Consulte também bancos de dados
carregamento de conteúdo HTML de 233
suporte técnico 9
suporte a arrastar e soltar 133, 142
SVG (gráficos vetoriais escaláveis) 220
suporte a copiar e colar 149
X
XML
classe 239
definição de menus usando 94
xmlns (arquivo do descritor do
aplicativo) 45
Download