Pobierz Pomoc w formacie
Transkrypt
Pobierz Pomoc w formacie
Tworzenie aplikacji ADOBE AIR 1.5 w programie ADOBE FLASH CS4 PROFESSIONAL ® ® ® ™ © 2008 Adobe Systems Incorporated. Wszelkie prawa zastrzeżone. Prawa autorskie Tworzenie aplikacji Adobe® AIR™ 1.5 w programie Adobe® Flash® CS4 Niniejszy podręcznik, jak również opisane w nim oprogramowanie, udostępniane jest na licencji i może być używany i kopiowany tylko zgodnie z warunkami tej licencji. Poza sytuacjami dozwolonymi przez postanowienia licencji, zabronione jest powielanie, przechowywanie w systemie dostępu lub transmisja jakiejkolwiek części niniejszej publikacji, w dowolnej formie i dowolną metodą, elektroniczną, mechaniczną, w drodze nagrania lub w inny sposób, bez uprzedniego pisemnego zezwolenia Adobe Systems Incorporated. Zawartość tego podręcznika chroniona jest prawami autorskimi, nawet jeśli nie jest rozprowadzana z oprogramowaniem zawierającym licencję użytkownika. Zawartość tego podręcznika udostępniana jest tylko w celach informacyjnych, może ulec zmianie bez powiadomienia i nie może być interpretowana jako zobowiązanie ze strony Adobe Systems Incorporated. Adobe Systems Incorporated nie przyjmuje żadnej odpowiedzialności ani zobowiązań z tytułu błędów lub niedokładnych informacji, jakie mogą pojawić się w tym podręczniku. Proszę pamiętać, że istniejąca grafika lub obrazki, które użytkownik zechce umieścić w swoim projekcie, mogą być chronione prawami autorskimi. Nieupoważnione użycie takiego materiału we własnej pracy może stanowić naruszenie praw autorskich jego właściciela. Proszę pamiętać o uzyskaniu wszystkich niezbędnych zezwoleń od posiadacza praw autorskich. Wszelkie odniesienia do nazw firm lub nazwisk osób w załączonych szablonach mają cel wyłącznie demonstracyjny i nie odnoszą się do jakichkolwiek istniejących organizacji ani osób. 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 Spis treści Rozdział 1: Instalacja środowiska Adobe AIR Instalowanie środowiska Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Usuwanie środowiska Adobe AIR ...................................................................................... 2 Instalowanie i uruchamianie przykładowych aplikacji dla środowiska AIR ................................................ 2 Rozdział 2: Konfigurowanie programu Flash CS3 dla Adobe AIR Wymagania systemowe dla aktualizacji środowiska Adobe AIR dla programu Flash CS3 Instalowanie aktualizacji środowiska Adobe AIR dla programu Flash CS3 Usuwanie aktualizacji środowiska Adobe AIR dla programu Flash CS3 Dodatki AIR do Flash CS3 .................................. 4 ................................................ 4 ................................................... 5 .............................................................................................. 6 Rozdział 3: Wprowadzenie do środowiska Adobe AIR Co nowego w środowisku AIR 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Co nowego w środowisku AIR 1.5 ...................................................................................... 9 Rozdział 4: Znajdowanie zasobów dotyczących środowiska AIR Rozdział 5: Tworzenie pierwszej aplikacji dla środowiska AIR przy użyciu programu Flash CS3 lub CS4 Tworzenie aplikacji Hello World w programie Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Testowanie aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Konwertowanie pliku FLA na aplikację Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Rozdział 6: Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Tworzenie pliku Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Definiowanie ustawień publikowania programu Adobe AIR Wyświetlanie podglądu aplikacji Adobe AIR Debugowanie aplikacji Adobe AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Tworzenie plików aplikacji AIR i plików instalatora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Tworzenie niestandardowego pliku deskryptora aplikacji Podpisywanie aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Rozdział 7: Zabezpieczenia w środowisku AIR Podstawowe informacje o zabezpieczeniach w środowisku AIR Instalowanie i aktualizowanie Obszary izolowane Zabezpieczenia HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Treść odwołująca się do skryptów w różnych domenach Zapis na dysk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Bezpieczna praca z treścią niezaufaną . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Sprawdzone procedury zabezpieczeń przeznaczone dla programistów Podpisywanie kodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Rozdział 8: Definiowanie ustawień aplikacji AIR Struktura pliku deskryptora aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Definiowanie właściwości w pliku deskryptora aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL iv Spis treści Rozdział 9: Adobe AIR – charakterystyczne funkcje Klasy charakterystyczne dla środowiska AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Klasy środowiska wykonawczego z funkcjami charakterystycznymi dla produktu AIR Klasy infrastruktury monitorowana usług Rozdział 10: Praca z oknami rodzimymi Dodatkowe informacje online o rodzimych oknach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Podstawowe informacje o oknach w środowisku AIR Tworzenie okien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Zarządzanie oknami . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Wykrywanie zdarzeń okien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Wyświetlanie okien w trybie pełnoekranowym . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Rozdział 11: Ekrany Dodatkowe informacje o ekranach dostępne w Internecie Podstawowe informacje o ekranach Wyliczanie ekranów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Rozdział 12: Praca z rodzimymi menu Dodatkowe informacje online o rodzimych menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Podstawowe informacje o menu w środowisku AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Tworzenie rodzimych menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Informacje o menu kontekstowych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Informacje o menu kontekstowych w HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Deklaratywne definiowanie rodzimych menu Wyświetlanie menu podręcznych Obsługa zdarzeń menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Przykład: menu aplikacji i okna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Rozdział 13: Ikony paska zadań Dodatkowe informacje o ikonach paska zadań dostępne w Internecie Informacje o ikonach paska zadań Ikony Docku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Ikony zasobnika systemowego . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Ikony i przyciski okien na pasku zadań . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Rozdział 14: Praca z systemem plików Dodatkowe informacje online dotyczące interfejsu API plików programu AIR Podstawowe informacje o plikach AIR Praca z obiektami File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Uzyskiwanie informacji o systemie plików Praca z katalogami Praca z plikami . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Odczyt i zapis plików . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Rozdział 15: Przeciąganie i upuszczanie Dodatkowe informacje online dotyczące przeciągania i upuszczania Podstawowe informacje o przeciąganiu i upuszczaniu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL v Spis treści Obsługa gestu przeciągania na zewnątrz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Obsługa gestu przeciągania do wewnątrz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Przeciąganie i upuszczanie w treści HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Rozdział 16: Kopiowanie i wklejanie Dodatkowe informacje online dotyczące kopiowania i wklejania Kopiowanie i wklejanie HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Polecenia menu i naciśnięcia klawiszy kopiowania i wklejania Rozdział 17: Praca z tablicami bajtów Odczytywanie i zapisywanie obiektu ByteArray Przykład ByteArray: odczytywanie pliku .zip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Rozdział 18: Praca z lokalnymi bazami danych SQL Dodatkowe informacje online na temat lokalnych baz danych SQL Informacje o lokalnych bazach danych SQL Tworzenie i modyfikowanie bazy danych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Manipulowanie danymi w bazie danych SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Korzystanie z synchronicznych i asynchronicznych operacji bazy danych Korzystanie z szyfrowania w bazach danych SQL Strategie pracy z bazami danych SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Rozdział 19: Przechowywanie danych zaszyfrowanych Rozdział 20: Informacje o środowisku HTML Przegląd środowiska HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Rozszerzenia AIR i Webkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Rozdział 21: Programowanie w językach HTML i JavaScript Informacje o klasie HTMLLoader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Unikanie błędów JavaScript związanych z bezpieczeństwem Dostęp do klas API środowiska AIR z JavaScript Informacje o adresach URL w środowisku AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 Udostępnianie obiektów ActionScript dla kodu JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Dostęp do modelu DOM HTML i obiektów JavaScript z kodu ActionScript Osadzanie treści SWF w kodzie HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Korzystanie z bibliotek ActionScript na stronie HTML Konwertowanie obiektów Date i RegExp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Manipulowanie szablonem strony HTML z kodu ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Rozdział 22: Obsługa zdarzeń powiązanych z HTML HTMLLoader, zdarzenia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Obsługa zdarzeń DOM za pomocą kodu ActionScript Reagowanie na niewychwycone wyjątki JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Obsługa zdarzeń środowiska wykonawczego za pomocą JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL vi Spis treści Rozdział 23: Wywoływanie skryptów w kontenerze HTML Właściwości wyświetlania obiektów HTMLLoader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Przewijanie treści HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Dostęp do listy historii HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 Ustawianie agenta użytkownika używanego podczas ładowania treści HTML Ustawianie kodowania znaków do użytku z treścią HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Definiowanie interfejsów użytkownika w stylu przeglądarki dla treści HTML Tworzenie podklas klasy HTMLLoader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 Rozdział 24: Dodawanie treści w formacie PDF Wykrywanie możliwości dotyczących treści PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 Ładowanie treści PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 Wywoływanie skryptów w treści PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 Znane ograniczenia treści PDF w środowisku AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Rozdział 25: Korzystanie z mechanizmów Digital Rights Management Dodatkowe informacje o mechanizmach DRM dostępne w Internecie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Omówienie przepływu pracy z zaszyfrowanym plikiem FLV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Elementy i zdarzenia klasy NetStream związane z mechanizmem DRM Korzystanie z klasy DRMStatusEvent Korzystanie z klasy DRMAuthenticateEvent Korzystanie z klasy DRMErrorEvent Korzystanie z klasy DRMManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 Korzystanie z klasy DRMContentData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 Rozdział 26: Uruchamianie aplikacji i opcje zamykania Wywołanie aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 Przechwytywanie argumentów wiersza poleceń Uruchamianie podczas logowania Wywołanie z przeglądarki Zamykanie aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Rozdział 27: Odczytywanie ustawień aplikacji Odczytywanie pliku deskryptora aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 Pobieranie identyfikatorów aplikacji i wydawcy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 Rozdział 28: Praca z informacjami o środowisku wykonawczym i systemie operacyjnym Zarządzanie skojarzeniami plików . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 Pobieranie wersji środowiska wykonawczego i poziomu poprawek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Wykrywanie możliwości środowiska AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Monitorowanie obecności użytkownika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Rozdział 29: Monitorowanie połączeń sieciowych Wykrywanie zmian w połączeniach sieciowych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 Podstawy monitorowania usług Wykrywanie połączeń HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 Wykrywanie połączeń z gniazdami . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL vii Spis treści Rozdział 30: Żądania URL i praca w sieci Korzystanie z klasy URLRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Zmiany klasy URLStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Otwieranie adresu URL w domyślnej przeglądarce internetowej systemu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Rozdział 31: Komunikacja między aplikacjami Rozdział 32: Dystrybucja, instalowanie i uruchamianie aplikacji AIR Instalowanie i uruchamianie aplikacji AIR z pulpitu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 Instalowanie i uruchamianie aplikacji AIR ze strony internetowej Wdrożenie w przedsiębiorstwie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Elektroniczne podpisywanie pliku AIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Rozdział 33: Aktualizowanie aplikacji AIR Informacje o aktualizowaniu aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Prezentacja niestandardowego interfejsu użytkownika służącego do aktualizacji aplikacji Pobieranie pliku AIR na komputer użytkownika Sprawdzanie, czy aplikacja została uruchomiona po raz pierwszy Korzystanie z architektury aktualizacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 Rozdział 34: Lokalizowanie aplikacji AIR Wprowadzenie do lokalizowania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Lokalizowanie nazwy i opisu aplikacji w instalatorze aplikacji Wybieranie ustawień narodowych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Lokalizowanie treści Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Lokalizowanie treści HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Lokalizowanie walut oraz zapisu daty i godziny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Rozdział 35: Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Korzystanie z programu uruchamiającego ADL (AIR Debug Launcher) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Pakowanie pliku instalacyjnego aplikacji AIR za pomocą narzędzia AIR Developer Tool (ADT) Podpisywanie pliku AIR w celu zmiany certyfikatu aplikacji Tworzenie certyfikatu samopodpisanego za pomocą narzędzia ADT Korzystanie z narzędzia Apache Ant z narzędziami SDK Indeks . . . . . . . . . . . . . . . . . . . . . . . . . . 360 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 1 Rozdział 1: Instalacja środowiska Adobe AIR Środowisko wykonawcze Adobe® AIR™ umożliwia uruchamianie aplikacji AIR w systemie lokalnym. Środowisko wykonawcze można zainstalować na różne sposoby: • instalując je niezależnie od aplikacji AIR; • instalując je razem z pierwszą aplikacją AIR (wówczas pojawia się monit o zainstalowanie także środowiska wykonawczego); • konfigurując środowisko programistyczne AIR, takie jak AIR SDK, Adobe® Flex™ Builder™ 3 lub Adobe Flex™ 3 SDK (które zawiera narzędzia programistyczne AIR wywoływane z wiersza komend). Środowisko wykonawcze wystarczy zainstalować jeden raz na danym komputerze. Wymagania systemowe dla instalacji środowiska AIR i uruchamiania aplikacji AIR zostały szczegółowo opisane na stronie: Adobe AIR: wymagania systemowe(http://www.adobe.com/products/air/systemreqs/). Instalowanie środowiska Adobe AIR Poniżej przedstawiono procedurę pobierania i instalowania wersji środowiska AIR dla systemów Windows®, Mac OS X i Linux. Aby zaktualizować środowisko wykonawcze, użytkownik musi mieć uprawnienia administracyjne w systemie. Instalowanie środowiska wykonawczego na komputerze z systemem Windows 1 Pobierz plik instalacyjny środowiska wykonawczego. 2 Kliknij dwukrotnie plik instalacyjny środowiska wykonawczego. 3 Postępuj zgodnie z monitami wyświetlanymi w oknie instalacji, aby przeprowadzić instalację. Instalowanie środowiska wykonawczego na komputerze Mac 1 Pobierz plik instalacyjny środowiska wykonawczego. 2 Kliknij dwukrotnie plik instalacyjny środowiska wykonawczego. 3 Postępuj zgodnie z monitami wyświetlanymi w oknie instalacji, aby przeprowadzić instalację. 4 Jeśli instalator wyświetli okno dialogowe uwierzytelniania, wprowadź swoją nazwę użytkownika systemu Mac OS oraz hasło. Instalowanie środowiska wykonawczego na komputerze z systemem Linux 1 Pobierz plik instalacyjny środowiska wykonawczego. 2 Ustaw uprawnienia do pliku, tak aby można było uruchomić aplikację instalatora: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 2 Instalacja środowiska Adobe AIR Ustaw w wierszu poleceń uprawnienia do pliku za pomocą polecenia chmod +x installer.bin. Niektóre wersje systemu Linux umożliwiają ustawianie uprawnień do pliku w oknie dialogowym właściwości otwieranym za pomocą menu kontekstowego. 3 Uruchom instalator z wiersza poleceń lub kliknij dwukrotnie plik instalacyjny środowiska wykonawczego. 4 Postępuj zgodnie z monitami wyświetlanymi w oknie instalacji, aby przeprowadzić instalację. Środowisko AIR jest instalowane z pakietów rpm lub dpkg o następujących nazwach: adobeairv.n i adobecerts. Instalacja wymaga działającego serwera X. Środowisko AIR rejestruje typ MIME: application/vnd.adobe.airapplication-installer-package+zip. Usuwanie środowiska Adobe AIR Zainstalowane środowisko wykonawcze można usunąć, postępując według poniższych procedur. Usuwanie środowiska wykonawczego z komputera z systemem Windows 1 W menu Start systemu Windows wybierz kolejno polecenia Ustawienia > Panel sterowania. 2 Wybierz aplet Dodaj lub usuń programy. 3 Wybierz pozycję „Adobe AIR”, aby usunąć środowisko wykonawcze. 4 Kliknij przycisk Zmień/usuń. Usuwanie środowiska wykonawczego z komputera z systemem Mac • Kliknij dwukrotnie program „Adobe AIR Uninstaller”, który znajduje się w folderze /Applications/Utilities. Usuwanie środowiska wykonawczego z komputera z systemem Linux Wykonaj jedną z następujących czynności: • Wybierz polecenie „Adobe AIR Uninstaller” z menu Applications. • Uruchom plik binarny instalatora środowiska AIR z opcją -uninstall • Usuń pakiety środowiska AIR (adobeairv.n i adobecerts) z menedżerem pakietów. Instalowanie i uruchamianie przykładowych aplikacji dla środowiska AIR Dostępne są aplikacje przykładowe, które ilustrują możliwości środowiska AIR. Aplikacje te można pobrać i zainstalować, postępując według poniższych instrukcji: 1 Pobierz i uruchom aplikacje przykładowe dla środowiska AIR. Dostępne są zarówno aplikacje skompilowane, jak i ich kod źródłowy. 2 Aby pobrać i uruchomić aplikację przykładową, kliknij jej przycisk Install Now (Zainstaluj teraz). Zostanie wyświetlone pytanie o zainstalowanie i uruchomienie aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 3 Instalacja środowiska Adobe AIR 3 Jeśli chcesz pobrać aplikacje przykładowe i uruchomić je później, wybierz łącza pobierania. Aplikacje AIR można uruchamiać w dowolnym momencie w następujący sposób: • W systemie Windows kliknij dwukrotnie ikonę aplikacji na pulpicie lub wybierz aplikację z menu Start systemu Windows. • W systemie Mac OS kliknij dwukrotnie ikonę aplikacji zainstalowaną domyślnie w folderze Applications katalogu użytkownika (Na przykład: Macintosh HD/Users/JoeUser/Applications/). • W systemie Linux kliknij dwukrotnie ikonę aplikacji na pulpicie lub wybierz aplikację z menu Applications. Aplikacje AIR są zainstalowane w ich własnych folderach w katalogu /opt. Uwaga: Aktualizacje tych instrukcji znajdują się w uwagach do wydania środowiska AIR, dostępnych pod adresem: http://www.adobe.com/go/learn_air_relnotes_pl. 4 Rozdział 2: Konfigurowanie programu Flash CS3 dla Adobe AIR Aktualizacja środowiska Adobe® AIR™ dla programu Adobe® Flash® CS3 Professional rozszerza środowisko programistyczne Flash o elementy, które umożliwiają tworzenie aplikacji AIR w programie Flash. Umożliwia tworzenie, testowanie i debugowanie plików aplikacji AIR w programie Flash. Program Adobe® Flash® CS4 Professional ma wbudowane mechanizmy umożliwiające tworzenie aplikacji dla środowiska AIR. Więcej informacji zawiera rozdział Publikowanie dla środowiska Adobe AIR w podręczniku Korzystanie z programu Flash. Aktualizacja środowiska Adobe AIR dla programu Flash CS3 obsługuje aplikacje przeznaczone dla wersji AIR 1.0, 1.1 oraz programu Flash Player 9.x. Do tworzenia aplikacji dla wersji AIR 1.5 i programu Flash Player 10 wymagany jest program Flash CS4. Wymagania systemowe dla aktualizacji środowiska Adobe AIR dla programu Flash CS3 W celu korzystania z programu Flash CS3 do tworzenia i uruchamiania aplikacji AIR wymagane jest zainstalowanie następującego oprogramowania: • Flash CS3 Professional Kopię programu Flash CS3 Professional można zakupić na stronie WWW Adobe: http://www.adobe.com/products/flash/ • Adobe AIR Informacje na temat instalowania Adobe AIR zawiera sekcja „Instalacja środowiska Adobe AIR” na stronie 1. • Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Jeśli wcześniej zainstalowano aktualizację środowiska Adobe AIR dla programu Flash CS3, najpierw należy je usunąć, wykonując czynności przedstawione w sekcji Odinstalowanie aktualizacji środowiska Adobe AIR dla programu Flash CS3. Jeśli wcześniej nie zainstalowano aktualizacji środowiska Adobe AIR dla programu Flash CS3, należy przejść do sekcji „Instalowanie aktualizacji środowiska Adobe AIR dla programu Flash CS3” na stronie 4. Instalowanie aktualizacji środowiska Adobe AIR dla programu Flash CS3 Przed zainstalowaniem aktualizacji środowiska Adobe AIR dla programu Flash CS3 należy wyłączyć program Flash oraz wszystkie otwarte okna przeglądarki. • Pobierz aktualizację Adobe AIR update for Flash CS3. • Po zakończeniu aktualizowania kliknij dwukrotnie plik aktualizacji, aby go zainstalować. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 5 Konfigurowanie programu Flash CS3 dla Adobe AIR Usuwanie aktualizacji środowiska Adobe AIR dla programu Flash CS3 Jeśli wcześniej zainstalowano aktualizację środowiska Adobe AIR dla programu Flash CS3, należy wykonać poniższe czynności, aby usunąć to oprogramowanie przed zainstalowaniem aktualizacji środowiska Adobe AIR dla programu Flash CS3. 1 Usuń następujący folder: (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\AIK (Mac) HD:/Applications/Adobe Flash CS3/AIK 2 Przejdź do następującej lokalizacji: (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\<lang>\First Run\Commands\ (Mac) HD:/Applications/Adobe Flash CS3/First Run/Commands a następnie usuń następujące pliki/foldery: • Folder AIR • AIR - Application and Installer Settings.jsfl • AIR - Create AIR File.jsfl 3 Usuń następujący plik: (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\<lang>\Configuration\External Libraries\FLAir.dll (Mac) HD:/Applications/Adobe Flash CS3/Configuration/External Libraries/FLAir.bundle. 4 Usuń następujący plik: (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\<lang>\Configuration\Players\AdobeAIR1_0.xml (Mac) HD:/Applications/Adobe Flash CS3/Configuration/Players/ AdobeAIR1_0.xml 5 Przejdź do następującej lokalizacji: (Windows) HD:\Document and Settings\<username>\Local Settings\Application Data\Adobe\Flash CS3\<lang>\Configuration\Commands\ (Mac) HD:/Users/<username>/Library/Application Support/Adobe/Flash CS3/<lang>/Configuration/Commands/ a następnie usuń następujące pliki/foldery: • Folder AIR • AIR - Application and Installer Settings.jsfl • AIR - Create AIR File.jsfl Uwaga: Jeśli w systemie Windows określona lokalizacja nie jest widoczna, należy zaznaczyć pole „Pokaż ukryte pliki i foldery” w opcjach folderów. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 6 Konfigurowanie programu Flash CS3 dla Adobe AIR Dodatki AIR do Flash CS3 Po zainstalowaniu aktualizacji środowiska Adobe AIR widoczne będą następujące zmiany w programie Flash: • W oknie dialogowym Ustawienia publikowania (Plik -> Ustawienia publikowania), na karcie Flash, widoczna będzie nowa pozycja w menu Wersja — pozycja Adobe AIR 1.0 • Ekran powitalny aktualizacji, który zawiera pozycję dla tworzenia pliku — Plik Flash (Adobe AIR) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\StartPage (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\StartPage\resources Uwaga: jeśli w systemie MacIntosh nie będzie widoczna pozycja Plik Flash (Adobe AIR) na ekranie powitalnym, należy usunąć poniższy folder i ponownie uruchomić program Flash: HD:/Users/<username>/Libraries/Application Support/Adobe/Flash CS3/<language>/Configuration/StartPage • Nowy plik playerglobal.swc, który zawiera wszystkie interfejsy API języka ActionScript 3.0 oraz interfejsy API Adobe AIR w folderze ActionScript 3.0/Classes (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\ActionScript 3.0 Classes (Mac) HD:/Applications/Adobe Flash CS3/Configuration/ActionScript 3.0/Classes/ • Nowe pliki jsfl (AIR - Application and Installer Settings.jsfl, AIR - Publish AIR File.jsfl) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\Commands (Mac) HD:/Applications/Adobe Flash CS3/First Run/Commands/ • Pakiet Adobe AIR Software Development Kit (AIK) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\AIK • Biblioteka zewnętrzna (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\External Libraries (Mac) HD:/Applications/Adobe Flash CS3/Configuration/External Libraries/ • Docelowy plik konfiguracji (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\Players\ (Mac) HD:/Applications/Adobe Flash CS3/Configuration/Players 7 Rozdział 3: Wprowadzenie do środowiska Adobe AIR Adobe® AIR™ jest środowiskiem wykonawczym dla różnych systemów operacyjnych, które umożliwia użytkownikowi wykorzystanie umiejętności projektowania stron WWW (np. znajomość programów i języków Adobe® Flash® CS3 Professional, Adobe® Flash® CS4 Professional, Adobe® Flex™, Adobe® ActionScript® 3.0, HTML, JavaScript®, Ajax) w celu tworzenia i projektowania aplikacji typu RIA (Rich Internet Applications) dla komputerów stacjonarnych. Więcej informacji na temat rozpoczynania pracy ze środowiskiem Adobe AIR można znaleźć w serwisie Adobe AIR Developer Connection (http://www.adobe.com/devnet/air/). Środowisko AIR umożliwia programiście pracę w znanym mu otoczeniu i za pomocą znanych narzędzi oraz strategii, a jednocześnie pozwala wykorzystać technologie Flash, Flex, HTML, JavaScript i Ajax do tworzenia oprogramowania spełniającego oczekiwania użytkowników. Aplikacje można na przykład tworzyć przy użyciu następujących kombinacji technologii: • Flash / Flex / ActionScript • HTML / JavaScript / CSS / Ajax • W każdej aplikacji można korzystać z formatu PDF. W rezultacie możliwe jest tworzenie następujących aplikacji AIR: • Opartych na technologii Flash lub Flex: takich, których treść główna to kod w formacie Flash/Flex (SWF). • Opartych na technologii Flash lub Flex oraz dodatkowo formacie HTML lub PDF. Aplikacji, których treść główna to kod w formacie Flash/Flex (SWF) zawierający treść w formacie HTML (HTML, JS, CSS) lub PDF. • Opartych na formacie HTML. Aplikacji, których treść główna jest zapisana w formacie HTML, JS, CSS. • Opartych na formacie HTML oraz dodatkowo zawierające kod Flash/Flex lub dane PDF. Aplikacji, których treść główna jest zapisana w formacie HTML i zawiera kod w Flash/Flex (SWF) lub dane PDF. Użytkownik korzysta z aplikacji AIR w taki sam sposób, jak z rodzimych aplikacjami lokalnymi. Środowisko wykonawcze jest instalowane jednokrotnie na komputerze użytkownika. Następnie możliwe jest instalowanie aplikacji AIR w taki sam sposób, jak innych aplikacji lokalnych. Środowisko wykonawcze udostępnia spójną platformę i architekturę niezależną od systemu operacyjnego. Można w nim instalować aplikacje, eliminując konieczność testowania ich w różnych przeglądarkach w celu zapewnienia spójnego działania i interakcji w różnych środowiskach lokalnych. Zamiast opracowywać aplikację z myślą o konkretnym systemie operacyjnym, programista tworzy aplikację dla środowiska wykonawczego. Taka strategia ma szereg zalet: • Aplikacje opracowane dla środowiska AIR działają w wielu różnych systemach operacyjnych, bez dodatkowego nakładu pracy ze strony programisty. Środowisko wykonawcze zapewnia spójną i przewidywalną formę prezentacji oraz interakcji we wszystkich obsługiwanych systemach operacyjnych. • Aplikacje można tworzyć szybciej, wykorzystując istniejące technologie sieci Web i wzorce projektowe. Ponadto opracowane wcześniej aplikacje internetowe można przenieść do środowiska lokalnego bez konieczności poznawania tradycyjnych technologii programistycznych i skomplikowanych zasad pisania kodu rodzimego. • Tworzenie aplikacji jest prostsze niż w językach niższego poziomu, takich jak C i C++. Jeśli nie jest konieczne używanie złożonych, niskopoziomowych wywołań API specyficznych dla systemu operacyjnego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 8 Wprowadzenie do środowiska Adobe AIR Podczas opracowywania aplikacji dla środowiska AIR można korzystać z bogatej gamy architektur i interfejsów API: • interfejsów API specyficznych dla środowiska AIR, udostępnianych przez to środowisko i jego architekturę; • interfejsów API języka ActionScript, używanych w plikach SWF oraz architekturze Flex (oraz innych bibliotekach i architekturach opartych na języku ActionScript); • HTML, CSS i JavaScript; • większości architektur Ajax. Środowisko AIR radykalnie zmienia sposób tworzenia, wdrażania i użytkowania aplikacji. Aby uzyskać większą swobodę twórczą, programista może przenieść swoje aplikacje oparte na technologiach Flash, Flex, HTML i Ajax do środowiska lokalnego, bez konieczności poznawania tradycyjnych technologii programistycznych. Co nowego w środowisku AIR 1.1 Środowisko Adobe AIR 1.1 wprowadza nowe możliwości: • Instalacja i inne okna dialogowe środowiska wykonawczego zostały przetłumaczone na następujące języki: • portugalski (Brazylia) • chiński (tradycyjny i uproszczony) • francuski • niemiecki • włoski • japoński • koreański • rosyjski • francuski • hiszpański • Obsługa tworzenia międzynarodowych aplikacji, w tym wprowadzanie danych z klawiatury dla języków z kodowaniem dwubajtowym. Więcej infromacji zawiera sekcja „Lokalizowanie aplikacji AIR” na stronie 346. • Obsługa lokalizowania atrybutów nazw i opisów w pliku deskryptora aplikacji. • Obsługa lokalizowania komunikatów o błędach, np. SQLError.detailID i SQLError.detailArguments w bazie danych SQLite. • Dodatek dla właściwość Capabilities.languages, który służy do pobierania tablicy preferowanych języków interfejsu użytkownika, które są ustawione w systemie operacyjnym. • Etykiety przycisków HTML oraz domyślne menu takie, jak menu kontekstowe i pasek menu systemu Mac zostały zlokalizowane dla wszystkich obsługiwanych języków. • Obsługa migracji certyfikatów z aplikacji z certyfikatem samopodpisanym do aplikacji, która łączy się z ośrodkiem certyfikacji. • Obsługa systemu Microsoft Windows XP Tablet PC Edition oraz 64-bitowych edycji systemów Windows Vista® w wersji Home Premium, Business, Ultimate lub Enterprise. • Dodatek dla interfejsu API File.spaceAvailable, który służy do uzyskiwania informacji o ilości dostępnego miejsca na dysku. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 9 Wprowadzenie do środowiska Adobe AIR • Dodatkową właściwość NativeWindow.supportsTransparency, która służy do określania, czy okno może być rysowane przez bieżący system operacyjny jako przezroczyste. Więcej informacji na temat środowiska AIR 1.1 znajduje się na stronie Uwagi do wydania środowiska Adobe AIR 1.1 (http://www.adobe.com/go/learn_air_relnotes_pl). Co nowego w środowisku AIR 1.5 Środowisko Adobe AIR 1.5 wprowadza nowe funkcje: • Wsparcie dla następujących funkcji programu Flash Player 10. • Niestandardowe filtry i efekty • Udoskonalone interfejsy API do rysowania • Dynamiczne generowanie dźwięku • Typ danych wektorowych • Udoskonalone interfejsy API do wysyłania i pobierania pliku • Protokół RTMFP • Efekty 3D • Zaawansowana obsługa tekstu • Zarządzanie kolorami • Mechanizm tekstowy • Dynamiczne strumieniowanie • Koder-dekoder audio Speex Więcej informacji na temat tych funkcji znajduje się na stronie http://www.adobe.com/products/flashplayer/features/. • Dodatkowe języki obsługiwane w instalatorze aplikacji AIR 1.5 oraz innych oknach dialogowych środowiska wykonawczego to: czeski, holenderski, szwedzki, turecki i polski. • Szyfrowanie bazy danych. Pliki bazy danych mogą być szyfrowane w środowisku AIR 1.5. Cała zwartość bazy danych, w tym metadane, może być szyfrowana, tak aby danych nie można było odczytać poza aplikacją AIR, która ją zaszyfrowała. Ta funkcja umożliwia programistom szyfrowanie, odszyfrowanie i ponowne szyfrowanie plików bazy danych. Więcej informacji zawiera sekcja „Przechowywanie danych zaszyfrowanych” na stronie 217. • Wersja silnika WebKit używana w środowisku Adobe AIR została zaktualizowana i zawiera aktualnie wsparcie dla interpretera JavaScript SquirrelFish. • Nowe interfejsy API do sprawdzania poprawności podpisów XML można stosować do weryfikacji integralności danych lub informacji oraz tożsamości osoby je podpisującej. Więcej informacji zawiera sekcja Weryfikacja podpisów XML. Więcej informacji na temat środowiska AIR 1.5 znajduje się na stronie Uwagi do wydania środowiska Adobe AIR 1.5 (http://www.adobe.com/go/learn_air_relnotes_pl). 10 Rozdział 4: Znajdowanie zasobów dotyczących środowiska AIR Więcej informacji na temat tworzenia aplikacji dla środowiska Adobe® AIR™ można znaleźć w następujących źródłach i zasobach: Źródło Położenie Programowanie w języku ActionScript 3.0 http://www.adobe.com/go/learn_fl_cs4_programmingAS3_pl Skorowidz języka i składników ActionScript 3.0 (obejmuje dokumentację środowiska AIR) http://www.adobe.com/go/learn_flashcs4_langref_pl Podręczniki Szybki start dotyczące środowiska Adobe AIR do programu Flash http://www.adobe.com/go/learn_air_flash_qs_pl Korzystanie z programu Flash http://www.adobe.com/go/learn_fl_cs4_using_pl Korzystanie ze składników języka ActionScript 3.0 http://www.adobe.com/go/learn_fl_cs4_as3components_pl Artykuły, przykłady i prezentacje opracowane przez firmę Adobe i doświadczonych członków społeczności można znaleźć w serwisie Adobe AIR Developer Connection pod adresem http://www.adobe.com/devnet/air/. W tym samym serwisie można pobrać środowisko Adobe AIR i pokrewne oprogramowanie. Sekcja przeznaczona specjalnie dla programistów korzystających z programu Flash znajduje się pod adresem http://www.adobe.com/devnet/air/flash/. Witryna pomocy technicznej firmy Adobe pod adresem http://www.adobe.com/support/ zawiera informacje o rozwiązywaniu problemów z produktami oraz o opcjach bezpłatnej i płatnej pomocy technicznej. Łącze Szkolenia zapewnia dostęp do książek wydawnictwa Adobe Press, rozmaitych materiałów szkoleniowych, programów certyfikacji oprogramowania Adobe i wielu innych zasobów. 11 Rozdział 5: Tworzenie pierwszej aplikacji dla środowiska AIR przy użyciu programu Flash CS3 lub CS4 W niniejszej sekcji przedstawiono krótką, interaktywną prezentację sposobu działania programu Adobe® AIR™ — należy postępować wg instrukcji w niniejszym temacie w celu utworzenia i spakowania prostej aplikacji AIR „Hello World” za pomocą programu Adobe® Flash® CS3 Professional. Należy pobrać i zainstalować aktualizację środowiska Adobe AIR dla programu Flash CS3, oczywiście jeśli wcześniej ta aktualizacja nie została zainstalowana. Więcej informacji o instalowaniu Adobe AIR dla programu Flash CS3 zawiera dokument „Konfigurowanie programu Flash CS3 dla Adobe AIR” na stronie 4. Obsługa środowiska Adobe AIR jest uwzględniona w programie Adobe® Flash® CS4 Professional, dlatego użytkownicy tej wersji nie muszą instalować żadnych składników przed rozpoczęciem pracy. Tworzenie aplikacji Hello World w programie Flash Tworzenie aplikacji Adobe AIR w programie Flash przypomina tworzenie każdego innego pliku FLA. Różnica jest taka, że należy rozpocząć od utworzenia pliku Flash (Adobe AIR) z ekranu powitalnego, a w celu zakończenia należy zdefiniować ustawienia aplikacji i instalatora oraz zainstalować aplikację AIR. Poniższa procedura zawiera wytyczne dotyczące procesu tworzenia prostej aplikacji Hello World w programie Flash CS3 lub Flash CS4. Aby utworzyć aplikację Hello World 1 Uruchom program Flash. 2 Na ekranie powitalnym kliknij przycisk Plik Flash (Adobe AIR), aby utworzyć pusty plik FLA z ustawieniami publikowania Adobe AIR. 3 Kliknij przycisk OK w oknie dialogowym Tworzenie dla AIR w programie Flash CS3. Za pierwszym razem wyświetlanie tego okna dialogowego może potrwać kilka sekund. (To okno dialogowe nie jest wyświetlane w programie Flash CS4). 4 Wybierz narzędzie Tekst w panelu Narzędzia, a następnie utwórz pole tekstu statycznego (domyślnie) w środku stołu montażowego. Rozszerz pole na tyle, aby mogło zawierać od 15 do 20 znaków. 5 Do pola tekstowego wprowadź tekst „Hello World”. 6 Zapisz plik, nadając mu nazwę (na przykład helloAIR). Testowanie aplikacji 1 Naciśnij klawisze Ctrl + Enter lub wybierz opcje Sterowanie ->Testuj film, aby przetestować aplikację w Adobe AIR. 2 Aby użyć funkcji Debuguj film, najpierw należy dodać do aplikacji kod ActionScript. W tym celu można dodać poniższą instrukcję trace: trace("Running AIR application using Debug Movie"); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 12 Tworzenie pierwszej aplikacji dla środowiska AIR przy użyciu programu Flash CS3 lub CS4 3 Naciśnij klawisze Ctrl + Shift + Enter lub wybierz opcje Sterowanie->Debuguj film, aby uruchomić aplikację z opcją Debuguj film. 4 Wybierz opcje Polecenia > Ustawienia aplikacji i instalatora środowiska Adobe AIR, aby otworzyć okno dialogowe AIR - Ustawienia instalatora i aplikacji. W programie Flash CS4 można otworzyć to okno dialogowe, wybierając kolejno opcje Plik > Ustawienia AIR. 5 Podpisz pakiet Adobe AIR certyfikatem elektronicznym z auto-podpisem: a Kliknij przycisk Ustaw… dla obszaru podpisu elektronicznego, aby otworzyć okno dialogowe Podpis elektroniczny. b Kliknij przycisk Utwórz..., aby otworzyć okno dialogowe Utwórz Elektroniczny certyfikat z auto-podpisem. c Wprowadź wartości do pól Wydawca, Jednostka organizacji, Nazwa organizacji, E-mail, Kraj, Hasło i Potwierdź hasło. d Określ typ certyfikatu. Opcja typu certyfikatu określa poziom zabezpieczenia: w przypadku certyfikatu 1024- RSA stosowany jest klucz 1024-bitowy (mniej bezpieczny), a w przypadku certyfikatu 2048-RSA stosowany jest klucz 2048-bitowy (bardziej bezpieczny). e Zapisz informacje w certyfikacie poprzez określenie wartości dla opcji Zapisz jako lub kliknięcie przycisku Przeglądaj... w celu wybrania lokalizacji folderu. (Na przykład: C:/Temp/mycert.pfx). Po zakończeniu kliknij przycisk OK. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 13 Tworzenie pierwszej aplikacji dla środowiska AIR przy użyciu programu Flash CS3 lub CS4 f W programie Flash ponownie zostanie wyświetlone okno dialogowe Podpis elektroniczny. Ścieżka i nazwa pliku certyfikatu samopodpisanego pojawią się w oknie dialogowym Certyfikat. Jeśli się nie pojawią, należy wprowadzić ścieżkę i nazwę pliku lub kliknąć przycisk Przeglądaj w celu zlokalizowania i wybrania pliku. g Do pola Hasło w oknie dialogowym Podpis elektroniczny wprowadź to samo hasło, które zostało wprowadzone w kroku c, a następnie kliknij przycisk OK. Więcej informacji o podpisywaniu aplikacji Adobe AIR zawiera sekcja „Podpisywanie aplikacji” na stronie 22. 6 W celu utworzenia aplikacji i pliku instalatora kliknij przycisk Publikuj plik AIR. Przed utworzeniem pliku AIR należy wykonać operację Testuj film lub Debuguj film, aby utworzyć plik SWF i pliki application.xml. 7 W celu zainstalowania aplikacji kliknij dwukrotnie plik AIR (application.air) w folderze, w którym zapisano aplikację. 8 Kliknij przycisk Instal (Zainstaluj) w oknie dialogowym Application Install (Instalowanie aplikacji). 9 Zapoznaj się z ustawieniami Installation Preferences (Preferencje instalowania) oraz Location (Lokalizacja), a następnie upewnij się, że zaznaczone jest pole wyboru Start application after installation (Uruchom aplikację po zainstalowaniu). Następnie kliknij przycisk Continue (Kontynuuj). 10 Kliknij przycisk Finish (Zakończ), gdy pojawi się komunikat Installation Completed (Instalowanie zakończone). Aplikacja Hello World została przedstawiona na ilustracji: Konwertowanie pliku FLA na aplikację Adobe AIR Istniejący plik FLA można przekonwertować na aplikację AIR. Więcej informacji zawiera sekcja „Definiowanie ustawień publikowania programu Adobe AIR” na stronie 15. Użytkownicy programu Flash CS4 powinni zapoznać się z rozdziałem Publikowanie dla środowiska Adobe AIR w podręczniku Korzystanie z programu Flash. 14 Rozdział 6: Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Aktualizacja środowiska Adobe® AIR™ dla programu Adobe® Flash® CS3 Professional rozszerza środowisko programistyczne i umożliwia tworzenie, debugowanie i pakowanie aplikacji Adobe AIR w programie Flash. Proces tworzenia aplikacji Adobe AIR obejmuje utworzenie pliku FLA Adobe AIR, określenie ustawień publikowania, napisanie kodu aplikacji, a następnie utworzenie plików aplikacji oraz instalatora, który umożliwi zainstalowanie aplikacji. Użytkownicy programu Adobe® Flash® CS4 Professional powinni zapoznać się z rozdziałem Publikowanie w środowisku Adobe AIR w podręczniku Korzystanie z programu Flash; rozdział ten zawiera informacje na temat tworzenia aplikacji dla środowiska AIR. Informacje o interfejsach API środowiska Adobe AIR ActionScript®3.0, z których można korzystać w aplikacji, zawiera Skorowidz języka i składników ActionScript 3.0. Listę interfejsów API Adobe AIR ActionScript zawiera sekcja „Adobe AIR – charakterystyczne funkcje” na stronie 55. Uwaga: W celu korzystania z klas z pakietu air.net należy przeciągnąć składnik ServiceMonitorShim z panelu Składniki do panelu Biblioteka, a następnie dodać poniższą instrukcję import do kodu ActionScript 3.0: import air.net.*; Tworzenie pliku Adobe AIR Dokumenty Plik Flash (Adobe AIR) można tworzyć, korzystając z ekranu powitalnego Flash, lub możliwe jest utworzenie pliku Flash (ActionScript 3.0), a następnie jego przekonwertowanie na plik Adobe AIR za pośrednictwem okna dialogowego Ustawienia publikowania. Pliku Adobe AIR nie można utworzyć za pomocą okna dialogowego Nowy dokument (Plik > Nowy). Informacje na temat konwertowania pliku FLA na plik Adobe AIR zawiera sekcja „Definiowanie ustawień publikowania programu Adobe AIR” na stronie 15. 1 Uruchom program Flash, a jeśli jest już uruchomiony, zamknij otwarte okno, aby powrócić do ekranu powitalnego. Uwaga: Jeśli zablokowano wyświetlanie ekranu powitalnego, można go ponownie wyświetlić wybierając opcje Edycja > Preferencje, a następnie wybierając opcję Ekran powitalny z menu podręcznego Przy uruchomieniu, w kategorii Ogólne. 2 Na ekranie powitalnym, kliknij przycisk Plik Flash (Adobe AIR). Pojawi się komunikat z informacją o sposobie dostępu do ustawień aplikacji Adobe AIR oraz o sposobie dostępu do dokumentacji pomocy. Aby zablokować wyświetlanie tego komunikatu w przyszłości, zaznacz pole wyboru Nie pokazuj ponownie — jednak po zaznaczeniu tego pola nie będzie możliwości ponownego wyświetlenia komunikatu. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 15 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Definiowanie ustawień publikowania programu Adobe AIR Ustawienia publikowania programu Flash służą do sprawdzania i zmiany ustawień dla pliku AIR oraz w celu konwertowania pliku Flash (ActionScript 3.0) na plik Flash (Adobe AIR). Wyświetlanie ustawień publikowania Adobe AIR 1 Na ekranie powitalnym Flash otwórz dokument Plik Flash (Adobe AIR). 2 Wybierz opcje Plik > Ustawienia publikowania, a następnie kliknij kartę Flash, aby wyświetlić ustawienia publikowania Adobe AIR. Po otwarciu dokumentu Adobe AIR w menu Wersja automatycznie zostanie wybrana wersja Adobe AIR 1.0. Jako wersja języka ActionScript automatycznie ustawiana jest wersja ActionScript 3.0. Ustawienie Zabezpieczenie odtwarzania lokalnego jest wyszarzone, ponieważ nie jest istotne dla pliku SWF AIR. Otwarty plik FLA Flash można przekonwertować na plik AIR Flash — w tym celu należy zmienić ustawienia publikowania. Konwertowanie pliku FLA Flash na plik AIR Flash za pomocą okna dialogowego Ustawienia publikowania 1 Wykonaj jedną z następujących czynności: • Otwórz istniejący plik FLA. • W celu utworzenia nowego pliku FLA skorzystaj z ekranu powitalnego lub wybierz opcje Plik > Nowy. 2 Wybierz polecenie Plik > Ustawienia publikowania. 3 Na karcie Flash wybierz w menu podręcznym Wersja pozycję Adobe AIR 1.0. Wybranie wersji ActionScript jest niemożliwe, ponieważ jedyną wersją możliwą dla pliku AIR jest ActionScript 3.0. Pozostałe opcje domyślne są takie same dla pliku FLA oraz dla pliku Adobe AIR. 4 Kliknij przycisk Publikuj, a następnie kliknij przycisk OK, aby zamknąć okno dialogowe Ustawienia publikowania. Po wybraniu narzędzia Zaznaczanie w Inspektorze właściwości pojawi się Adobe AIR 1 jako obiekt docelowy dla programu Player. Uwaga: Po wybraniu profilu Adobe AIR 1.0 program Flash automatycznie doda lokalizację oraz plik playerglobal.swc AIR do zmiennej środowiskowej Classpath. Plik AIR playerglobal.swc umożliwia korzystanie z interfejsów API ActionScript AIR. Jednak w przypadku przełączenia z Adobe AIR 1 na Adobe® Flash® Player 9, program Flash nie przywróci domyślnego profilu i nie zmieni ustawienia Classpath w celu korzystania z pliku playerglobal.swc dla wersji Flash Player 9. Jeśli ustawienia publikowania zostaną zmienione z Adobe AIR 1 na Flash Player 9, należy zmienić profil publikowania na Domyślny. Dodatkowe informacje na temat okna dialogowego Ustawienia publikowania zawiera sekcja Using Flash na stronie www.adobe.com/go/learn_fl_using_pl. Konwertowanie pliku FLA Flash na plik aplikacji Flash AIR za pomocą menu Polecenia 1 Otwórz plik FLA Flash. 2 Jeśli otwierasz nowy plik Flash (ActionScript 3.0), zapisz go. Jeśli plik nie zostanie zapisany, w następnym kroku pojawi się ostrzeżenie. 3 Wybierz opcje Polecenia > AIR - Ustawienia instalatora i aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 16 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Pojawi się komunikat z zapytaniem o to, czy wymagane jest przekonwertowanie pliku na ustawienia publikowania Adobe AIR. 4 Kliknij przycisk OK, aby przekonwertować plik FLA na ustawienia publikowania Adobe AIR. Zostanie wyświetlone okno dialogowe AIR - Ustawienia instalatora i aplikacji. Informacje na temat okna dialogowego AIR - Ustawienia instalatora i aplikacji zawiera sekcja „Tworzenie plików aplikacji AIR i plików instalatora” na stronie 17. Dla pliku FLA AIR po przekonwertowaniu można stosować polecenia Testuj film, Debuguj film oraz Utwórz plik AIR. Wyświetlanie podglądu aplikacji Adobe AIR Istnieje możliwość wyświetlenia podglądu pliku SWF Flash AIR i wyświetlenia go w postaci, w jakiej będzie widoczny w oknie aplikacji AIR. Wyświetlanie podglądu jest użyteczne, gdy wymagane jest przejrzenie widocznych elementów aplikacji bez pakowania i instalowania aplikacji. 1 Należy się upewnić, że określono ustawienia publikowania dla aplikacji Adobe AIR. Więcej informacji zawiera sekcja „Definiowanie ustawień publikowania programu Adobe AIR” na stronie 15. 2 Wybierz opcje Sterowanie > Testuj film lub naciśnij klawisze Control+Enter. Jeśli ustawienia aplikacji nie zostały określone w oknie dialogowym AIR - Ustawienia instalatora i aplikacji, program Flash wygeneruje domyślny plik deskryptora aplikacji (swfname-app.xml) w tym samym folderze, w którym zapisano plik SWF. Jeśli w oknie dialogowym AIR - Ustawienia instalatora i aplikacji zdefiniowano ustawienia aplikacji, plik deskryptora aplikacji będzie odzwierciedlał te ustawienia. Debugowanie aplikacji Adobe AIR Plik SWF Adobe AIR może zostać zdebugowany, podobnie jak plik SWF Flash Player 9 ActionScript 3.0, ale nie jest możliwe debugowanie zdalne. 1 Upewnij się, że wybrane zostały ustawienia publikowania Adobe AIR. 2 Dodaj kod ActionScript do panelu Operacje (Okno > Operacje). W celu testowania można po prostu dodać instrukcję trace(), jak poniżej dla panelu Operacje, do pierwszej klatki na osi czasu: trace("My application is running"); 3 Wybierz opcje Debuguj > Debuguj film lub naciśnij klawisze Control+Shift+Enter. Program Flash uruchomi debuger ActionScript i wyeksportuje plik SWF z informacjami o debugowaniu. Jeśli ustawienia aplikacji nie zostały określone w oknie dialogowym AIR - Ustawienia instalatora i aplikacji, program Flash wygeneruje domyślny plik deskryptora aplikacji (swfname-app.xml) w tym samym folderze, w którym zapisano plik SWF. Jeśli w oknie dialogowym AIR - Ustawienia instalatora i aplikacji zdefiniowano ustawienia aplikacji, plik deskryptora aplikacji będzie odzwierciedlał te ustawienia. Po wybraniu opcji Debuguj > Debuguj film lub naciśnięciu klawiszy Control+Shift+Enter w celu debugowania aplikacji program Flash wyświetli alert, jeśli aplikacja nie zawiera żadnego kodu ActionScript. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 17 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Tworzenie plików aplikacji AIR i plików instalatora Po ukończeniu aplikacji należy utworzyć pliki aplikacji AIR oraz pliki instalatora w celu zainstalowania aplikacji. Środowisko Adobe AIR doda dwa nowe polecenia menu do menu Polecenia Flash: polecenie AIR - Ustawienia instalatora i aplikacji oraz polecenie AIR- Utwórz plik AIR. Po utworzeniu aplikacji AIR i określeniu ustawień instalatora można użyć opcji AIR- Utwórz plik AIR w celu ponownego utworzenia pliku AIR (.air) z istniejącymi ustawieniami. Tworzenie plików aplikacji Adobe AIR i plików instalatora 1 W programie Flash otwórz stronę lub zbiór stron, które tworzą aplikację Adobe AIR. 2 Zapisz plik FLA Adobe AIR przed otwarciem okna dialogowego AIR - Ustawienia instalatora i aplikacji. 3 Wybierz opcje Polecenia > AIR - Ustawienia instalatora i aplikacji. 4 Wybierz opcje w oknie dialogowym AIR - Ustawienia instalatora i aplikacji, a następnie kliknij przycisk Publikuj plik AIR. Po kliknięciu przycisku Publikuj plik AIR zostanie utworzony pakiet zawierający następujące pliki: plik FLA, plik SWF, plik deskryptora aplikacji, pliki ikon aplikacji, a także pliki zawarte w polu tekstowym Dołączone pliki. Jeśli nie utworzono jeszcze certyfikatu elektronicznego, po kliknięciu przycisku Publikuj plik AIR program Flash wyświetli okno dialogowe Podpis elektroniczny. Okno dialogowe AIR - Ustawienia instalatora i aplikacji jest podzielone na dwie sekcje: Ustawienia aplikacji i Ustawienia instalatora. Więcej informacji o tych ustawieniach zawierają poniższe sekcje. Ustawienia aplikacji Sekcja Ustawienia aplikacji w oknie AIR - Ustawienia instalatora i aplikacji zawiera następujące opcje: Nazwa pliku Nazwa głównego pliku aplikacji. Domyślnie jest to nazwa pliku SWF. Nazwa Nazwa używana przez instalator w celu wygenerowania nazwy pliku aplikacji oraz folderu aplikacji. Nazwa musi zawierać jeden poprawny znak dla nazw plików lub nazw folderów. Domyślnie jest to nazwa pliku SWF. Wersja Opcjonalnie. Określa numer wersji aplikacji. Domyślnie: puste. ID Zawiera unikalny identyfikator aplikacji. W razie potrzeby unikalny identyfikator można zmienić. Identyfikator nie powinien zawierać spacji ani znaków specjalnych. Jedynymi poprawnymi znakami są: 0-9, a-z, A-Z, . (kropka) i (kreska) — długość od 1 do 212 znaków. Domyślnie: com.adobe.example.application_name. Opis Opcjonalnie. Umożliwia wprowadzenie opisu aplikacji, jaki zostanie wyświetlony, gdy użytkownik zainstaluje aplikację. Domyślnie: puste. Prawa autorskie Opcjonalnie. Umożliwia wprowadzenie informacji o prawach autorskich, jakie pojawią się, gdy użytkownik zainstaluje aplikację. Styl okna Określa styl (lub karnację) okna interfejsu użytkownika, gdy użytkownik uruchomi aplikację na komputerze. Możliwe jest wybranie karnacji Chrom systemowy — jest to styl systemu operacyjnego. Możliwe jest również wybranie opcji: Chrom własny (nieprzezroczysty) lub Chrom własny (przezroczysty). W celu wyświetlenia aplikacji bez karnacji systemu, wybierz opcję Brak. W przypadku karnacji systemowej aplikacja jest otoczona opcjami sterowania standardowymi dla systemu operacyjnego. Wybranie opcji Chrom własny (nieprzezroczysty) następuje usunięcie karnacji systemowej, co umożliwia utworzenie karnacji dla własnej aplikacji. (Niestandardową karnację należy utworzyć bezpośrednio w pliku FLA). Opcja Chrom własny (przezroczysty) jest podobna do karnacji nieprzezroczystej, ale dodaje przezroczyste elementy do krawędzi strony. Dzięki temu możliwe jest tworzenie okien aplikacji, które nie są kwadratowe ani prostokątne. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 18 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Ikona Opcjonalnie. Umożliwia określenie ikony dla aplikacji. Ikona pojawia się po zainstalowaniu aplikacji i uruchomieniu jej w środowisku Adobe AIR. Możliwe jest określenie czterech różnych rozmiarów dla ikon (128, 48, 32 i 16 pikseli), dzięki czemu możliwe jest wyświetlenie czterech różnych widoków, w których ikona będzie się pojawiać. Na przykład: ikona może się pojawić w przeglądarce plików w widoku miniaturki, widoku szczegółowym lub widoku mozaiki. Może być również widoczna jako ikona na pulpicie oraz w tytule, w oknie aplikacji AIR, a także w innych miejscach. Jeśli nie określono innych plików ikon, domyślnie obraz ikony jest przykładową ikoną aplikacji AIR. W celu określenia ikony kliknij przycisk Wybierz ikony w oknie dialogowym AIR - Ustawienia instalatora i aplikacji. W oknie dialogowym obrazów ikon, które się pojawi, kliknij folder dla każdego rozmiaru ikony, a następnie wybierz plik ikony do użycia. Pliki muszą być w formacie PNG (Portable Network Graphics). Poniższa ilustracja przedstawia okno dialogowe Ikony z domyślnymi ikonami aplikacji Adobe AIR. Określanie różnych rozmiarów obrazów dla ikony aplikacji Wybrany obraz musi mieć określony rozmiar (128x128, 48x48, 32x32 lub 16x16). Jeśli dla określonej ikony obraz nie zostanie określony, program Adobe AIR zmieni skalę dostępnych obrazów celu utworzenia brakującego obrazu ikony. Ustawienia zaawansowane Przycisk Ustawienia w oknie dialogowym AIR - Ustawienia instalatora i aplikacji umożliwia określenie zaawansowanych ustawień dla pliku deskryptora aplikacji. Po kliknięciu przycisku Ustawienia pojawia się okno dialogowe Ustawienia zaawansowane. Okno dialogowe Ustawienia zaawansowane umożliwia określenie dowolnego skojarzonego typu plików, który powinien być obsługiwany przez aplikację. Na przykład: jeśli wymagane jest, aby aplikacja była główną aplikacją dla obsługi plików HTML, należy określić to ustawienie w polu tekstowym Powiązane typy plików. Możliwe jest również określenie ustawień dla następujących aspektów aplikacji: • Wielkość i położenie okna początkowego TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 19 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional • Folder, do którego aplikacja zostanie zainstalowana • Folder menu Program, w którym aplikacja zostanie umieszczona. Okno dialogowe zawiera następujące opcje: Powiązane typy plików Umożliwia określenie powiązanych typów plików, które będą obsługiwane przez aplikację AIR. Kliknij przycisk Plus (+), aby dodać nowy typ pliku do pola tekstowego. Kliknięcie przycisku Plus powoduje wyświetlenie okna dialogowego Ustawienia typu pliku. Kliknięcie przycisku Minus (-) powoduje usunięcie pozycji, która została zaznaczona w polu tekstowym. Kliknięcie przycisku Ołówek powoduje wyświetlenie okna dialogowego Ustawienia typu pliku oraz umożliwia edytowanie pozycji wybranej w polu tekstowym. Domyślnie przyciski Minus () i Ołówek są nieaktywne. Wybranie pozycji w polu tekstowym powoduje aktywację przycisków Minus (-) oraz Ołówek, co umożliwia usunięcie lub edycję pozycji. Domyślną wartością w polu tekstowym jest Brak. Więcej informacji na temat skojarzonych typów plików zawiera sekcja „Ustawienia typu pliku” na stronie 20. Wstępne ustawienia okna Umożliwia określenie ustawień wielkości i położenia dla początkowego okna aplikacji. • Szerokość: określa początkową szerokość okna w pikselach. Domyślnie wartość nie jest określona. • Wysokość określa początkową szerokość okna w pikselach. Domyślnie wartość nie jest określona. • X: określa początkową pozycję w poziomie okna w pikselach. Domyślnie wartość nie jest określona. • Y: określa początkową pozycję w pionie okna w pikselach. Domyślnie wartość nie jest określona. • Maksymalna szerokość i Maksymalna wysokość: określają maksymalną wielkość okna w pikselach. Domyślnie te wartości nie są określone. • Minimalna szerokość i Minimalna wysokość: określają minimalną wielkość okna w pikselach. Domyślnie te wartości nie są określone. • Podlegający powiększaniu: umożliwia określenie, czy użytkownik może zmaksymalizować okno. Domyślnie ta opcja jest wybrana (true). • Podlegający zmniejszaniu: umożliwia określenie, czy użytkownik może zminimalizować okno. Domyślnie ta opcja jest wybrana (true). • Podlegający zmianie wielkości: umożliwia określenie, czy użytkownik może zmienić wielkość okna. Jeśli ta opcja nie została zaznaczona, wówczas opcje Maksymalna szerokość, Maksymalna wysokość, Minimalna szerokość i Minimalna wysokość są nieaktywne. Domyślnie ta opcja jest wybrana (true). • Widoczny: umożliwia określenie, czy na początku okno aplikacje jest widoczne. Domyślnie ta opcja jest wybrana (true). Inne ustawienia Umożliwia określenie dodatkowych ustawień po zakończeniu instalacji: • Miejsce instalacji: określa folder, w którym aplikacja jest zainstalowana. • Folder menu programu: określa nazwę folderu menu programu dla aplikacji. • Niestandardowy UI aktualizacji: określa operacje, jakie zostaną wykonane, gdy użytkownik otworzy plik AIR dla aplikacji, która jest już zainstalowana. Domyślnie w środowisku AIR wyświetlane jest okno dialogowe, które umożliwia użytkownikowi zaktualizowanie zainstalowanej wersji za pomocą wersji z pliku AIR. Tę opcję należy zaznaczyć, jeśli konieczne jest, aby aplikacja miała pełną kontrolę nad jej aktualizacjami (wówczas użytkownik nie podejmuje decyzji). Wybranie tej opcji powoduje zastąpienie domyślnego działania i zapewnia aplikacji kontrolę nad jej aktualizacjami. Informacje na temat programowego aktualizowania aplikacji AIR zawiera sekcja „Aktualizowanie aplikacji AIR” na stronie 331. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 20 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Ustawienia typu pliku Program Flash wyświetla okno dialogowe Ustawienia typu pliku po kliknięciu przycisku Plus (+) lub przycisku Ołówek w oknie dialogowym Ustawienia zaawansowane w celu dodania lub edycji skojarzonych typów plików dla aplikacji. W tym oknie dialogowym są tylko dwa pola wymagane: Nazwa i Rozszerzenie. W przypadku kliknięcia przycisku OK, gdy jedno z tych pól jest puste, program Flash wyświetla okno dialogowe błędu. Możliwe jest określenie następujących ustawień dla skojarzonego typu pliku: Nazwa Nazwa typu pliku (na przykład: Hypertext Markup Language, Text File lub Example). Rozszerzenie Rozszerzenie nazwy (na przykład: html, txt lub xmpl) maksymalnie do 39 podstawowych znaków alfanumerycznych, (A-Za-z0-9) i bez kropki poprzedzającej. Opis Opcjonalnie. Opis typu pliku (na przykład: Adobe Video File). Typ zawartości Opcjonalnie. Określa typ MIME dla pliku. Ustawienia ikony typu pliku Opcjonalnie. Umożliwia określenie ikony powiązanej z typem pliku. Możliwe jest określenie czterech różnych rozmiarów dla ikon (128x128, 48x48, 32x32 oraz 16x16 pikseli), dzięki czemu możliwe jest wyświetlenie czterech różnych widoków, w których ikona będzie się pojawiać. Na przykład: ikona może się pojawić w przeglądarce plików w widoku miniaturki, widoku szczegółowym lub widoku mozaiki. Jeśli obraz zostanie określony, powinien być zgodny z określonym rozmiarem. Jeśli nie zostanie określony plik dla konkretnego rozmiaru, w środowisku AIR zostanie użyty obraz o najbliższym rozmiarze. Środowisko zmieni skalę obrazu w celu dopasowania go do odpowiedniego wystąpienia. W celu określenia ikony kliknij folder dla wielkości ikony, a następnie wybierz plik ikony lub wprowadź ścieżkę i nazwę pliku dla pliku ikony do pola tekstowego obok monitu. Plik ikony musi być w formacie PNG. Po utworzeniu nowy plik pojawi się w polu listy Typ pliku w oknie dialogowym Ustawienia zaawansowane. Ustawienia pliku deskryptora aplikacji Ustawienia aplikacji są zapisywane w pliku nazwa_aplikacji-app.xml. Istnieje jednak możliwość wybrania w programie Flash niestandardowego pliku deskryptora aplikacji. Użyj własnego pliku deskryptora aplikacji Umożliwia wybranie niestandardowego pliku deskryptora aplikacji. Po wybraniu opcji Użyj własnego pliku deskryptora aplikacji następuje dezaktywacja sekcji Ustawienia aplikacji w oknie dialogowym. W celu określenia lokalizacji niestandardowego pliku deskryptora aplikacji należy wprowadzić lokalizację do pola tekstowego pod opcją Użyj własnego pliku deskryptora aplikacji lub kliknąć ikonę folderu, a następnie przejść do lokalizacji. Więcej informacji na temat pliku deskryptora aplikacji zawiera sekcja „Tworzenie niestandardowego pliku deskryptora aplikacji” na stronie 21. Ustawienia instalatora Druga sekcja okna dialogowego AIR - Ustawienia instalatora i aplikacji zawiera ustawienia, które dotyczą instalowania aplikacji. Podpis elektroniczny Wszystkie aplikacje Adobe AIR muszą być podpisane — tylko wówczas możliwe jest ich zainstalowanie na innym systemie. Informacje na temat przypisywania podpisu elektronicznego do aplikacji Flash Adobe AIR zawiera sekcja „Podpisywanie aplikacji” na stronie 22. Miejsce docelowe Określa lokalizację zapisu pliku AIR. Lokalizacją domyślną jest lokalizacja, w której zapisano plik FLA. Kliknij ikonę folderu, aby wybrać inną lokalizację. Domyślnie nazwa pakietu zawiera nazwę aplikacji i rozszerzenie .air. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 21 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional Dołączone pliki/foldery Określa dodatkowe pliki i foldery, jakie zostały dołączone do aplikacji. Kliknij przycisk Plus (+), aby dodać pliki oraz przycisk folderu, aby dodać foldery. W celu usunięcia pliku lub folderu z listy należy wybrać plik lub folder, a następnie kliknąć przycisk Minus (-). Domyślnie plik deskryptora aplikacji oraz główny plik SWF zostaną automatycznie dodane do listy pakietu. Lista pakietu będzie zawierała te pliki, nawet jeśli nie opublikowano jeszcze pliku FLA Adobe AIR. Lista pakietu prezentuje pliki i foldery w postaci struktury płaskiej. Pliki w folderze nie są wyświetlone, a pełne ścieżki do plików są w razie potrzeby obcinane. Lista nie zawiera plików ikon. Gdy program Flash pakuje pliki, kopiuje pliki ikon do folderu tymczasowego, który jest względny wobec lokalizacji pliku SWF. Program Flash usuwa folder po zakończeniu pakowania. Niepowodzenie utworzenia plików aplikacji i plików instalatora W następujących sytuacjach utworzenie plików aplikacji i instalatora może się nie powieść: • Ciąg znaków identyfikatora aplikacji ma niepoprawną długość lub zawiera niepoprawne znaki. Ciąg znaków identyfikatora aplikacji zawiera znaki w liczbie spoza zakresu od 1 do 212 lub zawiera znaki inne niż następujące: 0-9, a-z, A-Z, . (kropka), - (kreska). • Pliki z listy instalatora nie istnieją. • Wielkości plików niestandardowych ikon są niepoprawne. • Brak uprawnień do zapisu w folderze docelowym AIR. • Aplikacja nie została podpisana lub nie określono, że jest to aplikacja Adobe AIRI, która zostanie podpisana później. Tworzenie niestandardowego pliku deskryptora aplikacji Plik deskryptora aplikacji to plik w formacie XML, który może być edytowany za pomocą edytora tekstu. W celu utworzenia niestandardowego pliku deskryptora aplikacji należy przeprowadzić edycję wartości w celu określenia żądanych wartości. Wartości domyślne przedstawiono poniżej: • 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 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 22 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional • icon • image128x128 = icons/AIRApp_128.png • image48x48 = icons/AIRApp_48.png • image32x32 = icons/AIRApp_32.png • image16x16 = icons/AIRApp_16.png • customUpdateUI = false • allowBrowserInvocation = false Więcej informacji na temat pliku deskryptora aplikacji zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45. Podpisywanie aplikacji Wszystkie aplikacje Adobe AIR muszą być podpisane — tylko wówczas możliwe jest ich zainstalowanie na innym systemie. Program Flash umożliwia jednak tworzenie niepodpisanych plików instalatora Adobe AIR, dzięki czemu aplikacja może zostać podpisana później. Niepodpisane pliki instalatora Adobe AIR są nazywane pakietem AIRI. Jest to szczególnie użyteczne w przypadkach, w których certyfikat znajduje się na innym komputerze lub podpisywanie było obsługiwane osobno, oprócz instalowania aplikacji. Podpisywanie aplikacji Adobe AIR za pomocą zakupionego wcześniej certyfikatu elektronicznego od głównego wystawcy certyfikatów 1 Kliknij przycisk Ustaw w obszarze Podpis elektroniczny, w oknie dialogowym AIR - Ustawienia instalatora i aplikacji. Zostanie wyświetlone okno dialogowe Podpis elektroniczny. To okno dialogowe zawiera dwa przyciski opcji, które umożliwiają podpisanie aplikacji Adobe AIR za pomocą certyfikatu elektronicznego lub przygotuj pakiet AIRI. W celu podpisania aplikacji AIR można użyć certyfikatu elektronicznego wydanego przez głównego wystawcę certyfikatów lub można utworzyć certyfikat z autopodpisem. Certyfikat z autopodpisem można łatwo utworzyć, ale nie można mu ufać w tym samym stopniu, co certyfikatowi nadanemu przez głównego wystawcę certyfikatu. Okno dialogowe Podpis cyfrowy przeznaczone do podpisywania aplikacji AIR 2 Wybierz plik certyfikatu z menu podręcznego lub kliknij przycisk Przeglądaj, aby zlokalizować plik certyfikatu. 3 Wybierz certyfikat. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 23 Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional 4 Wprowadź hasło. 5 Kliknij przycisk OK. Więcej informacji na temat podpisywaniu aplikacji AIR zawiera sekcja „Elektroniczne podpisywanie pliku AIR” na stronie 323. Tworzenie certyfikatu elektronicznego z autopodpisem 1 Kliknij na przycisk Utwórz Nowy. Zostanie wyświetlone okno dialogowe certyfikatu elektronicznego z autopodpisem. 2 Wprowadź wartości do pól Wydawca, Jednostka organizacji, Nazwa organizacji, Kraj, Hasło i Potwierdź hasło. 3 Określ typ certyfikatu. Opcja Typ dotyczy poziomu zabezpieczenia certyfikatu: w przypadku certyfikatu 1024-RSA stosowany jest klucz 1024-bitowy (mniej bezpieczny), a w przypadku certyfikatu 2048-RSA stosowany jest klucz 2048-bitowy (bardziej bezpieczny) 4 Zapisz informacje w certyfikacie poprzez określenie wartości dla opcji Zapisz jako lub kliknięcie przycisku Przeglądaj w celu wybrania lokalizacji folderu. 5 Kliknij przycisk OK. 6 W oknie dialogowym Podpis elektroniczny wprowadź hasło przypisane w drugim kroku tej procedury i kliknij przycisk OK. Po ustawieniu certyfikatu elektronicznego przycisk Ustaw zmienia się na przycisk Zmień. Aby program Flash zapamiętał hasło użyte dla tej sesji, kliknij opcję Zapamiętaj hasło dla tej sesji. Jeśli opcja Znacznik czasowy nie jest zaznaczona, a użytkownik kliknie przycisk OK, pojawi się okno dialogowe z ostrzeżeniem o tym, że aplikacja nie zostanie zainstalowana po utracie ważności certyfikatu elektronicznego. Jeśli w oknie dialogowym zostanie kliknięty przycisk Tak, wówczas znacznik czasowy zostanie wyłączony. W przypadku kliknięcia przycisku Nie opcja Znacznik czasowy zostanie automatycznie zaznaczona, a znacznik czasowy zostanie włączony. Więcej informacji na temat tworzenia certyfikatu elektronicznego z autopodpisem zawiera sekcja „Elektroniczne podpisywanie pliku AIR” na stronie 323. Można również utworzyć aplikację AIR Intermediate (AIRI) bez podpisu elektronicznego. Jednak użytkownik nie będzie mógł zainstalować aplikacji na pulpicie do czasu dodania podpisu elektronicznego. Przygotowanie pakietu AIRI, który zostanie podpisany później ❖ W oknie dialogowy Podpis elektroniczny wybierz opcję Przygotuj plik AIR Intermediate (AIRI), który zostanie podpisany później, a następnie kliknij przycisk OK. Nastąpi zmiana statusu podpisu elektronicznego w celu wskazania, że wybrano utworzenie pakietu AIRI, który zostanie podpisany później. Przycisk Ustaw zmieni się na przycisk Zmień. 24 Rozdział 7: Zabezpieczenia w środowisku AIR W niniejszym rozdziale opisano kwestie związane z bezpieczeństwem, o jakich należy pamiętać podczas tworzenia aplikacji AIR. Podstawowe informacje o zabezpieczeniach w środowisku AIR Aplikacje AIR działają z tymi samymi uprawnieniami użytkownika, co aplikacje rodzime. W ogólnym wypadku te uprawnienia umożliwiają dostęp do funkcji systemu operacyjnego, takich jak odczyt i zapis plików, uruchamianie aplikacji, rysowanie na ekranie, a także komunikację z siecią. Ograniczenia systemu operacyjnego dotyczące aplikacji rodzimych, takie jak uprawnienia dla poszczególnych użytkowników, obowiązują tak samo w aplikacjach AIR. Model zabezpieczeń środowiska Adobe® AIR™ stanowi rozwinięcie modelu zabezpieczeń programu Adobe® Flash® Player, ale mechanizm zabezpieczeń jest inny niż mechanizm stosowany w przeglądarce. Ten mechanizm umożliwia programistom bezpieczne wzbogacanie aplikacji o nowe funkcje, które byłyby nieodpowiednie w aplikacjach działających w przeglądarce. Aplikacje AIR są pisane przy użyciu skompilowanego kodu bajtowego (treść SWF) lub interpretowanego skryptu (JavaScript, HTML). Dzięki takiemu rozwiązaniu pamięcią zarządza środowisko wykonawcze. To zmniejsza prawdopodobieństwo tego, że na aplikacje AIR będą wpływać słabe punkty związane z zarządzaniem pamięcią, np. przepełnienia buforów i uszkodzenia pamięci. Są to najczęstsze ze słabych punktów, jakie wpływają na aplikacje pulpitowe pisane w kodzie rodzimym. Instalowanie i aktualizowanie Aplikacje AIR są dystrybuowane za pośrednictwem plików instalacyjnych AIR, które są zapisywane z rozszerzeniem air. Po zainstalowaniu środowiska Adobe AIR i otwarciu pliku instalacyjnego AIR procesem instalowania zarządza środowisko wykonawcze. Uwaga: Programiści mogą określać wersję, nazwę aplikacji i źródło wydawcy, ale początkowy strumień instalowania nie może być modyfikowany. To ograniczenie jest szczególnie korzystne dla użytkowników, ponieważ aplikacje AIR korzystają z bezpiecznej, uproszczonej i spójnej procedury instalacji zarządzanej przez środowisko wykonawcze. Jeśli konieczne jest dostosowanie aplikacji, jest to możliwe przy jej pierwszym uruchomieniu. Lokalizacja instalacji w środowisku wykonawczym Aplikacje AIR najpierw wymagają zainstalowania środowiska wykonawczego w komputerze użytkownika, tak jak pliki SWF najpierw wymagają zainstalowania wtyczki przeglądarki Flash Player. Środowisko wykonawcze jest instalowane w następującej lokalizacji na komputerze użytkownika: • Mac OS: /Library/Frameworks/ • Windows: C:\Program Files\Common Files\Adobe AIR TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 25 Zabezpieczenia w środowisku AIR • Linux: /opt/Adobe AIR/ W celu zainstalowania zaktualizowanej wersji aplikacji w systemie Mac OS użytkownik musi mieć odpowiednie uprawnienia dostępu do zainstalowania w katalogu aplikacji. W systemach Windows i Linux użytkownik musi mieć uprawnienia administracyjne. Środowisko wykonawcze może być instalowane na dwa sposoby: za pomocą funkcji instalacji bezproblemowej (instalowanie bezpośrednio z przeglądarki internetowej) lub poprzez instalację ręczną. Więcej informacji zawiera sekcja „Dystrybucja, instalowanie i uruchamianie aplikacji AIR” na stronie 314. Instalacja bezproblemowa (środowisko wykonawcze i aplikacja) Funkcja instalacji bezproblemowej umożliwia programistom uproszczenie instalacji dla użytkowników, którzy nie zainstalowali jeszcze środowiska Adobe AIR. W bezproblemowej metodzie instalacji programista tworzy plik SWF, który prezentuje aplikację przeznaczoną do instalacji. Gdy użytkownik kliknie plik SWF w celu zainstalowania aplikacji, plik SWF podejmuje próbę wykrycia środowiska wykonawczego. Jeśli nie można wykryć zainstalowanego środowiska wykonawczego, zostaje ono zainstalowane i aktywowane bezpośrednio przez proces instalacji aplikacji. Instalacja ręczna Użytkownik może również ręcznie pobrać i zainstalować środowisko wykonawcze przed otwarciem pliku AIR. Wówczas programista może dystrybuować plik AIR innymi sposobami (np. poczta e-mail, odsyłacz HTML na stronie internetowej). Po otwarciu pliku AIR środowisko wykonawcze rozpoczyna proces instalowania aplikacji. Więcej informacji na temat tego procesu zawiera sekcja „Dystrybucja, instalowanie i uruchamianie aplikacji AIR” na stronie 314. Strumień instalowania aplikacji Model zabezpieczeń środowiska AIR umożliwia użytkownikom podejmowanie decyzji o tym, czy aplikacja AIR ma zostać zainstalowana. Sposób instalowania aplikacji AIR został udoskonalony (w porównaniu z technologiami instalowania aplikacji rodzimych), dzięki czemu podejmowanie decyzji o instalowaniu jest dla użytkowników łatwiejsze: • Środowisko wykonawcze zapewnia jednakowy przebieg procesu instalowania na wszystkich systemach operacyjnych, nawet gdy aplikacja AIR jest instalowana z odsyłacza w przeglądarce sieci Web. Większość procesów instalowania aplikacji rodzimych jest uzależniona od przeglądarki i innych aplikacji, które udostępniają informacje o zabezpieczeniach (jeśli są one dostępne). • Proces instalowania aplikacji AIR identyfikuje źródło aplikacji oraz informacje dotyczące uprawnień dostępnych dla aplikacji (jeśli użytkownik umożliwia kontynuowanie procesu instalowania). • Środowisko wykonawcze zarządza procesem instalowania aplikacji AIR. Aplikacja AIR nie może zmodyfikować procesu instalowania, z którego korzysta środowisko wykonawcze. Użytkownicy nie powinni instalować żadnych aplikacji pochodzących ze źródeł, którym nie ufają lub których nie można sprawdzić. Konieczność udowodnienia bezpieczeństwa dla aplikacji rodzimych obowiązuje dla aplikacji AIR, jak również innych instalowanych aplikacji. Miejsce docelowe aplikacji Katalog instalacyjny można ustawić za pomocą jednej z dwóch następujących opcji: 1 Użytkownik wybiera miejsce docelowe podczas instalowania. Aplikacja instaluje się w miejscu wskazanym przez użytkownika. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 26 Zabezpieczenia w środowisku AIR 2 Jeśli użytkownik nie zmieni miejsca docelowego instalacji, aplikacja instaluje się w domyślnej ścieżce określonej przez środowisko wykonawcze: • Mac OS: ~/Applications/ • Windows XP i wersje wcześniejsze: C:\Program Files\ • Windows Vista: ~/Apps/ • Linux: /opt/ Jeśli programista zdefiniuje w pliku deskryptora aplikacji ustawienie installFolder, aplikacja zostanie zainstalowana w podfolderze tego katalogu. System plików środowiska AIR Proces instalacji aplikacji AIR kopiuje wszystkie pliki, które programista dołączył do pliku instalatora AIR, na komputer lokalny użytkownika. Zainstalowana aplikacja zawiera: • Windows: katalog zawierający wszystkie pliki dołączone do pliku instalatora AIR. Środowisko wykonawcze tworzy również plik exe podczas instalowania aplikacji AIR. • Linux: katalog zawierający wszystkie pliki dołączone do pliku instalatora AIR. Środowisko wykonawcze tworzy również plik BIN podczas instalowania aplikacji AIR. • Mac OS: plik app, który zawiera wszystkie elementy pliku instalatora AIR. Treść można sprawdzić za pomocą opcji wyświetlania zawartości pakietu w Finderze. Środowisko wykonawcze tworzy plik app jako część procesu instalowania aplikacji AIR. Aplikacja AIR jest uruchamiana poprzez: • Windows: uruchomienie pliku .exe w folderze instalacji lub skrótu, który odpowiada temu plikowi (np. skrót w menu Start albo na pulpicie). • Linux: uruchomienie pliku BIN w folderze instalacji, wybranie aplikacji z menu Applications lub uruchomienie przez alias lub skrót na pulpicie. • Mac OS: uruchomienie pliku .app lub aliasu, który na niego wskazuje. System plików aplikacji zawiera również podkatalogi powiązane z funkcją aplikacji. Na przykład: informacje zapisywane do zaszyfrowanej pamięci lokalnej są zapisywane w podkatalogu lub katalogu o nazwie zgodnej z identyfikatorem aplikacji. Miejsce zapisu aplikacji AIR Aplikacje AIR mają uprawnienia do zapisu w dowolnej lokalizacji na dysku twardym użytkownika; jednak programistów zachęca się do używania ścieżki app-storage:/ w celu lokalnego zapisu elementów związanych z aplikacją. Pliki zapisane w app-storage:/ z aplikacji są umieszczane w standardowej lokalizacji w zależności od systemu operacyjnego: • W systemie Mac OS: katalog zapisu aplikacji to <appData>/<appId>/Local Store/, gdzie <appData> to „folder preferencji” użytkownika, zwykle /Users/<user>/Library/Preferences • W systemie Windows: katalog zapisu aplikacji to <appData>\<appId>\Local Store\ , gdzie <appData> to „folder specjalny” CSIDL_APPDATA, zwykle C:\Documents and Settings\<user>\Application Data • W systemie Linux: <appData>/<appID>/Local Store/, gdzie <appData> to /home/<user>/.appdata TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 27 Zabezpieczenia w środowisku AIR Dostęp do katalogu zapisu aplikacji można uzyskać za pomocą właściwości air.File.applicationStorageDirectory. Dostęp do treści tego katalogu można uzyskać za pomocą metody resolvePath() klasy File. Szczegółowe informacje zawiera sekcja „Praca z systemem plików” na stronie 107. Aktualizowanie środowiska Adobe AIR Gdy użytkownik zainstaluje aplikację AIR, która wymaga zaktualizowanej wersji środowiska wykonawczego, środowisko wykonawcze automatycznie instaluje wymaganą aktualizację. W celu zaktualizowania środowiska wykonawczego użytkownik musi posiadać uprawnienia administracyjne do komputera. Aktualizowanie aplikacji AIR Tworzenie i wdrażanie aktualizacji oprogramowania to jedno z największych zagrożeń dla bezpieczeństwa, z jakimi borykają się twórcy aplikacji w kodzie rodzimym. Interfejs API AIR udostępnia mechanizm, który umożliwia poprawę bezpieczeństwa: metoda Updater.update() może zostać wywołana po uruchomieniu w celu sprawdzania zdalnej lokalizacji pliku AIR. Jeśli aktualizacja jest odpowiednia, plik AIR jest pobierany, instalowany, a następnie restartowana jest aplikacja. Programiści mogą korzystać z tej klasy nie tylko w celu udostępniania nowych funkcji, a także w celu reagowania na słabe punkty zabezpieczeń. Uwaga: Programista może określić wersję aplikacji poprzez ustawienie właściwości version pliku deskryptora aplikacji. Środowisko AIR w żaden sposób nie interpretuje ciągu znaków wersji. Dlatego wersja „3.0” nie jest w żaden sposób traktowana jako bardziej aktualna niż wersja „2.0”. Dlatego programista musi kontrolować wersje. Szczegółowe informacje zawiera sekcja „Definiowanie właściwości w pliku deskryptora aplikacji” na stronie 46. Deinstalacja aplikacji AIR Użytkownik może zdeinstalować aplikację AIR: • W systemie Windows: usuwając aplikację za pomocą panelu Dodaj/Usuń programy. • W systemie Mac OS: usuwając plik app z lokalizacji instalacji. Usunięcie aplikacji AIR powoduje usunięcie wszystkich plików z katalogu instalacji. Jednak nie powoduje to usunięcia plików, które aplikacja zapisała na zewnątrz katalogu aplikacji. Usunięcie aplikacji AIR nie powoduje odwrócenia zmian, jakie aplikacja AIR wykonała na plikach poza katalogiem aplikacji. Deinstalacja środowiska Adobe AIR Środowisko AIR można zdeinstalować: • W systemie Windows: poprzez uruchomienie funkcji Dodaj/Usuń programy z Panelu sterowania, zaznaczenie pola Adobe AIR i wybranie opcji „Usuń”. • W systemie Mac OS: poprzez uruchomienie aplikacji Adobe AIR Uninstaller z katalogu Applications. Ustawienia rejestru Windows dla administratorów W systemie Windows administratorzy mogą skonfigurować komputer w taki sposób, aby umożliwić (lub uniemożliwić) aktualizowanie aplikacji AIR i środowiska wykonawczego AIR. Te ustawienia znajdują się w rejestrze systemu Windows w następującym kluczu: HKLM\Software\Policies\Adobe\AIR. Są to między innymi następujące ustawienia: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 28 Zabezpieczenia w środowisku AIR Ustawienie rejestru Opis AppInstallDisabled Określa, że instalowanie i deinstalowanie aplikacji AIR jest możliwe. Ustawienie 0: „allowed”, ustawienie 1: „disallowed”. UntrustedAppInstallDisabled Określa, że instalacja niezaufanych aplikacji AIR (aplikacje, które nie zawierają certyfikatu zaufanego) jest dozwolona (patrz „Elektroniczne podpisywanie pliku AIR” na stronie 323). Ustawienie 0: „allowed”, ustawienie 1: „disallowed”. UpdateDisabled Określa, że aktualizowanie środowiska wykonawczego jest dozwolone w postaci zadania działającego w tle lub jako część instalacji jawnej. Ustawienie 0: „allowed”, ustawienie 1: „disallowed”. Obszary izolowane Środowisko AIR udostępnia kompletną architekturę zabezpieczeń, która definiuje uprawnienia zgodnie z poszczególnymi plikami w aplikacji AIR — wewnętrznie i zewnętrznie. Uprawnienia są nadawane plikom zgodnie z ich źródłem i pliki są przypisywane do logicznych grup zabezpieczeń, zwanych obszarami izolowanymi. Informacje o obszarach izolowanych aplikacji AIR Model zabezpieczeń środowiska wykonawczego dotyczący obszarów izolowanych obejmuje model zabezpieczeń Flash Player udoskonalony o obszary izolowane aplikacji. Dla plików, które nie znajdują się w obszarze izolowanym aplikacji, obowiązują te same ograniczenia, jaki są określone przez model zabezpieczeń programu Flash Player. Środowisko wykonawcze korzysta z tych bezpiecznych obszarów izolowanych w celu zdefiniowania zakresu danych, do jakich kod może uzyskać dostęp, oraz operacji, jakie mogą być wykonywane. W celu utrzymania bezpieczeństwa lokalnego pliki w poszczególnych obszarach izolowanych są odizolowane od plików w innych obszarach izolowanych. Na przykład: plik SWF załadowany do aplikacji AIR z adresu URL z Internetu zewnętrznego jest umieszczany w zdalnym obszarze izolowanym i domyślnie nie ma uprawnienia do generowania skryptów do plików, które znajdują się w katalogu aplikacji, które są przypisane do tego obszaru izolowanego aplikacji. W poniższej tabeli opisano poszczególne typy obszarów izolowanych: Obszar izolowany Opis application Plik znajduje się w katalogu aplikacji i działa z pełnym zestawem uprawnień AIR. remote Plik pochodzi z internetowego adresu URL i działa zgodnie z domenowymi regułami obszaru izolowanego, które są analogiczne z regułami, jakie mają zastosowanie do plików zdalnych w programie Flash Player. (Istnieją osobne zdalne obszary izolowane dla każdej domeny sieciowej, np. http://www.example.com i https://foo.example.org). local-trusted Plik jest lokalny, a użytkownik określił go jako zaufany przy użyciu menedżera ustawień lub pliku konfiguracyjnego zaufania programu Flash Player. Plik SWF może odczytywać lokalne źródła danych i może komunikować się z Internetem, ale nie ma pełnego zestawu uprawnień AIR. local-with-networking Plik jest lokalnym plikiem SWF opublikowanym jako sieciowy, ale użytkownik nie wyznaczył mu w sposób jawny statusu pliku zaufanego. Plik może komunikować się z Internetem, ale nie może czytać z lokalnych źródeł danych. Ten obszar izolowany jest dostępny wyłącznie dla treści SWF. local-with-filesystem Plik jest lokalnym plikiem skryptowym, który nie został opublikowany jako sieciowy i użytkownik nie wyznaczył mu w sposób jawny statusu pliku zaufanego. Obejmuje pliki JavaScript, które nie są zaufane. Plik może odczytywać lokalne źródła danych, ale nie może komunikować się z Internetem. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 29 Zabezpieczenia w środowisku AIR W niniejszej sekcji omówiono przede wszystkim obszar izolowany aplikacji oraz jego relacje z innymi obszarami izolowanymi w aplikacji AIR. Programiści, którzy korzystają z treści przypisanych do innych obszarów izolowanych, powinni zapoznać się z dodatkową dokumentacją dotyczącą modelu zabezpieczeń programu Flash Player. Więcej informacji zawiera rozdział „Zabezpieczenia programu Flash Player” w dokumentacji Programowanie w języku ActionScript 3.0 (http://www.adobe.com/go/flashcs4_prog_as3_security_pl) oraz artykuł na temat zabezpieczeń w programie Flash Player 9 (http://www.adobe.com/go/fp9_0_security) lub artykuł na temat zabezpieczeń w programie Flash Player 10 (http://www.adobe.com/go/fp10_0_security_pl). Obszar izolowany aplikacji Podczas instalowania aplikacji wszystkie pliki zawarte w pliku instalatora AIR zostają zainstalowane na komputerze użytkownika, w katalogu aplikacji. Programiści mogą odwoływać się do tego katalogu w kodzie za pośrednictwem schematu URL app:/ (patrz „Korzystanie ze schematów URL środowiska AIR w adresach URL” na stronie 308). Wszystkie pliki z drzewa katalogów aplikacji zostają przypisane do obszaru izolowanego aplikacji po uruchomieniu aplikacji. Treść obszaru izolowanego aplikacji ma pełne uprawnienia, jakie posiada aplikacja AIR, łącznie z możliwością oddziaływania z lokalnym systemem plików. Podczas działania wiele aplikacji AIR korzysta tylko z tych lokalnie zainstalowanych plików. Jednak aplikacje AIR nie są ograniczone tylko do plików w katalogu aplikacji — mogą załadować dowolny typ pliku z dowolnego źródła. Łącznie z plikami lokalnymi na komputerze użytkownika, a także plikami z dostępnych źródeł zewnętrznych, np. w lokalnej sieci lub w Internecie. Typy plików nie mają wpływu na zabezpieczenia; załadowane pliki HTML mają te same uprawnienia, co załadowane pliki SWF z tego samego źródła. Treść bezpiecznego obszaru izolowanego aplikacji ma dostęp do interfejsów API AIR, do których nie ma dostępu treść innych obszarów izolowanych. Na przykład: właściwość air.NativeApplication.nativeApplication.applicationDescriptor, która zwraca treść pliku deskryptora aplikacji dla aplikacji, ma dostęp wyłącznie do treści bezpiecznego obszaru izolowanego aplikacji. Innym przykładem interfejsu API o ograniczonych uprawnieniach jest klasa FileStream, która zawiera metody odczytu i zapisu w lokalnym systemie plików. Interfejsy API ActionScript, które są dostępne wyłącznie dla treści bezpiecznego obszaru izolowanego aplikacji, są oznaczone logo AIR w Skorowidzu języka ActionScript 3.0 dla środowiska Adobe AIR. Użycie tych interfejsów API w innych bezpiecznych obszarach izolowanych powoduje wyjątek SecurityError w środowisku wykonawczym. W przypadku treści HTML (w obiekcie HTMLLoader) wszystkie interfejsy API AIR JavaScript (dostępne za pośrednictwem właściwości window.runtime lub obiektu air podczas korzystania z pliku AIRAliases.js) są dostępne dla treści bezpiecznego obszaru izolowanego aplikacji. Treść HTML w innym obszarze izolowanym nie ma dostępu do właściwości window.runtime, dlatego ta treść nie może uzyskać dostępu do interfejsów API AIR. Ograniczenia w językach JavaScript i HTML Dla treści HTML w bezpiecznym obszarze izolowanym aplikacji obowiązują ograniczenia dotyczące korzystania z interfejsów API, które mogą dynamicznie przekształcać ciągi znaków na kod wykonywalny — po załadowaniu kodu. Takie rozwiązanie zapobiega przypadkowemu wstrzyknięciu i wykonaniu kodu ze źródeł nieaplikacyjnych (np. potencjalnie niebezpiecznych domen sieciowych). Przykładem może być użycie funkcji eval(). Szczegółowe informacje zawiera sekcja „Ograniczenia kodu dotyczące treści różnych obszarów izolowanych” na stronie 33. Ograniczenia w znacznikach img w treści pola tekstowego ActionScript Aby zapobiec możliwym próbom oszukańczego pozyskania informacji poufnej, znaczniki img w treści HTML w obiektach TextField ActionScript są ignorowane w treści SWF w bezpiecznym obszarze izolowanym aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 30 Zabezpieczenia w środowisku AIR Ograniczenia dotyczące protokołu asfunction Treść obszaru izolowanego aplikacji nie może korzystać z protokołu asfunction w treści HTML w polach tekstowych języka ActionScript 2.0. Brak dostępu do międzydomenowego buforu trwałego Treść SWF w obszarze izolowanym aplikacji nie może korzystać z buforu międzydomenowego — korzystanie z tego buforu było możliwe od aktualizacji 3. programu Flash Player 9. Takie ustawienie umożliwiało programowi Flash Player trwałe zapisywanie w buforze treści składników platformy Adobe, a także ponowne używanie tej treści w załadowanej treści SWF na żądanie (co eliminuje potrzebę wielokrotnego ładowania treści). Uprawnienia dotyczące treści nieaplikacyjnych obszarów izolowanych Pliki załadowane z lokalizacji sieciowej lub Internetowej są przypisywane do remote (zdalnego) obszaru izolowanego. Pliki załadowane z zewnątrz katalogu aplikacji są przypisane do obszaru izolowanego local-with-filesystem (lokalnego z systemem plików), local-with-networking (lokalnego z obsługą sieci) lub local-trusted (lokalnego zaufanego); to jest uzależnione od sposobu, w jaki plik został utworzony i od tego, czy użytkownik jawnie określił plik jako zaufany za pomocą menedżera ustawień globalnych programu Flash Player. Szczegółowe informacje zawiera strona http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html. Ograniczenia w językach JavaScript i HTML Treść JavaScript — w odróżnieniu od treści bezpiecznego obszaru izolowanego aplikacji — w nieaplikacyjnym obszarze izolowanym może wywoływać funkcję eval() w celu wykonywania kodu wygenerowanego w sposób dynamiczny w dowolnym czasie. Jednak istnieją ograniczenia dotyczące kodu JavaScript w nieaplikacyjnym obszarze izolowanym. Między innymi: • Kod JavaScript w nieaplikacyjnym obszarze izolowanym nie ma dostępu do obiektu window.runtime i dlatego kod nie może uruchamiać interfejsów API AIR. • Domyślnie treść nieaplikacyjnego bezpiecznego obszaru izolowanego nie może wywoływać żądań XMLHttpRequest w celu załadowania danych z domen innych niż domena wywołująca żądanie. Jednak kod aplikacji może nadawać treści nieaplikacyjnej uprawienia do wywoływania tych zadań — w tym celu ustawia atrybut allowCrossdomainXHR w ramce zawierającej lub ramce pływającej. Więcej informacji zawiera sekcja „Treść odwołująca się do skryptów w różnych domenach” na stronie 36. • Istnieją ograniczenia dotyczące wywoływania metody window.open() JavaScript. Szczegółowe informacje zawiera sekcja „Ograniczenia dotyczące wywoływania metody window.open() JavaScript” na stronie 35. Szczegółowe informacje zawiera sekcja „Ograniczenia kodu dotyczące treści różnych obszarów izolowanych” na stronie 33. Ograniczenia dotyczące ładowania elementów CSS, ramek, ramek pływających i img Treść HTML w zdalnych (sieciowych) obszarach izolowanych może ładować tylko treść CSS, treść frame, iframe i img z domen zdalnych (z sieciowych adresów URL). Treść HTML w lokalnym obszarze izolowanym z systemem plików, lokalnym obszarze izolowanym z obsługą sieci lub lokalnym zaufanym obszarze izolowanym może ładować tylko treść CSS, treść frame, iframe i img z lokalnych obszarów izolowanych (nie z aplikacji ani sieciowych adresów URL). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 31 Zabezpieczenia w środowisku AIR Zabezpieczenia HTML Środowisko wykonawcze wymusza reguły i udostępnia mechanizmy przeznaczone dla wzmacniania słabych punktów zabezpieczeń w językach HTML i JavaScript. Te same reguły są wprowadzane niezależnie od tego, czy aplikacja jest napisana w kodzie JavaScript lub czy treść HTML i JavaScript została załadowana do aplikacji SWF. Treść w obszarze izolowanym aplikacji i nieaplikacyjnym bezpiecznym obszarze izolowanym (patrz „Obszary izolowane” na stronie 28) ma różne uprawnienia. Podczas ładowania treści do ramki lub ramki pływającej środowisko wykonawcze udostępnia most obszaru izolowanego, dzięki któremu treść ramki lub ramki pływającej może się bezpiecznie komunikować z treścią obszaru izolowanego aplikacji. W niniejszym temacie opisano architekturę zabezpieczeń HTML AIR oraz sposób korzystania z ramek, ramek pływających i mostów obszarów izolowanych w celu konfigurowania aplikacji. Więcej informacji zawiera sekcja „Unikanie błędów JavaScript związanych z bezpieczeństwem” na stronie 237. Przegląd konfigurowania aplikacji opartej na formacie HTML Ramki i ramki pływające stanowią wygodny sposób organizowania treści HTML w AIR. Ramki umożliwiają zachowanie spójności danych i bezpieczną pracę z treścią zdalną. HTML w aplikacji AIR zachowuje normalną nawigację opartą na stronach, dlatego środowisko HTML zostaje całkowicie odświeżone, jeśli z górnej ramki treści HTML nastąpi przejście do innej strony. Ramki i ramki pływające mogą być używane do zachowywania spójności danych w AIR, podobnie jak w aplikacji sieci Web działającej w przeglądarce. Główne obiekty aplikacji należy zdefiniować w najwyższej ramce — te obiekty pozostaną niezmienione do czasu przejścia w ramce do następnej strony. W celu wyświetlania przejściowych sekcji aplikacji należy używać ramek i ramek pływających. (Istnieją różne sposoby na zachowanie spójności danych, które mogą być używane razem z ramkami oraz oprócz ramek. Należą do nich pliki cookie, lokalne obiekty współużytkowane, lokalny obszar zapisu plików, magazyn plików zaszyfrowanych oraz lokalny obszar zapisu bazy danych). Ponieważ kod HTML w środowisku AIR zachowuje w swój standardowy, pośredni charakter między kodem wykonywalnym a danymi, środowisko AIR wstawia treść w górnej ramce HTML w obszarze izolowanym aplikacji. Po zdarzeniu load strony środowisko AIR ogranicza wszystkie operacje (np. eval()), które mogą konwertować ciąg znaków tekstu na wykonywalny obiekt. To ograniczenie jest wymuszane nawet wówczas, gdy aplikacja nie ładuje treści zdalnej. Aby umożliwić treści HTML wykonanie tych ograniczonych operacji, należy użyć ramek lub ramek pływających w celu umieszczenia treści w nieaplikacyjnym obszarze izolowanym. (Uruchomienie treści w ramce podrzędnej z obszaru izolowanego może być konieczne, jeśli używane są niektóre architektury aplikacji JavaScript, które odwołują się do funkcji eval()). Pełną listę ograniczeń JavaScript w obszarze izolowanym aplikacji zawiera sekcja „Ograniczenia kodu dotyczące treści różnych obszarów izolowanych” na stronie 33. HTML w AIR zachowuje zdolność ładowania zdalnej, prawdopodobnie niebezpiecznej treści, dlatego środowisko AIR wymusza strategię jednego źródła, która zapobiega interakcjom między treścią jednej domeny z treścią innej domeny. Aby umożliwić interakcje między treścią jednej domeny z treścią drugiej domeny, należy skonfigurować most, który będzie służył jako połączenie między ramką nadrzędną i podrzędną. Konfigurowanie relacji nadrzędny-podrzędny dla obszarów izolowanych Środowisko AIR dodaje atrybuty sandboxRoot i documentRoot do elementów ramek i ramek pływających HTML. Te atrybuty umożliwiają traktowanie treści aplikacji w taki sposób, jakby pochodziła z innej domeny: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 32 Zabezpieczenia w środowisku AIR Atrybut Opis sandboxRoot Adres URL przeznaczony do określenia obszaru izolowanego i domeny, do której należy wprowadzić treść ramki. Należy użyć schematów URL: file:, http: lub https:. documentRoot Adres URL, z którego ładowana jest treść ramki. Należy użyć schematów URL: file:, app: lub app-storage:. Poniższy przykład odwzorowuje treść zainstalowaną w podkatalogu sandbox aplikacji w celu uruchomienia w zdalnym obszarze izolowanym oraz domenie www.example.com: <iframe src="ui.html" sandboxRoot="http://www.example.com/local/" documentRoot="app:/sandbox/"> </iframe> Konfigurowanie mostu między ramkami nadrzędnymi i podrzędnymi w różnych obszarach izolowanych i domenach Środowisko AIR dodaje właściwości childSandboxBridge i parentSandboxBridge do obiektu window dowolnej ramki podrzędnej. Te właściwości umożliwiają definiowanie mostów, które służą jako połączenia między ramką podrzędną i nadrzędną. Każdy most jest jednokierunkowy: childSandboxBridge — właściwość childSandboxBridge umożliwia ramce podrzędnej zaprezentowanie interfejsu do treści ramki nadrzędnej. W celu zaprezentowania interfejsu należy ustawić dla właściwości childSandbox funkcję lub obiekt ramki podrzędnej. Następnie można uzyskać dostęp do obiektu lub funkcji z treści ramki nadrzędnej. Poniższy przykład przedstawia, w jaki sposób skrypt uruchomiony w ramce podrzędnej może prezentować obiekt zawierający funkcję i właściwość dla jej obiektu nadrzędnego: var interface = {}; interface.calculatePrice = function(){ return .45 + 1.20; } interface.storeID = "abc" window.childSandboxBridge = interface; Jeśli treść podrzędna znajduje się w ramce pływającej, do której przypisano id"child", wówczas można uzyskać dostęp do interfejsu z treści nadrzędnej poprzez odczytanie właściwości childSandboxBridge ramki: var childInterface = document.getElementById("child").childSandboxBridge; air.trace(childInterface.calculatePrice()); //traces "1.65" air.trace(childInterface.storeID)); //traces "abc" parentSandboxBridge — właściwość parentSandboxBridge umożliwia ramce nadrzędnej zaprezentowanie interfejsu do treści ramki podrzędnej. W celu zaprezentowania interfejsu należy ustawić właściwość parentSandbox ramki podrzędnej na funkcję lub obiekt ramki nadrzędnej. Następnie można uzyskać dostęp do obiektu lub funkcji z treści ramki podrzędnej. Poniższy przykład przedstawia, w jaki sposób skrypt uruchomiony w ramce nadrzędnej może prezentować obiekt zawierający funkcję zapisu obiektowi podrzędnemu: var interface = {}; interface.save = function(text){ var saveFile = air.File("app-storage:/save.txt"); //write text to file } document.getElementById("child").parentSandboxBridge = interface; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 33 Zabezpieczenia w środowisku AIR Za pomocą tego interfejsu treść ramki podrzędnej może zapisywać tekst do pliku o nazwie save.txt. Jednak treść nie będzie miała dostępu do systemu plików. W przypadku ogólnym treść aplikacji powinna prezentować innym obszarom izolowanym interfejs o najmniejszych ograniczeniach. Treść elementu podrzędnego może wywołać funkcję save w następujący sposób: var textToSave = "A string."; window.parentSandboxBridge.save(textToSave); Jeśli treść elementu podrzędnego podejmie próbę ustawienia właściwości obiektu parentSandboxBridge, wówczas środowisko wykonawcze zgłasza wyjątek SecurityError. Jeśli treść elementu nadrzędnego podejmie próbę ustawienia właściwości obiektu childSandboxBridge, wówczas środowisko wykonawcze zgłasza wyjątek SecurityError. Ograniczenia kodu dotyczące treści różnych obszarów izolowanych We wstępie do sekcji „Zabezpieczenia HTML” na stronie 31 opisano, że środowisko wykonawcze wymusza reguły i udostępnia mechanizmy przeciwdziałania możliwym słabym punktom zabezpieczeń w HTML i JavaScript. W niniejszym temacie przedstawiono te ograniczenia. Jeśli kod podejmuje próbę wywołania ograniczonych interfejsów API, wówczas środowisko wykonawcze zgłasza błąd z komunikatem „Naruszenie zabezpieczeń środowiska wykonawczego Adobe AIR dla kodu JavaScript w obszarze izolowanym zabezpieczeń aplikacji”. Więcej informacji zawiera sekcja „Unikanie błędów JavaScript związanych z bezpieczeństwem” na stronie 237. Ograniczenia dotyczące korzystania z funkcji eval() JavaScript oraz z innych technik Dla treści HTML w bezpiecznym obszarze izolowanym aplikacji obowiązują ograniczenia dotyczące korzystania z interfejsów API, które mogą dynamicznie przekształcać ciągi znaków na kod wykonywalny — po załadowaniu kodu (po wywołaniu zdarzenia onload elementu body oraz po zakończeniu działania funkcji modułu obsługi onload ). Takie rozwiązanie zapobiega przypadkowemu wstrzyknięciu i wykonaniu kodu ze źródeł nieaplikacyjnych (np. potencjalnie niebezpiecznych domen sieciowych). Na przykład: jeśli aplikacja korzysta z danych w postaci ciągu znaków ze źródła zdalnego w celu zapisywania we właściwości innerHTML elementu DOM, wówczas ciąg znaków może zawierać kod wykonywalny(JavaScript), który może wykonywać niebezpieczne operacje. Jednak podczas ładowania treści nie ma zagrożeń związanych z wstawianiem zdalnych ciągów znaków do elementu DOM. Jedno ograniczenie dotyczy korzystania z funkcji eval() JavaScript. Po załadowaniu kodu do obszaru izolowanego aplikacji i przetworzeniu modułu obsługi zdarzenia onload możliwe jest korzystanie z funkcji eval() w ograniczonym zakresie. Poniższe reguły dotyczą stosowania funkcji eval()po załadowaniu kodu z obszaru izolowanego aplikacji: • Dozwolone są wyjątki obejmujące literały. Na przykład: eval("null"); eval("3 + .14"); eval("'foo'"); • Dozwolone są literały obiektów, jak poniżej: { prop1: val1, prop2: val2 } • Stosowanie literałów obiektów set/get jest zabronione, jak poniżej: { get prop1() { ... }, set prop1(v) { ... } } • Dozwolone są literały tablic, jak poniżej: [ val1, val2, val3 ] • Wyrażenia zawierające odczyty właściwości są zabronione, jak poniżej: a.b.c TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 34 Zabezpieczenia w środowisku AIR • Wywołanie funkcji jest zabronione. • Definicje funkcji są zabronione. • Ustawienie właściwości jest zabronione. • Literały funkcji są zabronione. Jednak podczas ładowania kodu przed zdarzeniem onload oraz podczas działania funkcji modułu obsługi zdarzeń onload te ograniczenia nie dotyczą treści bezpiecznego obszaru izolowanego aplikacji. Na przykład: po załadowaniu kodu wykonanie poniższego kodu powoduje wyjątek w środowisku wykonawczym: eval("alert(44)"); eval("myFunction(44)"); eval("NativeApplication.applicationID"); Kod wygenerowany dynamicznie, np. podczas wywoływania funkcji eval() może spowodować zagrożenie, jeśli uzyska dostęp do obszaru izolowanego aplikacji. Przykład: aplikacja może przypadkowo wykonać ciąg znaków załadowany z domeny sieciowej, a ten ciąg znaków może zawierać złośliwy kod. Może to być na przykład kod, który spowoduje usunięcie lub modyfikację plików w komputerze. Lub może to być kod, który będzie zgłaszał treść pliku lokalnego do niezaufanej domeny sieciowej. Sposoby dynamicznego generowania kodu: • Wywołanie funkcji eval(). • Użycie właściwości innerHTML lub funkcji DOM w celu wstawienia znaczników script, które powodują ładowanie skryptu poza katalogiem aplikacji. • Użycie właściwości innerHTML lub funkcji DOM w celu wstawienia znaczników script zawierających kod wbudowany (zamiast ładowania skryptu za pomocą atrybutu src). • Ustawienie atrybutu src dla znaczników script w celu załadowania pliku JavaScript, który znajduje się na zewnątrz katalogu aplikacji. • Użycie schematu URL javascript (jak w href="javascript:alert('Test')"). • Użycie funkcji setInterval() lub setTimout(), w której pierwszy parametr (definiujący funkcję, która działa asynchronicznie) jest ciągiem znaków (wartość wynikowa), a nie nazwą funkcji (jak w przykładzie: setTimeout('x = 4', 1000)). • Wywołanie metody document.write() lub document.writeln(). Kod w obszarze izolowanym aplikacji może korzystać z tych metod tylko podczas ładowania treści. Te ograniczenia nie zapobiegają stosowania funkcji eval() z literałami obiektów JSON. Dzięki temu treść aplikacji może pracować z biblioteką JavaScript JSON. Niedozwolone jest natomiast korzystanie z przeciążonego kodu JSON (z podprogramami obsługi zdarzeń). W przypadku innych struktur Ajax i bibliotek kodu JavaScript należy upewnić się, czy kod w strukturze lub bibliotece działa zgodnie z tymi samymi ograniczeniami, które dotyczą kodu generowanego w sposób dynamiczny. Jeśli nie, należy dołączyć treść, która korzysta ze struktury lub biblioteki, do nieaplikacyjnego obszaru izolowanego. Szczegółowe informacje zawiera sekcja „Uprawnienia dotyczące treści nieaplikacyjnych obszarów izolowanych” na stronie 30 oraz „Treść aplikacyjna i nieaplikacyjna odwołująca się do skryptów” na stronie 41. Firma Adobe udostępnia listę środowisk Ajax, które obsługują bezpieczne obszary izolowane aplikacji, na stronie http://www.adobe.com/products/air/develop/ajax/features/. Treść JavaScript — w odróżnieniu od treści obszaru izolowanego aplikacji — w nieaplikacyjnym obszarze izolowanym może wywoływać funkcję eval() w celu wykonywania kodu wygenerowanego w sposób dynamiczny w dowolnym czasie. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 35 Zabezpieczenia w środowisku AIR Ograniczenia dostępu do interfejsów API AIR (dla nieaplikacyjnych obszarów izolowanych) Kod JavaScript w nieaplikacyjnym obszarze izolowanym nie ma dostępu do obiektu window.runtime i dlatego kod nie może uruchamiać interfejsów API AIR. Jeśli treść nieaplikacyjnego obszaru izolowanego wywoła poniższy kod, aplikacja zgłosi wyjątek TypeError: try { window.runtime.flash.system.NativeApplication.nativeApplication.exit(); } catch (e) { alert(e); } Wyjątek ma typ TypeError (wartość niezdefiniowana), ponieważ treść nieaplikacyjnego obszaru izolowanego nie rozpoznaje obiektu window.runtime, dlatego jest on widoczny jako wartość niezdefiniowana. Za pośrednictwem mostu można zaprezentować funkcje środowiska wykonawczego dla treści nieaplikacyjnego obszaru izolowanego. Szczegółowe informacje zawiera sekcja „Treść aplikacyjna i nieaplikacyjna odwołująca się do skryptów” na stronie 41. Ograniczenia dotyczące korzystania z wywołań XMLHttpRequest Treść HTML w obszarze izolowanym aplikacji nie może korzystać z synchronicznych metod XMLHttpRequest w celu ładowania danych spoza obszaru izolowanego aplikacji podczas ładowania treści HTML oraz podczas zdarzenia onLoad. Domyślnie treść HTML w nieaplikacyjnych obszarach izolowanych nie ma możliwości korzystania z obiektu XMLHttpRequest JavaScript w celu ładowania danych z domen innych niż domena wywołująca żądanie. Znacznik frame lub iframe może zawierać atrybut allowcrosscomainxhr. Ustawienie tego atrybutu na wartość inną niż null umożliwia treści ramki lub ramki pływającej korzystanie z obiektu XMLHttpRequest Javascript w celu ładowania danych z domen innych niż domena kodu wywołującego żądanie: <iframe id="UI" src="http://example.com/ui.html" sandboxRoot="http://example.com/" allowcrossDomainxhr="true" documentRoot="app:/"> </iframe> Więcej informacji zawiera sekcja „Treść odwołująca się do skryptów w różnych domenach” na stronie 36. Ograniczenia dotyczące ładowania elementów CSS, ramek, ramek pływających i img (dla treści nieaplikacyjnych obszarów izolowanych) Treść HTML w zdalnych (sieciowych) obszarach izolowanych może ładować tylko treść CSS, frame, iframe i img ze zdalnych obszarów izolowanych (z sieciowych adresów URL). Treść HTML w lokalnym obszarze izolowanym z systemem plików, lokalnym obszarze izolowanym z obsługą sieci lub lokalnym zaufanym obszarze izolowanym może ładować tylko treść CSS, ramek, ramek pływających i img z lokalnych obszarów izolowanych (nie z aplikacyjnych ani zdalnych obszarów izolowanych). Ograniczenia dotyczące wywoływania metody window.open() JavaScript Jeśli okno utworzone poprzez wywołanie metody window.open() JavaScript wyświetla treść nieaplikacyjnego obszaru izolowanego, wówczas tytuł okna rozpoczyna się od tytułu głównego okna (uruchamiania), po którym następuje znak dwukropka. Za pomocą kodu nie można przesunąć tej części tytułu okna poza ekran. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 36 Zabezpieczenia w środowisku AIR Treść nieaplikacyjnych obszarów izolowanych może wywoływać z powodzeniem metodę window.open() JavaScript w odpowiedzi na zdarzenie wywołane przez interakcję z myszą lub klawiaturą. Dzięki temu treść nieaplikacyjna nie może tworzyć okien, które mogłyby zostać wykorzystane oszukańczo (np. w atakach typu phishing). Ponadto moduł obsługi zdarzeń myszy lub klawiatury nie może ustawiać wykonywania metody window.open() po opóźnieniu (np. poprzez wywołanie funkcji setTimeout()). Treść w zdalnych (sieciowych) obszarach izolowanych może korzystać z metody window.open() wyłącznie w celu otwierania treści w zdalnych (sieciowych) obszarach izolowanych. Nie może korzystać z metody window.open() w celu otwierania treści z obszarów izolowanych aplikacji lub lokalnych obszarów izolowanych. Treść lokalnych obszarów izolowanych z systemem plików, lokalnych obszarów izolowanych z obsługą sieci i lokalnych zaufanych obszarów izolowanych (patrz „Obszary izolowane” na stronie 28 ) może korzystać z metody window.open() tylko w celu otwierania treści w lokalnych obszarach izolowanych. Nie może korzystać z metody window.open() w celu otwierania treści obszarów izolowanych aplikacji ani zdalnych obszarów izolowanych. Błędy podczas wywoływania kodu ograniczonego Jeśli wywołany zostanie kod, którego użycie zostało ograniczone ze względu na ograniczenia bezpieczeństwa, środowisko wykonawcze zgłosi błąd JavaScript: „Naruszenie zabezpieczeń środowiska wykonawczego Adobe AIR dla kodu JavaScript w obszarze izolowanym zabezpieczeń aplikacji”. Więcej informacji zawiera sekcja „Unikanie błędów JavaScript związanych z bezpieczeństwem” na stronie 237. Zabezpieczenie obszaru izolowanego podczas ładowania treści HTML z ciągu znaków Metoda loadString() klasy HTMLLoader umożliwia tworzenie treści HTML w czasie wykonywania. Jednak dane używane jako treść HTML mogą być uszkodzone, jeśli dane są ładowane z niebezpiecznego źródła z sieci Internet. Z tego względu domyślnie treść HTML utworzona za pomocą metody loadString() nie jest umieszczana w obszarze izolowanym aplikacji i nie ma dostępu do interfejsów API środowiska AIR. Jednak użytkownik może ustawić właściwość placeLoadStringContentInApplicationSandbox obiektu HTMLLoader na wartość true, aby umieścić treść HTML utworzoną za pomocą metody loadString() w obszarze izolowanym aplikacji. Więcej informacji zawiera sekcja „Ładowanie treści HTML z ciągu znaków” na stronie 235. Treść odwołująca się do skryptów w różnych domenach Zainstalowane aplikacje AIR mają specjalne uprawnienia. Bardzo ważne jest, aby te same uprawnienia nie przeciekły do innej treści, np. plików zdalnych lub lokalnych, które nie są częścią aplikacji. Informacje o moście obszaru izolowanego AIR W normalnych warunkach treść domen nie może wywoływać skryptów w innych domenach. W celu ochrony aplikacji AIR przed przypadkowym wyciekiem uprzywilejowanych informacji lub elementów sterujących poniższe ograniczenia są umieszczane dla treści w obszarze izolowanym application (treść instalowana z aplikacją): • Kod w bezpiecznym obszarze izolowanym aplikacji wywołujący metodę Security.allowDomain() nie ma dostępu do innych obszarów izolowanych. Wywołanie tej metody z bezpiecznego obszaru izolowanego aplikacji spowoduje wygenerowanie błędu. • Importowanie treści nieaplikacyjnej do obszaru izolowanego aplikacji poprzez ustawienie właściwości LoaderContext.securityDomain lub właściwości LoaderContext.applicationDomain jest niemożliwe. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 37 Zabezpieczenia w środowisku AIR Istnieją przypadki, w których główna aplikacja AIR wymaga, aby treść zdalnej domeny miała kontrolowany dostęp do skryptów w głównej aplikacji AIR i odwrotnie. W tym celu środowisko wykonawcze udostępnia mechanizm mostu obszaru izolowanego, który służy jako brama między dwoma obszarami izolowanymi. Most obszaru izolowanego może umożliwiać jawne oddziaływania między zdalnymi obszarami izolowanymi i obszarami izolowanymi aplikacji. Most obszaru izolowanego prezentuje dwa obiekty, do których mogą uzyskać dostęp skrypty załadowane i ładowane: • Dzięki obiektowi parentSandboxBridge treść ładowana może prezentować właściwości i funkcje dla skryptów w treści załadowanej. • Dzięki obiektowi childSandboxBridge treść załadowana może prezentować właściwości i funkcje dla skryptów w treści ładowanej. Obiekty prezentowane za pośrednictwem mostu obszaru izolowanego są przekazywane jako wartość, a nie jako odwołanie. Wszystkie dane są serializowane. Oznacza to, że obiekty zaprezentowane przez jedną stronę mostu nie mogą być ustawiane przez drugą stronę i wszystkie obiekty zaprezentowane nie mają określonych typów. Ponadto możliwe jest prezentowanie tylko prostych obiektów i funkcji; nie można prezentować obiektów złożonych. Jeśli treść elementu podrzędnego podejmie próbę ustawienia właściwości obiektu parentSandboxBridge, wówczas środowisko wykonawcze zgłasza wyjątek SecurityError. I podobnie: jeśli treść elementu nadrzędnego podejmie próbę ustawienia właściwości obiektu childSandboxBridge, wówczas środowisko wykonawcze zgłasza wyjątek SecurityError. Przykład mostu obszaru izolowanego (SWF) Załóżmy, że aplikacja sklepu muzycznego AIR chce zezwolić zdalnym plikom SWF na rozgłaszanie ceny albumów, ale nie chce, aby zdalny plik SWF ujawniał, czy cena jest ceną sprzedaży. Jest to możliwe, ponieważ klasa StoreAPI udostępnia metodę przeznaczoną do określenia ceny, ale przysłania cenę sprzedaży. Następnie instancja tej klasy StoreAPI zostaje przypisana do właściwości parentSandboxBridge obiektu LoaderInfo obiektu Loader, który ładuje zdalny plik SWF. Poniżej przedstawiono kod sklepu muzycznego AIR: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 38 Zabezpieczenia w środowisku 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> Obiekt StoreAPI wywołuje aplikację główną w celu pobrania standardowej ceny albumu, ale wywołanie metody getSaleAlbumPrice() powoduje zwrócenie komunikatu „Not available”. Poniższy kod definiuje klasę StoreAPI: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 39 Zabezpieczenia w środowisku 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(); } } Poniższy kod prezentuje przykład pliku PriceQuoter SWF, który zgłasza cenę sklepową, ale nie zgłasza ceny sprzedaży: 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()); } } } Przykład mostu obszaru izolowanego (HTML) W treści HTML właściwości parentSandboxBridge i childSandboxBridge są dodawane do obiektu okna JavaScript dokumentu podrzędnego. Przykład sposobu konfigurowania funkcji mostu w treści HTML zawiera sekcja „Konfigurowanie interfejsu mostu obszaru izolowanego” na stronie 251. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 40 Zabezpieczenia w środowisku AIR Ograniczanie ekspozycji interfejsu API Podczas prezentowania mostów obszarów izolowanych należy prezentować interfejsy API wysokiego poziomu, które ograniczają stopień wykorzystania mostów. Należy pamiętać, że treść wywołująca implementację mostu może być zmodyfikowania (np. na skutek wstrzyknięcia kodu). Dlatego prezentowanie metody readFile(path:String) (odczytuje treść dowolnego pliku) za pośrednictwem mostu może stanowić zagrożenie. Lepszym rozwiązaniem jest zaprezentowanie interfejsu API readApplicationSetting(), który nie przyjmuje ścieżki i odczytuje określony plik. Podejście bardziej semantyczne może ograniczyć uszkodzenia, jakie aplikacja może spowodować, gdy jej część zostanie zmodyfikowana. Zobacz także „Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych” na stronie 249 „Obszar izolowany aplikacji” na stronie 29 „Uprawnienia dotyczące treści nieaplikacyjnych obszarów izolowanych” na stronie 30 Zapis na dysk Aplikacje działające w przeglądarce sieci Web mogą tylko w ograniczonym zakresie oddziaływać z lokalnym systemem plików. Przeglądarki sieci Web implementują strategie zabezpieczeń, które zapewniają, że stanu komputera nie może naruszyć ładowanie treści sieci Web. Na przykład: plik SWF działający za pośrednictwem programu Flash Player w przeglądarce nie może oddziaływać bezpośrednio z plikami, które już znajdują się na komputerze użytkownika. Współużytkowane obiekty i pliki cookie mogą być zapisywane na komputerze użytkownika w celu zachowania preferencji użytkownika i innych danych, ale jest to limit oddziaływania na system plików. Aplikacje AIR są instalowane w trybie rodzimym, dlatego dla nich obowiązuje inny mechanizm zabezpieczeń — taki, który obejmuje możliwość odczytu i zapisy w lokalnym systemie plików. Ta swoboda nadaje programistom wiele uprawnień, ale również wymaga od nich odpowiedzialnego postępowania. Przypadkowe zagrożenia aplikacji narażają nie tylko funkcjonalność aplikacji, ale również integralność komputera użytkownika. Z tego powodu programiści powinni zapoznać się z sekcją „Sprawdzone procedury zabezpieczeń przeznaczone dla programistów” na stronie 42. Programiści AIR mogą zapisywać pliki i uzyskiwać do nich dostęp w lokalnym systemie plików za pomocą kilku schematów URL: Schemat URL Opis app:/ Alias katalogu aplikacji. Pliki, do których dostęp jest uzyskiwany z tej ścieżki, są przypisywane do obszaru izolowanego aplikacji i mają pełne uprawnienia nadane przez środowisko wykonawcze. app-storage:/ Alias lokalnego katalogu zapisu, standaryzowany przez środowisko wykonawcze. Pliki, do których dostęp jest uzyskiwany z tej ścieżki, są przypisane do nieaplikacyjnego obszaru izolowanego. file:/// Alias, który reprezentuje katalog główny dysku twardego. Plik, do którego dostęp jest uzyskiwany z tej ścieżki, jest przypisany do obszaru izolowanego aplikacji, pod warunkiem że plik istnieje w katalogu aplikacji — w przeciwnym wypadku plik jest przypisywany do nieaplikacyjnego obszaru izolowanego. Uwaga: Aplikacje AIR nie mogą modyfikować treści za pomocą schematu URL app:. Ponadto katalog aplikacji może być odczytywany tylko wówczas, gdy zezwalają na to ustawienia zdefiniowane przez administratora. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 41 Zabezpieczenia w środowisku AIR Jeśli administrator nie ograniczył dostępu do komputera użytkownika, aplikacje AIR mają uprawnienia do zapisywania w dowolnej lokalizacji na dysku twardym użytkownika. Programistom zaleca się korzystanie ze ścieżki app-storage:/ dla zapisu lokalnego powiązanego z aplikacjami. Pliki zapisane w ścieżce app-storage:/ z aplikacji są umieszczane w lokalizacji standardowej: • W systemie Mac OS: katalog zapisu aplikacji to <appData>/<appId>/Local Store/, gdzie <appData> to folder preferencji użytkownika. Jest to zwykle folder /Users/<user>/Library/Preferences • W systemie Windows: katalog zapisu aplikacji to <appData>\<appId>\Local Store\ gdzie <appData> to specjalny folder użytkownika CSIDL_APPDATA. Jest to zwykle folder C:\Documents and Settings\<userName>\Application Data • W systemie Linux: <appData>/<appID>/Local Store/, gdzie <appData> to /home/<user>/.appdata Jeśli aplikacja może oddziaływać z istniejącymi plikami w systemie plików użytkownika, należy zapoznać się z sekcją „Sprawdzone procedury zabezpieczeń przeznaczone dla programistów” na stronie 42. Bezpieczna praca z treścią niezaufaną Treść nie przypisana do obszaru izolowanego aplikacji może udostępniać dodatkowe funkcje skryptów w aplikacji, ale tylko wówczas, gdy spełnia kryteria zabezpieczeń określone przez środowisko wykonawcze. W niniejszym temacie opisano mechanizm zabezpieczeń AIR w przypadku treści nieaplikacyjnej. Security.allowDomain() Aplikacje AIR ograniczają dostęp skryptów w przypadku treści nieaplikacyjnej w sposób bardziej restrykcyjny niż przeglądarka Flash Player, która ogranicza dostęp do skryptów dla treści niezaufanej. Na przykład, jeśli w przeglądarce programu Flash Player plik SWF przypisany do local-trusted (lokalnie zaufanego) obszaru izolowanego wywoła metodę System.allowDomain(), dostęp do skryptów zostanie nadany każdemu plikowi SWF, który zostanie załadowany z określonej domeny. Analogiczne podejście nie jest dozwolone w przypadku treści application w aplikacjach AIR, ponieważ spowodowałoby to nieuzasadniony dostęp do pliku nieaplikacyjnego w systemie plików użytkownika. Pliki zdalne nie mogą bezpośrednio uzyskiwać dostępu do obszaru izolowanego aplikacji bez względu na wywołania metody Security.allowDomain(). Treść aplikacyjna i nieaplikacyjna odwołująca się do skryptów Dla aplikacji AIR, które odwołują się do skryptów między treścią aplikacyjną i nieaplikacyjną, obowiązują bardziej złożone zabezpieczenia. Pliki, które nie znajdują się w obszarach izolowanych aplikacji, mają dostęp do właściwości i metod plików w obszarze izolowanym aplikacji tylko za pośrednictwem mostu obszaru izolowanego. Most obszaru izolowanego działa jako brama między treścią aplikacyjną i nieaplikacyjną, umożliwiając jawne oddziaływania między dwoma plikami. Jeśli mosty są używane poprawnie, stanowią dodatkową warstwę zabezpieczeń, ograniczając dostęp treści nieaplikacyjnej do odwołań do obiektów, które stanowią część treści aplikacyjnej. Korzyści wynikające ze stosowania mostów obszarów izolowanych są najlepiej ilustrowane za pomocą przykładów. Załóżmy, że aplikacja sklepu muzycznego AIR chce udostępnić interfejs API dla reklamodawców, którzy będą tworzyć własne pliki SWF, z którymi następnie będzie się komunikować aplikacja sklepu. Sklep chce udostępnić reklamodawcom metody wyszukiwania artystów i płyt CD ze sklepu, ale ze względów bezpieczeństwa chce również odizolować niektóre metody i właściwości od plików SWF innych firm (reklamodawców). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 42 Zabezpieczenia w środowisku AIR Jest to możliwe dzięki mostowi obszaru izolowanego. Domyślnie treść ładowana z zewnątrz do aplikacji AIR w czasie wykonywania nie ma dostępu do żadnych metod ani właściwości w aplikacji głównej. Za pomocą implementacji niestandardowego mostu obszaru izolowanego programista może udostępniać usługi dla zdalnej treści bez konieczności prezentowania tych metod i właściwości. Most obszaru izolowanego należy traktować jako ścieżkę między treścią zaufaną i niezaufaną — most zapewnia komunikację między treścią ładującą a ładowaną, bez konieczności ujawniania odwołań do obiektów. Więcej informacji na temat bezpiecznego korzystania z mostów zawiera sekcja „Treść odwołująca się do skryptów w różnych domenach” na stronie 36. Ochrona przed dynamicznym generowaniem niebezpiecznej treści SWF Metoda Loader.loadBytes() udostępnia aplikacji sposób generowania treści SWF z tablicy bajtowej. Jednak ataki polegające na wstrzykiwaniu kodu do danych ładowanych ze źródeł zdalnych mogą powodować poważne uszkodzenia podczas ładowania treści. Jest to szczególnie istotne w przypadku ładowania danych do obszaru izolowanego aplikacji, gdy wygenerowana treść SWF ma dostęp do pełnego zestawu interfejsów API AIR. Istnieją przyczyny stosowania metody loadBytes() bez konieczności generowania wykonywalnego kodu SWF. Metoda loadBytes() może służyć na przykład do generowania danych obrazu w celu kontrolowania czasu wyświetlania obrazu. Istnieją również uzasadnione zastosowania oparte na wykonaniu kodu, np. w przypadku dynamicznego tworzenia treści SWF przeznaczonej do odtwarzania audio. W środowisku AIR domyślnie metoda loadBytes()nie umożliwia ładowania treści SWF; umożliwia wyłącznie ładowanie treści obrazu. W środowisku AIR właściwość loaderContext metody loadBytes() zawiera właściwość allowLoadBytesCodeExecution, dla której można ustawić wartość true, aby jawnie zezwolić aplikacji na korzystanie z metody loadBytes() w celu ładowania wykonywalnej treści SWF. Poniższy kod prezentuje użycie tej funkcji: var loader:Loader = new Loader(); var loaderContext:LoaderContext = new LoaderContext(); loaderContext.allowLoadBytesCodeExecution = true; loader.loadBytes(bytes, loaderContext); Jeśli metoda loadBytes() została wywołana w celu załadowania treści SWF, a dla właściwości allowLoadBytesCodeExecution obiektu LoaderContext ustawiono wartość false (domyślnie), wówczas obiekt Loader zwraca wyjątek SecurityError. Uwaga: W przyszłych wydaniach środowiska Adobe AIR ten interfejs API może ulec zmianie. W takim przypadku konieczne może być ponowne skompilowanie treści, która korzysta z właściwości allowLoadBytesCodeExecution klasy LoaderContext. Sprawdzone procedury zabezpieczeń przeznaczone dla programistów Aplikacje AIR są tworzone przy wykorzystaniu technologii sieci Web, ale bardzo ważne jest, aby programiści pamiętali o tym, że nie pracują w obszarze izolowanym przeglądarki. Oznacza to, że możliwe jest tworzenie aplikacji AIR, które nie będą uszkadzały systemu lokalnego celowo lub przypadkowo. Środowisko AIR podejmuje próby zminimalizowania ryzyka, ale istnieją nadal sposoby osłabienia zabezpieczeń. W niniejszym temacie omówiono potencjalne słabe punkty zabezpieczeń. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 43 Zabezpieczenia w środowisku AIR Ryzyko w przypadku importowania plików do obszaru izolowanego aplikacji Pliki, które istnieją w katalogu aplikacji, są przypisane do obszaru izolowanego aplikacji i mają pełne uprawnienia w środowisku wykonawczym. W przypadku aplikacji, które zapisują w lokalnym systemie plików, zalecany jest zapis zgodnie ze schematem app-storage:/. Katalog istnieje osobno od plików aplikacji na komputerze użytkownika — dlatego pliki nie są przypisane do obszaru izolowanego aplikacji i stanowią mniejsze zagrożenie. Programiści powinni rozważyć następujące zagadnienia: • Do pliku AIR (w zainstalowanej aplikacji) można dołączyć plik tylko w razie potrzeby. • Do pliku AIR (w zainstalowanej aplikacji) można dołączyć plik skryptowy tylko wówczas, gdy jego działanie jest w pełni zrozumiałe i jest to plik zaufany. • Nie należy zapisywać ani modyfikować treści w katalogu aplikacji. Środowisko wykonawcze uniemożliwia aplikacjom zapisywanie i modyfikowanie plików i katalogów za pomocą schematu URL app:/, ponieważ wywołuje wyjątek SecurityError. • Danych ze źródeł sieciowych nie należy używać w roli parametrów metod interfejsów API AIR, które mogą powodować wykonanie kodu. Obejmuje to użycie metody Loader.loadBytes() i funkcji eval() JavaScript. Zagrożenia związane z korzystaniem ze źródeł zewnętrznych w celu określenia ścieżek Działanie aplikacji AIR może zostać zakłócone podczas korzystania z danych lub treści zewnętrznej. Z tego powodu należy zachować szczególną ostrożność podczas korzystania z danych z sieci lub systemu plików. Określenie obiektu jako zaufanego zależy od programisty i połączeń sieciowych, jakie nawiązuje obiekt, ale ładowanie danych obcych jest ryzykowne i nie powinno być używane w przypadku wprowadzania danych do wrażliwych operacji. Programistom nie zaleca się: • Korzystania z danych pochodzących ze źródeł sieciowych w celu określania nazw plików • Korzystania z danych pochodzących ze źródeł sieciowych w celu konstruowania adresów URL, z których korzysta aplikacja w celu wysyłania informacji prywatnych Ryzyko związane z użyciem, zapisywaniem i przesyłaniem niebezpiecznych poświadczeń Zapisywanie poświadczeń użytkowników w lokalnym systemie plików wiąże się z zagrożeniem modyfikacji tych danych. Programiści powinni rozważyć następujące zagadnienia: • Jeśli konieczne jest lokalne zapisywanie poświadczeń, należy zaszyfrować te dane podczas zapisywania w lokalnym systemie plików. Środowisko wykonawcze udostępnia funkcję szyfrowania podczas zapisu unikalną dla każdej zainstalowanej aplikacji, za pośrednictwem klasy EncryptedLocalStore. Szczegółowe informacje zawiera sekcja „Przechowywanie danych zaszyfrowanych” na stronie 217. • Nie należy przesyłać niezaszyfrowanych poświadczeń użytkownika do źródła sieciowego, chyba że jest to źródło zaufane. • Nigdy nie należy określać hasła domyślnego podczas tworzenia poświadczeń — użytkownicy powinni definiować własne hasła. Użytkownicy, którzy pozostawią niezmienione wartości domyślne, narażają swoje poświadczenia na wykorzystanie przez agresora, który mógł wcześniej poznać hasło domyślne. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 44 Zabezpieczenia w środowisku AIR Ryzyko ataku na skutek zamiany wersji na starszą Podczas instalowania aplikacji środowisko wykonawcze sprawdza, czy konkretna wersja aplikacji nie jest już zainstalowana. Jeśli aplikacja jest już zainstalowana, środowisko wykonawcze porównuje ciąg znaków wersji z instalowaną wersją. Jeśli ciąg znaków jest inny, użytkownik może wybrać zaktualizowanie instalacji. Środowisko wykonawcze nie gwarantuje, że nowo zainstalowana wersja będzie nowsza od starszej wersji — jest to po prostu inna wersja. Agresor może dystrybuować starszą wersję w celu wykorzystania słabego punktu zabezpieczeń. Z tego powodu programista powinien sprawdzać wersje podczas uruchamiania aplikacji. Dobrym rozwiązaniem jest, gdy aplikacja sprawdza dostępność aktualizacji w sieci. Dzięki temu, gdy agresor spowoduje uruchomienie starej wersji, stara wersja rozpozna, że musi zostać zaktualizowana. Ponadto zastosowanie jasnego schematu wersji aplikacji utrudni oszukanie użytkowników w taki sposób, aby zainstalowali starszą wersję. Szczegółowe informacje o określaniu wersji aplikacji zawiera sekcja „Definiowanie właściwości w pliku deskryptora aplikacji” na stronie 46. Podpisywanie kodu Kod wszystkich plików instalatora AIR musi być podpisany. Podpisywanie kodu to proces kryptograficzny, który potwierdza, że określone źródło oprogramowania jest źródłem rzeczywistym. Aplikacje AIR mogą być podpisywane poprzez połączenie certyfikatu z zewnętrznego ośrodka certyfikacji lub poprzez utworzenie własnego certyfikatu. Zalecane jest stosowanie certyfikatów komercyjnych ze znanego ośrodka, ponieważ zapewnia on użytkowników o tym, że instalują aplikację, a nie jej falsyfikat. Jednak możliwe jest również tworzenie certyfikatów samopodpisanych — w tym celu należy użyć narzędzia adt z pakietu SDK lub użyć aplikacji Flash, Flex Builder albo innej aplikacji, która korzysta z narzędzia adt w celu generowania certyfikatów. Certyfikaty samopodpisane nie zapewniają, że instalowana aplikacja jest autentyczna. Więcej informacji o elektronicznym podpisywaniu aplikacji AIR zawiera sekcja „Elektroniczne podpisywanie pliku AIR” na stronie 323 i sekcja „Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń” na stronie 358. 45 Rozdział 8: Definiowanie ustawień aplikacji AIR Oprócz wszystkich plików i innych zasobów, które tworzą aplikację AIR, każda aplikacja AIR wymaga pliku deskryptora aplikacji. Plik deskryptora aplikacji jest plikiem XML, który definiuje podstawowe właściwości aplikacji. W przypadku tworzenia aplikacji AIR za pomocą aktualizacji środowiska Adobe® AIR™ dla programu Adobe® Flash® CS3 Professional lub Adobe® Flash® CS4 Professional, plik deskryptora aplikacji jest generowany automatycznie przy tworzeniu projektu AIR. Istnieje możliwość uzyskania dostępu do panelu w celu zmiany ustawień deskryptora aplikacji z menu Polecenia > AIR - Ustawienia instalatora i aplikacji. Możliwe jest także ręczne uzyskanie dostępu do pliku deskryptora aplikacji. Struktura pliku deskryptora aplikacji Plik deskryptora aplikacji zawiera właściwości, które wpływają na całą aplikację, np. jej nazwę, wersję itp. Dla pliku deskryptora aplikacji można użyć dowolnej nazwy. Jeśli plik AIR jest tworzony za pomocą ustawień domyślnych w programie Flash CS3 lub Flash CS4, nazwa pliku deskryptora aplikacji zostaje zmieniona na application.xml i plik zostaje umieszczony w specjalnym katalogu w pakiecie AIR. Poniżej przedstawiono przykładowy plik deskryptora aplikacji: <?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> </initialWindow> <installFolder>Example Co/Hello World</installFolder> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 46 Definiowanie ustawień aplikacji AIR <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> Definiowanie właściwości w pliku deskryptora aplikacji Elementy i atrybuty XML w deskryptorze aplikacji służą do definiowania następujących typów właściwości dla aplikacji AIR użytkownika: • Wymagana wersja środowiska wykonawczego AIR • Tożsamość aplikacji • Foldery instalacji i menu programu • Początkowa treść i właściwości okna • Pliki ikon aplikacji • Informacja o tym, czy aplikacja udostępnia niestandardowy interfejs aktualizacji • Informacja o tym, czy aplikacja może być wywoływana przez treść SWF uruchomioną w przeglądarce użytkownika • Powiązania typu pliku Określanie wymaganej wersji środowiska AIR Atrybuty elementu głównego pliku deskryptora aplikacji (application) określają wymaganą wersję środowiska wykonawczego AIR: <application xmlns="http://ns.adobe.com/air/application/1.5"> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 47 Definiowanie ustawień aplikacji AIR xmlns Przestrzeń nazw AIR, którą należy zdefiniować jako domyślną przestrzeń nazw XML. Przestrzeń nazw zmienia się z każdym głównym wydaniem środowiska AIR (ale nie w przypadku mniejszych poprawek). Ostatni segment przestrzeni nazw (np. „1.5”) wskazuje na wersję środowiska wykonawczego wymaganą przez aplikację. Należy upewnić się, że przestrzeń nazw jest ustawiona na AIR 1.5 ("http://ns.adobe.com/air/application/1.5"), jeśli aplikacja użytkownika używa dowolnej z nowych funkcji środowiska AIR 1.5. Dla aplikacji w formacie SWF wersja środowiska wykonawczego AIR podana w deskryptorze aplikacji określa maksymalną wersję pliku SWF, jaki może zostać załadowany jako początkowa treść aplikacji. Dla aplikacji, dla których została określona wersja środowiska AIR 1.0 lub AIR 1.1, jako początkowej treści można używać jedynie plików SWF9 (Flash Player 9) — nawet jeśli zostały uruchomione za pomocą środowiska wykonawczego AIR 1.5. Dla aplikacji, dla których została określona wersja środowiska AIR 1.5, jako początkowej treści można używać plików SWF9 lub SWF10 (Flash Player 10). Wersja SWF określa, które wersje interfejsów API środowiska AIR i programu Flash Player są dostępne. Jeśli plik SWF9 jest używany jako początkowa treść aplikacji AIR 1.5, aplikacja będzie miała dostęp jedynie do interfejsów API środowiska AIR 1.1 i programu Flash Player 9. Ponadto zmiany w działaniu dokonane w istniejących interfejsach API środowiska AIR 1.5 lub programu Flash Player 10 nie odniosą skutku. (Istotne zmiany w interfejsach API związane z bezpieczeństwem są odstępstwem od tej reguły i mogą być stosowane wstecz w bieżących lub przyszłych poprawkach środowiska wykonawczego). Dla aplikacji w formacie HTML wersja środowiska wykonawczego podana w deskryptorze aplikacji samodzielnie określa, które wersje interfejsów API środowiska AIR i programu Flash Player są dostępne dla aplikacji. Działanie kodu HTML, CSS i JavaScript jest zawsze określane przez wersję silnika Webkit używanego w zainstalowanym środowisku wykonawczym AIR, a nie przez deskryptor aplikacji. Podczas ładowania treści SWF przez aplikację AIR wersja interfejsów API środowiska AIR i programu Flash Player dostępnych dla tej treści zależy od sposobu jej ładowania. W poniższej tabeli został przedstawiony sposób, w jaki wersja interfejsu API jest określana w oparciu o metodę ładowania: Sposób ładowania treści Sposób określania wersji interfejsu API Początkowa treść, aplikacja w formacie SWF Wersja SWF załadowanego pliku Początkowa treść, aplikacja w formacie HTML Przestrzeń nazw deskryptora aplikacji Plik SWF załadowany przez treść SWF Wersja treści ładującej Biblioteka SWF załadowana przez treść HTML za pomocą znacznika <script> Przestrzeń nazw deskryptora aplikacji Plik SWF załadowany przez treść HTML za Przestrzeń nazw deskryptora aplikacji pomocą interfejsów API środowiska AIR lub programu Flash Player (np. flash.display.Loader) Plik SWF załadowany przez treść HTML za pomocą znaczników <object> lub <embed> (lub równoważnych interfejsów API języka JavaScript) Wersja SWF załadowanego pliku Podczas ładowania pliku SWF w wersji innej niż treść ładująca można napotkać na dwa problemy: • Ładowanie treści pliku SWF10 przez plik SWF9 (lub wcześniejszy) — odwołania do interfejsów API środowiska AIR 1.5 i programu Flash Player 10 w załadowanej treści nie zostaną przetłumaczone • Ładowanie treści pliku SWF9 (lub wcześniejszego) przez plik SWF10 — interfejsy API zmienione w środowisku AIR 1.5 i programie Flash Player 10 mogą działać w sposób nieoczekiwany przez załadowaną treść. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 48 Definiowanie ustawień aplikacji AIR minimumPatchLevel Atrybut opcjonalny. Atrybut minimumPatchLevel służy do określania minimalnego poziomu poprawki środowiska Adobe AIR wymaganego przez aplikację. Aplikacje AIR zwykle określają wymaganą wersję środowiska poprzez zdefiniowanie przestrzeni nazw w pliku deskryptora aplikacji. Przestrzeń nazw jest zmieniana w każdej głównej wersji środowiska AIR (np. 1.0 lub 1.5). Przestrzeń nazw nie zmienia się w wydaniach wersji. Wydania wersji zawierają tylko ograniczony zestaw poprawek i nie zawierają zmian interfejsów API. Zwykle aplikacje nie określają wersji poprawek, jakich wymagają. Jednak zainstalowanie poprawki może spowodować usunięcie błędu z aplikacji. W takiej sytuacji aplikacja może określać wartość dla atrybutu minimumPatchLevel w celu zapewnienia, że poprawka została zastosowana przed zainstalowaniem aplikacji. W razie potrzeby instalator aplikacji AIR wyświetli monit dotyczący pobrania i zainstalowania wymaganej wersji poprawki. Poniższy przykład prezentuje element aplikacji, który określa wartość atrybutu minimumPatchLevel: <application xmlns="http://ns.adobe.com/air/application/1.1" minimumPatchLevel="5331"> Definiowanie tożsamości aplikacji Poniższe elementy definiują identyfikator aplikacji, wersję, nazwę, nazwę pliku, opis oraz informacje o prawach autorskich: <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 Ciąg znaków identyfikatora unikalny dla aplikacji, znany jako identyfikator aplikacji. Wartość atrybutu jest ograniczona do następujących znaków: • 0–9 • a–z • A–Z • . (kropka) • - (kreska) Wartość musi zawierać od 1 do 212 znaków. Ten element jest wymagany. W ciągu znaków id zwykle stosowana jest hierarchia rozdzielana kropkami — zgodnie z odwróconym adresem domeny DNS, nazwą pakietu Java™ lub nazwą klasy albo zgodnie z identyfikatorem Universal Type Identifier w systemie Mac OS® X. Format przypominający adres DNS nie jest wymuszany, a środowisko AIR nie tworzy żadnych skojarzeń między nazwą i rzeczywistymi domenami DNS. version Określa informacje o wersji aplikacji. (Nie ma powiązania z wersją środowiska wykonawczego). Ciąg znaków wersji jest specyfikatorem zdefiniowanym w aplikacji. Środowisko AIR w żaden sposób nie interpretuje ciągu znaków wersji. Dlatego wersja „3.0” nie jest w żaden sposób traktowana jako bardziej aktualna niż wersja „2.0”. Przykłady: "1.0", ".4", "0.5", "4.9", "1.3.4a". Ten element jest wymagany. filename Ciąg znaków używany jako nazwa pliku aplikacji (bez rozszerzenia) po zainstalowaniu aplikacji. Plik aplikacji uruchamia aplikację AIR w środowisku wykonawczym. Jeśli nie określono wartości name, wówczas wartość filename jest używana również jako nazwa folderu instalacyjnego. Ten element jest wymagany. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 49 Definiowanie ustawień aplikacji AIR Właściwość filename może zawierać dowolne znaki Unicode (UTF-8) z wyjątkiem poniższych, których stosowanie jest zabronione w nazwach plików w różnych systemach plików: Znak Kod szesnastkowy różne 0x00 – x1F * x2A " x22 : x3A > x3C < x3E ? x3F \ x5C | x7C Wartość filename nie może kończyć się kropką. name (element opcjonalny, ale zalecany) Tytuł wyświetlany przez instalator aplikacji AIR. Po określeniu pojedynczego węzła text (zamiast wielu elementów text) instalator aplikacji AIR korzysta z tej nazwy bez względu na język systemu: <name>Test Application</name> Schemat deskryptora aplikacji AIR 1.0 zezwala na zdefiniowanie tylko jednego prostego węzła text dla nazwy (zamiast wielu elementów text). W środowisku AIR 1.1 (lub nowszym) można określić wiele języków w elemencie name. Przykład: poniżej przedstawiono nazwę w trzech językach (angielskim, francuskim i hiszpańskim): <name> <text xml:lang="en">Hello AIR</text> <text xml:lang="fr">Bonjour AIR</text> <text xml:lang="es">Hola AIR</text> </name> Atrybut xml:lang dla każdego elementu text określa kod języka zdefiniowany w normie RFC4646 (http://www.ietf.org/rfc/rfc4646.txt). Instalator aplikacji AIR korzysta z nazwy, która jest najbliższa językowi interfejsu systemu operacyjnego użytkownika. Na przykład: należy rozważyć instalację, w której element name pliku deskryptora aplikacji zawiera wartość ustawień narodowych en (angielski). Instalator aplikacji AIR korzysta z nazwy en pod warunkiem, że system operacyjny identyfikuje en (angielski) jako język interfejsu użytkownika. Korzysta z nazwy en również wówczas, gdy język interfejsu systemu operacyjnego to en-US (angielski USA). Jeśli jednak język interfejsu użytkownika to en-US, a plik deskryptora aplikacji definiuje nazwy en-US i en-GB, wówczas instalator aplikacji AIR korzysta z wartości en-US. Jeśli aplikacja nie definiuje nazwy zgodnej z językami interfejsu użytkownika systemu, wówczas instalator aplikacji AIR korzysta z pierwszej wartości name zdefiniowanej w pliku deskryptora aplikacji. Jeśli nie określono elementu name, instalator aplikacji AIR wyświetla wartość filename jako nazwę pliku. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 50 Definiowanie ustawień aplikacji AIR Element name definiuje tylko tytuł aplikacji używany w instalatorze aplikacji AIR. Instalator aplikacji AIR obsługuje wiele języków: chiński tradycyjny, chiński uproszczony, czeski, holenderski, angielski, francuski, niemiecki, włoski, japoński, koreański, polski, portugalski (Brazylia), rosyjski, hiszpański, szwedzki i turecki. Instalator aplikacji AIR wybiera język wyświetlany (dla tekstu innego niż tytuł i opis aplikacji) na podstawie języka interfejsu użytkownika systemu. Wybór języka jest uzależniony od ustawień w pliku deskryptora aplikacji. Element name nie definiuje ustawień narodowych dostępnych dla aplikacji działającej, zainstalowanej. Szczegółowe informacje na temat programowania aplikacji wielojęzycznych zawiera sekcja „Lokalizowanie aplikacji AIR” na stronie 346. description (opcjonalny) Opis aplikacji wyświetlany w instalatorze aplikacji AIR. Po określeniu pojedynczego węzła text (zamiast wielu elementów text) instalator aplikacji AIR korzysta z tego opisu bez względu na język systemu: <description>This is a sample AIR application.</description> Schemat deskryptora aplikacji AIR 1.0 zezwala na zdefiniowanie tylko jednego prostego węzła text dla nazwy (zamiast wielu elementów text). W środowisku AIR 1.1 (lub nowszym) można określić wiele języków w elemencie description. Przykład: poniżej przedstawiono opis w trzech językach (angielskim, francuskim i hiszpańskim): <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> Atrybut xml:lang dla każdego elementu text określa kod języka zdefiniowany w normie RFC4646 (http://www.ietf.org/rfc/rfc4646.txt). Instalator aplikacji AIR korzysta z opisu, który jest najbliższy językowi interfejsu systemu operacyjnego użytkownika. Na przykład: należy rozważyć instalację, w której element description pliku deskryptora aplikacji zawiera wartość ustawień narodowych en (angielski). Instalator aplikacji AIR korzysta z nazwy en pod warunkiem, że system użytkownika identyfikuje en (angielski) jako język interfejsu użytkownika. Korzysta z nazwy en również wówczas, gdy język interfejsu systemu operacyjnego to en-US (angielski USA). Jeśli jednak język interfejsu użytkownika to en-US, a plik deskryptora aplikacji definiuje nazwy en-US i en-GB, wówczas instalator aplikacji AIR korzysta z wartości en-US. Jeśli aplikacja nie definiuje nazwy zgodnej z językiem interfejsu użytkownika systemu, wówczas instalator aplikacji AIR korzysta z pierwszej wartości description zdefiniowanej w pliku deskryptora aplikacji. Więcej informacji na temat programowania aplikacji wielojęzycznych zawiera sekcja „Lokalizowanie aplikacji AIR” na stronie 346. copyright (opcjonalny) Informacje o prawach autorskich dotyczących aplikacji AIR. W systemie Mac OS tekst dotyczący praw autorskich pojawia się w oknie dialogowym informacji dla zainstalowanej aplikacji. W systemie Mac OS informacje o prawach autorskich są również wykorzystywane w polu NSHumanReadableCopyright w pliku Info.plist aplikacji. Definiowanie folderu instalacyjnego i folderu menu programu Foldery instalacyjne i foldery menu programu są zdefiniowane z następującymi ustawieniami właściwości: <installFolder>Acme</installFolder> <programMenuFolder>Acme/Applications</programMenuFolder> installFolder (opcjonalny) Identyfikuje podkatalog domyślnego katalogu instalacyjnego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 51 Definiowanie ustawień aplikacji AIR W systemie Windows domyślnym folderem instalacyjnym jest katalog Program Files. W systemie Mac OS jest to katalog /Applications. W systemie Linux jest to katalog /opt/. Na przykład: jeśli właściwość installFolder jest ustawiona na "Acme", a aplikacja ma nazwę "ExampleApp", wówczas aplikacja zostanie zainstalowana w folderze C:\Program Files\Acme\ExampleApp w systemie Windows, w folderze /Applications/Acme/Example.app w systemie MacOS i w folderze /opt/Acme/ExampleApp w systemie Linux. Znak ukośnika w prawo (/) powinien być używany jako znak separatora katalogu, jeśli wymagane jest określenie podkatalogu zagnieżdżonego, jak poniżej: <installFolder>Acme/Power Tools</installFolder> Właściwość installFolder może zawierać dowolne znaki Unicode (UTF-8) z wyjątkiem znaków, których użycie jest zabronione w nazwach folderów w różnych systemach plików (listę wyjątków przedstawiono w opisie właściwości filename). Właściwość installFolder jest opcjonalna. Jeśli właściwość installFolder nie zostanie określona, wówczas aplikacja zostanie zainstalowana w domyślnym katalogu instalacyjnym, zgodnie z właściwością name. programMenuFolder (opcjonalny) Identyfikuje lokalizację, do której należy wprowadzić skróty dot. aplikacji z menu Wszystkie programy systemu operacyjnego Windows lub z menu Applications systemu Linux. (To ustawienie jest aktualnie ignorowane w innych systemach operacyjnych). Ograniczenia dotyczące znaków dozwolonych w wartości właściwości są takie same, jak ograniczenia dotyczące właściwości installFolder. Znak ukośnika w prawo (/) nie może być używany jako ostatni znak w tej wartości. Definiowanie właściwości początkowego okna aplikacji Po załadowaniu aplikacji AIR środowisko wykonawcze korzysta z wartości elementu initialWindow w celu utworzenia początkowego okna aplikacji. Następnie środowisko wykonawcze ładuje plik SWF lub HTML określony w elemencie content do okna. Poniżej przedstawiono przykład elementu 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> Elementy podrzędne elementu initialWindow ustawiają właściwości okna, do którego ładowany jest nadrzędny plik treści. content Wartość określona dla elementu content jest adresem URL głównego pliku treści aplikacji. Może to być plik SWF lub HTML. Adres URL jest określony względem głównego katalogu folderu instalacyjnego aplikacji. (W przypadku uruchomienia aplikacji AIR za pomocą programu ADL adres URL jest określony względem folderu zawierającego plik deskryptora aplikacji. W celu określenia innego katalogu głównego należy określić parametr rootdir programu ADL). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 52 Definiowanie ustawień aplikacji AIR Uwaga: Wartość elementu content jest traktowana jako adres URL, dlatego znaki w nazwie pliku content muszą być zapisane w kodzie URL zgodnie z regułami zdefiniowanymi w normie RFC 1738. Na przykład: znaki spacji muszą być zakodowane jako %20. title (opcjonalny) Tytuł okna. systemChrome (opcjonalny) Jeśli ten atrybut zostanie ustawiony na wartość standard, zostanie wyświetlona standardowa karnacja systemowa dostępna w systemie operacyjnym. Jeśli zostanie ustawiona wartość none, żadna karnacja systemowa nie zostanie wyświetlona. W środowisku wykonawczym nie można zmienić ustawienia karnacji systemowej. transparent (opcjonalny) Wartość "true", jeśli wymagana jest obsługa mieszania alfa w oknie aplikacji. Okno, dla którego wybrano przezroczystość, może być wyświetlane wolniej i wykorzystywać więcej pamięci. Ustawienia przezroczystości nie można zmienić w środowisku wykonawczym. Ważne: Dla elementu transparent można ustawić wartość true, gdy element systemChrome ma wartość none. visible (opcjonalny) Element ma wartość true, jeśli główne okno ma być widoczne bezpośrednio po utworzeniu. Wartością domyślną jest false. Okno główne może być początkowo ukryte — wówczas zmiany położenia i wielkości okna oraz układu składników w oknie nie będą widoczne od razu. Następnie można wyświetlić okno poprzez wywołanie metody activate() okna lub poprzez ustawienie dla właściwości visible wartości true. Szczegółowe informacje zawiera sekcja „Praca z oknami rodzimymi” na stronie 60. x, y, width, height (opcjonalne) Początkowe ustawienie krawędzi okna głównego aplikacji. Jeśli te wartości nie zostaną określone, wówczas wielkość okna zostanie określona poprzez ustawienia głównego pliku SWF lub — w przypadku HTML — przez system operacyjny. minSize, maxSize (opcjonalne) Minimalne i maksymalne rozmiary okna. Jeśli te wartości nie zostaną ustawione, określi je system operacyjny. minimizable, maximizable, resizable (opcjonalne) Określa, czy okno może być minimalizowane, maksymalizowane oraz czy możliwa jest zmiana jego wielkości. Domyślnie te ustawienia mają wartość true. Uwaga: W systemach operacyjnych, takich jak Mac OS X, w których maksymalizowanie jest operacją zmiany rozmiaru, dla elementów maximizable i resizable należy ustawić wartość false, aby zapobiec powiększaniu okna lub zmianie jego wielkości. Określanie plików ikon Właściwość icon określa jeden lub większą liczbę plików ikon, jakie mogą być używane dla aplikacji. Dołączenie ikony jest opcjonalne. Jeśli właściwość icon nie zostanie określona, wówczas system operacyjny wyświetla ikonę domyślną. Ścieżka jest określona względem katalogu głównego aplikacji. Pliki ikon muszą być w formacie PNG. Możliwe jest określenie ikon we wszystkich następujących rozmiarach: <icon> <image16x16>icons/smallIcon.png</image16x16> <image32x32>icons/mediumIcon.png</image32x32> <image48x48>icons/bigIcon.png</image48x48> <image128x128>icons/biggestIcon.png</image128x128> </icon> Jeśli istnieje element określonego rozmiaru, obraz w pliku musi być dokładnie zgodny z określonym rozmiarem. Jeśli nie są dostępne wszystkie rozmiary, wówczas zmieniana jest skala rozmiaru najbliższego dla określonego zastosowania ikony przez system operacyjny. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 53 Definiowanie ustawień aplikacji AIR Uwaga: Określone ikony nie są automatycznie dodawane do pakietu AIR. Podczas pakowania aplikacji pliki ikon musza być dołączane do odpowiednich lokalizacji względnych. W celu zapewnienia najlepszych rezultatów należy udostępnić obraz dla każdego z dostępnych rozmiarów. Ponadto należy się upewnić, że ikony wyglądają odpowiednio w trybach koloru 16- i 32-bitowego. Udostępnienie niestandardowego interfejsu aplikacji dla aktualizacji aplikacji Środowisko AIR instaluje i aktualizuje aplikacje za pomocą domyślnych okien dialogowych instalacji. Jednak można udostępnić własny interfejs użytkownika dla aktualizowania aplikacji. W celu wskazania, że aplikacja powinna samodzielnie zająć się procesem aktualizowania, należy ustawić dla elementu customUpdateUI wartość true: <customUpdateUI>true</customUpdateUI> Jeśli element customUpdateUI zainstalowanej wersji aplikacji jest ustawiony na true, a użytkownik kliknie dwukrotnie plik AIR dla nowej wersji lub zainstaluje aktualizację aplikacji za pomocą funkcji instalacji bezproblemowej, wówczas środowisko operacyjne otworzy zainstalowaną wersję aplikacji zamiast domyślnego instalatora aplikacji AIR. Logika aplikacji może wówczas określić sposób kontynuowania operacji aktualizacji. (Identyfikator aplikacji i identyfikator wydawcy w pliku AIR muszą być zgodne z identyfikatorami w zainstalowanej aplikacji — tylko wówczas możliwe będzie kontynuowanie aktualizacji). Uwaga: Mechanizm customUpdateUI jest uwzględniany tylko wówczas, gdy aplikacja jest już zainstalowana, a użytkownik kliknie dwukrotnie plik instalacyjny AIR zawierający aktualizację lub zainstaluje aktualizację aplikacji przy użyciu funkcji instalowania bezproblemowego. Aktualizację można pobrać i uruchomić za pośrednictwem logiki aplikacji, wyświetlając w razie potrzeby własny interfejs użytkownika, niezależnie od tego, czy dla customUpdateUI ustawiona jest wartość true. Więcej informacji zawiera sekcja „Aktualizowanie aplikacji AIR” na stronie 331. Zezwalanie na wywoływanie aplikacji z przeglądarki Jeśli poniższe ustawienie zostanie określone, wówczas zainstalowana aplikacja może być uruchamiana za pośrednictwem funkcji wywołania z przeglądarki (gdy użytkownik kliknie odsyłacz na stronie w przeglądarce sieci Web): <allowBrowserInvocation>true</allowBrowserInvocation> Wartością domyślną jest false. Jeśli dla wartości zostanie ustawiona wartość true, wówczas należy rozważyć zagadnienia związane z bezpieczeństwem opisane w sekcji „Wywołanie z przeglądarki” na stronie 296. Więcej informacji zawiera sekcja „Instalowanie i uruchamianie aplikacji AIR ze strony internetowej” na stronie 315. Deklarowanie skojarzeń typów plików Element fileTypes umożliwia deklarowanie typów plików, z którymi można kojarzyć aplikacje AIR. Po zainstalowaniu aplikacji AIR wszystkie zadeklarowane typy plików zostają zarejestrowane w systemie operacyjnym, a jeśli te typy plików nie są jeszcze skojarzone z inną aplikacją, wówczas są kojarzone z aplikacją AIR. W celu zastąpienia istniejącego skojarzenia między typem pliku a inną aplikacją należy użyć metody NativeApplication.setAsDefaultApplication() w środowisku wykonawczym (najlepiej za zgodą użytkownika). Uwaga: Metody środowiska wykonawczego mogą zarządzać tylko skojarzeniami dla typów plików zadeklarowanych w deskryptorze aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 54 Definiowanie ustawień aplikacji 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> Element fileTypes jest opcjonalny. Może zawierać dowolną liczbę elementów fileType. Elementy name i extension są wymagane dla każdej deklaracji fileType, która zostanie określona. Ta sama nazwa może zostać użyta dla wielu rozszerzeń. Rozszerzenie w sposób jednoznaczny identyfikuje typ pliku. (Rozszerzenie jest określone bez poprzedzającej kropki). Element description jest opcjonalny i jest wyświetlany użytkownikowi w interfejsie użytkownika systemu operacyjnego. Właściwość contentType jest wymagana w środowisku AIR 1.5 (była właściwością opcjonalną w środowisku AIR 1.0 i 1.1). Właściwość ułatwia systemowi operacyjnemu lokalizowanie najlepszej aplikacji do otwarcia pliku w określonych okolicznościach. Wartość powinna być typem MIME dla treści pliku. Należy zauważyć, że wartość jest ignorowana w systemie Linux, jeśli typ pliku jest już zarejestrowany i ma przypisany typ MIME. Ikony mogą być określone dla rozszerzenia pliku przy użyciu tego samego formatu, który obowiązuje dla elementu ikony aplikacji. Pliki ikon należy dołączyć do pliku instalacyjnego AIR (nie są pakowane automatycznie). Jeśli typ pliku jest skojarzony z aplikacją AIR, aplikacja zostanie wywołana, gdy użytkownik otworzy plik tego typu. Jeśli aplikacja już działa, wówczas środowisko AIR wywoła obiekt InvokeEvent dla działającej instancji. W przeciwnym wypadku środowisko AIR najpierw uruchomi aplikację. W obydwu przypadkach ścieżkę do pliku można uzyskać z obiektu InvokeEvent wywołanego przez obiekt NativeApplication. Ta ścieżka może służyć do otwarcia pliku. Więcej informacji zawierają sekcje „Zarządzanie skojarzeniami plików” na stronie 301 i „Przechwytywanie argumentów wiersza poleceń” na stronie 294. 55 Rozdział 9: Adobe AIR – charakterystyczne funkcje Ten temat zawiera przegląd funkcji środowiska Adobe® AIR™ dostępnych dla treści SWF działającej w programie Adobe® Flash® Player. Klasy charakterystyczne dla środowiska AIR Poniższe klasy środowiska wykonawczego są charakterystyczne dla produktu Adobe AIR. Nie są one dostępne dla zawartości pliku SWF uruchomionego w przeglądarce: Klasa Pakiet 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 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 56 Adobe AIR – charakterystyczne funkcje Klasa Pakiet 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 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 57 Adobe AIR – charakterystyczne funkcje Klasa Pakiet 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 Pakiet flash.security również zawiera interfejs IURIDereferencer, który jest charakterystyczny dla środowiska AIR. Klasy środowiska wykonawczego z funkcjami charakterystycznymi dla produktu AIR Następujące klasy są dostępne dla zawartości SWF uruchomionej w przeglądarce, AIR udostępnia jednak dodatkowe właściwości i metody: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 58 Adobe AIR – charakterystyczne funkcje Klasa Właściwość lub metoda Capabilities languages 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 Większość nowych właściwości lub metod jest dostępna wyłącznie dla treści w obszarze izolowanym w aplikacji AIR. Jednak nowe elementy w klasie URLRequest są również dostępne dla treści działającej w innych obszarach izolowanych. Metody ByteArray.compress() i ByteArray.uncompress() zawierają nowy parametr algorithm, który umożliwia wybieranie kompresji deflate i zlib. Ten parametr jest dostępny tylko dla treści działającej w środowisku AIR. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 59 Adobe AIR – charakterystyczne funkcje Klasy infrastruktury monitorowana usług Pakiet air.net zawiera klasy wykrywania sieci. Ten pakiet dostępny jest wyłącznie dla treści działającej w środowisku Adobe AIR. Jest on zawarty w pliku ServiceMonitor.swc. W pakiecie znajdują się następujące klasy: • ServiceMonitor • SocketMonitor • URLMonitor 60 Rozdział 10: Praca z oknami rodzimymi Klasy dostarczane przez interfejs API rodzimych okien w środowisku Adobe® AIR® służą do tworzenia i zarządzania oknami pulpitu. Dodatkowe informacje online o rodzimych oknach Więcej informacji na temat interfejsu API okien rodzimych i pracy z oknami rodzimymi zawierają następujące źródła: Podręczniki Szybki start (Adobe AIR Developer Connection) • Interakcja z oknem • Dostosowywanie wyglądu i działania rodzimego okna • Tworzenie okien o wyglądzie „kanapkowym” • Sterowanie kolejnością wyświetlania okien • Tworzenie nieprostokątnych okien o zmiennej wielkości Skorowidz języka • NativeWindow • NativeWindowInitOptions Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR windows”) Podstawowe informacje o oknach w środowisku AIR Środowisko AIR udostępnia łatwy w użyciu międzyplatformowy interfejs API okien do tworzenia rodzimych okien systemu operacyjnego za pomocą środowiska Flash®, Flex™ oraz techniki programowania w języku HTML. Dzięki środowisku AIR programista ma dużą swobodę w tworzeniu wyglądu aplikacji. Okna tworzone przez użytkownika mogą wyglądać jak standardowa aplikacja lokalna zgodna ze stylem wizualnym produktów Apple — są uruchamiane na komputerze Mac; mogą być równocześnie zgodne z konwencjami firmy Microsoft — gdy są uruchamiane na komputerze z systemem Windows; i jednocześnie zgodne z menedżerem okien systemu Linux. A wszystko to bez konieczności napisania nawet jednego wiersza kodu specyficznego dla konkretnej platformy. Można również użyć rozszerzalnej karnacji systemowej, dostarczanej przez środowisko Flex w celu utworzenia własnego stylu niezależnie od systemu, na którym uruchamiana jest aplikacja. Możliwe jest również rysowanie własnych karnacji okien za pomocą kompozycji wektorowej i bitmapowej w pełni obsługującej przeźroczystość i mieszanie kanału alfa dla pulpitu. Znudzony prostokątnymi oknami? Narysuj okrągłe. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 61 Praca z oknami rodzimymi Okna w środowisku AIR Środowisko AIR obsługuje trzy różne interfejsy API do pracy z oknami: • Klasa NativeWindow zorientowana na język ActionScript udostępnia interfejs API najniższego poziomu dla okna. Klasy NativeWindows należy używać w aplikacjach pisanych w języku ActionScript i Flash CS. Należy rozważyć rozszerzenie klasy NativeWindow w celu wyspecjalizowania okien w aplikacji użytkownika. • Klasy mx:WindowedApplication i mx:Window środowiska Flex udostępniają „opakowanie” Flex dla klasy NativeWindow. Składnik WindowedApplication zastępuje składnik Application podczas tworzenia aplikacji AIR za pomocą środowiska Flex i musi być zawsze używany jako okno początkowe aplikacji Flex. • W środowisku HTML można używać klasy JavaScript Window, tak jak w aplikacji sieci Web działającej w przeglądarce. Wywołania metod JavaScript Window są przekazywane do podstawowego obiektu rodzimego okna. Okna w języku ActionScript Podczas tworzenia okien za pomocą klasy NativeWindow należy bezpośrednio korzystać ze stołu montażowego i listy wyświetlania programu Flash Player. Aby dodać do NativeWindow obiekt ekranowy, należy dodać obiekt do listy wyświetlania dla stołu montażowego okna lub do innego kontenera obiektu wyświetlanego stołu montażowego. Okna środowiska Flex Środowisko Flex definiuje własne składniki okna, które opakowują interfejs API NativeWindow. Składników tych (mx:WindowedApplication i mx:Window) nie można używać poza środowiskiem, dlatego też nie można ich używać w aplikacjach AIR utworzonych za pomocą programu Flash CS. Okna HTML Podczas tworzenia okien HTML do wyświetlania treści należy używać języka HTML, CSS i JavaScript. Aby dodać obiekt ekranowy do okna HTML, należy dodać tę treść do modelu DOM HTML. Okna HTML są specjalną kategorią NativeWindow. Host środowiska AIR definiuje właściwość nativeWindow w oknach HTML, która zapewnia dostęp do podstawowej instancji NativeWindow. Można użyć tej właściwości w celu uzyskania dostępu do właściwości, metod i zdarzeń NativeWindow opisanych w tej części. Uwaga: Obiekt Window języka JavaScript zawiera również metody wywoływania skryptów w oknie, w którym są zawarte, np. moveTo() i close(). W miejscach, w których dostępne są metody przysłaniające, można użyć najdogodniejszej metody. Początkowe okno aplikacji Pierwsze okno aplikacji jest automatycznie tworzone za programistę przez środowisko AIR. Środowisko AIR ustawia właściwości i treść okna za pomocą parametrów określonych w elemencie initialWindow pliku deskryptora aplikacji. Jeśli główną treścią jest plik SWF, środowisko AIR utworzy instancję NativeWindow, załaduje plik SWF i doda go do stołu montażowego okna. Jeśli główną treścią jest plik HTML, środowisko AIR utworzy okno HTML i załaduje plik HTML. Więcej informacji na temat właściwości okna określonych w deskryptorze aplikacji zawiera sekcja „Struktura pliku deskryptora aplikacji” na stronie 45. Klasy rodzimych okien Interfejs API rodzimych okien zawiera następujące klasy: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 62 Praca z oknami rodzimymi Pakiet Klasy flash.display • NativeWindow • NativeWindowInitOptions • NativeWindowDisplayState • NativeWindowResize • NativeWindowSystemChrome • NativeWindowType Stałe ciągi znaków okien zdefiniowane są w następujących klasach: flash.events • NativeWindowDisplayState • NativeWindowResize • NativeWindowSystemChrome • NativeWindowType • NativeWindowBoundsEvent • NativeWindowDisplayStateEvent Strumień zdarzenia rodzimego okna Rodzime okna wywołują zdarzenia, aby powiadomić powiązane składniki, że wkrótce nastąpi lub już nastąpiła istotna zmiana. Wiele zdarzeń związanych z oknami jest wywoływanych parami. Pierwsze zdarzenie ostrzega o tym, że wkrótce nastąpi zmiana. Drugie zdarzenie informuje o dokonaniu zmiany. Zdarzenie ostrzegawcze można anulować, ale nie można anulować zdarzenia powiadamiającego. Poniższa sekwencja ilustruje strumień zdarzeń, który występuje w momencie kliknięcia przez użytkownika przycisku maksymalizacji okna: 1 Obiekt NativeWindow wywołuje zdarzenie displayStateChanging. 2 Jeśli żaden z zarejestrowanych detektorów nie anuluje zdarzenia, okno zostanie zmaksymalizowane. 3 Obiekt NativeWindow wywołuje zdarzenie displayStateChange. Ponadto obiekt NativeWindow wywołuje także zdarzenia związane ze zmianą rozmiaru i położenia okna. Okno nie wywołuje zdarzeń ostrzegawczych dla tych zmian. Powiązane zdarzenia to: a Zdarzenie move jest wywoływane, gdy lewy górny róg okna zostanie przesunięty z powodu operacji maksymalizacji okna. b Zdarzenie resize jest wywoływane, gdy rozmiar okna zostanie zmieniony z powodu operacji maksymalizacji okna. Obiekt NativeWindow wywołuje podobną sekwencję zdarzeń podczas minimalizowania, przywracania, zamykania, przesuwania i zmiany rozmiaru okna. Zdarzenia ostrzegawcze są wywoływane tylko wtedy, gdy zmiana jest inicjowana przez karnację własną okna lub inny mechanizm sterowany przez system operacyjny. W momencie wywołania metody okna w celu zmiany jego rozmiaru i położenia lub wyświetlenia stanu okno wywoła tylko zdarzenie informujące o zmianie. W razie potrzeby zdarzenie ostrzegawcze można wywołać za pomocą metody dispatchEvent(), a następnie sprawdzić, czy zdarzenie ostrzegawcze zostało anulowane przed wykonaniem zmiany. Szczegółowe informacje o klasach, metodach, właściwościach i zdarzeniach interfejsu API okien zawiera Skorowidz języka i składników ActionScript 3.0 (http://www.adobe.com/go/learn_flash_aslr_pl). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 63 Praca z oknami rodzimymi Ogólne informacje na temat korzystania z listy wyświetlania w programie Flash zawiera sekcja „Programowanie wyświetlania” w odwołaniu Programowanie w języku Adobe ActionScript 3.0 (http://www.adobe.com/go/learn_fl_cs4_programmingAS3_pl). Właściwości sterujące stylem i zachowaniem rodzimego okna Poniższe właściwości sterują podstawowym wyglądem i zachowaniem okna: • type • systemChrome • transparent Podczas tworzenia okna należy ustawić te właściwości w obiekcie NativeWindowInitOptions przekazywanym do konstruktora okna. Środowisko AIR odczytuje właściwości dla początkowego okna aplikacji z deskryptora aplikacji. (Poza właściwością type, której nie można ustawić w deskryptorze aplikacji i ma zawsze wartość normal). Właściwości nie można zmienić po utworzeniu okna. Niektóre ustawienia tych właściwości wykluczają się: właściwości systemChrome nie można ustawić na standard, jeśli właściwość transparent ma wartość true lub właściwość type ma wartość lightweight. Typy okien Typy okien w środowisku AIR łączą atrybuty chrome i visibility rodzimego systemu operacyjnego w celu utworzenia trzech funkcjonalnych typów okien. Aby odwołać się do nazw typów w kodzie, należy użyć stałych zdefiniowanych w klasie NativeWindowType. Środowisko AIR dostarcza następujące typy okien: Typ Opis Normal Zwykłe okno. Okna typu normal mają pełny rozmiar karnacji systemowej i są wyświetlane na pasku zadań systemu Windows oraz w menu okna systemu Mac OS X. Utility Paleta narzędzi. Okna typu utility korzystają z węższej wersji karnacji systemowej i nie są wyświetlane na pasku zadań systemu Windows oraz w menu okna systemu Mac OS X. Lightweight Okna typu lightweight nie mają karnacji systemowej i nie są wyświetlane na pasku zadań systemu Windows oraz w menu okna systemu Mac OS X. Ponadto okna typu lightweight nie mają menu systemowego dostępnego w systemie Windows za pośrednictwem klawiszy Alt+spacja. Okna typu lightweight są odpowiednie dla okien powiadomień i elementów sterowania (np. pola listy kombinowanej), które aktywują obszary wyświetlania o krótkim czasie życia. Jeśli używana jest właściwość type o wartości lightweight, właściwość systemChrome należy ustawić na none. Karnacja okna Karnacja okna jest zestawem elementów sterowania umożliwiającym użytkownikom manipulowanie oknem na pulpicie. Elementy karnacji to: pasek tytułowy, przyciski paska tytułowego, obwiednia i uchwyty zmiany rozmiaru. Karnacja systemowa Właściwość systemChrome można ustawić na wartość standard lub none. Aby przypisać do okna zestaw standardowych elementów sterowania utworzonych przez system operacyjny użytkownika i mających jego styl, należy wybrać dla karnacji systemowej wartość standard. Aby dostarczyć własną karnację dla okna, należy wybrać wartość none. Aby odwołać się do ustawień karnacji systemowej w kodzie, należy użyć stałych zdefiniowanych w klasie NativeWindowSystemChrome. Karnacją systemową zarządza system. Aplikacja nie ma bezpośredniego dostępu do elementów sterowania, ale może reagować na zdarzenia wywoływane w momencie ich użycia. Podczas korzystania ze standardowej karnacji dla okna właściwość transparent należy ustawić na wartość false, a właściwość type na wartość normal lub utility. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 64 Praca z oknami rodzimymi Karnacja niestandardowa Jeśli tworzone jest okno bez karnacji systemowej, wówczas należy dodać własne elementy sterowania karnacji, aby obsłużyć interakcję między użytkownikiem a oknem. Programista ma wtedy również możliwość swobodnego tworzenia przezroczystych, nieprostokątnych okien. Przezroczystość okna Aby umożliwić mieszanie kanału alfa okna z pulpitem lub innymi oknami, należy ustawić właściwość transparent okna na wartość true. Właściwość transparent należy ustawić przed utworzeniem okna i nie można jej zmienić. Przezroczyste okno nie ma domyślnego tła. Każdy obszar okna, który nie zawiera obiektu narysowanego przez aplikację, jest niewidoczny. Jeśli wyświetlany obiekt ma dla kanału alfa ustawioną wartość mniejszą od jednego, wówczas wszystko co znajduje się pod obiektem jest widoczne, łącznie z innymi wyświetlanymi obiektami tego samego okna, innymi oknami i pulpitem. Renderowanie dużych obszarów z mieszaniem kanału alfa może być powolne, dlatego należy tego efektu używać z umiarem. Przezroczyste okna są użyteczne, gdy zachodzi konieczność utworzenia aplikacji z nieregularnymi krawędziami lub krawędziami, które „zanikają” lub są niewidoczne. Ważne: W systemie Linux zdarzenia myszy nie są przekazywane przez piksele o pełnej przezroczystości. Należy unikać tworzenia okien z dużymi obszarami o pełnej przezroczystości, ponieważ można w ten sposób zablokować użytkownikowi dostęp do innych okien lub elementów na jego pulpicie. W systemach Mac OS i Windows zdarzenia myszy są przekazywane przez piksele o pełnej przezroczystości. Przezroczystości nie można używać w oknach, które mają karnację systemową. Ponadto treść SWF i PDF w kodzie HTML nie jest wyświetlana w przezroczystych oknach. Więcej informacji zawiera sekcja „Zagadnienia dotyczące ładowania treści SWF lub PDF na stronie HTML” na stronie 261. W niektórych systemach operacyjnych przezroczystość może nie być obsługiwana ze względu na konfigurację sprzętu lub oprogramowania lub opcje wyświetlania użytkownika. Jeśli przezroczystość nie jest obsługiwana, aplikacja jest składana na czarnym tle. W takim przypadku każdy przezroczysty obszar aplikacji zostanie wyświetlony jako nieprzezroczysty czarny obszar. Właściwość statyczna NativeWindow.supportsTransparency informuje o tym, czy dostępna jest przezroczystość okna. Jeśli test tej właściwości da w wyniku wartość false, programista może na przykład wyświetlić użytkownikowi okno dialogowe z ostrzeżeniem lub wyświetlić awaryjny, prostokątny i nieprzezroczysty interfejs użytkownika. Należy zauważyć, że przezroczystość jest zawsze obsługiwana w systemach operacyjnych Mac i Windows. Obsługa w systemach operacyjnych Linux wymaga kompozytowego menedżera okien, ale nawet jeśli kompozytowy menedżer okien jest aktywny, przezroczystość może być niedostępna ze względu na opcje wyświetlania użytkownika lub konfigurację sprzętową. Przezroczystość w oknie aplikacji HTML Domyślnie tło treści HTML wyświetlanej w oknach HTML i obiektach HTMLLoader jest nieprzezroczyste, nawet jeśli okno je zawierające jest przezroczyste. Aby wyłączyć domyślne tło wyświetlane dla treści HTML, należy ustawić właściwość paintsDefaultBackground na wartość false. Poniższy przykład tworzy obiekt HTMLLoader i wyłącza domyślne tło: var html:HTMLLoader = new HTMLLoader(); html.paintsDefaultBackground = false; W przykładzie tym kod JavaScript używany jest do wyłączenia domyślnego tła okna HTML: window.htmlLoader.paintsDefaultBackground = false; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 65 Praca z oknami rodzimymi Jeśli element dokumentu HTML ustawi kolor tła, tło tego elementu nie będzie przezroczyste. Ustawienie wartości częściowej przezroczystości (lub krycia) nie jest obsługiwane. Można jednak użyć przezroczystej grafiki w formacie PNG jako tła dla strony lub elementu strony w celu otrzymania podobnego efektu wizualnego. Wizualny katalog okien Poniższa tabela ilustruje efekty wizualne różnych kombinacji ustawień właściwości okna w systemach operacyjnych Mac OS X, Windows i Linux: Ustawienia okna Type: normal SystemChrome: standard Transparent: false Type: utility SystemChrome: standard Transparent: false Mac OS X Microsoft Windows Linux* TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 66 Praca z oknami rodzimymi Ustawienia okna Mac OS X Microsoft Windows Linux* Type: dowolne SystemChrome: none Transparent: false Type: dowolne SystemChrome: none Transparent: true mxWindowedApplication lub mx:Window Type: dowolne SystemChrome: none Transparent: true * System Ubuntu z menedżerem okien Compiz Uwaga: Poniższe elementy karnacji systemowej nie są obsługiwane w środowisku AIR: pasek narzędziowy Mac OS X, ikona proxy Mac OS X, ikony paska tytułowego Windows i alternatywne karnacje systemowe. Tworzenie okien Środowisko AIR automatycznie tworzy pierwsze okno dla aplikacji, ale możliwe jest utworzenie dowolnych dodatkowych okien. Aby utworzyć rodzime okno, należy użyć metody konstruktora NativeWindow. Aby utworzyć okno HTML, należy użyć metody createRootWindow() obiektu HTMLLoader lub wywołać z dokumentu HTML metodę window.open() języka JavaScript. Określanie właściwości inicjowania okna Właściwości inicjowania okna nie można zmienić po utworzeniu okna pulpitu. Stałe właściwości i ich wartości domyślne: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 67 Praca z oknami rodzimymi Właściwość Wartość domyślna systemChrome standard type normal transparent false maximizable true minimizable true resizable true Właściwości należy ustawić dla początkowego okna utworzonego przez środowisko AIR w pliku deskryptora aplikacji. Główne okno aplikacji AIR jest zawsze typu normal. (Dodatkowe właściwości okna można określić w pliku deskryptora np. visible, width i height, ale te właściwości można zmienić w dowolnym momencie). Właściwości należy ustawić dla innych rodzimych okien i okien HTML utworzonych przez aplikację za pomocą klasy NativeWindowInitOptions. Po utworzeniu okna należy przekazać obiekt NativeWindowInitOptions, określając właściwości okna w funkcji konstruktora NativeWindow lub metodzie createRootWindow() obiektu HTMLLoader. Poniższy kod tworzy obiekt NativeWindowInitOptions dla okna typu utility: var options:NativeWindowInitOptions = new NativeWindowInitOptions(); options.systemChrome = NativeWindowSystemChrome.STANDARD; options.type = NativeWindowType.UTILITY options.transparent = false; options.resizable = false; options.maximizable = false; Ustawienie właściwości systemChrome na wartość standard, gdy właściwość transparent o wartości true lub type o wartości lightweight nie jest obsługiwana. Uwaga: Nie można ustawić właściwości inicjowania dla okna utworzonego za pomocą funkcji window.open() języka JavaScript. Można jednak przysłonić sposób tworzenia okien, implementując własną klasę HTMLHost. Więcej informacji zawiera sekcja „Obsługa wywołań JavaScript do funkcji window.open()” na stronie 270. Tworzenie początkowego okna aplikacji Środowisko AIR tworzy początkowe okno aplikacji w oparciu o właściwości określone w deskryptorze aplikacji i ładuje plik, do którego istnieje odwołanie w elemencie treści. Element treści musi odwoływać się do pliku SWF lub HTML. Początkowe okno może być oknem głównym aplikacji lub może służyć po prostu do uruchamiania jednego lub większej ilości innych okien. Nie musi być ono widoczne. Narzędzie do tworzenia treści Flash automatycznie tworzy plik SWF i dodaje odpowiednie odwołanie do deskryptora aplikacji podczas testowania lub publikowania projektu środowiska AIR. Główna oś czasu służy jako punkt wejścia dla aplikacji. Podczas uruchamiania aplikacji środowisko AIR tworzy okno i ładuje plik SWF aplikacji. Aby sterować oknem pulpitu za pomocą języka ActionScript, należy użyć właściwości nativeWindow obiektu Stage w celu pobrania odwołania do obiektu NativeWindow. Można wówczas ustawić właściwości okna i wywołać jego metody. Poniższy przykład uaktywnia główne okno w stanie zmaksymalizowanym (z pierwszej ramki pliku FLA Flash): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 68 Praca z oknami rodzimymi import flash.display.NativeWindow; var mainWindow:NativeWindow = this.stage.nativeWindow; mainWindow.maximize(); mainWindow.activate(); Tworzenie obiektu NativeWindow Aby utworzyć obiekt NativeWindow, należy przekazać obiekt NativeWindowInitOptions do konstruktora NativeWindow: var options:NativeWindowInitOptions = new NativeWindowInitOptions(); options.systemChrome = NativeWindowSystemChrome.STANDARD; options.transparent = false; var newWindow:NativeWindow = new NativeWindow(options); Okno nie zostanie wyświetlone, dopóki właściwość visible nie zostanie ustawiona na wartość true lub wywołana zostanie metoda activate(). Po utworzeniu okna programista może inicjować jego właściwości i ładować treść do okna za pomocą właściwości stage i technik list wyświetlania Flash. W większości przypadków właściwość scaleMode stołu montażowego nowego okna rodzimego należy ustawić na wartość noScale (w tym celu należy użyć stałej StageScaleMode.NO_SCALE). Tryby skalowania Flash zostały zaprojektowane do obsługi sytuacji, w których autor aplikacji nie zna z wyprzedzeniem proporcji przestrzeni wyświetlania aplikacji. Tryby skalowania umożliwiają autorowi wybranie najmniej niekorzystnego kompromisu: przycięcie treści, jej rozciągnięcie lub ściśnięcie albo wypełnienie pustą przestrzenią. Ponieważ programista ma możliwość sterowania przestrzenią wyświetlania w środowisku AIR (ramka okna), możliwe jest dopasowanie rozmiaru okna do treści lub treści do okna, unikając w ten sposób kompromisu. Uwaga: Aby określić maksymalny i minimalny rozmiar okna dozwolony w bieżącym systemie operacyjnym, należy użyć następujących właściwości statycznych NativeWindow: var maxOSSize:Point = NativeWindow.systemMaxSize; var minOSSize:Point = NativeWindow.systemMinSize; Tworzenie okna HTML Aby utworzyć okno HTML, można wywołać metodę Window.open() JavaScript lub metodę createRootWindow() klasy HTMLLoader AIR. Treść HTML w dowolnym obszarze izolowanym zabezpieczeń może korzystać ze standardowej metody Window.open() JavaScript. Jeśli treść działa poza obszarem izolowanym aplikacji, metoda open() może zostać wywołana tylko w odpowiedzi na interakcję użytkownika np. kliknięcie myszą lub naciśnięcie klawisza. Wywołanie metody open() powoduje utworzenie okna z karnacją systemową w celu wyświetlenia treści dla określonego URL. Na przykład: newWindow = window.open("xmpl.html", "logWindow", "height=600, width=400, top=10, left=10"); Uwaga: Programista może rozszerzyć klasę HTMLHost w kodzie ActionScript, aby dostosować okno utworzone za pomocą funkcji window.open() JavaScript. Patrz „Informacje o rozszerzaniu klasy HTMLHost” na stronie 265. Treść w obszarze izolowanym zabezpieczeń aplikacji ma dostęp do bardziej zaawansowanej metody tworzenia okien — HTMLLoader.createRootWindow(). Za pomocą tej metody możliwe jest określenie wszystkich opcji tworzenia nowego okna. Na przykład: poniższy kod JavaScript tworzy okno typu lightweight bez karnacji systemowej o rozmiarach 300x400 pikseli: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 69 Praca z oknami rodzimymi 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")); Uwaga: Jeśli treść załadowana przez nowe okno znajduje się poza obszarem izolowanym zabezpieczeń aplikacji, obiekt okna nie zawiera właściwości środowiska AIR: runtime, nativeWindow lub htmlLoader. Okna utworzone za pomocą metody createRootWindow() pozostają niezależne w stosunku do okna, z którego zostały otwarte. Właściwości parent i opener obiektu Window języka JavaScript mają wartość null. Okno otwierające może uzyskać dostęp do obiektu Window nowego okna za pomocą odwołania HTMLLoader zwróconego przez funkcję createRootWindow(). W kontekście poprzedniego przykładu instrukcja newHTMLLoader.window będzie odwoływała się do obiektu Window języka JavaScript utworzonego okna. Uwaga: Funkcja createRootWindow() może być wywoływana z kodu JavaScript i ActionScript. Dodawanie treści do okna Sposób, w jaki dodaje się treść do okna środowiska AIR, jest uzależniony od typu okna. Możliwe jest utworzenie klipu filmowego i użycie osi czasu do sterowania stanem aplikacji. Za pomocą HTML możliwe jest deklaratywne definiowanie podstawowej treści okna. Programista może osadzić zasoby w pliku SWF aplikacji lub załadować je z oddzielnych plików aplikacji. Całą treść Flash i HTML można utworzyć „w locie” i dodać do okna dynamicznie. Podczas ładowania treści SWF lub HTML zawierającej kod JavaScript należy wziąć pod uwagę model zabezpieczeń środowiska AIR. Dowolna treść obszaru izolowanego zabezpieczeń aplikacji tj. treść zainstalowana z aplikacją i treść, którą można załadować za pomocą schematu URL app: ma wszystkie uprawnienia, aby uzyskać dostęp do interfejsów API środowiska AIR. Dowolna treść załadowana spoza tego obszaru izolowanego nie uzyska dostępu do interfejsów API środowiska AIR. Treść JavaScript spoza obszaru izolowanego aplikacji nie może używać właściwości runtime, nativeWindow lub htmlLoader obiektu Window języka JavaScript. Aby umożliwić bezpieczne wywoływanie skryptów, można użyć mostu obszaru izolowanego w celu dostarczenia ograniczonego interfejsu między treścią aplikacji a treścią nieaplikacyjną. W treści HTML możliwe jest również odwzorowanie stron aplikacji na nieaplikacyjny obszar izolowany, aby umożliwić kodowi na stronie odwoływanie się do skryptów zewnętrznej treści. Patrz „Zabezpieczenia w środowisku AIR” na stronie 24. Ładowanie pliku SWF lub obrazu Pliki SWF programu Flash lub obrazy można ładować na listę wyświetlania rodzimego okna z użyciem klasy flash.display.Loader: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 70 Praca z oknami rodzimymi 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); } } } Można załadować plik SWF, który zawiera kod biblioteki do użytku w aplikacji opartej na HTML. Najprostszym sposobem na załadowanie pliku SWF do okna HTML jest użycie znacznika script, ale możliwe jest także bezpośrednie użycie interfejsu API Loader. Uwaga: Starsze pliki SWF utworzone za pomocą ActionScript 1 lub 2 współużytkują globalne stany np. definicje klas, obiekty singleton i globalne zmienne, jeśli są ładowane do tego samego okna. Jeśli taki plik SWF w celu poprawnej pracy polega na nietkniętych stanach globalnych, nie może zostać załadowany więcej niż raz do tego samego okna, ani załadowany do tego samego okna jako inny plik SWF z użyciem przysłaniania definicji i zmiennych klasy. Ta treść może być ładowana do oddzielnych okien. Ładowanie treści HTML do obiektu NativeWindow Aby załadować treść HTML do obiektu NativeWindow, można dodać obiekt HTMLLoader na stół montażowy okna i załadować treść HTML do obiektu HTMLLoader lub utworzyć okno, które zawiera już obiekt HTMLLoader, za pomocą metody HTMLLoader.createRootWindow(). W poniższym przykładzie przedstawiono wyświetlanie treści HTML w obszarze wyświetlania 300 na 500 pikseli na stole montażowym rodzimego okna: //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) ); Uwaga: Treść SWF lub PDF w pliku HTML nie jest wyświetlana, jeśli okno używa przezroczystości (tj. właściwość transparent okna ma wartość true) lub został przeskalowany element sterowania HTMLLoader. Dodawanie treści SWF jako nakładki okna HTML Ponieważ okna HTML zawierają się w instancji NativeWindow, programista może dodawać obiekty wyświetlane Flash do listy wyświetlania powyżej i poniżej warstwy HTML. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 71 Praca z oknami rodzimymi Aby dodać obiekt wyświetlania powyżej warstwy HTML, należy użyć metody addChild() właściwości window.nativeWindow.stage. Metoda addChild() dodaje treść ułożoną na warstwie powyżej istniejącej treści w oknie. Aby dodać obiekt wyświetlany poniżej warstwy HTML, należy użyć metody addChildAt() właściwości window.nativeWindow.stage, przekazując w parametrze index wartość zero. Umieszczenie obiektu w miejscu o indeksie zero powoduje przesunięcie istniejącej treści, łącznie z widoczną treścią HTML, w górę o jedną warstwę i wstawienie nowej treści na dole. Aby treść znajdująca się na dolnej warstwie strony HTML była widoczna, należy ustawić właściwość paintsDefaultBackground obiektu HTMLlLoader na wartość false. Ponadto wszystkie elementy strony, dla których ustawiony został kolor tła, nie będą przezroczyste. Jeśli na przykład dla treści strony ustawiony został kolor tła, żadna część strony nie będzie przezroczysta. Poniższy przykład ilustruje sposób dodawania obiektów wyświetlanych Flash jako nakładek i podkładek dla strony HTML. Poniższy przykład tworzy dwa proste obiekty kształtu — jeden dodawany jest pod treść HTML, drugi nad nią. Przykład aktualizuje również położenie kształtu w oparciu o zdarzenie 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){ TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 72 Praca z oknami rodzimymi 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> Ten przykład zawiera ogólne wprowadzenie do niektórych zaawansowanych technik, które zacierają granice między językami JavaScript i ActionScript w środowisku AIR. W przypadku niewystarczającej znajomości sposobów używania obiektów wyświetlanych ActionScript należy skorzystać z sekcji Programowanie wyświetlania podręcznika Programowanie w języku Adobe ActionScript 3.0, aby uzyskać więcej informacji. Przykład: tworzenie rodzimego okna Poniższy przykład ilustruje, w jaki sposób utworzyć rodzime okno: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 73 Praca z oknami rodzimymi 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(); } Zarządzanie oknami Właściwości i metody klasy NativeWindow służą do zarządzania wyglądem, zachowaniem i cyklem życia okien pulpitu. Pobieranie instancji NativeWindow Aby manipulować oknem, należy najpierw pobrać instancję okna. Instancję okna można pobrać z jednego z następujących miejsc: • Konstruktor rodzimego okna używany do utworzenia okna: var win:NativeWindow = new NativeWindow(initOptions); • Właściwość nativeWindow stołu montażowego okna: var win:NativeWindow = stage.nativeWindow; • Właściwość stage obiektu wyświetlanego w oknie: var win:NativeWindow = displayObject.stage.nativeWindow; • Właściwość target zdarzenia rodzimego okna wywoływanego przez okno: private function onNativeWindowEvent(event:NativeWindowBoundsEvent):void { var win:NativeWindow = event.target as NativeWindow; } • Właściwość nativeWindow strony HTML wyświetlanej w oknie: var win:NativeWindow = htmlLoader.window.nativeWindow; • Właściwości activeWindow i openedWindows obiektu NativeApplication: var nativeWin:NativeWindow = NativeApplication.nativeApplication.activeWindow; var firstWindow:NativeWindow = NativeApplication.nativeApplication.openedWindows[0]; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 74 Praca z oknami rodzimymi NativeApplication.nativeApplication.activeWindow odwołuje się do aktywnego okna aplikacji (ale zwraca wartość null, jeśli aktywne okno nie jest oknem tej aplikacji AIR). Tablica NativeApplication.nativeApplication.openedWindows zawiera wszystkie okna w aplikacji AIR, które nie zostały zamknięte. Aktywowanie, wyświetlanie i ukrywanie okien Aby aktywować okno, należy wywołać metodę activate() NativeWindow. Aktywowanie okna przenosi okno na wierzch i przypisuje mu obszar aktywności dla klawiatury i myszy oraz, jeśli zachodzi taka konieczność, spowoduje, że okno stanie się widoczne, przywracając okno lub ustawiając właściwość visible na wartość true. Aktywowanie okna nie zmienia kolejności pozostałych okien w aplikacji. Wywołanie metody activate() powoduje, że okno wywołuje zdarzenie activate. Aby wyświetlić ukryte okno, nie aktywując go, należy ustawić właściwość visible na wartość true. Spowoduje to przeniesienie okna na wierzch, ale nie przypisze do niego obszaru aktywności. Aby ukryć okno, należy ustawić jego właściwość visible na wartość false. Ukrycie okna blokuje wyświetlanie obu elementów: okna oraz powiązanych ikon paska zadań oraz (w systemie Mac OS X) wpisu w menu Okno. Uwaga: W systemie Mac OS X nie jest możliwe pełne ukrycie zminimalizowanego okna, które ma ikonę w części okna Docku. Jeśli właściwość visible ma wartość false dla zminimalizowanego okna, ikona Docku okna jest wciąż wyświetlana. Jeśli użytkownik kliknie ikonę, okno zostanie przywrócone i wyświetlone ponownie. Zmiana kolejności wyświetlania okna Środowisko AIR dostarcza kilka metod do bezpośredniej zmiany kolejności wyświetlania okien. Programista może przesuwać okno na wierzch lub pod spód kolejności wyświetlania; możliwe jest również przesunięcie przed lub za inne okno. W tym samym czasie użytkownik może ponownie ustawić kolejność okien, aktywując je. Okno można zachować na wierzchu w stosunku do pozostałych okien, ustawiając jego właściwość alwaysInFront na wartość true. Jeśli więcej niż jedno okno ma to ustawienie, wówczas kolejność wyświetlania dla tych okien jest sortowana między nimi, ale sortowanie to wykonywane jest zawsze nad oknami, dla których we właściwości alwaysInFront ustawiona została wartość false. Okna w grupie na samym wierzchu wyświetlane są również nad oknami w innych aplikacjach, nawet jeśli aplikacja AIR nie jest aktywna. Ponieważ to zachowanie może zakłócać pracę użytkownika, ustawienie właściwości alwaysInFront na wartość true powinno być używane tylko, jeśli jest konieczne i odpowiednie. Przykłady uzasadnionych zastosowań obejmują: • Tymczasowe okna podręczne dla elementów sterowania np. podpowiedzi, podręczne listy, niestandardowe menu lub pola kombinowane. Ponieważ okna te powinny zostać zamknięte po utracie aktywności; w ten sposób unikniona zostanie irytacja z powodu blokowania użytkownikowi możliwości wyświetlenia innego okna. • Niezwykle pilne komunikaty o błędach i alerty. Wypchnięcie okna z alertem na wierzch może być uzasadnione w momencie wystąpienia nieodwołalnej zmiany i konieczności odpowiedzi na nią w odpowiednim czasie. Jednak większość błędów i alertów można obsłużyć w normalnej kolejności wyświetlania. • Tymczasowe okna o wyglądzie „kanapkowym”. Uwaga: Środowisko AIR nie narzuca właściwego używania właściwości alwaysInFront. Jeśli jednak aplikacja zakłóci pracę użytkownika, prawdopodobnie aplikacja ta wyląduje w jego koszu. Klasa NativeWindow dostarcza następujących właściwości i metod do ustawiania kolejności wyświetlania okna względem innych okien: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 75 Praca z oknami rodzimymi Element Opis właściwość alwaysInFront Określa, czy okno jest wyświetlane w grupie okien na wierzchu. W większości przypadków wartość false jest najlepszym ustawieniem. Zmiana wartości z false na true przenosi okno na wierzch wszystkich okien (ale nie powoduje jego aktywowania). Zmiana wartości z true na false powoduje ustawienie dla okna kolejności za oknami pozostającymi w grupie na wierzchu, ale pozostawia je wciąż na górze względem innych okien. Ustawienie właściwości okna na jej bieżącą wartość nie zmienia kolejności wyświetlania okna. orderToFront() Przenosi okno na wierzch. orderInFrontOf() Przenosi okno bezpośrednio przed konkretne okno. orderToBack() Wysyła okno na spód za pozostałe okna. orderBehind() Wysyła okno bezpośrednio za konkretne okno. activate() Przeniesie okno na wierzch (spowoduje również, że okno stanie się widoczne i przypisze do niego obszar aktywności). Uwaga: Jeśli okno jest ukryte (właściwość visible ma wartość false) lub zminimalizowane, wówczas wywołanie metod dotyczących kolejności wyświetlania nie przynosi żadnego efektu. W systemie operacyjnym Linux różne menedżery okien wymuszają różne zasady w zależności od kolejności wyświetlania okien: • W niektórych menedżerach okien okna utility są zawsze wyświetlane przed zwykłymi oknami. • W niektórych menedżerach okien okno w trybie pełnoekranowym z właściwością alwaysInFront ustawioną na wartość true jest zawsze wyświetlane przed innymi oknami, dla których właściwość alwaysInFront jest również ustawiona na wartość true. Zamykanie okna Aby zamknąć okno, należy użyć metody NativeWindow.close(). Zamknięcie okna powoduje wyładowanie treści okna, ale jeśli inne obiekty mają odwołania do tej treści, obiekty treści nie zostaną zniszczone. Metoda NativeWindow.close() wykonywana jest asynchronicznie; aplikacja zawarta w oknie kontynuuje działanie podczas procesu zamykania. Metoda close wywołuje zdarzenie close, gdy operacja zamykania zostanie zakończona. Obiekt NativeWindow pozostaje technicznie prawidłowy, ale dostęp do większości właściwości i metod zamkniętego okna generuje błąd IllegalOperationError. Nie można ponownie otworzyć zamkniętego okna. Aby przeprowadzić test, czy okno zostało zamknięte, należy sprawdzić właściwość closed okna. Aby ukryć okno, należy ustawić właściwość NativeWindow.visible na wartość false. Jeśli właściwość Nativeapplication.autoExit ma wartość true (sytuacja domyślna), wówczas aplikacja zakończy działanie, gdy zamknięte zostanie jej ostatnie okno. Zezwalanie na anulowanie operacji okna Jeśli okno korzysta z karnacji systemowej, interakcja użytkownika z oknem może zostać anulowana przez wykrywanie i anulowanie domyślnego zachowania odpowiednich zdarzeń. Na przykład: jeśli użytkownik kliknie przycisk zamykania karnacji systemowej, wywołane zostanie zdarzenie closing. Jeśli dowolny zarejestrowany detektor wywoła metodę preventDefault() zdarzenia, wówczas okno nie zostanie zamknięte. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 76 Praca z oknami rodzimymi Jeśli okno nie korzysta z karnacji systemowej, zdarzenia powiadomień dla zamierzonych zmian nie są automatycznie wywoływane przed dokonaniem zmiany. W skutek tego, jeśli wywołane zostaną metody w celu zamknięcia okna, zmiany jego stanu lub ustawienia dowolnej właściwości obwiedni, zmiany nie można anulować. Aby powiadomić składniki w aplikacji przed zmianą okna, logika aplikacji może wywołać stosowane zdarzenie powiadomienia za pomocą metody dispatchEvent() okna. Na przykład: poniższa logika implementuje moduł obsługi zdarzenia cancelable dla przycisku zamykania okna: public function onCloseCommand(event:MouseEvent):void{ var closingEvent:Event = new Event(Event.CLOSING,true,true); dispatchEvent(closing); if(!closingEvent.isDefaultPrevented()){ win.close(); } } Metoda dispatchEvent() zwraca wartość false, jeśli metoda preventDefault() zdarzenia wywoływana jest przez detektor. Możne jednak zwrócić również wartość false z innych powodów, dlatego lepszym rozwiązaniem jest jawne użycie metody isDefaultPrevented() w celu przetestowania, czy zmianę należy anulować. Maksymalizowanie, minimalizowanie i przywracanie okna Aby zmaksymalizować okno, należy użyć metody maximize() klasy NativeWindow. myWindow.maximize(); Aby zminimalizować okno, należy użyć metody minimize() klasy NativeWindow. myWindow.minimize(); Aby przywrócić okno (tj. powrócić do rozmiaru przed minimalizacją lub maksymalizacją), należy użyć metody restore() klasy NativeWindow. myWindow.restore(); Uwaga: Zachowanie wynikające z maksymalizacji okna środowiska AIR jest różne od standardowego zachowania w systemie Mac OS X. Zamiast przełączania między „standardowym” rozmiarem zdefiniowanym przez aplikację a rozmiarem ostatnio ustawionym przez użytkownika, okna środowiska AIR przełączają się między rozmiarem ostatnio ustawionym przez aplikację lub użytkownika i pełnym dostępnym obszarem ekranu. W systemie operacyjnym Linux różne menedżery okien wymuszają różne zasady w zależności od ustawienia stanu wyświetlania okien: • W niektórych menedżerach okien okna utility nie mogą być maksymalizowane. • Jeśli dla okna zostanie ustawiony maksymalny rozmiar, wówczas niektóre okna nie zezwalają na maksymalizację. Niektóre inne menedżery okien ustawiają stan wyświetlania na zmaksymalizowany, ale nie zmieniają rozmiaru okna. W żadnym z tych przypadków nie jest wywoływane zdarzenie zmiany stanu wyświetlania. • Niektóre menedżery okien nie uznają ustawień maximizable ani minimizable okna. Przykład: minimalizowanie, maksymalizowanie, przywracanie i zamykanie okna Poniższy przykład kodu ActionScript dla treści Flash tworzy cztery pola tekstowe, które można kliknąć i które wywołują metody minimize(), maximize(), restore() i close() klasy NativeWindow: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 77 Praca z oknami rodzimymi 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); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 78 Praca z oknami rodzimymi 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(); } } } Zmiana rozmiaru i przesuwanie okna Jeśli okno korzysta z karnacji systemowej, karnacja dostarcza elementów sterowania przeciąganiem do zmiany rozmiaru okna i przesuwania po pulpicie. Jeśli okno nie korzysta z karnacji systemowej, należy dodać własne elementy sterowania, aby zezwolić użytkownikowi na zmianę rozmiaru i przesuwanie okna. Uwaga: Aby zmienić rozmiar lub przesunąć okno, należy najpierw uzyskać odwołanie do instancji NativeWindow. Informacje na temat tego, w jaki sposób uzyskać odwołanie okna, zawiera sekcja „Pobieranie instancji NativeWindow” na stronie 73. Zmiana rozmiaru okna Aby umożliwić użytkownikowi interaktywne zmienianie rozmiaru okna, należy użyć metody startResize() obiektu NativeWindow. Jeśli metoda zostanie wywołana ze zdarzenia mouseDown, operacja zmiany rozmiaru będzie sterowana przez mysz i zakończy się w momencie odebrania przez system operacyjny zdarzenia mouseUp. W momencie wywołania metody startResize() należy przekazać argument, który określa krawędź lub róg, z którego dokonywana będzie zmiana rozmiaru okna. Aby programowo ustawić rozmiar okna, należy ustawić właściwości width, height lub bounds okna na żądane wymiary. Podczas ustawiania obwiedni rozmiar i położenie okna mogą być zmieniane w tym samym czasie. Jednak kolejność występowania zmian nie jest zagwarantowana. Niektóre menedżery okien systemu Linux nie zezwalają, aby okna wykraczały poza granice pulpitu (ekranu). W tych przypadkach końcowy rozmiar okna może być ograniczony z powodu kolejności w jakiej są ustawiane właściwości, mimo że łącznie wszystkie zmiany „netto” doprowadziłyby do uzyskania poprawnego okna. Na przykład, jeśli zostanie zmieniona wysokość i położenie y okna u dołu ekranu, wówczas zmiana wysokości na pełną może nie nastąpić, jeśli zmiana wysokości zostanie zastosowana przez zmianą położenia y. Uwaga: W systemie Linux właściwości okna są zmieniane asynchronicznie. Jeśli użytkownik zmieni właściwość w jednym wierszu programu i odczyta wartość w kolejnym, odczyt wartości będzie nadal odzwierciedlał stare ustawienie. Zdarzeń wygenerowanych przez okno można używać do wykrywania w momencie zastosowania zmiany. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 79 Praca z oknami rodzimymi Tryb skalowania stołu montażowego określa sposób zachowania stołu montażowego okna i jego treści w chwili zmiany rozmiaru okna. Należy pamiętać, że tryby skalowania stołu montażowego zostały zaprojektowane do obsługi sytuacji (np. w przeglądarkach internetowych), w których aplikacja nie steruje rozmiarem lub proporcją jej obszaru wyświetlania. Na ogół najlepsze wyniki uzyskiwane są przez ustawienie właściwości scaleMode stołu montażowego na wartość StageScaleMode.NO_SCALE. Jeśli zajdzie konieczność przeskalowania treści okna, można ustawić parametry treści scaleX i scaleY w odpowiedzi na zmiany obwiedni okna. Przesuwanie okna Aby przesunąć okno, nie zmieniając jego rozmiaru, należy użyć metody startMove() klasy theNativeWindow. Podobnie jak metoda startResize() w chwili wywołania metody startMove() ze zdarzenia mouseDown proces przesuwania jest sterowany myszą i zostanie zakończony, gdy system operacyjny odbierze zdarzenie mouseUp. Więcej informacji o metodach startResize i startMove zawiera Skorowidz języka i składników ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_pl). Przykład: zmiana rozmiarów i przesuwanie okien Poniższy przykład przedstawia sposób, w jaki inicjowane są operacje zmiany rozmiaru i przesuwania dla okna: 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(); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 80 Praca z oknami rodzimymi 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(); } } } Wykrywanie zdarzeń okien Aby wykrywać zdarzenia wywoływane przez okno, należy zarejestrować detektor dla instancji okna. Na przykład: aby wykryć zdarzenie closing, należy zarejestrować detektor dla okna w następujący sposób: myWindow.addEventListener(Event.CLOSING, onClosingEvent); Po wywołaniu zdarzenia właściwość target odwołuje się do okna wysyłającego zdarzenie. Większość zdarzeń okna ma dwa związane z nim komunikaty. Pierwszy komunikat sygnalizuje nadejście zmiany okna (i nie można go anulować), podczas gdy drugi komunikat sygnalizuje, że zmiana już wystąpiła. Na przykład: w komendzie kliknięcia przez użytkownika przycisku zamykania wywoływany jest komunikat dla zdarzenia closing. Jeśli żaden detektor nie anuluje zdarzenia, okno zostanie zamknięte, a zdarzenie close wywołane do dowolnego detektora. Zazwyczaj zdarzenia ostrzegawcze (np. closing) wywoływane są tylko, gdy karnacja systemowa użyta została do wywołania zdarzenia. Wywołanie na przykład metody close() okna nie powoduje automatycznego wywołania zdarzenia closing — wywoływane jest tylko zdarzenie close. Możliwe jest jednak skonstruowanie obiektu zdarzenia closing i wywołanie go za pomocą metody dispatchEvent() okna. Zdarzenia okna, które wywołują obiekt Event: Zdarzenie Opis activate Wywoływane, gdy do okna przeniesiony zostanie obszar aktywności. deactivate Wywoływane, gdy obszar aktywności przeniesiony zostanie poza okno. closing Wywoływane, gdy okno ma wkrótce zostać zamknięte. Zdarzenie występuje automatycznie tylko w chwili naciśnięcia przycisku zamykania karnacji systemowej lub w momencie wywołania polecenia zakończenia pracy w systemie Mac OS X. close Wywoływane po zamknięciu okna. Zdarzenia okna, które wywołują obiekt NativeWindowBoundsEvent: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 81 Praca z oknami rodzimymi Zdarzenie Opis moving Wywoływane bezpośrednio przed zmianą położenia lewego górnego rogu okna w wyniku przesunięcia, zmiany rozmiaru lub zmiany stanu wyświetlania okna. move Wywoływane po zmianie położenia lewego górnego rogu. resizing Wywoływane bezpośrednio przed zmianą szerokości lub wysokości okna w wyniku zmiany rozmiaru lub zmiany stanu wyświetlania okna. resize Wywoływane po zmianie rozmiaru okna. Do określania obwiedni okna przed i po nadejściu lub zakończeniu zmiany dla zdarzeń NativeWindowBoundsEvent można używać właściwości beforeBounds i afterBounds. Zdarzenia okna, które wywołują obiekt NativeWindowDisplayStateEvent: Zdarzenie Opis displayStateChanging Wywoływane bezpośrednio przed zmianą stanu wyświetlania okna. displayStateChange Wywoływane po zmianie stanu wyświetlania okna. Do określania stanu wyświetlania okna przed i po nadejściu lub zakończeniu zmiany dla zdarzeń NativeWindowDisplayStateEvent można używać właściwości beforeDisplayState i afterDisplayState. W niektórych menedżerach okien systemu Linux zdarzenie zmiany stanu wyświetlania nie jest wywoływane, jeśli maksymalizowane jest okno o rozmiarze maksymalnym. (Stan wyświetlania okna zostanie ustawiony na zmaksymalizowany, ale jego rozmiar nie ulegnie zmianie). Wyświetlanie okien w trybie pełnoekranowym Ustawienie właściwości displayState stołu montażowego na wartość StageDisplayState.FULL_SCREEN_INTERACTIVE powoduje przeniesienie okna w tryb pełnoekranowy, a wprowadzanie danych z klawiatury jest w tym trybie dozwolone. (W treści SWF uruchomionej w przeglądarce wprowadzanie danych z klawiatury nie jest dozwolone). Aby wyjść z trybu pełnoekranowego, należy nacisnąć klawisz Escape. Uwaga: Niektóre menedżery okien systemu Linux nie zmienią wymiarów okna w celu wypełnienia całego ekranu, jeśli dla okna ustawiony został maksymalny rozmiar (ale usuną systemową karnację okna). Poniższy przykład kodu ActionScript dla treści Flash symuluje prosty, pełnoekranowy terminal tekstowy: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 82 Praca z oknami rodzimymi 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); } } 83 Rozdział 11: Ekrany Klasa Screen w środowisku Adobe® AIR® umożliwia dostęp do informacji o ekranach monitorów podłączonych do komputera. Dodatkowe informacje o ekranach dostępne w Internecie Więcej informacji na temat klasy Screen i pracy z ekranami można znaleźć w następujących źródłach: Podręczniki Szybki start (Adobe AIR Developer Connection) • Mierzenie wirtualnego pulpitu Skorowidz języka • Screen Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR screens”) Podstawowe informacje o ekranach Interfejs API do obsługi ekranów zawiera jedną klasę, Screen, która udostępnia elementy statyczne służące do pobierania informacji o ekranie systemowym, a także elementy instancji służące do opisywania konkretnego ekranu. Do systemu komputerowego może być podłączonych kilka monitorów lub wyświetlaczy, które mogą odpowiadać kilku pulpitom (ekranom) tworzącym przestrzeń wirtualną. Klasa Screen środowiska AIR udostępnia informacje o ekranach, ich wzajemnym położeniu i użytecznej przestrzeni. Jeśli ten sam ekran jest wyświetlany (odwzorowany) na kilku monitorach, istnieje tylko jeden ekran logiczny. Jeśli rozmiar ekranu jest większy od obszaru wyświetlania monitora, nie ma możliwości określenia, która część ekranu jest w danej chwili widoczna. Ekran reprezentuje niezależny obszar wyświetlanego pulpitu. Ekrany są opisane jako prostokąty na wirtualnym pulpicie. Lewy górny narożnik ekranu wyznaczonego jako monitor główny jest początkiem układu współrzędnych wirtualnego pulpitu. Wszystkie wartości opisujące ekran są podawane w pikselach. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 84 Ekrany Granice ekranu Ekran wirtualny Granice obszaru roboczego W tym układzie ekranów na wirtualnym pulpicie istnieją dwa ekrany. Współrzędne lewego górnego narożnika ekranu głównego (nr 1) są zawsze równe (0,0). Jeśli w wyniku zmiany układu ekranów ekran nr 2 zostanie wyznaczony jako ekran główny, współrzędne ekranu nr 1 staną się ujemne. Paski menu, paski zadań i Docki nie są uwzględniane w podawanych granicach ekranu wyznaczających obszar, z którego może korzystać aplikacja. Szczegółowe informacje o klasie, metodach, właściwościach i zdarzeniach związanych z obsługą ekranów w interfejsie API można znaleźć w Skorowidzu języka i składników ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_pl). Wyliczanie ekranów Poniższe metody i właściwości ekranu umożliwiają wyliczenie ekranów pulpitu wirtualnego: Metoda lub właściwość Opis Screen.screens Udostępnia tablicę obiektów Screen opisujących dostępne ekrany. Należy zwrócić uwagę, że kolejność obiektów w tablicy nie jest znacząca. Screen.mainScreen Udostępnia obiekt Screen reprezentujący ekran główny. W systemie Mac OS X ekranem głównym jest ekran, na którym jest wyświetlany pasek menu. W systemie Windows ekranem głównym jest ekran wybrany w systemie jako podstawowy. Screen.getScreensForRectangle() Udostępnia tablicę obiektów Screen opisujących ekrany, które przecina dany prostokąt. Prostokąt przekazywany do tej metody jest opisany współrzędnymi pikselowymi na pulpicie wirtualnym. Jeśli prostokąt nie przecina żadnych ekranów, tablica jest pusta. Metody tej można używać w celu sprawdzenia, na których ekranach jest wyświetlane określone okno. Nie należy zapisywać wartości zwracanych przez metody i właściwości klasy Screen. Użytkownik lub system operacyjny może w dowolnym momencie zmienić dostępność i układ ekranów. W poniższym przykładzie zastosowano interfejs API ekranów do przenoszenia okna między wieloma ekranami w odpowiedzi na naciskanie klawiszy ze strzałkami. Aby przenieść okno na następny ekran, program pobiera tablicę screens i sortuje ją pionowo lub poziomo (w zależności od tego, który klawisz ze strzałką został naciśnięty). Następnie program kolejno przechodzi przez obiekty w posortowanej tablicy i porównuje każdy ekran ze współrzędnymi ekranu bieżącego. Aby określić, na którym ekranie obecnie znajduje się okno, program wywołuje metodę Screen.getScreensForRectangle(), przekazując do niej granice okna. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 85 Ekrany 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 += TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 86 Ekrany 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; } } } 87 Rozdział 12: Praca z rodzimymi menu Klasy w interfejsie API rodzimego menu służą do definiowania menu aplikacji, okien, menu kontekstowych i podręcznych. Dodatkowe informacje online o rodzimych menu Więcej informacji o interfejsie API rodzimych menu oraz pracy z rodzimymi menu zawierają trzy poniższe źródła: Podręczniki Szybki start (Adobe AIR Developer Connection) • Adding native menus to an AIR application Skorowidz języka • NativeMenu • NativeMenuItem Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR menus”) Podstawowe informacje o menu w środowisku AIR Klasy rodzimego menu umożliwiają dostęp do elementów rodzimego menu systemu operacyjnego, na którym uruchamiana jest aplikacja. Obiektów NativeMenu można używać w menu aplikacji (dostępne w systemie Mac OS X), menu okien (dostępne w systemie Windows i Linux) oraz menu kontekstowych i podręcznych. Klasy menu w środowisku AIR Klasy menu środowiska Adobe® AIR™: Pakiet Klasy flash.display • NativeMenu • NativeMenuItem • ContextMenu • ContextMenuItem • Event • ContextMenuEvent flash.ui flash.events TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 88 Praca z rodzimymi menu Odmiany menu Środowisko AIR obsługuje następujące typy menu: Menu aplikacji Menu aplikacji jest menu globalnym, które znajduje zastosowanie w całej aplikacji. Menu aplikacji obsługiwane są w systemie Mac OS X, ale nie w systemie Windows ani Linux. W systemie operacyjnym Mac OS X menu aplikacji tworzone jest automatycznie. Aby dodać pozycje i podmenu do standardowych menu, użytkownik może użyć interfejsu API menu środowiska AIR. Aby obsłużyć istniejące polecenia menu, można dodać detektory. Można również usunąć istniejące pozycje. Menu okien Menu okna jest skojarzone z pojedynczym oknem i wyświetlane poniżej paska tytułu. Menu mogą być dodawane do okna przez utworzenie obiektu NativeMenu i przypisanie go do właściwości menu obiektu NativeWindow. Menu okien obsługiwane są w systemach operacyjnych Windows i Linux, ale nie w systemie Mac OS X. Rodzimych menu okien można używać tylko w oknach, które mają karnację systemową. Menu kontekstowe Menu kontekstowe otwierane są w odpowiedzi na kliknięcie prawym przyciskiem myszy lub kliknięcie z przytrzymanym klawiszem command na interaktywnym obiekcie w treści SWF lub elemencie dokumentu w treści HTML. Menu kontekstowe można utworzyć za pomocą klasy NativeMenu lub ContextMenu. W treści HTML do dodawania menu kontekstowych do elementów HTML można używać silnika Webkit HTML i interfejsów API JavaScript. Menu ikon Docku i paska zadań Menu ikon są podobne do menu kontekstowych i przypisywane są do aplikacji w Docku systemu Mac OS X lub obszaru powiadomień na pasku zadań systemu Windows i Linux. Menu ikon Docku i paska zadań korzystają z klasy NativeMenu. W systemie Mac OS X pozycje w menu dodawane są nad standardowymi elementami systemu operacyjnego. W systemie Windows i Linux nie ma standardowego menu. Menu podręczne Menu podręczne środowiska AIR podobne jest do menu kontekstowego, ale niekoniecznie jest skojarzone z konkretnym obiektem lub składnikiem aplikacji. Menu podręczne może być wyświetlane dowolnym miejscu w oknie przez wywołanie metody display() dowolnego obiektu NativeMenu. Niestandardowe menu Natywne menu rysowane są w całości przez system operacyjny i jako takie istnieją poza modelami renderowania Flash i HTML. Użytkownik może dowolnie tworzyć własne, nierodzime menu za pomocą języka MXML, ActionScript lub JavaScript. Klasy menu środowiska AIR nie zapewniają żadnych narzędzi do sterowania rysowaniem rodzimych menu. Domyślne menu Domyślne menu dostarczane przez system operacyjny lub wbudowaną klasę środowiska AIR: • Menu aplikacji w systemie Mac OS X • Menu ikony Docku w systemie Mac OS X • Menu kontekstowe dla tekstu lub obrazów zaznaczonych w treści HTML • Menu kontekstowe dla tekstu zaznaczonego w obiekcie TextField (lub obiekcie, który rozszerza TextField) Struktura menu Menu mają strukturę hierarchiczną. Obiekty NativeMenu zawierają obiekty podrzędne NativeMenuItem. Obiekty NativeMenuItem, które reprezentują podmenu, mogą zawierać kolejne obiekty NativeMenu. Obiekt menu poziomu najwyższego lub głównego struktury reprezentuje pasek menu aplikacji i menu okien. (Menu kontekstowe, ikon i podręczne nie mają paska menu). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 89 Praca z rodzimymi menu Poniższy diagram ilustruje strukturę typowego menu. Menu główne reprezentuje pasek menu i zawiera dwie pozycje menu odwołujące się do podmenu File i Edit. Podmenu File zawiera w strukturze dwie pozycje polecenia i pozycję, która dowołuje się do podmenu Open Recent Menu, która sama zawiera trzy pozycje. Podmenu Edit zawiera trzy polecenia i separator. NativeMenu Root Menu NativeMenuItem “File” NativeMenu File Menu NativeMenuItem “New” NativeMenuItem “Save” NativeMenuItem “Open Recent” NativeMenu NativeMenuItem NativeMenu Open Recent Menu NativeMenuItem “GreatGatsby.pdf” NativeMenuItem “WarAndPeace.pdf” NativeMenuItem “Iliad.pdf” “Edit” Edit Menu NativeMenuItem “Copy” NativeMenuItem “Paste” NativeMenuItem Separator NativeMenuItem “Preferences” Podczas definiowania podmenu wymagane są oba obiekty NativeMenu i NativeMenuItem. Obiekt NativeMenuItem definiuje etykietę wyświetlaną w menu elementu nadrzędnego i umożliwia użytkownikowi otwieranie podmenu. Obiekt NativeMenu służy jako kontener dla pozycji podmenu. Obiekt NativeMenuItem odwołuje się do obiektu NativeMenu za pomocą właściwości submenu NativeMenuItem. Aby zobaczyć przykładowy kod, który tworzy menu, spójrz do sekcji „Przykład: menu aplikacji i okna” na stronie 99. Zdarzenia menu Oba obiekty NativeMenu i NativeMenuItem wywołują zdarzenia displaying i select: Displaying: Bezpośrednio przed wyświetleniem menu, menu i jego pozycje wywołują zdarzenie displaying do wszystkich zarejestrowanych detektorów. Zdarzenie displaying daje możliwość aktualizacji treści menu lub wyglądu pozycji przed jej wyświetleniem. Na przykład: w detektorze dla zdarzenia displaying menu „Open Recent (Otwórz ostatnie)” można zmienić pozycje menu, aby odzwierciedlić bieżącą listę ostatnio wyświetlanych dokumentów. Właściwością target obiektu zdarzenia jest zawsze menu, które należy wyświetlić. Obiekt currentTarget jest obiektem, dla którego rejestrowany jest detektor: menu lub jedna z jego pozycji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 90 Praca z rodzimymi menu Uwaga: Zdarzenie displaying wywoływane jest również zawsze w momencie dostępu do stanu menu lub jednej z jego pozycji. Select: Po wybraniu przez użytkownika pozycji polecenia, pozycja wywołuje zdarzenie select dla wszystkich zarejestrowanych detektorów. Pozycji podmenu i separatora nie można wybrać, dlatego nigdy nie wywołują zdarzenia select. Zdarzenie select jest propagowane w górę z pozycji menu do menu, w której jest zawarta, a następnie dalej do menu głównego. Zdarzenia select można wykrywać bezpośrednio dla pozycji; można je wykrywać również wyżej w strukturze menu. Podczas wykrywania zdarzenia select dla menu wybraną pozycję można wskazać za pomocą właściwości target zdarzenia. Podczas propagacji w hierarchii menu bieżący obiekt menu wskazywany jest we właściwości currentTarget. Uwaga: Obiekty ContextMenu i ContextMenuItem wywołują zdarzenia menuItemSelect i menuSelect, a także zdarzenia select i displaying. Odpowiedniki klawiszy dla poleceń menu Do polecenia menu można przypisać odpowiednik klawisza (nazywany czasami klawiszem skrótu). Pozycja menu wywołuje zdarzenie select dla wszystkich zarejestrowanych detektorów w momencie naciśnięcia klawisza lub kombinacji klawiszy. Aby polecenie zostało wywołane, menu zawierające pozycję musi być częścią menu aplikacji lub aktywnym oknem. Odpowiedniki klawiszy mają dwie części: ciąg reprezentujący klawisz podstawowy oraz tablicę klawiszy modyfikatorów, które również muszą zostać naciśnięte. Aby przypisać klawisz podstawowy, należy ustawić dla tego klawisza właściwość keyEquivalent pozycji menu na pojedynczy znak. Jeśli użyta zostanie wielka litera, klawisz Shift zostanie automatycznie dodany do tablicy modyfikatorów. W systemie Mac OS X domyślnym modyfikatorem jest klawisz Command (Keyboard.COMMAND). W systemie Windows i Linux jest nim klawisz Control (Keyboard.CONTROL). Te klawisze domyślne są dodawane do tablicy modyfikatorów automatycznie. Aby przypisać inne klawisze modyfikatorów, należy przypisać do właściwości keyEquivalentModifiers nową tablicę zawierającą pożądane kody klawiszy. Domyślna tablica zostanie zastąpiona. Niezależnie od tego, czy używane są modyfikatory domyślne, czy przypisana została własna tablica modyfikatorów, dodany zostanie klawisz Shift, jeśli ciąg przypisany do właściwości keyEquivalent jest wielką literą. Stałe kodów klawiszy używane dla klawiszy modyfikatorów są zdefiniowane w klasie Keyboard. Przypisany ciąg odpowiednika klawisza jest wyświetlany automatycznie pod nazwą pozycji menu. Format zależy od systemu operacyjnego użytkownika i ustawień systemu. Uwaga: Jeśli w systemie operacyjnym Windows do tablicy klawiszy modyfikatorów przypisana zostanie wartość Keyboard.COMMAND, żaden odpowiednik klawisza nie zostanie wyświetlony w menu. Jednak do aktywacji polecenia menu należy użyć klawisza Control. Poniższy przykład przypisuje klawisze Ctrl+Shift+G jako odpowiednik klawisza dla pozycji menu: var item:NativeMenuItem = new NativeMenuItem("Ungroup"); item.keyEquivalent = "G"; Ten przykład przypisuje klawisze Ctrl+Shift+G jako odpowiednik klawisza, bezpośrednio ustawiając tablicę modyfikatorów: var item:NativeMenuItem = new NativeMenuItem("Ungroup"); item.keyEquivalent = "G"; item.keyEquivalentModifiers = [Keyboard.CONTROL]; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 91 Praca z rodzimymi menu Uwaga: Odpowiedniki klawiszy wywoływane są tylko dla menu aplikacji i okien. Jeśli użytkownik doda odpowiednik klucza do menu kontekstowego lub podręcznego, odpowiednik klucza zostanie wyświetlony w etykiecie menu, ale skojarzone polecenie menu nigdy nie zostanie wywołane. Mnemonika Mnemoniki są częścią interfejsu klawiatury systemu operacyjnego dla menu. Systemy Linux, Mac OS X i Windows umożliwiają użytkownikom na otwieranie menu i wybieranie poleceń za pomocą klawiatury, ale istnieją dla nich delikatne różnice. W systemie Mac OS X użytkownik wpisuje pierwszą lub dwie pierwsze litery menu lub polecenia, a następnie nacisk klawisz Return. Właściwość mnemonicIndex jest ignorowana. W systemie Windows znaczenie ma tylko jedna litera. Domyślnie literą znaczącą jest pierwszy znak etykiety, ale jeśli do pozycji przypisany zostanie mnemonik, wówczas znakiem znaczącym stanie się wskazana litera. Jeśli dwie pozycje w menu mają te same znaki znaczące (bez względu na to, czy mnemonik został przypisany czy nie), wówczas interakcja klawiatury i menu nieznacznie się zmienia. Zamiast nacisnąć pojedynczą literę w celu wybrania menu lub polecenia, użytkownik musi nacisnąć literę tyle razy, ile konieczne jest do podświetlenia żądanej pozycji, a następnie nacisnąć klawisz Enter, aby dokonać wyboru. Aby zachować konsekwentne działanie, należy przypisać unikalny mnemonik dla każdej pozycji menu w menu okien. System Linux nie udostępnia domyślnych mnemonik. Dla właściwości mnemonicIndex należy określić wartość pozycji menu, aby udostępnić mnemonik. Znak mnemonika należy określić indeksem ciągu etykiety. Indeksem pierwszego znaku etykiety jest 0. Dlatego, aby użyć znaku „r” jako mnemonika dla pozycji menu z etykietą „Format”, należy ustawić właściwość mnemonicIndex na wartość 2. var item:NativeMenuItem = new NativeMenuItem("Format"); item.mnemonicIndex = 2; Stan pozycji menu Pozycje menu mają dwie właściwości stanu, checked i enabled: checked Ustawiona na wartość true wyświetla obok etykiety pozycji znacznik wyboru. var item:NativeMenuItem = new NativeMenuItem("Format"); item.checked = true; enabled Przełącza wartość między true i false, aby sterować aktywnością polecenia. Wyłączone pozycje są „wyszarzone” i nie można wywoływać dla nich zdarzeń select. var item:NativeMenuItem = new NativeMenuItem("Format"); item.enabled = false; Dołączanie obiektu do pozycji menu Właściwość data klasy NativeMenuItem umożliwia odwoływanie się do arbitralnego obiektu w każdej pozycji. Na przykład: w menu „Open Recent (Otwórz ostatnie)” można przypisać obiekt File każdego dokumentu do każdej pozycji menu. var file:File = File.applicationStorageDirectory.resolvePath("GreatGatsby.pdf") var menuItem:NativeMenuItem = docMenu.addItem(new NativeMenuItem(file.name)); menuItem.data = file; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 92 Praca z rodzimymi menu Tworzenie rodzimych menu W tym rozdziale omówiono sposób tworzenia różnych typów rodzimych menu obsługiwanych w środowisku AIR. Tworzenie głównego obiektu menu Aby utworzyć obiekt NativeMenu, który będzie służył jako obiekt główny menu, należy użyć konstruktora NativeMenu: var root:NativeMenu = new NativeMenu(); W menu aplikacji i okien menu główne reprezentowane jest przez pasek menu, który powinien zawierać tylko pozycje otwierające podmenu. Menu kontekstowe i menu podręczne nie mają paska menu, dlatego menu główne może zawierać polecenia, wiersze separatorów oraz podmenu. Po utworzeniu menu można dodawać pozycje menu. Pozycje wyświetlane są w menu w kolejności, w jakiej zostały dodane chyba, że zostaną dodane w konkretnym miejscu za pomocą metody addItemAt() obiektu menu. Przypisz menu do menu aplikacji, okna, ikony lub menu kontekstowe lub wyświetl je jako menu podręczne tak, jak zostało to przedstawione w poniższych sekcjach: Ustawianie menu aplikacji NativeApplication.nativeApplication.menu = root; Uwaga: System Mac OS X definiuje menu zawierające standardowe pozycje dla każdej aplikacji. Przypisanie nowego obiektu NativeMenu do właściwości menu obiektu NativeApplication zastępuje standardowe menu. Można również użyć standardowego menu zamiast je zastępować. Ustawianie menu okna nativeWindowObject.menu = root; Ustawianie menu kontekstowego dla interaktywnego obiektu interactiveObject.contextMenu = root; Ustawianie menu ikony Docku DockIcon(NativeApplication.nativeApplication.icon).menu = root; Uwaga: System Mac OS X definiuje menu standardowe dla ikony Docku aplikacji. Po przypisaniu nowego obiektu NativeMenu do właściwości menu obiektu DockIcon pozycje w menu są wyświetlane nad pozycjami standardowymi. Do pozycji standardowego menu nie można uzyskać dostępu, usunąć ich, ani zmodyfikować. Ustawianie menu ikony paska zadań SystemTrayIcon(NativeApplication.nativeApplication.icon).menu = root; Wyświetlanie menu jako podręcznego root.display(stage, x, y); Tworzenie podmenu Aby utworzyć podmenu, należy dodać obiekt NativeMenuItem do menu nadrzędnego, a następnie przypisać obiekt NativeMenu definiujący podmenu do właściwości submenu pozycji. Środowisko AIR udostępnia dwa sposoby tworzenia pozycji podmenu i skojarzonych z nimi obiektów menu: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 93 Praca z rodzimymi menu Użytkownik może utworzyć pozycję menu i powiązane z nią obiekty menu w pojedynczym kroku za pomocą metody addSubmenu(): var editMenuItem:NativeMenuItem = root.addSubmenu(new NativeMenu(), "Edit"); Można także utworzyć pozycję i przypisać obiekt menu do jej właściwości submenu oddzielnie: var editMenuItem:NativeMenuItem = root.addItem("Edit", false); editMenuItem.submenu = new NativeMenu(); Tworzenie polecenia menu Aby utworzyć polecenie menu, należy dodać obiekt NativeMenuItem do menu, a następnie dodać detektor zdarzeń odwołujący się do funkcji implementującej polecenie menu: var copy:NativeMenuItem = new NativeMenuItem("Copy", false); copy.addEventListener(Event.SELECT, onCopyCommand); editMenu.addItem(copy); Zdarzenie select można wykrywać bezpośrednio w pozycji polecenia (tak jak ilustruje to przykład) lub wykrywać zdarzenie select w nadrzędnym obiekcie menu. Uwaga: Pozycje menu, które reprezentują podmenu i wiersze separatora, nie wywołują zdarzeń select i dlatego nie mogą być używane jako polecenia. Tworzenie wiersza separatora menu Aby utworzyć wiersze separatora, należy utworzyć obiekt NativeMenuItem, ustawiając w konstruktorze parametr isSeparator na wartość true. Następnie we właściwym położeniu należy dodać pozycję separatora do menu: var separatorA:NativeMenuItem = new NativeMenuItem("A", true); editMenu.addItem(separatorA); Etykieta określona dla separatora nie jest wyświetlana. Informacje o menu kontekstowych Każdemu obiektowi w treści SWF, który dziedziczy po obiekcie InteractiveObject, można przydzielić menu kontekstowe, przypisując obiekt menu do jego właściwości contextMenu. Obiekt menu przypisany do właściwości contextMenu może mieć typ NativeMenu lub ContextMenu. W czasie korzystania z klas ContextMenu i ContextMenuItem można wykrywać zdarzenia dla rodzimych menu lub menu kontekstowych; wywoływane są zdarzenia obu menu. Jedną z korzyści jakie udostępniają właściwości obiektu ContextMenuEvent jest to, że właściwość contextMenuOwner identyfikuje obiekt, do którego jest dołączane menu, a właściwość mouseTarget identyfikuje obiekt, który został kliknięty w celu otwarcia menu. Ta informacja nie jest dostępna z obiektu NativeMenuEvent. W poniższym przykładzie opisano tworzenie obiektu Sprite i dodawanie prostego menu kontekstowego edycji: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 94 Praca z rodzimymi menu 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");} Uwaga: W przeciwieństwie do treści SWF wyświetlanej w przeglądarce, menu kontekstowe w środowisku AIR nie mają żadnych wbudowanych poleceń. Informacje o menu kontekstowych w HTML W treści HTML zdarzenie contextmenu może być używane do wyświetlania menu kontekstowego. Domyślnie menu kontekstowe wyświetlane jest automatycznie, kiedy użytkownik wywoła zdarzenie menu kontekstowego dla zaznaczonego tekstu (klikając na tekst prawym przyciskiem myszy lub z wciśniętym klawiszem Command). Aby zapobiec otwarciu domyślnego menu, należy wykryć zdarzenie contextmenu, a następnie wywołać metodę preventDefault() obiektu zdarzenia: function showContextMenu(event){ event.preventDefault(); } Użytkownik może następnie wyświetlić niestandardowe menu kontekstowe za pomocą technik DHTML lub wyświetlając rodzime menu kontekstowe środowiska AIR. Poniższy przykład ilustruje wyświetlanie rodzimego menu kontekstowego przez wywołanie metody display() menu w odpowiedzi na zdarzenie contextmenu HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 95 Praca z rodzimymi menu <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> Deklaratywne definiowanie rodzimych menu Kodowanie właściwości menu i jego pozycji może być nieco żmudne. Ponieważ jednak menu mają strukturę hierarchiczną, możliwe jest bezpośrednie napisanie funkcji, która utworzy menu za pomocą definicji sformatowanej w postaci XML. Poniższa klasa rozszerza klasę NativeMenu, pobierając obiekt XML w jej konstruktorze, aby utworzyć wspomniane wcześniej menu: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 96 Praca z rodzimymi menu 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 Aby utworzyć menu za pomocą tej klasy, należy przekazać definicję XML menu, która wygląda w sposób następujący: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 97 Praca z rodzimymi menu 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); Aby wykrywać zdarzenia menu, można wykrywać je na poziomie menu głównego, a następnie użyć właściwości event.target.name w celu wykrycia wybranych poleceń. Użytkownik może także wyszukiwać pozycje w menu na podstawie nazwy i dodawać pojedyncze detektory zdarzeń. Wyświetlanie menu podręcznych Wszystkie obiekty NativeMenu można wyświetlać w dowolnym czasie i miejscu nad oknem przez wywołanie metody display() menu. Metoda wymaga odwołania do stołu montażowego; dlatego tylko treść w obszarze izolowanym aplikacji może wyświetlać menu jako podręczne. Poniższa metoda wyświetla menu zdefiniowane przez obiekt NativeMenu o nazwie popupMenu w odpowiedzi na kliknięcie myszą: private function onMouseClick(event:MouseEvent):void { popupMenu.display(event.target.stage, event.stageX, event.stageY); } Uwaga: Nie jest wymagane, aby menu wyświetlane było w bezpośredniej odpowiedzi na zdarzenie. Każda metoda może wywołać funkcję display(). Obsługa zdarzeń menu Menu wywołuje zdarzenia w momencie wybrania przez użytkownika menu lub wybrania pozycji menu. Podsumowanie zdarzeń dla klas menu Aby obsłużyć zdarzenia menu, należy dodać do menu detektory zdarzeń lub pojedyncze pozycje. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 98 Praca z rodzimymi menu Obiekt Wywołane zdarzenia NativeMenu NativeMenuEvent.DISPLAYING NativeMenuEvent.SELECT (propagowane od podrzędnych pozycji i podmenu) NativeMenuItem NativeMenuEvent.SELECT NativeMenuEvent.DISPLAYING (propagowane od nadrzędnych menu) ContextMenu ContextMenuEvent.MENU_SELECT ContextMenuItem ContextMenuEvent.MENU_ITEM_SELECT NativeMenu.SELECT Zdarzenia select menu Aby obsłużyć kliknięcie pozycji menu, należy dodać do obiektu NativeMenuItem detektor zdarzeń dla zdarzenia select: var menuCommandX:NativeMenuItem = new NativeMenuItem("Command X"); menuCommand.addEventListener(Event.SELECT, doCommandX) Ponieważ zdarzenia select są propagowane w menu, w którym się zawierają, dlatego można również wykrywać zdarzenia select menu nadrzędnych. Podczas wykrywania na poziomie menu użytkownik może korzystać z właściwości target obiektu zdarzenia w celu określenia, które polecenie menu zostało wybrane. Poniższy przykład ilustruje odrysowanie etykiety wybranego polecenia: 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"); } Jeśli używana jest klasa ContextMenuItem, możliwe jest wykrywanie zdarzenia select lub menuItemSelect. Zdarzenie menuItemSelect dostarcza dodatkowych informacji o obiekcie, do którego należy menu kontekstowe, ale nie propaguje ich do menu, w których się zawiera. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 99 Praca z rodzimymi menu Zdarzenia displaying menu Aby obsłużyć otwieranie menu, można dodać detektor dla zdarzenia displaying, które wywoływane jest przed wyświetleniem menu. Zdarzenia displaying można używać do aktualizowania menu, na przykład przez dodanie lub usunięcie pozycji lub przez aktualizację stanów enabled lub checked dla pojedynczych pozycji. Przykład: menu aplikacji i okna Poniższy przykład ilustruje tworzenie menu, które przedstawione zostało w sekcji „Struktura menu” na stronie 88. Menu zostało zaprojektowane do pracy na obu systemach: Windows, w którym można obsługiwać tylko menu okien, oraz Mac OS X, w którym można obsługiwać tylko menu aplikacji. Aby dokonać rozróżnienia, konstruktor klasy MenuExample sprawdza właściwość statyczną supportsMenu klas NativeWindow i NativeApplication. Jeśli właściwość NativeWindow.supportsMenu ma wartość true, wówczas konstruktor tworzy obiekt NativeMenu dla okna, a następnie tworzy i dodaje podmenu File i Edit. Jeśli właściwość NativeApplication.supportsMenu ma wartość true, wówczas konstruktor tworzy i dodaje menu File i Edit do istniejącego menu dostarczonego przez system operacyjny Mac OS X. Przykład ilustruje również obsługę zdarzeń menu. Zdarzenie select obsługiwane jest na poziomie pozycji oraz na poziomie menu. Każde menu na drodze między menu zawierającym wybraną pozycję a głównym menu odpowiada na zdarzenie select. Zdarzenie displaying jest używane z menu „Open Recent (Otwórz ostatnie)”. Przed otwarciem menu pozycje w menu są odświeżane z tablicy Documents (która faktycznie w tym przykładzie nie zmienia się). Mimo że nie zostało to przedstawione w tym przykładzie, możliwe jest również wykrywanie zdarzenia displaying dla pojedynczych pozycji. 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(); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 100 Praca z rodzimymi menu if (NativeApplication.supportsMenu){ 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); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 101 Praca z rodzimymi menu for each (var file:File in recentDocuments) { 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; } } } 102 Rozdział 13: Ikony paska zadań Wiele systemów operacyjnych udostępnia pasek zadań, taki jak Dock w systemie Mac OS X, który może zawierać ikony reprezentujące aplikacje. Środowisko Adobe® AIR® udostępnia interfejs służący do interakcji z ikoną aplikacji na pasku zadań za pośrednictwem właściwości NativeApplication.nativeApplication.icon. Dodatkowe informacje o ikonach paska zadań dostępne w Internecie Więcej informacji na temat pracy z paskami zadań można znaleźć w następujących źródłach: Podręczniki Szybki start (Adobe AIR Developer Connection) • Korzystanie z ikon zasobnika systemowego i Docku Skorowidz języka • DockIcon • SystemTrayIcon Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR taskbar icons”) Informacje o ikonach paska zadań Środowisko AIR automatycznie tworzy obiekt NativeApplication.nativeApplication.icon. Typem obiektu jest DockIcon albo SystemTrayIcon, w zależności od systemu operacyjnego. Korzystając z właściwości NativeApplication.supportsDockIcon i NativeApplication.supportsSystemTrayIcon, można określić, którą z tych podklas klasy InteractiveIcon środowisko AIR obsługuje w bieżącym systemie operacyjnym. Klasa bazowa InteractiveIcon udostępnia właściwości width, height i bitmaps, których można używać do zmiany obrazu ikony. Jednak próba dostępu do właściwości charakterystycznych dla klasy DockIcon lub SystemTrayIcon w niewłaściwym systemie operacyjnym spowoduje zgłoszenie błędu w czasie wykonywania. Aby ustawić lub zmienić obraz ikony, należy utworzyć tablicę zawierającą jeden lub większą liczbę obrazów, i przypisać tę tablicę do właściwości NativeApplication.nativeApplication.icon.bitmaps. Rozmiary ikon paska narzędzi mogą być różne w różnych systemach operacyjnych. Aby uniknąć pogorszenia jakości obrazu wskutek skalowania, można dodać do tablicy bitmaps wiele obrazów o różnych rozmiarach. W wypadku udostępnienia więcej niż jednego obrazu środowisko AIR wybiera rozmiar najbliższy aktualnemu rozmiarowi wyświetlanej ikony paska zadań, a skaluje obraz tylko wtedy, gdy jest to konieczne. W poniższym przykładzie ustawiany jest obraz ikony paska narzędzi. Przypisywana jest tablica zawierająca dwa obrazy: NativeApplication.nativeApplication.icon.bitmaps = [bmp16x16.bitmapData, bmp128x128.bitmapData]; Aby zmienić obraz ikony, należy przypisać tablicę zawierającą nowy obraz lub obrazy do właściwości bitmaps. Możliwe jest animowanie ikony poprzez zmianę obrazu w odpowiedzi na zdarzenie enterFrame lub timer. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 103 Ikony paska zadań Aby usunąć ikonę z obszaru powiadomień w systemie Windows i Linux lub przywrócić domyślny wygląd ikony w systemie Mac OS X, należy przypisać właściwości bitmaps pustą tablicę: NativeApplication.nativeApplication.icon.bitmaps = []; Ikony Docku Środowisko AIR obsługuje ikony Docku, gdy właściwość NativeApplication.supportsDockIcon ma wartość true. Właściwość NativeApplication.nativeApplication.icon reprezentuje ikonę aplikacji w Docku (a nie ikonę okna w Docku). Uwaga: Środowisko AIR nie umożliwia zmiany ikon okien w Docku w systemie Mac OS X. Ponadto zmiana ikony aplikacji w Docku obowiązuje tylko w czasie, gdy aplikacja jest uruchomiona — po zakończeniu działania aplikacji przywracany jest normalny wygląd ikony. Menu ikon Docku Istnieje możliwość dodawania poleceń do standardowego menu Docku. Należy w tym celu utworzyć obiekt NativeMenu zawierający polecenia i przypisać go do właściwości NativeApplication.nativeApplication.icon.menu. Elementy w menu będą wyświetlane powyżej standardowych elementów menu ikony Docku. Podskakiwanie ikony w Docku Można wymusić podskakiwanie ikony Docku, wywołując metodę NativeApplication.nativeApplication.icon.bounce(). W wypadku ustawienia parametru bounce() priority na wartość informational ikona podskoczy jeden raz. W wypadku ustawienia tego parametru na wartość cirtical, ikona będzie podskakiwać, dopóki użytkownik nie uaktywni aplikacji. Stałe dla parametru priority są zdefiniowane w klasie NotificationType. Uwaga: Ikona nie podskakuje, jeśli aplikacja jest już aktywna. Zdarzenia związane z ikonami Docku Kliknięcie ikony Docku powoduje wywołanie zdarzenia invoke przez obiekt NativeApplication. Jeśli aplikacja nie działa, system ją uruchomi. W przeciwnym razie zdarzenie invoke zostanie dostarczone do działającej instancji aplikacji. Ikony zasobnika systemowego Środowisko AIR obsługuje ikony zasobnika systemowego, gdy właściwość NativeApplication.supportsSystemTrayIcon jest równa true. Ten warunek jest obecnie spełniony tylko w systemie Windows oraz w większości dystrybucji systemu Linux. W systemie Windows i Linux ikony zasobnika systemowego są wyświetlane w obszarze powiadomień na pasku zadań. Domyślnie ikona nie jest wyświetlana. Aby wyświetlić ikonę, należy przypisać tablicę zawierającą obiekty BitmapData do właściwości bitmaps ikony. Aby zmienić obraz ikony, należy przypisać tablicę zawierającą nowe obrazy do właściwości bitmaps. Aby usunąć ikonę, należy przypisać właściwości bitmaps wartość null. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 104 Ikony paska zadań Menu ikon zasobnika systemowego Istnieje możliwość dodania menu do ikony zasobnika systemowego. W tym celu należy utworzyć obiekt NativeMenu i przypisać go do właściwości NativeApplication.nativeApplication.icon.menu (system operacyjny nie udostępnia menu domyślnego). Dostęp do menu ikony w zasobniku systemowym uzyskuje się, klikając ikonę prawym przyciskiem myszy. Podpowiedzi narzędzi ikony zasobnika systemowego Aby dodać do ikony podpowiedź narzędzia, należy ustawić jej właściwość tooltip: NativeApplication.nativeApplication.icon.tooltip = "Application name"; Zdarzenia związane z ikonami zasobnika systemowego Obiekt SystemTrayIcon, do którego odwołuje się właściwość NativeApplication.nativeApplication.icon, wywołuje zdarzenie ScreenMouseEvent w odpowiedzi na zdarzenia click, mouseDown, mouseUp, rightClick, rightMouseDown i rightMouseUp. Można wykorzystać te narzędzia, wraz z menu ikony, aby stworzyć użytkownikom możliwość interakcji z aplikacją, gdy aplikacja nie wyświetla widocznych okien. Przykład: tworzenia aplikacji bez okien W poniższym przykładzie tworzona jest aplikacja AIR, która ma ikonę w zasobniku systemowym, ale nie ma widocznych okien. Ikona w zasobniku systemowym ma menu zawierające jedno polecenie kończące pracę z aplikacją. 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")); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 105 Ikony paska zadań var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon; 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]; } } } Uwaga: W przykładzie przyjęto, że w podkatalogu icons aplikacji istnieją pliki obrazów o nazwach AIRApp_16.png i AIRApp_128.png. (Przykładowe pliki ikon, które można skopiować do własnego folderu projektu, są dołączone do pakietu AIR SDK). Ikony i przyciski okien na pasku zadań W obszarze okien na pasku zadań lub Docku wyświetlane są zazwyczaj ikonograficzne reprezentacje okien, które umożliwiają użytkownikom szybki dostęp do tła lub zminimalizowanych okien. W Docku systemu Mac OS X wyświetlane są ikony aplikacji oraz ikony wszystkich zminimalizowanych okien. Na paskach zadań systemu Microsoft Windows i Linux wyświetlane są przyciski wszystkich zwykłych okien aplikacji. Każda ikona zawiera ikonę programu i tytuł okna. Podświetlanie przycisku okna na pasku zadań Gdy okno znajduje się w tle, można poinformować użytkownika o zajściu zdarzenia związanego z tym oknem. W systemie Mac OS X takie powiadomienie użytkownika jest realizowane poprzez wywołanie podskakiwania ikony aplikacji w Docku (co opisano w sekcji „Podskakiwanie ikony w Docku” na stronie 103). W systemie Windows i Linux można podświetlić przycisk okna na pasku narzędzi, wywołując metodę notifyUser() instancji klasy NativeWindow. Parametr type przekazany do metody określa, jak pilne jest powiadomienie: • NotificationType.CRITICAL: ikona okna miga, dopóki użytkownik nie przeniesie okna na pierwszy plan. • NotificationType.INFORMATIONAL: ikona okna jest podświetlana poprzez zmianę koloru. Uwaga: W systemie Linux obsługiwany jest jedynie typ informacyjny powiadomień. Przekazanie innej wartości typu do funkcji notifyUser() wywoła ten sam efekt. Poniższa instrukcja podświetla przycisk okna na pasku zadań: stage.nativeWindow.notifyUser(NotificationType.CRITICAL); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 106 Ikony paska zadań Wywołanie metody NativeWindow.notifyUser() w systemie operacyjnym, który nie obsługuje powiadamiania na poziomie okien, nie odnosi żadnego skutku. Aby sprawdzić, czy powiadamianie jest obsługiwane, należy skorzystać z właściwości NativeWindow.supportsNotification. Tworzenie okien bez przycisków lub ikon na pasku zadań W systemie operacyjnym Windows okna, przy których tworzeniu zadeklarowano typ utility lub lightweight, nie są widoczne na pasku zadań. Na pasku zadań nie pojawiają się także okna niewidoczne. Ponieważ pierwsze okno aplikacji zawsze jest typu normal, aby utworzyć aplikację bez widocznych okien na pasku zadań, należy zamknąć pierwsze okno lub pozostawić je w stanie niewidocznym. Aby zamknąć wszystkie okna aplikacji, nie kończąc jej działania, należy ustawić właściwość autoExit obiektu NativeApplication na false przed zamknięciem ostatniego okna. Aby zapobiec uwidacznianiu pierwszego okna aplikacji, wystarczy dodać wpis <visible>false</visible> do elementu <initalWindow> w pliku deskryptora aplikacji (i nie ustawiać właściwości visible na true ani nie wywoływać metody activate() okna). W nowych oknach otwieranych przez aplikację należy przypisywać właściwości typeobiektu NativeWindowInitOption przekazanego do konstruktora okna wartość NativeWindowType.UTILITY lub NativeWindowType.LIGHTWEIGHT. W systemie Mac OS X okna zminimalizowane są wyświetlane na pasku zadań w Docku. Można zapobiec wyświetlaniu ikon okien zminimalizowanych, ukrywając okna, zamiast je minimalizować. Poniższy przykład ilustruje wykrywanie zdarzeń zamiany nativeWindowDisplayState i anulowanie zdarzenia, jeśli okno jest minimalizowane. Program obsługi ustawia natomiast właściwość visible okna na false: private function preventMinimize(event:NativeWindowDisplayStateEvent):void{ if(event.afterDisplayState == NativeWindowDisplayState.MINIMIZED){ event.preventDefault(); event.target.visible = false; } } Jeśli okno jest zminimalizowane do Docku systemu Mac OS X, to po ustawieniu właściwości visible na false ikona z Docku nie jest usuwana. Użytkownik może kliknąć ikonę i spowodować ponowne wyświetlenie okna. 107 Rozdział 14: Praca z systemem plików Za pomocą klas udostępnionych przez interfejs API systemu plików programu Adobe® AIR™ można uzyskiwać dostęp do systemu plików na hoście. Korzystając z tych klas, można uzyskiwać dostęp do katalogów i plików, a także zarządzać nimi. Można tworzyć katalogi i pliki, zapisywać dane do plików itd. Dodatkowe informacje online dotyczące interfejsu API plików programu AIR Więcej informacji na temat korzystania z klas interfejsu API plików zawierają następujące źródła: Podręczniki Szybki start (Adobe AIR Developer Connection) • Budowanie edytora plików tekstowych Skorowidz języka • File • FileStream • FileMode Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR filesystem”) Podstawowe informacje o plikach AIR Środowisko Adobe AIR udostępnia klasy przeznaczone do uzyskiwania dostępu, tworzenia i zarządzania plikami i folderami. Te klasy, dostępne w pakiecie flash.filesystem, mają następujące zastosowania: Klasy File Opis File Obiekt File reprezentuje ścieżkę do pliku lub katalogu. Obiekt File służy do utworzenia wskaźnika do pliku lub folderu, który inicjuje interakcję z plikiem lub folderem. FileMode Klasa FileMode definiuje stałe w postaci ciągu znaków używane w parametrze fileMode metod open() i openAsync() klasy FileStream. Parametr fileMode tych metod określa możliwości obiektu FileStream po otwarciu pliku, łącznie z odczytem, zapisem, dołączaniem i aktualizacją. FileStream Obiekt FileStream służy do otwierania plików do odczytu i zapisu. Po utworzeniu obiektu File, który wskazuje na nowy lub istniejący plik, należy przekazać ten wskaźnik do obiektu FileStream, aby umożliwić otwarcie, a następnie manipulowanie danymi w pliku. Niektóre metody w klasie File mają wersje synchroniczne i asynchroniczne: • File.copyTo() i File.copyToAsync() • File.deleteDirectory() i File.deleteDirectoryAsync() • File.deleteFile() i File.deleteFileAsync() TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 108 Praca z systemem plików • File.getDirectoryListing() i File.getDirectoryListingAsync() • File.moveTo() i File.moveToAsync() • File.moveToTrash() i File.moveToTrashAsync() Ponadto operacje FileStream mogą działać synchronicznie lub asynchronicznie w zależności od sposobu, w jaki obiekt FileStream otwiera plik: poprzez wywołanie metody open() lub poprzez wywołanie metody openAsync(). Wersje asynchroniczne umożliwiają inicjowanie procesów, które działają w tle, a także wywoływanie zdarzeń po zakończeniu tych procesów (lub w przypadku wystąpienia zdarzeń błędów). Podczas tych asynchronicznych procesów wykonywanych w tle może być wykonywany inny kod. W przypadku asynchronicznych wersji operacji należy skonfigurować funkcje detektora zdarzeń, korzystając w tym celu z metody addEventListener() obiektu File lub obiektu FileStream, który wywołuje funkcję. Wersje synchroniczne umożliwiają pisanie prostszego kodu, który nie jest oparty na konfigurowaniu detektorów zdarzeń. Podczas wykonywania metody synchronicznej nie jest możliwe wykonywanie innego kodu i dlatego istotne procesy, takie jak renderowanie obiektów wyświetlanych i animacji, mogą zostać wstrzymane. Praca z obiektami File Obiekt File jest wskaźnikiem do pliku lub katalogu w systemie plików. Klasa File stanowi rozszerzenie klasy FileReference. Klasa FileReference, która jest dostępna w programie Adobe® Flash® Player, a także w programie AIR, reprezentuje wskaźnik do pliku, ale klasa File dodaje właściwości i metody, które nie są dostępne w programie Flash Player (w pliku SWF działającym w przeglądarce) z powodu zagadnień związanych z bezpieczeństwem. Informacje o klasie File Klasa File może służyć do wykonywania następujących czynności: • Pobieranie ścieżki do katalogów specjalnych, między innymi do katalogu użytkownika, katalogu dokumentów użytkownika, katalogu aplikacji oraz katalogu, z którego została uruchomiona aplikacja • Kopiowanie plików i katalogów • Przenoszenie plików i katalogów • Usuwanie plików i katalogów (lub przenoszenie ich do kosza) • Wyświetlanie list plików i katalogów zawartych w katalogu • Tworzenie tymczasowych plików i folderów Jeśli obiekt File wskazuje na ścieżkę pliku, można użyć go w celu odczytania lub zapisania danych pliku za pomocą klasy FileStream. Obiekt File może wskazywać na ścieżkę pliku lub katalog, który jeszcze nie istnieje. Taki obiekt File może zostać wykorzystany podczas tworzenia pliku lub katalogu. Ścieżki obiektów File Każdy obiekt File ma dwie właściwości, które definiują jego ścieżkę: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 109 Praca z systemem plików Właściwość Opis nativePath Określa ścieżkę do pliku właściwą dla platformy. Na przykład: w systemie Windows ścieżka może być następująca „c:\Przykładowy katalog\test.txt”, a w systemie Mac OS może być taka: „/Przykładowy katalog/test.txt”. Właściwość nativePath wykorzystuje znak ukośnika w lewo (\) jako separator katalogów w systemie Windows, a w systemie Mac OS i Linux wykorzystuje ukośnik w prawo (/). url Dzięki temu możliwe jest użycie schematu adresu URL pliku w celu wskazania na plik. Na przykład: w systemie Windows ścieżka może być następująca „file:///c:/Przykładowy%20katalog/test.txt”, a w systemie Mac OS może być taka: „file:///Przykładowy%20katalog/test.txt”. Środowisko wykonawcze zawiera również inne specjalne schematy URL oprócz schematów file i zostały one opisane w sekcji „Obsługiwane schematy URL” na stronie 113 Klasa File zawiera właściwości przeznaczone do wskazywania na standardowe katalogi w systemie Mac OS, Windows i Linux. Wskazywanie obiektu File na katalog Istnieją różne sposoby konfigurowania obiektu File w taki sposób, aby wskazywał na katalog. Wskazywanie na katalog osobisty użytkownika Obiekt File może wskazywać na katalog osobisty użytkownika. W systemie Windows katalog osobisty jest nadrzędny wobec katalogu „Moje dokumenty” (na przykład: „C:\Documents and Settings\nazwa_użytkownika\Moje dokumenty”). W systemie Mac OS jest to katalog Users/nazwa_użytkownika. W systemie Linux jest to katalog /home/nazwa_użytkownika. Poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na podkatalog AIR Test katalogu osobistego: var file:File = File.userDirectory.resolvePath("AIR Test"); Wskazywanie na katalog dokumentów użytkownika Obiekt File może wskazywać na katalog dokumentów użytkownika. W systemie Windows domyślną lokalizacją jest katalog „Moje dokumenty” (na przykład: „C:\Documents and Settings\nazwa_użytkownika\Moje dokumenty”). W systemie Mac OS domyślną lokalizacją jest katalog Users/nazwa_użytkownika/Documents. W systemie Linux domyślną lokalizacją jest katalog /home/nazwa_użytkownika/Documents. Poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na podkatalog AIR Test katalogu dokumentów: var file:File = File.documentsDirectory.resolvePath("AIR Test"); Wskazywanie na katalog na pulpicie Obiekt File może wskazywać na katalog znajdujący się na pulpicie. Poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na podkatalog AIR Test znajdujący się na pulpicie: var file:File = File.desktopDirectory.resolvePath("AIR Test"); Wskazywanie na katalog zapisu aplikacji Obiekt File może wskazywać na katalog zapisu aplikacji. Dla każdej aplikacji AIR istnieje unikalna skojarzona ścieżka, która definiuje katalog zapisu aplikacji. Ten katalog jest unikalny dla każdej aplikacji i każdego użytkownika. W tym katalogu można zapisywać dane dot. aplikacji dla konkretnego użytkownika (np. dane użytkownika lub pliki preferencji). Przykład: poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na plik preferencji prefs.xml zawarty w katalogu zapisu aplikacji: var file:File = File.applicationStorageDirectory; file = file.resolvePath("prefs.xml"; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 110 Praca z systemem plików Lokalizacja katalogu zapisu aplikacji jest uzależniona od nazwy użytkownika, identyfikatora aplikacji i identyfikatora wydawcy: • W systemie Mac OS: /Users/nazwa użytkownika/Library/Preferences/id_aplikacji.id_wydawcy/Local Store/ Na przykład: /Users/babbage/Library/Preferences/com.example.TestApp.02D88EEED35F84C264A183921344EEA353 A629FD.1/Local Store • W systemie Windows: w katalogu Documents and Settings: nazwa użytkownika/Application Data/id_aplikacji.id_wydawcy/Local Store/ Na przykład: C:\Documents and Settings\babbage\Application Data\com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Local Store • W systemie Linux: w katalogu /home/nazwa użytkownika/.appdata/id_aplikacji.id_wydawcy/Local Store/ Na przykład: /home/babbage/.appdata/com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1/Loc al Store Adres URL (i właściwość url) dla obiektu File utworzonego w katalogu File.applicationStorageDirectory korzysta ze schematu URL app-storage (patrz „Obsługiwane schematy URL” na stronie 113), co przedstawiono poniżej: var dir:File = File.applicationStorageDirectory; dir = dir.resolvePath("preferences"); trace(dir.url); // app-storage:/preferences Wskazywanie na katalog aplikacji Obiekt File może wskazywać na katalog, w którym została zainstalowana aplikacja — jest to tzw. katalog aplikacji. Za pomocą właściwości File.applicationDirectory można tworzyć dowołania do tego katalogu. Za pomocą tego katalogu można sprawdzić plik deskryptora aplikacji lub inne zasoby zainstalowane w aplikacji. Na przykład: poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na katalog images w katalogu aplikacji: var dir:File = File.applicationDirectory; dir = dir.resolvePath("images"); Adres URL (i właściwość url) dla obiektu File utworzonego w File.applicationDirectory korzysta ze schematu URL app (patrz „Obsługiwane schematy URL” na stronie 113), co przedstawiono poniżej: var dir:File = File.applicationDirectory; dir = dir.resolvePath("images"); trace(dir.url); // app:/images Wskazywanie na katalog główny systemu plików Metoda File.getRootDirectories() zawiera listę wszystkich woluminów głównych, takich jak C:, oraz woluminów podłączonych, w komputerze z systemem Windows. W systemie Mac OS i Linux ta metoda zawsze zwraca unikalny katalog główny komputera (katalog „/”). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 111 Praca z systemem plików Wskazywanie na katalog jawny Obiekt File może wskazywać na katalog jawny — w tym celu należy ustawić właściwość nativePath obiektu File, jak w poniższym przykładzie (w systemie Windows): var file:File = new File(); file.nativePath = "C:\\AIR Test\"; Nawigacja do ścieżek względnych Za pomocą metody resolvePath() można uzyskiwać ścieżkę względną do określonej innej ścieżki. Na przykład: poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na podkatalog „AIR Test” katalogu osobistego: var file:File = File.userDirectory; file = file.resolvePath("AIR Test"); Można również użyć właściwości url obiektu File, aby wskazywał on na katalog na podstawie ciągu znaków URL, jak w poniższym przykładzie: var urlStr:String = "file:///C:/AIR Test/"; var file:File = new File() file.url = urlStr; Więcej informacji zawiera sekcja „Modyfikowanie ścieżek File” na stronie 113. Zezwalanie użytkownikowi na przeglądanie w celu wybrania katalogu Klasa File zawiera metodę browseForDirectory(), która powoduje wyświetlenie systemowego okna dialogowego, w którym użytkownik może wybrać podkatalog, jaki zostanie przypisany do obiektu. Metoda browseForDirectory() jest asynchroniczna. Wywołuje zdarzenie select, gdy użytkownik wybierze katalog i kliknie przycisk Otwórz, lub wywołuje zdarzenie cancel, gdy użytkownik kliknie przycisk Anuluj. Przykład: poniższy kod umożliwia użytkownikowi wybranie katalogu, a po wybraniu generuje ścieżkę katalogu: var file:File = new File(); file.addEventListener(Event.SELECT, dirSelected); file.browseForDirectory("Select a directory"); function dirSelected(e:Event):void { trace(file.nativePath); } Wskazywanie na katalog, z którego aplikacja została wywołana W celu uzyskania lokalizacji katalogowej, z której aplikacja została wywołana, należy sprawdzić wartość właściwości currentDirectory obiektu InvokeEvent wywołanego przy wywołaniu aplikacji. Szczegółowe informacje zawiera sekcja „Przechwytywanie argumentów wiersza poleceń” na stronie 294. Wskazywanie obiektu File na plik Istnieją różne sposoby ustawiania pliku, na który ma wskazywać obiekt File. Wskazywanie na jawną ścieżkę pliku Za pomocą metody resolvePath() można uzyskiwać ścieżkę względną do określonej innej ścieżki. Przykład: poniższy kod ustawia obiekt File w taki sposób, aby wskazywał na plik log.txt w katalogu zapisu aplikacji: var file:File = File.applicationStorageDirectory; file = file.resolvePath("log.txt"); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 112 Praca z systemem plików Można użyć właściwości url obiektu File, aby wskazywał on na plik lub katalog na podstawie ciągu znaków URL, jak w poniższym przykładzie: var urlStr:String = "file:///C:/AIR Test/test.txt"; var file:File = new File() file.url = urlStr; Możliwe jest również przekazanie adresu URL do funkcji konstruktora File(), jak w poniższym przykładzie: var urlStr:String = "file:///C:/AIR Test/test.txt"; var file:File = new File(urlStr); Właściwość url zawsze zwraca zakodowaną wersję URL (na przykład: spacje zastąpione znakami "%20): file.url = "file:///c:/AIR Test"; trace(file.url); // file:///c:/AIR%20Test W celu ustawienia ścieżki jawnej obiektu File można również użyć właściwości nativePath. Przykład: poniższy kod uruchomiony w komputerze z systemem Windows ustawia obiekt File na plik test.txt w podkatalogu AIR Test na dysku C: var file:File = new File(); file.nativePath = "C:/AIR Test/test.txt"; Tę ścieżkę można również przekazać do funkcji konstruktora File(), co przedstawiono poniżej: var file:File = new File("C:/AIR Test/test.txt"); W systemie Windows, w postaci ogranicznika ścieżki dla właściwości nativePath, można użyć znaku ukośnika w prawo (/) lub w lewo (\). W systemie Mac OS i Linux jako ogranicznika ścieżki dla nativePath należy używać znaku (/): var file:File = new File(/Users/dijkstra/AIR Test/test.txt"); Więcej informacji zawiera sekcja „Modyfikowanie ścieżek File” na stronie 113. Wyliczanie plików w katalogu Za pomocą metody getDirectoryListing() obiektu File można uzyskać tablicę obiektów File wskazujących na pliki i podkatalogi na najwyższym poziomie katalogu. Więcej informacji zawiera sekcja „Wyliczanie katalogów” na stronie 118. Zezwalanie użytkownikowi na przeglądanie w celu wybrania pliku Klasa File zawiera następujące metody, które powodują wyświetlenie systemowego okna dialogowego, w którym użytkownik może wybrać plik, jaki zostanie przypisany do obiektu: • browseForOpen() • browseForSave() • browseForOpenMultiple() Każda z tych metod jest asynchroniczna. Metody browseForOpen() i browseForSave() wywołują zdarzenie select, gdy użytkownik wybierze plik (lub ścieżkę docelową w przypadku metody browseForSave()). W przypadku metod browseForOpen() i browseForSave() wybranie powoduje, że docelowy obiekt File wskazuje na wybrane pliki. Metoda browseForOpenMultiple() wywołuje zdarzenie selectMultiple, gdy użytkownik wybierze pliki. Zdarzenie selectMultiple jest typu FileListEvent, który zawiera właściwość files będącą tablicą obiektów File (wskazują na wybrane pliki). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 113 Praca z systemem plików Przykład: poniższy kod powoduje wyświetlenie okna dialogowego „Otwórz”, w którym użytkownik może wybrać plik: 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); } Jeśli aplikacja zawiera inne okno dialogowe przeglądarki, które zostało otwarte po wywołaniu metody przeglądania, wówczas podczas wykonywania zwracany jest wyjątek Error. Modyfikowanie ścieżek File Ścieżkę istniejącego obiektu File można również zmodyfikować poprzez wywołanie metody resolvePath() albo modyfikację właściwości nativePath lub url obiektu, jak w poniższych przykładach (w systemie 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 Jeśli używana jest właściwość nativePath, w postaci ogranicznika ścieżek w systemie Windows można użyć ukośnika w prawo (/) lub ukośnika w lewo (\); w systemie Mac OS i Linux należy używać znaku (/). W systemie Windows należy napisać znak ukośnika w prawo dwukrotnie w literale łańcuchowym. Obsługiwane schematy URL Podczas definiowania właściwości url obiektu File można korzystać z następujących schematów URL: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 114 Praca z systemem plików schemat URL Opis file Służy do określania ścieżki względnej do katalogu głównego systemu plików. Na przykład: file:///c:/AIR Test/test.txt Standard URL określa, że adres URL pliku ma format: file://<host>/<path>. W szczególnym przypadku część <host> może zawierać pusty łańcuch, co jest interpretowane jako „komputer, z którego adres URL jest interpretowany”. Z tego powodu adresy URL file często zawierają trzy ukośniki (///). app Służy do określania ścieżki względnej dla katalogu głównego zainstalowanej aplikacji (katalog, który zawiera plik application.xml zainstalowanej aplikacji). Przykład: poniższa ścieżka wskazuje na podkatalog images katalogu zainstalowanej aplikacji: app:/images app-storage Służy do określania ścieżki względnej do katalogu zapisu aplikacji. Dla każdej zainstalowanej aplikacji program AIR definiuje unikalny katalog zapisu aplikacji, który jest użytecznym miejscem zapisu danych dla tej aplikacji. Na przykład: poniższa ścieżka wskazuje na plik prefs.xml w podkatalogu settings katalogu zapisu aplikacji: app-storage:/settings/prefs.xml Znajdowanie ścieżki względnej między dwoma plikami Metoda getRelativePath() służy do wyszukiwania ścieżki względnej między dwoma plikami: 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 Drugi parametr metody getRelativePath() — parametr useDotDot — umożliwia zwrot składni .. w wynikach w celu oznaczenia katalogów nadrzędnych: 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 Uzyskiwanie kanonicznych wersji nazw plików W systemach Windows i Mac OS w nazwach plików i ścieżek nie jest rozróżniana wielkość liter. W poniższym kodzie dwa obiekty File wskazują na ten sam plik: File.documentsDirectory.resolvePath("test.txt"); File.documentsDirectory.resolvePath("TeSt.TxT"); Jednak nazwy dokumentów i katalogów mogą zawierać wielkie litery. Przykład: w poniższym kodzie obowiązuje założenie, że istnieje folder AIR Test w katalogu documents, jak w poniższych przykładach: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 115 Praca z systemem plików var file:File = File.documentsDirectory.resolvePath("AIR test"); trace(file.nativePath); // ... AIR test file.canonicalize(); trace(file.nativePath); // ... AIR Test Metoda canonicalize() konwertuje obiekt nativePath w celu użycia poprawnej wielkości liter dla nazwy pliku i katalogu. W systemach, w których jest rozróżniana wielkość liter (np. w systemie Linux), gdy istnieje wiele plików z nazwami różniącymi się jedynie wielkością liter metoda canonicalize() dostosowuje ścieżkę, tak aby była zgodna z pierwszym znalezionym plikiem (w kolejności określonej przez system plików). Metoda canonicalize() może również służyć do konwertowania krótkich nazw plików (nazwy „8.3”) na długie nazwy plików w systemie Windows, jak w poniższych przykładach: var path:File = new File(); path.nativePath = "C:\\AIR~1"; path.canonicalize(); trace(path.nativePath); // C:\AIR Test Praca z pakietami i dowiązaniami symbolicznymi Różne systemy operacyjne obsługują pliki pakietów oraz pliki dowiązań symbolicznych: Pakiety W systemie Mac OS katalogi mogą być ustawiane jako pakiety i mogą być widoczne w narzędziu Finder systemu Mac OS jako pojedynczy plik, a nie katalog. Dowiązania symboliczne W systemach Mac OS, Linux i Windows Vista dowiązania symboliczne są obsługiwane. Dowiązania symboliczne umożliwiają plikowi na wskazywanie innego pliku lub katalogu na dysku. Istnieją pewne podobieństwa, jednak dowiązania nie są aliasami. Alias jest zawsze zgłaszany jako plik (a nie katalog), a odczyt z aliasu i zapis do aliasu lub skrótu nigdy nie wpływa na oryginalny plik lub katalog, na który on wskazuje. Z drugiej strony dowiązanie symboliczne działa dokładnie, jak plik lub katalog, na który wskazuje. Może być zgłaszane jako plik lub katalog, a odczyt dowiązania lub zapis do dowiązania wpływa na plik lub katalog, na który wskazuje, a nie na dowiązanie symboliczne. Ponadto w systemach Windows właściwość isSymbolicLink obiektu File odwołująca się do punktu połączenia (używanego w systemie plików NTFS) jest ustawiona na wartość true. Klasa File zawiera właściwości isPackage i isSymbolicLink umożliwiające sprawdzenie, czy obiekt File odwołuje się do pakietu lub dowiązania symbolicznego. Poniższy kod przechodzi przez katalog na pulpicie, prezentując podkatalogi, które nie są pakietami: 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); } } Poniższy kod przechodzi przez katalog na pulpicie, prezentując pliki i podkatalogi, które nie dowiązaniami symbolicznymi: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 116 Praca z systemem plików var desktopNodes:File = File.desktopDirectory.getDirectoryListing(); for (var i:uint = 0; i < desktopNodes.length; i++) { if (!desktopNodes[i].isSymbolicLink) { trace(desktopNodes[i].name); } } Metoda canonicalize() zmienia ścieżkę dowiązania symbolicznego w taki sposób, aby wskazywała na plik lub katalog, do którego odwołuje się dowiązanie. Poniższy kod przechodzi przez katalog na pulpicie i zgłasza ścieżki, do których odwołują się pliki będące dowiązaniami symbolicznymi: 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); } } Określanie ilości miejsca dostępnego na woluminie Właściwość spaceAvailable obiektu File to ilość miejsca dostępnego do wykorzystania w lokalizacji File, wyrażona w bajtach. Przykład: poniższy kod sprawdza ilość miejsca dostępnego w katalogu zapisu aplikacji: trace(File.applicationStorageDirectory.spaceAvailable); Jeśli obiekt File odwołuje się do katalogu, wówczas właściwość spaceAvailable wskazuje ilość miejsca w katalogu, jaką mogą wykorzystać pliki. Jeśli obiekt File odwołuje się do pliku, wówczas właściwość spaceAvailable wskazuje maksymalną ilość miejsca, jaką może zajmować plik. Jeśli lokalizacja pliku nie istnieje, wówczas właściwość spaceAvailable ma wartość 0. Jeśli obiekt File odwołuje się do dowiązania symbolicznego, wówczas właściwość spaceAvailable jest ustawiona na ilość miejsca dostępnego w lokalizacji, na którą wskazuje dowiązanie symboliczne. Zwykle ilość miejsca dostępnego dla katalogu lub pliku jest taka sama, jak ilość miejsca dostępnego w woluminie zawierającym katalog lub plik. Jednak ilość miejsca dostępnego może uwzględniać przydziały i limity dla poszczególnych katalogów. Dodanie pliku lub katalogu do woluminu zwykle powoduje wykorzystanie większej ilości miejsca niż rzeczywisty rozmiar pliku lub rozmiar zawartości katalogu. Na przykład: system operacyjny może wymagać większej ilości miejsca w celu zapisu danych indeksu. Lub wymagane sektory dysku mogą wykorzystywać dodatkową ilość miejsca. Ponadto dostępna ilość miejsca zmienia się w sposób dynamiczny. Dlatego nie można oczekiwać, że możliwa będzie alokacja całej zgłaszanej ilości miejsca dla zapisu plików. Informacje na temat zapisywania danych w systemie plików zawiera sekcja „Odczyt i zapis plików” na stronie 122. Uzyskiwanie informacji o systemie plików Klasa File zawiera następujące właściwości statyczne, które udostępniają użyteczne informacje o systemie plików: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 117 Praca z systemem plików Właściwość Opis File.lineEnding Sekwencja znaku końca linii używana przez system operacyjny hosta. W systemie Mac OS i Linux jest to znak nowej linii. W systemie Windows jest to znak powrotu karetki, po którym następuje znak nowej linii. File.separator Znak ogranicznika składnika ścieżki systemu operacyjnego hosta. W systemie Mac OS i Linux jest to znak ukośnika w prawo. W systemie Windows jest to znak ukośnika w lewo (\). File.systemCharset Domyślne kodowanie używane dla plików przez system operacyjny hosta. Dotyczy zestawu znaków używanego przez system operacyjny — odpowiada językowi systemu. Klasa Capabilities zawiera również użyteczne informacje o systemie, które mogą być istotne podczas pracy z plikami: Właściwość Opis Capabilities.hasIME Określa, czy odtwarzacz działa w systemie zawierającym edytor IME (true), czy w systemie, który nie zawiera zainstalowanego edytora IME (false). Capabilities.language Określa kod języka systemu, w którym uruchomiono odtwarzacz. Capabilities.os Określa bieżący system operacyjny. Praca z katalogami Środowisko wykonawcze udostępnia możliwości pracy z katalogami w lokalnym systemie plików. Szczegółowe informacje na temat tworzenia obiektów File, które wskazują na katalogi, zawiera sekcja „Wskazywanie obiektu File na katalog” na stronie 109. Tworzenie katalogów Metoda File.createDirectory() służy do tworzenia katalogów. Przykład: poniższy kod tworzy katalog o nazwie AIR Test jako podkatalog katalogu osobistego użytkownika: var dir:File = File.userDirectory.resolvePath("AIR Test"); dir.createDirectory(); Jeśli katalog istnieje, metoda createDirectory() nie wykonuje żadnej operacji. Ponadto w niektórych trybach obiekt FileStream tworzy katalogi podczas otwierania plików. Brakujące katalogi są tworzone podczas tworzenia instancji FileStream za pomocą parametru fileMode konstruktora FileStream(), dla którego ustawiono FileMode.APPEND lub FileMode.WRITE. Więcej informacji zawiera sekcja „Przepływ pracy odczytu i zapisu plików.” na stronie 122. Tworzenie katalogu tymczasowego Klasa File zawiera metodę createTempDirectory(), która tworzy katalog w folderze tymczasowego katalogu dla systemu, jak w poniższym przykładzie: var temp:File = File.createTempDirectory(); Metoda createTempDirectory() automatycznie tworzy unikalny katalog tymczasowy (dzięki czemu użytkownik nie musi określać nowej unikalnej lokalizacji). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 118 Praca z systemem plików Ten tymczasowy katalog może służyć do tymczasowego zapisu plików używanych dla sesji aplikacji. Istnieje również metoda createTempFile() przeznaczona do tworzenia nowych, unikatowych plików w katalogu tymczasowym systemu. Przed zamknięciem aplikacji konieczne może być usunięcie tymczasowego katalogu, ponieważ nie jest on usuwany automatycznie. Wyliczanie katalogów Za pomocą metody getDirectoryListing() lub metody getDirectoryListingAsync() obiektu File można uzyskać tablicę obiektów File wskazujących na pliki lub podfoldery w katalogu. Przykład: poniższy kod zawiera listę zawartości katalogu dokumentów użytkownika (bez sprawdzania podkatalogów): 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); } Gdy używana jest asynchroniczna wersja metody, wówczas obiekt zdarzenia directoryListing zawiera właściwość files, która jest tablicą obiektów File odnoszących się do katalogów: 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); } } Kopiowanie i przenoszenie katalogów Katalog można skopiować lub przenieść, korzystając z tych samych metod, jakie są używane do kopiowania i przenoszenia plików. Przykład: poniższy kod kopiuje katalog synchronicznie: var sourceDir:File = File.documentsDirectory.resolvePath("AIR Test"); var resultDir:File = File.documentsDirectory.resolvePath("AIR Test Copy"); sourceDir.copyTo(resultDir); Jeśli dla parametru overwrite metody copyTo() zostanie określona wartość true, wówczas wszystkie pliki i foldery istniejącego katalogu docelowego zostaną usunięte i zastąpione plikami i folderami z katalogu źródłowego (nawet jeśli plik docelowy nie istnieje w katalogu docelowym). Katalog określony jako parametr newLocation metody copyTo() określa ścieżkę do istniejącego katalogu; nie określa katalogu nadrzędnego, który będzie zawierał katalog wynikowy. Szczegółowe informacje zawiera sekcja „Kopiowanie i przenoszenie plików” na stronie 120. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 119 Praca z systemem plików Usuwanie zawartości katalogu Klasa File zawiera metodę deleteDirectory() oraz metodę deleteDirectoryAsync(). Te metody służą do usuwania katalogów — pierwsza z nich działa synchronicznie, a druga działa asynchronicznie (patrz „Podstawowe informacje o plikach AIR” na stronie 107). Obydwie metody zawierają parametr deleteDirectoryContents (który przyjmuje wartość logiczną); jeśli dla tego parametru ustawiona jest wartość true (wartością domyślną jest false), wówczas wywołanie metody powoduje usunięcie niepustych katalogów; w przeciwnym wypadku usuwane są tylko puste katalogi. Przykład: poniższy kod synchronicznie usuwa podkatalog AIR Test katalogu dokumentów użytkownika: var directory:File = File.documentsDirectory.resolvePath("AIR Test"); directory.deleteDirectory(true); Poniższy kod asynchronicznie usuwa podkatalog AIR Test katalogu dokumentów użytkownika: var directory:File = File.documentsDirectory.resolvePath("AIR Test"); directory.addEventListener(Event.COMPLETE, completeHandler) directory.deleteDirectoryAsync(true); function completeHandler(event:Event):void { trace("Deleted.") } Dostępne są również metody moveToTrash() i moveToTrashAsync(), które mogą służyć do przenoszenia katalogu do kosza systemu. Szczegółowe informacje zawiera sekcja „Przenoszenie pliku do kosza” na stronie 121. Praca z plikami Za pomocą interfejsu API plików AIR można dodawać do aplikacji proste operacje na plikach. Na przykład: możliwe jest odczytywanie i zapisywanie plików, usuwanie plików itp. Aplikacje mogą uzyskiwać dostęp do lokalnego systemu plików, dlatego należy zapoznać się z rozdziałem „Zabezpieczenia w środowisku AIR” na stronie 24. Uwaga: Z aplikacją AIR można skojarzyć typ pliku (wówczas dwukrotne kliknięcie pliku powoduje otwarcie aplikacji). Szczegółowe informacje zawiera sekcja „Zarządzanie skojarzeniami plików” na stronie 301. Uzyskiwanie informacji o pliku Klasa File zawiera następujące właściwości, które udostępniają informacje o pliku lub katalogu, na który wskazuje obiekt File: Właściwość File Opis creationDate Data utworzenia pliku na dysku lokalnym. creator Przestarzała — należy używać właściwości extension. (Ta właściwość określa typ programu Macintosh, za pomocą którego utworzono plik file, jest używany wyłącznie w wersjach systemu Mac OS poprzedzających wersje Mac OS X). exists Informuje o tym, czy istnieje plik lub katalog, do którego istnieje odwołanie. extension Rozszerzenie pliku, które jest częścią nazwy pliku po ostatniej kropce („.”) (bez tej kropki). Jeśli nazwa pliku nie zawiera kropki, rozszerzenie ma wartość null. icon Obiekt Icon zawierający ikony zdefiniowane dla pliku. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 120 Praca z systemem plików Właściwość File Opis isDirectory Informuje o tym, czy obiekt File odwołuje się do katalogu. modificationDate Data ostatniej modyfikacji pliku lub katalogu na dysku lokalnym. name Nazwa pliku lub katalogu (łącznie z rozszerzeniem, jeśli istnieje) na dysku lokalnym. nativePath Pełna ścieżka reprezentacji systemu operacyjnego hosta. Patrz „Ścieżki obiektów File” na stronie 108. parent Folder, który zawiera folder lub plik reprezentowany przez obiekt File. Ta właściwość ma wartość null, jeśli obiekt File odwołuje się do pliku lub katalogu w katalogu głównym systemu plików. size Rozmiar pliku na dysku lokalnym (w bajtach). type Przestarzała — należy używać właściwości extension. (W systemie Macintosh ta właściwość określa czteroznakowy typ pliku, który jest używany tylko w wersjach systemu Mac OS poprzedzających wersję Mac OS X). url Adres URL pliku lub katalogu. Patrz „Ścieżki obiektów File” na stronie 108. Szczegółowe informacje o tych właściwościach zawiera opis klasy File na stronie Skorowidz języka i składników ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_pl). Kopiowanie i przenoszenie plików Klasa File zawiera dwie metody przeznaczone do kopiowania plików lub katalogów: copyTo() i copyToAsync(). Klasa File zawiera dwie metody do przenoszenia plików lub katalogów: moveTo() i moveToAsync(). Metody copyTo() i moveTo() działają synchronicznie, a metody copyToAsync() oraz moveToAsync() działają asynchronicznie (patrz „Podstawowe informacje o plikach AIR” na stronie 107). W celu skopiowania lub przeniesienia pliku należy skonfigurować dwa obiekty File. Jeden powinien wskazywać na plik przeznaczony do skopiowania lub przeniesienia — ten obiekt wywołuje metodę kopiowania lub przenoszenia; drugi powinien wskazywać na ścieżkę docelową (wynikową). Poniższy kod kopiuje plik test.txt z podkatalogu AIR Test katalogu dokumentów użytkownika do pliku o nazwie copy.txt w tym samym katalogu: var original:File = File.documentsDirectory.resolvePath("AIR Test/test.txt"); var newFile:File = File.resolvePath("AIR Test/copy.txt"); original.copyTo(newFile, true); W tym przykładzie parametr overwrite metody copyTo() (drugi parametr) ma wartość true. Ustawienie wartości true powoduje, że istniejący plik docelowy zostaje zastąpiony. Ten parametr jest opcjonalny. Jeśli zostanie ustawiona wartość false (domyślna), wówczas operacja wywołuje zdarzenie IOErrorEvent, pod warunkiem że plik docelowy istnieje (plik nie jest kopiowany). Wersje „Async” metod kopiowania i przenoszenia działają asynchronicznie. Metoda addEventListener() służy do monitorowania zakończenia zadania lub warunku powodującego błąd, jak w poniższym kodzie: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 121 Praca z systemem plików 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."); } Klasa File zawiera również metody File.moveToTrash() i File.moveToTrashAsync(), które przenoszą plik lub katalog do kosza systemowego. Usuwanie pliku Klasa File zawiera metodę deleteFile() oraz metodę deleteFileAsync(). Te metody służą do usuwania plików — pierwsza z nich działa synchronicznie, a druga działa asynchronicznie (patrz „Podstawowe informacje o plikach AIR” na stronie 107). Przykład: poniższy kod synchronicznie usuwa plik test.txt z katalogu dokumentów użytkownika: var file:File = File.documentsDirectory.resolvePath("test.txt"); file.deleteFile(); Przykład: poniższy kod asynchronicznie usuwa plik test.txt z katalogu dokumentów użytkownika: var file:File = File.documentsDirectory.resolvePath("test.txt"); file.addEventListener(Event.COMPLETE, completeHandler) file.deleteFileAsync(); function completeHandler(event:Event):void { trace("Deleted.") } Dostępne są również metody moveToTrash() i moveToTrashAsync, które mogą służyć do przenoszenia pliku lub katalogu do kosza systemu. Szczegółowe informacje zawiera sekcja „Przenoszenie pliku do kosza” na stronie 121. Przenoszenie pliku do kosza Klasa File zawiera metodę moveToTrash() oraz metodę moveToTrashAsync(). Te metody wysyłają plik lub katalog do kosza systemu — pierwsza z nich działa w sposób synchroniczny, a druga w sposób asynchroniczny (patrz „Podstawowe informacje o plikach AIR” na stronie 107). Przykład: poniższy kod synchronicznie przenosi plik test.txt z katalogu dokumentów użytkownika do kosza systemowego: var file:File = File.documentsDirectory.resolvePath("test.txt"); file.moveToTrash(); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 122 Praca z systemem plików Tworzenie pliku tymczasowego Klasa File zawiera metodę createTempFile(), która tworzy plik w folderze systemowego katalogu tymczasowego, jak w poniższym przykładzie: var temp:File = File.createTempFile(); Metoda createTempFile() automatycznie tworzy unikalny plik tymczasowy (dzięki czemu użytkownik nie musi określać nowej unikalnej lokalizacji). Ten tymczasowy plik może służyć do tymczasowego zapisu informacji używanych w sesji aplikacji. Istnieje również metoda createTempDirectory() przeznaczona do tworzenia unikalnego katalogu tymczasowego w katalogu tymczasowym systemu. Przed zamknięciem aplikacji konieczne może być usunięcie tymczasowego pliku, ponieważ nie jest on usuwany automatycznie. Odczyt i zapis plików Klasa FileStream umożliwia aplikacji AIR odczyt i zapis w systemie plików. Przepływ pracy odczytu i zapisu plików. Przepływ pracy odczytu i zapisu plików jest następujący. Należy zainicjować obiekt File, który będzie wskazywał na ścieżkę. Jest to ścieżka wybranego pliku (lub pliku, który zostanie utworzony później). var file:File = File.documentsDirectory; file = file.resolvePath("AIR Test/testFile.txt"); W przykładzie wykorzystano właściwość File.documentsDirectory oraz metodę resolvePath() obiektu File w celu zainicjowania obiektu File. Istnieje jednak wiele innych sposobów na to, aby obiekt File wskazywał na plik. Więcej informacji zawiera sekcja „Wskazywanie obiektu File na plik” na stronie 111. Inicjowanie obiektu FileStream. Należy wywołać metodę open() lub metodę openAsync() obiektu FileStream. Metoda, którą należy wywołać, jest uzależniona od tego, czy wymagane jest otwarcie pliku do operacji synchronicznych lub asynchronicznych. Obiekt File powinien być używany jako parametr file metody open(). Dla parametru fileMode należy określić stałą z klasy FileMode, która określa sposób używania pliku. Przykład: poniższy kod inicjuje obiekt FileStream, który zostanie użyty do utworzenia pliku i zastąpienia istniejących danych: var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.WRITE); Więcej informacji zawierają sekcje „Inicjowanie obiektu FileStream oraz otwieranie i zamykanie plików” na stronie 124 oraz „Tryby otwierania FileStream” na stronie 123. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 123 Praca z systemem plików Jeśli plik został otwarty asynchronicznie (za pomocą metody openAsync()), należy do obiektu FileStream dodać detektory zdarzeń i skonfigurować je. Te metody detektorów zdarzeń reagują na zdarzenia wywołane przez obiekt FileStream w różnych sytuacjach, takich jak odczyt danych z pliku, błędy we/wy lub pełny zapis danych przeznaczonych do zapisu. Szczegółowe informacje zawiera sekcja „Asynchroniczne programowanie oraz zdarzenia wygenerowane przez obiekt FileStream otwarty asynchronicznie” na stronie 128. Dołączanie kodu dla odczytu i zapisu danych — w razie potrzeby. Istnieje wiele metod klasy FileStream, które są przeznaczone do odczytu i zapisu. (Nazwa każdej z nich rozpoczyna się od słowa „read” lub „write”). Wybór metody do odczytu lub zapisu danych jest uzależniony od formatu danych w pliku docelowym. Na przykład: jeśli dane w pliku docelowym mają format tekstu w formacie UTF, wówczas możliwe jest wykorzystanie metod readUTFBytes() i writeUTFBytes(). Jeśli dane będą traktowane jako tablice bajtowe, można użyć metod readByte(), readBytes(), writeByte() i writeBytes(). Szczegółowe informacje zawiera sekcja „Formaty danych oraz wybór metod odczytu i zapisu” na stronie 129. Jeśli plik został otwarty w sposób asynchroniczny, przed wywołaniem metody należy upewnić się, że dostępna jest dostateczna ilość danych. Szczegółowe informacje zawiera sekcja „Bufor odczytu oraz właściwość bytesAvailable obiektu FileStream” na stronie 126. Jeśli przed zapisaniem w pliku wymagane jest sprawdzenie ilości miejsca dostępnego na dysku, należy sprawdzić właściwość spaceAvailable obiektu File. Więcej informacji zawiera sekcja „Określanie ilości miejsca dostępnego na woluminie” na stronie 116. Po zakończeniu pracy z plikiem należy wywołać metodę close() obiektu FileStream. Dzięki temu plik stanie się dostępny dla innych aplikacji. Szczegółowe informacje zawiera sekcja „Inicjowanie obiektu FileStream oraz otwieranie i zamykanie plików” na stronie 124. Przykładową aplikację, w której wykorzystano klasę FileStream do odczytywania i zapisywania plików, zawierają poniższe artykuły na stronie Adobe AIR Developer Center: • Budowanie edytora plików tekstowych Praca z obiektami FileStream Klasa FileStream definiuje metody przeznaczone do otwierania, odczytywania i zapisywania plików. Tryby otwierania FileStream Metody open() i openAsync() obiektu FileStream zawierają parametr fileMode, który definiuje niektóre właściwości dla strumienia pliku, między innymi następujące: • Możliwość odczytu z pliku • Możliwość zapisu w pliku • Informacja o tym, czy dane będą zawsze dołączane za końcem pliku (podczas odczytu) • Informacja o sposobie postępowania, gdy plik nie istnieje (oraz gdy nie istnieją jego katalogi nadrzędne) Poniżej przedstawiono różne tryby file (można je określić jako parametr fileMode metod open() i openAsync()): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 124 Praca z systemem plików Tryb File Opis FileMode.READ Określa, że plik jest otwarty tylko dla odczytu. FileMode.WRITE Określa, że plik jest otwarty dla zapisu. Jeśli plik nie istnieje, zostaje utworzony po otwarciu obiektu FileStream. Jeśli plik istnieje, istniejące dane zostają usunięte. FileMode.APPEND Określa, że plik jest otwarty dla dołączania. Jeśli plik nie istnieje, zostaje utworzony. Jeśli plik istnieje, istniejące dane nie są zastępowane, a wszystkie operacje zapisu rozpoczynają się na koniec pliku. FileMode.UPDATE Określa, że plik jest otwarty dla odczytu i zapisu. Jeśli plik nie istnieje, zostaje utworzony. Ten tryb należy wybrać dla różnych operacji zapisu i odczytu pliku. Możliwy jest odczyt z dowolnego miejsca pliku, a w przypadku zapisu pliku tylko bajty zapisywane zastępują bajty istniejące (wszystkie pozostałe pozostają niezmienione). Inicjowanie obiektu FileStream oraz otwieranie i zamykanie plików Otwarty obiekt FileStream staje się dostępny do odczytu i zapisu danych w pliku. Obiekt FileStream należy otworzyć poprzez przekazanie obiektu File do metody open() lub openAsync() obiektu FileStream: var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt"); var myFileStream:FileStream = new FileStream(); myFileStream.open(myFile, FileMode.READ); Parametr fileMode (drugi parametr metod open() i openAsync()) określa tryb, w którym plik zostanie otwarty: do odczytu, zapisu, dołączania lub aktualizacji. Szczegółowe informacje zawiera poprzednia sekcja „Tryby otwierania FileStream” na stronie 123. Jeśli metoda openAsync() jest używana do otwierania pliku dla asynchronicznych operacji na pliku, należy skonfigurować detektory zdarzeń w celu obsługi zdarzeń asynchronicznych: 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 { // ... } Plik jest otwierany dla operacji synchronicznych lub asynchronicznych w zależności od tego, czy użyto metody open() czy metody openAsync(). Szczegółowe informacje zawiera sekcja „Podstawowe informacje o plikach AIR” na stronie 107. Jeśli dla parametru fileMode ustawiono wartość FileMode.READ lub FileMode.UPDATE w metodzie open obiektu FileStream, wówczas dane zostają wczytane do bufora odczytu po otwarciu obiektu FileStream. Szczegółowe informacje zawiera sekcja „Bufor odczytu oraz właściwość bytesAvailable obiektu FileStream” na stronie 126. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 125 Praca z systemem plików Metoda close() obiektu FileStream służy do zamykania skojarzonego pliku, co sprawia, że plik staje się dostępny dla innych aplikacji. Właściwość position obiektu FileStream Właściwość position obiektu FileStream określa, czy dane są odczytywane lub zapisywane przez następną metodę odczytu lub zapisu. Przed wykonaniem operacji odczytu lub zapisu należy ustawić właściwość position na poprawną pozycję w pliku. Przykład: poniższy kod zapisuje ciąg znaków "hello" (kodowanie UTF) w pozycji 8 w pliku: 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"); Przy pierwszym otwarciu obiektu FileStream dla właściwości position ustawiona zostaje wartość 0. Przed operacją odczytu wartość position musi wynosić co najmniej 0 i musi być mniejsza niż liczba bajtów w pliku (bajty są istniejącymi pozycjami w pliku). Wartość właściwości position jest modyfikowana w następujących warunkach: • Po jawnym ustawieniu właściwości position. • Po wywołaniu metody read. • Po wywołaniu metody write. Po wywołaniu metody read lub write obiektu FileStream właściwość position jest natychmiast zwiększana o liczbę bajtów odczytywanych lub zapisywanych. W zależności od tego, która metoda read jest używana, właściwość position jest zwiększana o liczbę bajtów określonych do odczytu lub o liczbę bajtów dostępnych. Jeśli następie zostanie wywołana metoda read lub write, metoda wykona operację odczytu lub zapisu począwszy od nowej pozycji. 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 Istnieje jednak jeden wyjątek: w przypadku obiektu FileStream otwartego w trybie append właściwość position nie jest zmieniana po wywołaniu metody write. (W trybie append dane są zawsze zapisywane na końcu pliku niezależnie od wartości właściwości position). W przypadku pliku otwartego dla operacji asynchronicznych operacja write nie kończy działania przed wykonaniem kolejnego wiersza kodu. Jednak możliwe jest wywołanie kolejno wielu metod asynchronicznych, a wówczas środowisko wykonawcze wykonuje je w określonej kolejności: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 126 Praca z systemem plików 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."); } Wynik (trace (output)) dla tego kodu jest następujący: started. finished. Możliwe jest określenie wartości position bezpośrednio po wywołaniu metody read lub call (lub w dowolnym czasie), a wówczas następna operacja odczytu lub zapisu odbywa się od tej pozycji. Przykład: poniższy kod ustawia właściwość position po wywołaniu operacji writeBytes(), a dla parametru position ustawiana jest ta wartość (300) nawet po zakończeniu operacji write: 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 Bufor odczytu oraz właściwość bytesAvailable obiektu FileStream Po otwarciu obiektu FileStream z funkcją odczytu (taki, w którym dla parametru fileMode metody open() lub openAsync() ustawiono wartość READ lub UPDATE) środowisko wykonywania przechowuje dane w buforze wewnętrznym. Obiekt FileStream rozpoczyna wczytywanie danych do buforu po otwarciu pliku (poprzez wywołanie metody open() lub openAsync() obiektu FileStream). W przypadku pliku otwartego dla operacji synchronicznych (za pomocą metody open()) zawsze można ustawić wskaźnik position na dowolną poprawną metodę (w granicach pliku), a następnie rozpocząć odczyt dowolnej ilości danych (w granicach pliku), co przedstawia poniższy kod (w którym założono, że plik zawiera co najmniej 100 bajtów danych): 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); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 127 Praca z systemem plików Niezależnie od tego, czy plik jest otwarty dla operacji synchronicznych, czy asynchronicznych, metoda read zawsze odczytuje z bajtów „dostępnych” reprezentowanych przez właściwość bytesAvalable. W przypadku odczytu synchronicznego wszystkie bajty pliku są dostępne przez cały czas. W przypadku odczytu asynchronicznego bajty stają się dostępne począwszy od pozycji określonej przez właściwość position — w seriach asynchronicznego wypełniania buforu, o czym powiadamiają zdarzenia progress. W przypadku plików otwartych dla operacji synchronicznych właściwość bytesAvailable jest zawsze ustawiona w taki sposób, aby reprezentowała liczbę bajtów od właściwości position do końca pliku (wszystkie bajty pliku są przez cały czas dostępne do odczytu). W przypadku plików otwartych dla operacji asynchronicznych przed wywołaniem metody read należy upewnić się, że bufor odczytu zawiera dostateczną ilość danych. W przypadku pliku otwartego asynchronicznie, w miarę postępu operacji odczytu, dane z pliku — począwszy od pozycji position określonej przy uruchamianiu operacji odczytu — są dodawane do buforu, a wartość właściwości bytesAvailable wzrasta z każdym odczytanym bajtem. Właściwość bytesAvailable wskazuje liczbę dostępnych bajtów począwszy od pozycji określonej przez właściwość position do końca buforu. Co pewien czas obiekt FileStream wysyła zdarzenie progress. W przypadku pliku otwartego asynchronicznie — w miarę udostępniania danych w buforze odczytu — obiekt FileStream co pewien czas wywołuje zdarzenie progress. Na przykład: poniższy kod wczytuje dane do obiektu ByteArray, bytes, w miarę wczytywania danych do buforu: 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); } W przypadku pliku otwartego asynchronicznie możliwy jest tylko odczyt danych z buforu odczytu. Ponadto w miarę odczytu dane są usuwane z buforu odczytu. Przed wywołaniem operacji odczytu należy się upewnić, że dane istnieją w buforze odczytu. Przykład: poniższy kod odczytuje 8000 bajtów danych począwszy od pozycji 4000 w pliku: 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"); } } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 128 Praca z systemem plików Podczas operacji odczytu obiekt FileStream nie wczytuje danych do buforu odczytu. Po zakończeniu operacji zapisu (wszystkie dane z buforu zapisu zostają zapisane do pliku) obiekt FileStream uruchamia nowy bufor odczytu (przy założeniu, że skojarzony obiekt FileStream został otwarty z funkcjami odczytu), a następnie rozpoczyna wczytywanie danych do buforu odczytu, począwszy od pozycji określonej przez właściwość position. Właściwość position może określać pozycję ostatniego zapisanego bajtu lub może to być inna pozycja, jeśli użytkownik określił inną wartość dla obiektu position po operacji zapisu. Asynchroniczne programowanie oraz zdarzenia wygenerowane przez obiekt FileStream otwarty asynchronicznie Jeśli plik został otwarty asynchronicznie (za pomocą metody openAsync()), wówczas odczyt i zapis plików odbywa się asynchronicznie. W miarę wczytywania danych do buforu odczytu oraz zapisywania danych wyjściowych możliwe jest wykonywanie innego kodu ActionScript. To oznacza, że konieczne jest zarejestrowanie dla zdarzeń wygenerowanych przez obiekt FileStream otwarty asynchronicznie. Zarejestrowanie dla zdarzenia progress sprawia, że użytkownik może być powiadamiany w miarę udostępniania nowych danych dla odczytu, jak w poniższym kodzie: 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"); } Możliwe jest odczytanie wszystkich danych poprzez zarejestrowanie zdarzenia complete, jak w poniższym przykładzie: 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"); } W bardzo podobny sposób dane wejściowe są buforowane, co umożliwia odczyt asynchroniczny — dane zapisywane w strumieniu asynchronicznym są buforowane i zapisywane do pliku w sposób asynchroniczny. W miarę zapisywania danych do pliku obiekt FileStream okresowo wywołuje obiekt OutputProgressEvent. Obiekt OutputProgressEvent zawiera właściwość bytesPending, która jest ustawiona na liczbę bajtów pozostałych do zapisania. Użytkownik może zarejestrować się dla zdarzenia outputProgress, dzięki czemu będzie powiadamiany w miarę zapisywania buforu do pliku — być może w celu wyświetlenia okna dialogowego postępu. Jednak zwykle nie jest to konieczne. Możliwe jest wywołanie metody close() bez konieczności sprawdzania niezapisanych bajtów. Obiekt FileStream będzie kontynuował zapisywanie danych, a zdarzenie close zostanie wygenerowane po zapisaniu ostatniego bajtu do pliku i zamknięciu pliku. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 129 Praca z systemem plików Formaty danych oraz wybór metod odczytu i zapisu Każdy plik jest zestawem bajtów na dysku. W języku ActionScript dane z pliku mogą być zawsze reprezentowane przez obiekt ByteArray. Przykład: poniższy kod odczytuje dane z pliku do obiektu ByteArray o nazwie 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); } I podobnie: poniższy kod zapisuje dane z obiektu ByteArray (o nazwie bytes) do pliku: 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); Jednak często zdarza się, że zapisywanie danych w obiekcie ByteArray języka ActionScript nie jest pożądane. I często dane są w określonym formacie. Na przykład: dane pliku mogą być w formacie pliku tekstowego i konieczne może być reprezentowanie takich danych w obiekcie String. Z tego powodu klasa FileStream zawiera metody read i write przeznaczone do odczytu i zapisu danych do/z obiektów innych niż ByteArray. Na przykład: metoda readMultiByte() umożliwia odczyt danych z pliku oraz zapis danych w postaci ciągu znaków, jak w poniższym kodzie: 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"); } Drugi parametr metody readMultiByte() określa format tekstowy, z którego korzysta język ActionScript w celu interpretacji danych (w tym przykładzie „iso-8859-1”). Język ActionScript obsługuje najczęściej stosowane kody zestawu znaków, które zostały określone w Skorowidzu języka ActionScript 3.0 (patrz Obsługiwane zestawy znaków na stronie http://livedocs.macromedia.com/flex/2/langref/charset-codes.html). Klasa FileStream zawiera również metodę readUTFBytes(), która wczytuje dane z buforu odczytu do ciągu znaków, wykorzystując zestaw znaków UTF-8. Znaki w zestawie znaków UTF-8 mają różną długość, dlatego nie należy używać metody readUTFBytes() w metodzie, która reaguje na zdarzenie progress, ponieważ dane na końcu buforu odczytu mogą reprezentować niepełny znak. (To obowiązuje również w przypadku zastosowania metody readMultiByte() z kodowaniem znaków o różnej długości). Z tego powodu należy odczytać cały zestaw danych, gdy obiekt FileStream wywoła zdarzenie complete. Istnieją również podobne metody zapisu: writeMultiByte() i writeUTFBytes() przeznaczone do pracy z obiektami String oraz plikami tekstowymi. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 130 Praca z systemem plików Metody readUTF() oraz writeUTF() (nie należy ich mylić z metodami readUTFBytes() i writeUTFBytes()) również odczytują i zapisują dane tekstowe do pliku, ale zakładają, że tekst jest poprzedzony danymi określającymi długość danych tekstowych, co nie jest często stosowane w przypadku standardowych plików tekstowych. Niektóre pliki tekstowe zapisane w formacie UTF rozpoczynają się od znaku „UTF-BOM” (oznaczenie kolejności danych), który definiuje kolejność bajtów, a także format kodowania (taki jak UTF-16 lub UTF-32). Przykład odczytu i zapisu pliku tekstowego zawiera sekcja „Przykłady: wczytywanie pliku XML do obiektu XML” na stronie 131. Metody readObject() i writeObject() są zawsze wygodnymi sposobami na zapisywanie i pobieranie danych dla złożonych obiektów ActionScript. Dane są zakodowane w formacie AMF (ActionScript Message Format). Ten format jest zastrzeżony dla języka ActionScript. Aplikacje inne niż AIR, Flash Player, Flash Media Server oraz Flex Data Services nie zawierają wbudowanych interfejsów API przeznaczonych do pracy w tym formacie. Istnieją również inne metody odczytu i zapisu (takie jak readDouble() i writeDouble()). Jednak w przypadku korzystania z tych metod należy się upewnić, że format pliku jest zgodny z formatami danych definiowanych przez te metody. Formaty plików są często bardziej złożone niż proste formaty tekstowe. Na przykład: plik MP3 zawiera skompresowane dane, które mogą być interpretowane za pomocą algorytmów dekompresji i dekodowania, które są właściwe dla plików MP3. Pliki MP3 mogą również zawierać znaczniki ID3, które zawierają informacje o pliku w znacznikach metadanych (np. tytuł i wykonawca utworu). Istnieje wiele wersji formatu ID3, a najprostszy z nich (ID3 w wersji 1) został omówiony w sekcji „Przykład: Odczyt i zapis danych z dostępem losowym” na stronie 132. Inne formaty plików (dla obrazów, baz danych, dokumentów aplikacji itp.) mają inne struktury, a w celu korzystania z ich danych w języku ActionScript należy poznać strukturę danych. Korzystanie z metod load() i save() Metody load() i save() zostały dodane do klasy FileReference przez program Flash Player 10. Te metody są zawarte również w środowisku AIR 1.5, a klasa File dziedziczy metody z klasy FileReference. Te metody zostały zaprojektowane w celu udostępnienia użytkownikom bezpiecznych sposobów na ładowanie i zapisywanie danych plików w programie Flash Player. Jednak aplikacje AIR również mogą korzystać z tych metod jako łatwego sposobu na asynchroniczne ładowanie i zapisywanie plików. Na przykład poniższy kod zapisuje ciąg znaków do pliku tekstowego: 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."); } Parametr data metody save() może pobrać wartość String, XML lub ByteArray. Jeśli argumentem jest wartość String lub XML, metoda zapisuje plik jako plik tekstowy z kodowaniem UTF-8. W momencie wykonania tego przykładowego kodu aplikacja wyświetli okno dialogowe, w którym użytkownik będzie mógł wybrać miejsce docelowe dla zapisywanego pliku. Poniższy kod ładuje ciąg znaków z pliku tekstowego z kodowaniem UTF-8: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 131 Praca z systemem plików 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); } Klasa FileStream udostępnia więcej funkcji niż ta udostępniona przez metody load() and save(): • Za pomocą klasy FileStream można odczytywać i zapisywać dane w sposób synchroniczny i asynchroniczny. • Klasa FileStream umożliwia stopniowe zapisywanie do pliku. • Klasa FileStream umożliwia otwieranie pliku z dostępem losowym (odczyt z i zapis do dowolnej sekcji pliku). • Klasa FileStream umożliwia określanie typu dostępu do pliku przez ustawienie parametru fileMode metody open() lub openAsync(). • Klasa FileStream umożliwia zapisywanie danych do plików bez wyświetlania użytkownikowi okna dialogowego otwierania lub zapisywania. • Podczas odczytywania danych z klasy FileStream można bezpośrednio korzystać również z innych typów niż tablica bajtów. Przykłady: wczytywanie pliku XML do obiektu XML Poniższe przykłady demonstrują sposób zapisu i odczytu pliku, który zawiera dane XML. W celu odczytania danych z pliku należy zainicjować obiekty File i FileStream, wywołać metodę readUTFBytes() obiektu FileStream, a następnie przekształcić ciąg znaków na obiekt 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(); I podobnie — w celu zapisania danych do pliku wystarczy skonfigurować odpowiednie obiekty File i FileStream, a następnie wywołać metodę write obiektu FileStream. Następnie należy przekazać dane XML w postaci ciągu znaków do metody write, jak w poniższym kodzie: 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(); W poniższych przykładach używane są metody readUTFBytes() i writeUTFBytes(), ponieważ założono, że pliki są w formacie UTF-8. Jeśli format jest inny, konieczne może być użycie innej metody (patrz „Formaty danych oraz wybór metod odczytu i zapisu” na stronie 129). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 132 Praca z systemem plików W poniższych przykładach wykorzystano obiekty FileStream otwarte dla operacji synchronicznych. Możliwe jest również otwieranie plików dla operacji asynchronicznych (których odpowiedzi na zdarzenia są uzależnione od funkcji detektorów zdarzeń). Przykład: poniższy kod prezentuje sposób asynchronicznego wczytywania pliku XML: 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(); } Metoda processXMLData() jest wywoływana, gdy cały plik zostanie wczytany do buforu odczytu (gdy obiekt FileStream wywoła zdarzenie complete). W kodzie wywoływana jest metoda readUTFBytes() w celu uzyskania danych odczytywanych w wersji ciągu znaków, a następnie tworzony jest obiekt XML prefsXML na podstawie tego ciągu znaków. Przykład: Odczyt i zapis danych z dostępem losowym Pliki MP3 mogą zawierać znaczniki ID3, które są sekcjami na początku lub końcu pliku i zawierają metadane identyfikujące nagranie. Format znacznika ID3 ma różne wersje. Niniejszy przykład prezentuje sposób zapisu i odczytu z pliku MP3, który zawiera najprostszy format ID3 (wersja ID3 1.0) korzystający z „losowego dostępu do danych pliku”, co oznacza, że zapis i odczyt odbywa się z/do dowolnych miejsc w pliku. Plik MP3, który zawiera znacznik ID3 w wersji 1, zawiera dane ID3 na końcu, w ostatnich 128 bajtach. W przypadku uzyskiwania dostępu do pliku dla losowego odczytu/zapisu należy określić FileMode.UPDATE jako parametr fileMode metody open() lub openAsync(): var file:File = File.documentsDirectory.resolvePath("My Music/Sample ID3 v1.mp3"); var fileStr:FileStream = new FileStream(); fileStr.open(file, FileMode.UPDATE); Dzięki temu możliwe będzie odczytywanie i zapisywanie w pliku. Po otwarciu pliku można ustawić wskaźnik position na pozycję przesuniętą o 128 bajtów przed końcem pliku: fileStr.position = file.size - 128; Poniższy kod ustawia właściwość position na tę pozycję w pliku, ponieważ format ID3 v1.0 określa, że dane znacznika ID3 są zapisane w ostatnich 128 bajtach pliku. Specyfikacja określa również następujące zależności: • Pierwsze 3 bajty znacznika zawierają ciąg znaków "TAG". • Następne 30 znaków zawiera tytuł ścieżki MP3 w postaci ciągu znaków. • Następnie 30 znaków zawiera nazwę wykonawcy w postaci ciągu znaków. • Następnie 30 znaków zawiera nazwę albumu w postaci ciągu znaków. • Następnie 4 znaki zawierają rok w postaci ciągu znaków. • Następnie 30 znaków zawiera komentarz w postaci ciągu znaków. • Następny bajt zawiera kod wskazujący gatunek ścieżki. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 133 Praca z systemem plików • Wszystkie dane tekstowe są w formacie ISO 8859-1. Metoda id3TagRead() sprawdza dane po jej wczytaniu (po wywołaniu zdarzenia 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); } } Możliwy jest również zapis do pliku z dostępem losowym. Na przykład: możliwe jest przeanalizowanie zmiennej id3Title w celu zapewnienia, że jej znaki są poprawnej wielkości (za pomocą metod klasy String), a następnie zapisanie zmodyfikowanego ciągu znaków (o nazwie newTitle) do nowego pliku, jak poniżej: fileStr.position = file.length - 125; // 128 - 3 fileStr.writeMultiByte(newTitle, "iso-8859-1"); W celu zapewnienia zgodności ze standardem ID3 w wersji 1 długość ciągu znaków newTitle powinna wynosić 30 znaków, a koniec ciągu należy uzupełnić znakiem o kodzie 0 (String.fromCharCode(0)). 134 Rozdział 15: Przeciąganie i upuszczanie Klasy interfejsu API do przeciągania i upuszczania służą do obsługi gestów przeciągania i upuszczania interfejsu użytkownika. Gest w tym znaczeniu jest operacją użytkownika pośredniczącą między system operacyjnym a aplikacją, wyrażającą zamiar skopiowania, przeniesienia lub połączenia informacji. Gest przeciągania na zewnątrz występuje w momencie przeciągania przez użytkownika obiektu poza składnik lub aplikację. Gest przeciągania do wewnątrz występuje w momencie przeciągania przez użytkownika obiektu do składnika lub aplikacji. Za pomocą interfejsu API do przeciągania i upuszczania można zezwolić użytkownikowi na przeciąganie danych między aplikacjami i między składnikami w aplikacji. Obsługiwane formaty przesyłania: • Bitmapy • Pliki • Tekst w formacie HTML • Tekst • Dane w formacie RTF (Rich Text Format) • Adresy URL • Obiekty serializowane obiekty • Odwołania obiektów (tylko poprawne w aplikacji źródłowej) Dodatkowe informacje online dotyczące przeciągania i upuszczania Więcej informacji na temat pracy z interfejsem API przeciągania i upuszczania zawierają następujące źródła: Podręczniki Szybki start (Adobe AIR Developer Connection) • Obsługa przeciągania i upuszczania oraz kopiowania i wklejania Skorowidz języka • NativeDragManager • NativeDragOptions • Clipboard • NativeDragEvent Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR drag and drop”) Podstawowe informacje o przeciąganiu i upuszczaniu Interfejs API do przeciągania i upuszczania zawiera następujące klasy: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 135 Przeciąganie i upuszczanie Pakiet Klasy flash.desktop • NativeDragManager • NativeDragOptions • Clipboard • NativeDragActions • ClipboardFormat • ClipboardTransferModes Stałe używane w interfejsie API do przeciągania i upuszczania zdefiniowane są w następujących klasach: flash.events • NativeDragActions • ClipboardFormat • ClipboardTransferModes NativeDragEvent Etapy gestu przeciągania i upuszczania Gest przeciągania i upuszczania składa się z trzech etapów: Inicjowanie Użytkownik inicjuje operację przeciągania i upuszczania przez przeciąganie ze składnika lub z elementu składnika, przytrzymując wciśnięty przycisk myszy. Składnik będący źródłem przeciąganego elementu wskazywany jest zazwyczaj jako inicjator przeciągania i wywołuje zdarzenia nativeDragStart i nativeDragComplete. Aplikacja Adobe® AIR™ rozpoczyna operację przeciągania przez wywołanie metody NativeDragManager.doDrag() w odpowiedzi na zdarzenie mouseDown lub mouseMove. Jeśli operacja przeciągania zostanie zainicjowana spoza aplikacji AIR, nie istnieje obiekt inicjujący, który mógłby wygenerować zdarzenia nativeDragStart lub nativeDragComplete. Przeciąganie Przytrzymując wciśnięty przycisk myszy, użytkownik przesuwa kursor myszy do innego składnika, aplikacji lub na inny pulpit. W czasie trwania operacji przeciągania obiekt inicjatora wywołuje zdarzenia nativeDragUpdate. W momencie gdy użytkownik przesunie mysz nad obiekt, który może być obiektem docelowym upuszczenia w aplikacji AIR, obiekt ten wywołuje zdarzenie nativeDragEnter. Moduł obsługi zdarzenia może sprawdzić obiekt zdarzenia, aby określić, czy przeciągane dane są dostępne w formacie akceptowanym przez obiekt docelowy; jeśli tak, użytkownik będzie mógł upuścić dane na obiekt docelowy, wywołując metodę NativeDragManager.acceptDragDrop(). Tak długo, jak gest przeciągania pozostaje na obiektem interaktywnym, obiekt ten wywołuje zdarzenia nativeDragOver. Jeśli gest przeciągania opuści obiekt interaktywny, obiekt wywoła zdarzenie nativeDragExit. Upuszczanie Użytkownik zwalania przycisk myszy nad pożądanym obiektem docelowym upuszczania. Jeśli docelowy obiekt jest aplikacją AIR lub składnikiem, wówczas obiekt docelowy wywołuje zdarzenie nativeDragDrop. Moduł obsługi zdarzeń może uzyskać dostęp do przesyłanych danych z obiektu zdarzenia. Jeśli obiekt docelowy znajduje się poza środowiskiem AIR, upuszczenie obsłuży system operacyjny lub inna aplikacja. W obu przypadkach obiekt inicjujący wywoła zdarzenie nativeDragComplete (jeśli przeciąganie rozpoczęte zostało w środowisku AIR). Klasa NativeDragManager steruje oboma gestami: przeciągania do wewnątrz i przeciągania na zewnątrz. Wszystkie elementy klasy NativeDragManager są statyczne, dlatego nie należy tworzyć instancji tej klasy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 136 Przeciąganie i upuszczanie Obiekt Clipboard Dane przeciągane do lub z aplikacji lub składnika zawarte są w obiekcie Clipboard. Pojedynczy obiekt Clipboard może udostępniać różne reprezentacje tej samej informacji, aby zwiększyć prawdopodobieństwo, że inna aplikacja rozpozna i użyje danych. Na przykład: obraz może zostać umieszczony jako dane obrazu, obiekt serializowany Bitmap lub plik. Renderowanie danych można odroczyć dla funkcji renderującej, która nie zostanie wywołana, dopóki nie zostaną wczytane dane. Po rozpoczęciu gestu przeciągania dostęp do obiektu Clipboard można uzyskać jedynie z modułu obsługi zdarzeń nativeDragEnter, nativeDragOver i nativeDragDrop. Po zakończeniu gestu przeciągania nie można odczytać obiektu Clipboard i użyć go ponownie. Obiekt aplikacji można przesłać jako odwołanie lub jako obiekt serializowany. Odwołania są poprawne tylko w aplikacji źródłowej. Przesyłanie obiektów serializowanych jest dozwolone między aplikacjami AIR, ale tylko dla obiektów, które można poprawnie serializować i przywracać później do postaci pierwotnej. Obiekty, które są serializowane, konwertowane są do formatu AMF3 (Action Message Format for ActionScript 3) — formatu przesyłania danych opartym na ciągach znaków. Praca ze środowiskiem Flex W większości przypadków podczas tworzenia aplikacji Flex lepszym rozwiązaniem jest korzystanie z interfejsu API do przeciągania i upuszczania środowiska Adobe® Flex™. Środowisko Flex dostarcza odpowiedniego zestawu funkcji w czasie działania aplikacji Flex w środowisku AIR (używa wewnątrz klasy NativeDragManager środowiska AIR). Środowisko Flex zachowuje również bardziej ograniczony zestaw funkcji, gdy aplikacja lub składnik uruchamiane są w bardziej restrykcyjnym środowisku przeglądarki. Klas środowiska AIR nie można używać w składnikach lub aplikacjach, które działają poza środowiskiem wykonawczym AIR. Obsługa gestu przeciągania na zewnątrz Aby obsłużyć gest przeciągania na zewnątrz, należy utworzyć obiekt Clipboard w odpowiedzi na zdarzenie mouseDown i wysłać go do metody NativeDragManager.doDrag(). Aplikacja może wówczas wykrywać zdarzenie nativeDragComplete obiektu inicjującego, aby określić, jaką operację wykonać, gdy użytkownik zakończy lub porzuci gest. Przygotowywanie danych do przenoszenia Aby przygotować dane lub obiekt do przeniesienia, należy utworzyć obiekt Clipboard i dodać informację do przeniesienia w jednym lub większej ilości formatów. Programista może użyć standardowych formatów, aby przekazać dane, które można automatycznie przekształcić na rodzime formaty schowka i formaty definiowane przez aplikacje w celu przekazania obiektów. Jeśli koszt obliczeń dla konwersji informacji w celu przesłania w konkretnym formacie jest zbyt duży, można dostarczyć nazwę funkcji modułu obsługi do wykonania konwersji. Funkcja zostanie wywołana tylko wtedy, gdy odbierający składnik lub aplikacja odczyta skojarzony format. Więcej informacji na temat formatów schowka zawiera rozdział Kopiowanie i wklejanie w podręczniku Programowanie w języku ActionScript 3.0 (http://www.adobe.com/go/learn_fl_cs4_programmingAS3_pl). Poniższy przykład ilustruje sposób tworzenia obiektu Clipboard zawierającego bitmapę w kilku formatach: obiekt Bitmap, rodzimy format bitmapy oraz format listy plików zawierający plik, z którego bitmapa została pierwotnie załadowana: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 137 Przeciąganie i upuszczanie 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; } Rozpoczęcie operacji przeciągania na zewnątrz Aby rozpocząć operację przeciągania, należy wywołać metodę NativeDragManager.doDrag() w odpowiedzi na zdarzenie down myszy. Metoda doDrag() jest metodą statyczną, która pobiera następujące parametry: Parametr Opis initiator Obiekt, z którego rozpoczynane jest przeciąganie i który wywołuje zdarzenia dragStart i dragComplete. Inicjator musi być obiektem interaktywnym. clipboard Obiekt Clipboard zawierający dane do przenoszenia. Do obiektu Clipboard odwołują się obiekty NativeDragEvent wywoływane podczas sekwencji przeciągania i upuszczania. dragImage (Opcjonalnie) Obiekt BitmapData do wyświetlania podczas przeciągania. Obraz może określić wartość dla właściwości alpha. (Uwaga: System Microsoft Windows do przeciągania obrazów zawsze stosuje stałe przenikanie alfa). offset (Opcjonalnie) Obiekt Point określający przesunięcie obrazu przeciągania względem obszaru aktywnego myszy. Użycie ujemnych współrzędnych powoduje przesunięcie obrazu przeciągania do góry i w lewo względem kursora myszy. Jeśli przesunięcie nie zostanie określone, lewy górny róg obrazu przeciągania zostanie umieszczony w obszarze aktywnym myszy. actionsAllowed (Opcjonalnie) Obiekt NativeDragOptions określa, które czynności (kopiowanie, przenoszenie, łączenie) są prawidłowe dla operacji przeciągania. Jeśli żaden argument nie zostanie wprowadzony, dozwolone są wszystkie czynności. Obiekty NativeDragEvent odwołują się do obiektu DragOptions, aby umożliwić potencjalnemu celowi przeciągania sprawdzenie, czy dozwolone czynności są zgodne z przeznaczeniem docelowego składnika. Na przykład: składnik „kosz” może zaakceptować tylko gesty przeciągania, które zezwalają na czynność przenoszenia. Poniższy przykład ilustruje jak rozpocząć operację przeciągania dla obiektu bitmapy załadowanego z pliku. Poniższy przykład ładuje obraz i, dla zdarzenia mouseDown, rozpoczyna operację przeciągania. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 138 Przeciąganie i upuszczanie 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, TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 139 Przeciąganie i upuszczanie 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); } } } Zakończenie operacji przeciągania na zewnątrz W momencie upuszczenia przez użytkownika przeciąganego elementu, zwalniając przycisk myszy, obiekt inicjatora wywołuje zdarzenie nativeDragComplete. Programista może sprawdzić właściwość dropAction obiektu zdarzenia, a następnie wykonać właściwą operację. Na przykład: jeśli operacją jest NativeDragAction.MOVE, możliwe jest usunięcie źródła z jego pierwotnej lokalizacji. Użytkownik może porzucić gest przeciągania, zwalniając przycisk myszy, gdy kursor znajduje się poza pożądanym celem upuszczania. Menedżer przeciągania ustawia właściwość dropAction porzuconego gestu na wartość NativeDragAction.NONE. Obsługa gestu przeciągania do wewnątrz Aby obsłużyć gest przeciągania do wewnątrz, aplikacja (a zazwyczaj graficzny składnik aplikacji) musi odpowiadać na zdarzenia nativeDragEnter lub nativeDragOver. Kroki typowej operacji przeciągania Poniższa sekwencja zdarzeń jest charakterystyczna dla operacji przeciągania: 1 Użytkownik przeciąga obiekt schowka nad składnik. 2 Składnik wywołuje zdarzenie nativeDragEnter. 3 Moduł obsługi zdarzenia nativeDragEnter analizuje obiekt zdarzenia, aby sprawdzić dostępne formaty danych oraz dozwolone operacje. Jeśli składnik może obsłużyć przeciąganie, wywoływana jest metoda NativeDragManager.acceptDragDrop(). 4 NativeDragManager zmienia kursor myszy, aby wskazać, że obiekt można upuścić. 5 Użytkownik upuszcza obiekt nad składnikiem. 6 Odbierający składnik wywołuje zdarzenie nativeDragDrop. 7 Odbierający składnik odczytuje dane w pożądanym formacie z obiektu Clipboard w obiekcie zdarzenia. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 140 Przeciąganie i upuszczanie 8 Jeśli gest przeciągania został rozpoczęty w aplikacji AIR, wówczas inicjujący obiekt interaktywny wywołuje zdarzenie nativeDragComplete. Jeśli gest rozpoczęty został poza środowiskiem AIR, nie jest przesyłana żadna informacja zwrotna. Potwierdzanie gestu przeciągania do wewnątrz W momencie przeciągnięcia elementu schowka do obwiedni składnika graficznego składnik ten wywołuje zdarzenia nativeDragEnter i nativeDragOver. Aby określić, czy składnik może zaakceptować element schowka, moduły obsługi tych zdarzeń mogą sprawdzić właściwości clipboard oraz allowedActions obiektu zdarzenia. Aby zasygnalizować, że składnik może zaakceptować upuszczanie, moduł obsługi zdarzenia musi wywołać metodę NativeDragManager.acceptDragDrop(), przekazując odwołanie do odbierającego składnika. Jeśli więcej niż jeden zarejestrowany detektor zdarzenia wywoła metodę acceptDragDrop(), ostatni moduł zdarzenia na liście otrzymuje pierwszeństwo. Wywołanie acceptDragDrop() pozostanie poprawne, dopóki mysz nie opuści granic obiektu przyjmującego, wywołując zdarzenie nativeDragExit. Jeśli w parametrze allowedActions przekazanym do metody doDrag() dozwolona jest więcej niż jedna operacja, użytkownik może wskazać, przytrzymując klawisz modyfikatora, która z dozwolonych operacji ma zostać wykonana. Menedżer przeciągania zmienia obraz kursora, aby poinformować użytkownika o tym, jaka operacja zostanie wykonana w chwili upuszczenia. Zamierzona operacja zgłaszana jest przez właściwość dropAction obiektu NativeDragEvent. Zestaw operacji gestu przeciągania ma tylko charakter informacyjny. Składniki związane z przesyłaniem muszą implementować właściwe zachowanie. Aby zakończyć na przykład operację przesuwania, inicjator przeciągania może usunąć przeciągany element, a cel upuszczania może go dodać. Cel przeciągania może ograniczyć operację upuszczania do jednej z trzech możliwych operacji ustawiając właściwość dropAction klasy NativeDragManager. Jeśli użytkownik spróbuje wybrać inną operację za pomocą klawiatury, wówczas NativeDragManager wyświetli niedostępny kursor. Właściwość dropAction należy ustawić w modułach obsługi obu zdarzeń: nativeDragEnter i nativeDragOver. Poniższy przykład ilustruje moduł obsługi zdarzeń dla zdarzenia nativeDragEnter lub nativeDragOver. Ten moduł obsługi akceptuje jedynie gesty przeciągania do wewnątrz, jeśli przeciągany schowek zawiera dane w formacie tekstowym. 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 } } Zakończenie upuszczania W momencie upuszczenia przez użytkownika przeciąganego elementu na obiekt interaktywny, który zaakceptował gest, obiekt interaktywny wywołuje zdarzenie nativeDragDrop. Moduł obsługi dla tego zdarzenia może pobrać dane z właściwości clipboard obiektu zdarzenia. Jeśli schowek zawiera format zdefiniowany dla aplikacji, parametr transferMode przekazany do metody getData() obiektu Clipboard określa, czy menedżer przeciągania zwraca odwołanie lub serializowaną wersję obiektu. Poniższy przykład ilustruje moduł obsługi zdarzenia dla zdarzenia nativeDragDrop: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 141 Przeciąganie i upuszczanie 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)); } Po zakończeniu działania modułu obsługi zdarzenia obiekt Clipboard staje się obiektem nieważnym. Jakakolwiek próba uzyskania dostępu do obiektu lub jego danych spowoduje wygenerowanie błędu. Aktualizowanie formy graficznej składnika Składnik może aktualizować swoją formę graficzną w oparciu o zdarzenia NativeDragEvent. Poniższa tabela opisuje typy zmian, które typowy składnik wykona w odpowiedzi na różne zdarzenia: Zdarzenie Opis nativeDragStart Inicjujący obiekt interaktywny może użyć zdarzania nativeDragStart, aby dostarczyć graficznej informacji zwrotnej mówiącej o tym, że gest przeciągania pochodzi z obiektu interaktywnego. nativeDragUpdate Inicjujący obiekt interaktywny może użyć zdarzania nativeDragUpdate, aby zaktualizować swój stan podczas wykonywania gestu. nativeDragEnter Potencjalny, odbierający obiekt interaktywny może użyć tego zdarzenia, aby przyjąć obszar aktywności lub wskazać w sposób graficzny, że może/nie może zaakceptować upuszczanie. nativeDragOver Potencjalny, odbierający obiekt interaktywny może użyć tego zdarzenia, aby odpowiedzieć na ruch myszy w obiekcie interaktywnym, na przykład, gdy mysz znajdzie się w obszarze „aktywnym” złożonego składnika (np. mapa ulic). nativeDragExit Potencjalny, odbierający obiekt interaktywny może użyć tego zdarzenia, aby przywrócić swój stan, gdy gest przeciągania przesunie się poza jego obwiednię. nativeDragComplete Inicjujący obiekt interaktywny może użyć tego zdarzenia, aby zaktualizować swój skojarzony model danych np. przez usunięcie pozycji z listy i przywrócić swoją formę graficzną. Wyświetlanie położenia myszy podczas gestu przeciągania do wewnątrz Przytrzymanie gestu przeciągania nad składnikiem powoduje, że składnik ten wywołuje zdarzenia nativeDragOver. Zdarzenia wywoływane są co kilka milisekund, a także przy każdym przesunięciu myszy. Obiekt zdarzenia nativeDragOver może być używany do określania położenia myszy nad składnikiem. Dostęp do położenia myszy może być użyteczny w sytuacjach, w których odbierający składnik jest złożony, ale nie obejmuje podskładników. Na przykład, jeśli aplikacja wyświetla bitmapę zawierającą mapę ulic i obszary mapy mają być podświetlane w chwili przeciągania na nie informacji przez użytkownika, wówczas do wyświetlania położenia myszy na mapie można użyć współrzędnych myszy zgłaszanych w zdarzeniu nativeDragOver. Przeciąganie i upuszczanie w treści HTML Aby przeciągnąć dane do i z aplikacji opartej na HTML (lub do i z treści HTML wyświetlanej w obiekcie HTMLLoader), można użyć zdarzeń przeciągania i upuszczania w treści HTML. Interfejs API przeciągania i upuszczania HTML umożliwia przeciąganie do i z elementów DOM w treści HTML. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 142 Przeciąganie i upuszczanie Uwaga: Można użyć także interfejsów API NativeDragEvent i NativeDragManager środowiska AIR, wykrywając zdarzenia obiektu HTMLLoader zawierającego treść HTML. Jednak interfejs API HTML jest bardziej zintegrowany z modelem DOM HTML i umożliwia sterowanie domyślnym zachowaniem. Domyślne zachowanie przeciągania i upuszczania Środowisko HTML zapewnia domyślne zachowanie dla gestów przeciągania i upuszczania dotyczących tekstu, obrazów i adresów URL. Za pomocą domyślnego zachowania te typy danych można zawsze przeciągnąć poza element. Jednak do elementu można przeciągnąć tylko tekst i tylko do elementów edytowalnego obszaru strony. Przeciągając tekst między lub wewnątrz edytowalnych obszarów strony, zachowanie domyślne wykonuje operację przenoszenia. Jeśli tekst jest przeciągany do obszaru edytowalnego z obszaru nieedytowalnego lub spoza aplikacji, wówczas zachowanie domyślne wykonuje operację kopiowania. Zachowanie domyślne można przesłonić, samodzielnie obsługując zdarzenia przeciągania i upuszczania. Aby anulować zachowanie domyślne, należy wywołać metody preventDefault() obiektów wywołanych dla zdarzeń przeciągania i upuszczania. Można wówczas wstawić dane do celu upuszczania i usunąć dane ze źródła przeciągania, jeśli jest to konieczne do wykonania wybranej operacji. Domyślnie użytkownik może wybrać i przeciągnąć dowolny tekst oraz przeciągnąć obrazy i łącza. Właściwości CSS WebKit (-webkit-user-select) można używać do sterowania sposobem zaznaczania dowolnego elementu HTML. Na przykład, jeśli właściwość -webkit-user-select ustawiona zostanie na wartość none, wówczas treści elementu nie można zaznaczyć, dlatego też nie można jej przeciągnąć. Można użyć także właściwości CSS -webkit-user-drag, aby decydować, czy element można przeciągnąć jako całość. Jednak treść elementu jest traktowana oddzielnie. Użytkownik może nadal przeciągać wybrany fragment tekstu. Więcej informacji zawiera sekcja „Rozszerzenia CSS” na stronie 233. Zdarzenia przeciągania i upuszczania w HTML Zdarzenia wywoływane przez element inicjatora, z którego rozpoczynane jest przeciąganie: Zdarzenie Opis dragstart Wywoływane, gdy użytkownik rozpoczyna gest przeciągania. Moduł obsługi tego zdarzenia może zapobiec przeciąganiu (w razie konieczności), wywołując metodę preventDefault() obiektu zdarzenia. Aby decydować, czy przeciągane dane mogą być kopiowane, powiązane lub przenoszone, należy ustawić właściwość effectAllowed. Zaznaczony tekst, obrazy i łącza wstawiane są do schowka przez zachowanie domyślne, ale możliwe jest ustawienie innych danych dla gestu przeciągania za pomocą właściwości dataTransfer obiektu zdarzenia. drag Wywoływane w sposób ciągły podczas gestu przeciągania. dragend Wywoływane w chwili zwolnienia przycisku myszy przez użytkownika w celu zakończenia gestu przeciągania. Zdarzenia wywoływane przez cel przeciągania: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 143 Przeciąganie i upuszczanie Zdarzenie Opis dragover Wywoływane w sposób ciągły w czasie przytrzymania gestu przeciągania w granicach elementu. Moduł obsługi dla tego zdarzenia powinien ustawić właściwość dataTransfer.dropEffect, aby wskazywała, czy wynikiem przeciągania w chwili zwolnienia przycisku myszy będzie operacja kopiowania, przenoszenia czy połączenia. dragenter Wywoływane, gdy gest przeciągania znajdzie się w granicach elementu. Jeśli dowolne właściwości obiektu dataTransfer w module obsługi zdarzenia dragenter zostaną zmienione, zmiany te zostaną szybko przysłonięte przez kolejne zdarzenie dragover. Z drugiej strony istnieje niewielkie opóźnienie między zdarzeniem dragenter i pierwszym zdarzeniem dragover, które może spowodować migotanie kursora, jeśli ustawione zostały różne właściwości. W wielu przypadkach można użyć tego samego modułu obsługi zdarzenia dla obu zdarzeń. dragleave Wywoływane w momencie opuszczenia gestu przeciągania granic elementu. drop Wywoływane w momencie upuszczenia przez użytkownika danych na element. Dostęp do przeciąganych danych można uzyskać tylko w module obsługi dla tego zdarzenia. Obiekt zdarzenia wywoływany w odpowiedzi na te zdarzenia podobny jest do zdarzenia myszy. Właściwości zdarzenia myszy np. clientX, clientY i screenX, screenY można używać do określania położenia myszy. Najważniejszą właściwością obiektu zdarzenia drag jest dataTransfer, która zawiera przeciągane dane. Sam obiekt dataTransfer zawiera następujące właściwości i metody: Właściwość lub metoda Opis effectAllowed Efekt dozwolony przez źródło przeciągania. Wartość tę ustawia zazwyczaj moduł obsługi dla zdarzenia dragstart. Patrz „Efekty przeciągania w HTML” na stronie 144. dropEffect Efekt wybrany przez cel lub użytkownika. Jeśli właściwość dropEffect ustawiona zostanie w module obsługi zdarzenia dragover lub dragenter, wówczas środowisko AIR aktualizuje kursor myszy, aby wskazywany był efekt, który występuje w chwili zwolnienia przycisku myszy. Jeśli ustawienie właściwości dropEffect nie będzie zgodne z jednym z dozwolonych efektów, nie będzie możliwe żadne upuszczenie i wyświetlony zostanie niedostępny kursor. Jeśli właściwość dropEffect nie zostanie ustawiona w odpowiedzi na ostatnie zdarzenie dragover lub dragenter, wówczas użytkownik może wybierać z dozwolonych efektów za pomocą standardowych klawiszy modyfikatorów systemu operacyjnego. Efekt końcowy zgłaszany jest przez właściwość dropEffect obiektu wywołanego przez zdarzenie dragend. Jeśli użytkownik zaniecha upuszczania, zwalniając przycisk myszy poza odpowiednim celem, wówczas właściwość dropEffect ustawiana jest na wartość none. types Tablica zawierająca ciągi znaków typu MIME dla każdego formatu danych obecnego w obiekcie dataTransfer. getData(mimeType) Pobiera dane w formacie określonym przez parametr mimeType. Metoda getData() może być wywoływana tylko w odpowiedzi na zdarzenie drop. setData(mimeType) Dodaje dane do właściwości dataTransfer w formacie określonym przez parametr mimeType. Dane można dodać w wielu formatach przez wywołanie metody setData() dla każdego typu MIME. Wszystkie dane umieszczone przez domyślne zachowanie przeciągania w obiekcie dataTransfer zostaną usunięte. Metoda setData() może być wywoływana tylko w odpowiedzi na zdarzenie dragstart. clearData(mimeType) Usuwa wszystkie dane w formacie określonym przez parametr mimeType. setDragImage(image, offsetX, offsetY) Ustawia niestandardowy obraz przeciągania. Metoda setDragImage() może zostać wywołana jedynie w odpowiedzi na zdarzenie dragstart. Typy MIME dla przeciągania i upuszczania HTML Typy MIME do użytku w obiekcie dataTransfer zdarzenia przeciągania i upuszczania HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 144 Przeciąganie i upuszczanie Format danych Typ MIME Tekst "text/plain" HTML "text/html" URL "text/uri-list" Bitmapa "image/x-vnd.adobe.air.bitmap" Lista plików "application/x-vnd.adobe.air.file-list" Można również użyć innych ciągów znaków MIME, łącznie z ciągami znaków zdefiniowanymi przez aplikację. Jednak inne aplikacje mogą nie być w stanie rozpoznać lub użyć przesyłanych danych. Obowiązkiem programisty jest dodawanie danych do obiektu dataTransfer w oczekiwanym formacie. Ważne: Tylko kod działający w obszarze izolowanym aplikacji może uzyskać dostęp do upuszczanych plików. Próba odczytu lub ustawienia dowolnej właściwości obiektu File w nieaplikacyjnym obszarze izolowanym powoduje wygenerowanie błędu zabezpieczeń. Więcej informacji zawiera sekcja „Obsługa upuszczania plików w nieaplikacyjnym obszarze izolowanym HTML” na stronie 148. Efekty przeciągania w HTML Inicjator gestu przeciągania może ograniczyć dozwolone efekty przeciągania, ustawiając właściwość dataTransfer.effectAllowed w module obsługi dla zdarzenia dragstart. Można użyć następujących ciągów znaków: Ciąg znaków Opis "none" Żadna operacja przeciągania nie jest dozwolona. "copy" Dane zostaną skopiowane do celu, pozostawiając oryginalne dane na miejscu. "link" Dane będą współużytkowane z celem upuszczania za pomocą połączenia z oryginałem. "move” Dane zostaną skopiowane do celu i usunięte z oryginalnej lokalizacji. "copyLink" Dane mogą być kopiowane lub łączone. "copyMove" Dane mogą być kopiowane lub przenoszone. "linkMove" Dane mogą być łączone lub przenoszone. "all" Dane mogą być kopiowane, przenoszone lub łączone. All jest efektem domyślnym w przypadku zablokowania i zapobiega użyciu zachowania domyślnego. Cel gestu przeciągania może ustawić właściwość dataTransfer.dropEffect, aby wskazywana była operacja podejmowana w momencie zakończenia upuszczania. Jeśli efektem upuszczania jest jedna z dozwolonych operacji, wówczas system wyświetla odpowiedni kursor kopiowania, przesuwania lub łączenia. W przeciwnym razie system wyświetla niedostępny kursor. Jeśli żaden efekt upuszczania nie został ustawiony przez cel, użytkownik może wybierać z dozwolonych efektów za pomocą klawiszy modyfikatorów. Wartość właściwości dropEffect należy ustawić w modułach obsługi dla obu zdarzeń dragover i dragenter: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 145 Przeciąganie i upuszczanie 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"; } Uwaga: Mimo że zawsze należy ustawić właściwość dropEffect w module obsługi zdarzenia dragenter, programista powinien być świadomy tego, że kolejne zdarzenie dragover ponownie ustawia właściwość na jej wartość domyślną. Właściwość dropEffect należy ustawić w odpowiedzi na oba zdarzenia. Przeciąganie danych na zewnątrz elementu HTML Domyślne zachowanie umożliwia kopiowanie przez przeciąganie większość treści strony HTML. Programista może sterować treścią, która może być przeciągana za pomocą właściwości CSS -webkit-user-select i -webkit-userdrag. Domyślne zachowanie przeciągania na zewnątrz należy przesłonić w module obsługi dla zdarzenia dragstart. Aby wstawić własne dane do gestu przeciągania, należy wywołać metodę setData() właściwości dataTransfer obiektu zdarzenia. Aby wskazać, które z efektów przeciągania obsługiwane są przez obiekt źródłowy, jeśli domyślne zachowanie nie jest przekazywane, należy ustawić właściwość dataTransfer.effectAllowed obiektu zdarzenia wywołanego dla zdarzenia dragstart. Można wybrać dowolną kombinację efektów. Na przykład, jeśli źródłowy element obsługuje efekty kopiowanie i łączenie, właściwość należy ustawić na wartość "copyLink". Ustawianie przeciąganych danych Dane dla gestu przeciągania należy dodać w module obsługi dla zdarzenia dragstart za pomocą właściwości dataTransfer. Aby wstawić dane do schowka, należy użyć metody dataTransfer.setData(), przekazując typ MIME i dane do przeniesienia. Na przykład, jeśli w aplikacji programisty znajduje się obraz o identyfikatorze imageOfGeorge, można użyć następującego modułu obsługi zdarzenia dragstart. Ten przykład dodaje reprezentacje obrazu George'a w kilku formatach danych, co zwiększa prawdopodobieństwo, że inne aplikacje będą mogły użyć przeciąganych danych. 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)); } Uwaga: Wywołanie metody setData() obiektu dataTransfer powoduje, że żadne dane nie zostaną dodane przez domyślne zachowanie przeciągania i upuszczania. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 146 Przeciąganie i upuszczanie Przeciąganie danych do elementu HTML Zachowanie domyślne pozwala na przeciąganie do edytowanych obszarów strony tylko tekstu. Programista może określić, że element i jego elementy podrzędne będą edytowalne, umieszczając atrybut contenteditable w znaczniku otwierającym elementu. Możliwe jest również ustawienie całego dokumentu jako edytowalnego przez ustawienie właściwości designMode obiektu dokumentu na wartość "on". Alternatywne zachowanie przeciągania do wewnątrz można obsłużyć na stronie, obsługując zdarzenia dragenter, dragover i drop dla dowolnego elementu, który akceptuje przeciągane dane. Włączanie przeciągania do wewnątrz Aby obsłużyć gest przeciągania do wewnątrz, należy najpierw anulować zachowanie domyślne. Należy wykrywać zdarzenia dragenter i dragover wszystkich elementów HTML, które mają być używane jako cele upuszczania. W modułach obsługi dla tych zdarzeń należy wywołać metodę preventDefault() wywołanego obiektu zdarzenia. Anulowanie domyślnego zdarzenia pozwala nieedytowalnym obszarom na odbieranie upuszczania. Pobieranie upuszczonych danych Dostęp do upuszczonych danych można uzyskać w module obsługi dla zdarzenia ondrop: function doDrop(event){ droppedText = event.dataTransfer.getData("text/plain"); } Aby odczytać dane ze schowka, należy użyć metody dataTransfer.getData(), przekazując typ MIME formatu danych do odczytu. Dostępne formaty danych można znaleźć za pomocą właściwości types obiektu dataTransfer. Tablica types zawiera ciąg znaków typu MIME dla każdego dostępnego formatu. Po anulowaniu domyślnego zachowania w zdarzeniach dragenter lub dragover należy wstawić wszystkie upuszczone dane we właściwym miejscu w dokumencie. Nie istnieje żaden interfejs API do konwertowania położenia myszy na punkt wstawiania elementu. To ograniczenie utrudnia implementację gestów przeciągania typu wstawienie. Przykład: Przysłanianie domyślnego zachowania przeciągania do wewnątrz HTML Ten przykład implementuje cel upuszczania, wyświetlając tabelę, która przedstawia każdy format danych dostępny w upuszczanym elemencie. Zachowanie domyślne zostało użyte w celu umożliwienia przeciągania tekstu, łączy i obrazów w aplikacji. Przykład przesłania domyślne zachowanie przeciągania do wewnątrz dla elementu div, który służy jako cel upuszczania. Kluczowym krokiem we włączaniu nieedytowalnej treści w celu zaakceptowania gestu przyciągania do wewnątrz jest wywołanie metody preventDefault() obiektu zdarzenia dla obu zdarzeń dragenter i dragover. W odpowiedzi na zdarzenie drop moduł obsługi konwertuje przesłane dane na element wiersza HTML i wstawia wiersz do tabeli w celu wyświetlenia. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 147 Przeciąganie i upuszczanie <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> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 148 Przeciąganie i upuszczanie <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> Obsługa upuszczania plików w nieaplikacyjnym obszarze izolowanym HTML Nieaplikacyjna treść nie może uzyskać dostępu do obiektów File, które powstają w wyniku przeciągania plików do aplikacji AIR. Nie jest również możliwe przekazanie jednego z obiektów File do treści aplikacji za pomocą mostu obszaru izolowanego. (Do właściwości obiektu dostęp można uzyskać podczas serializacji). Nadal jest jednak możliwe upuszczanie plików w aplikacji przez wykrywanie zdarzeń nativeDragDrop środowiska AIR dla obiektu HTMLLoader. Zazwyczaj jeśli użytkownik upuści plik w ramce, która zawiera treść nieaplikacyjną, zdarzenie drop nie jest propagowane od elementu podrzędnego do elementu nadrzędnego. Ponieważ jednak zdarzenia wywoływane przez obiekt HTMLLoader (który jest kontenerem dla całej treści HTML w aplikacji AIR) nie są częścią strumienia zdarzenia HTML, zdarzenie drop można nadal odbierać w treści aplikacji. Aby odebrać zdarzenie dla upuszczania pliku, dokument nadrzędny dodaje detektor zdarzenia do obiektu HTMLLoader z użyciem odwołania dostarczonego przez window.htmlLoader: window.htmlLoader.addEventListener("nativeDragDrop",function(event){ var filelist = event.clipboard.getData(air.ClipboardFormats.FILE_LIST_FORMAT); air.trace(filelist[0].url); }); W poniższym przykładzie skorzystano z dokumentu nadrzędnego, który ładuje podrzędną stronę do zdalnego obszaru izolowanego (http://localhost/). Element nadrzędny wykrywa zdarzenie nativeDragDrop obiektu HTMLLoader i wyświetla adres URL pliku. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 149 Przeciąganie i upuszczanie <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> Dokument podrzędny musi przedstawić poprawny cel upuszczania, blokując metodę preventDefault() obiektu Event w modułach obsługi zdarzeń dragenter i dragover HTML, gdyż w przeciwnym razie zdarzenie drop nigdy nie wystąpi. <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> Więcej informacji zawiera sekcja „Programowanie w językach HTML i JavaScript” na stronie 235. 150 Rozdział 16: Kopiowanie i wklejanie Klasy w schowku API służą do kopiowania informacji z i do schowka systemowego. Formaty danych, które można przesyłać do i z aplikacji Adobe® AIR™ obejmują: • Bitmapy • Pliki • Tekst • Tekst HTML • Dane formatu RTF • Ciągi URL • Obiekty serializowane • Odniesienia do obiektów (wyłącznie w aplikacji inicjującej) W programie Adobe Flash Player 10 wprowadzono obsługę funkcji kopiowania i wklejania dostępnych w środowisku AIR 1.0. W niniejszym rozdziale omówiono funkcje kopiowania i wklejania charakterystyczne dla środowiska Adobe AIR. Szczegółowe informacje o tych funkcjach wspólnych dla wszystkich środowisk zawiera rozdział Kopiowanie i wklejanie w podręczniku Programowanie w języku Adobe ActionScript 3.0. Dodatkowe informacje online dotyczące kopiowania i wklejania Więcej informacji na temat kopiowania i wklejania znajduje się w następujących źródłach: Podręczniki Szybki start (Adobe AIR Developer Connection) • Obsługa przeciągania i upuszczania oraz kopiowania i wklejania Skorowidz języka • Clipboard • ClipboardFormats • ClipboardTransferMode Więcej informacji • Kopiowanie i wklejanie (w podręczniku Programowanie w języku Adobe ActionScript 3.0) • Adobe AIR Developer Connection for Flash (wyszukaj „AIR copy and paste”) TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 151 Kopiowanie i wklejanie Kopiowanie i wklejanie HTML Środowisko HTML udostępnia własny zestaw zdarzeń i domyślnych ustawień kopiowania i wklejania. Wyłącznie kod działający w obszarze izolowanym aplikacji ma bezpośredni dostęp do schowka systemowego za pomocą obiektu Clipboard.generalClipboard AIR. Kod JavaScript w obszarze izolowanym innym niż aplikacyjny ma dostęp do schowka za pomocą obiektu zdarzenia wywołanego w odpowiedzi na jedno ze zdarzeń kopiowania i wklejania wywołanych przez element w dokumencie HTML. Zdarzenia kopiowania i wklejania uwzględniają: copy, cut i paste. Obiekty wywołane dla tych zdarzeń umożliwiają dostęp do schowka za pomocą właściwości clipboardData. Ustawienia domyślne Domyślnie AIR kopiuje wybrane pozycje w odpowiedzi na polecenie kopiowania wygenerowane przez skrót klawiszowy lub menu kontekstowe. W obszarach edytowalnych środowosko AIR wycina tekst w odpowiedzi na polecenie wycinania lub wkleja tekst do kursora lub do wybranego miejsca w odpowiedzi na polecenie wklejania. Aby zmienić ustawienia domyślne, moduł obsługi zdarzeń może wywołać metodę preventDefault() wywołanego zdarzenia obiektu. Korzystanie z właściwości clipboardData obiektu zdarzenia Właściwość clipboardData obiektu zdarzenia wywołana w wyniku jednego ze zdarzeń kopiowania i wklejania umożliwia zapis i odczyt danych ze schowka. Aby zapisać dane do schowka w czasie obsługi zdarzenia kopiowania i wycinania, należy użyć metody setData() obiektu clipboardData, przekazując dane do skopiowania i typ MIME: function customCopy(event){ event.clipboardData.setData("text/plain", "A copied string."); } Aby uzyskać dostęp do wklejanych danych, należy użyć metody getData() obiektu clipboardData, przekazując typ MIME formatu danych. Dostępne formaty są zgłaszane przez właściwość types. function customPaste(event){ var pastedData = event.clipboardData("text/plain"); } Dostęp do metody getData() i właściwości types można uzyskać wyłącznie w obiektach zdarzeń wywołanych przez zdarzenie paste. Następujący przykład przedstawia sposób zastępowania domyślnych ustawień kopiowania i wklejania na stronę HTML. Moduł obsługi zdarzeń copy pochyla skopiowany tekst i kopiuje go do schowka jako tekst HTML. Moduł obsługi zdarzeń cut kopiuje wybrane dane do schowka i usuwa je z dokumentu. Moduł obsługi paste wstawia zawartość schowka jako tekst HTML i pogrubia wstawiony tekst. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 152 Kopiowanie i wklejanie <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> Polecenia menu i naciśnięcia klawiszy kopiowania i wklejania Funkcje kopiowania i wklejania są zazwyczaj wywoływane przez polecenia menu lub skróty klawiszy. W systemach OS X menu edycji z poleceniami kopiowania i wklejania jest tworzone automatycznie przez system operacyjny. Należy jednak dodać detektory dla tych poleceń menu, aby połączyć własne funkcje kopiowania i wklejania. W systemie Windows można dodawać natywne menu edycji do każdego okna korzystającego z karnacji systemowej. (Można również utworzyć menu inne niż natywne za pomocą Flex i ActionScript lub w treści HTML za pomocą DHTML (ale nie jest to omówione w treści tego rozdziału). Aby wywołać polecenie kopiowania i wklejania w odpowiedzi na skróty klawiszy, można przypisać odpowiedniki klawisza do odpowiednich pozycji polecenia w natywnej aplikacji lub w menu Okna lub można bezpośrednio wywołać naciśnięcie klawiszy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 153 Kopiowanie i wklejanie Rozpoczynanie czynności kopiowania lub wklejania za pomocą polecenia menu Aby wywołać czynność kopiowania i wklejania za pomocą polecenia menu, należy dodać detektory dla pozycji zdarzenia select w poleceniach menu wywołujących funkcje modułu obsługi. Po wywołaniu funkcji modułu obsługi można znaleźć obiekt, z którego następuje kopiowanie lub do którego można skopiować za pomocą właściwości focus stołu montażowego. Następnie można wywołać odpowiednią metodę aktywowanego obiektu (lub ogólną metodę rezerwy awaryjnej, jeśli żaden obiekt nie został aktywowany) w celu wykonania logiki kopiowania, wycinania i wklejania. Na przykład, następujący moduł obsługi zdarzeń copy sprawdza, czy aktywowany obiekt jest odpowiedniego typu, w tym wypadku klasa o nazwie Scrap, a następnie wywołuje metodę doCopy() obiektu. function copyCommand(event:Event):void{ if(NativeApplication.nativeApplication.activeWindow.stage.focus is Scrap){ Scrap(NativeApplication.nativeApplication.activeWindow.stage.focus).doCopy(); } else { NativeApplication.nativeApplication.copy(); } } Jeśli metoda copyCommand() w przykładzie nie rozpozna klasy aktywowanego obiektu, wywołuje metodę NativeApplication copy(). Metoda NativeApplication copy() przesyła wewnętrzne polecenie kopiowania do aktywowanego obiektu. Jeśli obiekt jest klasą wbudowaną, która implementuje wewnętrznie funkcje kopiowania i wklejania, obiekt wykona polecenie. Jedynymi takimi klasami wbudowanymi są obecnie klasy Textfield i HTMLLoader. Pozostałe obiekty interaktywne wywołają zdarzenie copy. Podobne polecenia są dostępne dla operacji wycinania, wklejania, zaznaczania wszystkiego i (wyłącznie dla składnika TextArea), usuwania, cofania i ponawiania. W treści HTML domyślne ustawienia kopiowania i wklejania mogą być wywołane za pomocą poleceń edycji NativeApplication. W następującym przykładzie utworzone jest menu Edycja dla edytowalnego dokumentu HTML. W poprzednim przykładzie zastąpione zostało menu aplikacji w systemie Mac OS X, ale można również skorzystać z domyślnego menu Edycja poprzez wyszukanie istniejących pozycji i dodanie do nich detektorów zdarzeń. W przypadku użycia menu kontekstowego w celu wywołania polecenia kopiowania i wklejania można skorzystać z właściwości contextMenuOwner obiektu ContextMenuEvent wywołanego podczas otwierania menu lub poprzez wybranie pozycji w celu określenia, który obiekt jest właściwym celem polecenia kopiowania lub wklejania. Wyszukiwanie domyślnych poleceń menu w systemie Mac OS X Aby wyszukać domyślne menu Edycja oraz określone pozycje polecenia kopiowania, wycinania i wklejania w menu aplikacji w systemie Mac OS X, można przeszukać hierarchię menu za pomocą właściwości label obiektów NativeMenuItem. Na przykład, następująca funkcja za pomocą nazwy wyszukuje pozycje ze zgodną etykietą w menu: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 154 Kopiowanie i wklejanie 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; } Parametr recurse można ustawić na wartość true, aby w wyszukiwaniu zostały uwzględnione podmenu lub false, aby uwzględnione zostały wyłącznie przekazane menu. Rozpoczynanie polecenia kopiowania lub wklejania za pomocą naciśnięcia klawisza Jeśli w aplikacji do kopiowania lub wklejania stosuje się natywne okno lub menu aplikacji, do poleceń menu można dodać odpowiedniki klawiszy w celu wdrożenia skrótów klawiszy. Jeśli w aplikacji do kopiowania lub wklejania stosuje się natywne okno lub menu aplikacji, do poleceń menu można dodać odpowiedniki klawiszy w celu wdrożenia skrótów klawiszy. W przeciwnym razie można wykryć samemu odpowiednie naciśnięcia klawiszy zgodnie z następującym przykładem: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 155 Kopiowanie i wklejanie 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; } } } W treści HTML skróty klawiatury dla polecenia kopiowania i wklejania są wdrażane domyślnie. Przy użyciu detektora zdarzeń klawiszy nie można wykryć wszystkich często używanych kombinacji klawiszy do kopiowania i wklejania. Aby przesłonić ustawienia domyślne, zaleca się wykrywanie samych zdarzeń copy i paste. 156 Rozdział 17: Praca z tablicami bajtów Klasa ByteArray umożliwia zapisywanie danych i odczytywanie ich z binarnego strumienia danych, stanowiącego zasadniczo tablice bajtów. Ta klasa umożliwia dostęp do najbardziej podstawowych danych. Ponieważ dane w komputerze składają się z bajtów lub grup złożonych z 8 bitów, możliwość odczytywania danych w bajtach oznacza, że użytkownik może uzyskać dostęp do danych, dla których nie istnieją klasy ani metody dostępu. Klasa ByteArray umożliwia analizę każdego strumienia danych, od bitmapy do strumienia danych przesyłanych w sieci na poziomie bajtów. Metoda writeObject() umożliwia zapisanie obiektu w serializowanym formacie AMF (Action Message Format) do obiektu ByteArray, natomiast metoda readObject() pozwala na zapisanie obiektu serializowanego z obiektu ByteArray do zmiennej pierwotnego typu danych. Można serializować dowolny obiekt z wyjątkiem obiektów wyświetlania stanowiących te obiekty, które można umieścić na liście wyświetlania. Obiekty serializowane można również ponownie przypisać do instancji klas niestandardowych, jeśli ta klasa jest dostępna w środowisku wykonawczym. Po konwersji obiektu do formatu AMF można skutecznie przesłać go za pomocą połączenia sieciowego lub zapisać w pliku. Przykładowa opisana tutaj aplikacja Adobe® AIR™ odczytuje pliki .zip jako przykład przetwarzania strumienia bajtów; rozpakowywania listy plików zawartych w pliku .zip file oraz zapisywania ich na pulpit. Odczytywanie i zapisywanie obiektu ByteArray Klasa ByteArray należy do pakietu flash.utils. Aby utworzyć obiekt ByteArray w programie ActionScript 3.0, należy zaimportować klasę ByteArray i wywołać konstruktora zgodnie z następującym przykładem: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray(); ByteArray, metody Każdy poprawny strumień danych jest uporządkowany w formacie, który można analizować w celu wyszukania żądanych informacji. Rekord w prostym pliku pracownika może na przykład zawierać imię i nazwisko, numer dowodu osobistego, adres, numer telefonu, itd. Plik audio MP3 zawiera znacznik ID3 określający autora, album, datę publikacji oraz gatunek pobieranego pliku. Format pozwala na określenie kolejności danych w strumieniu danych. Umożliwia również inteligentne odczytanie strumienia bajtów. Klasa ByteArray zawiera kilka metod ułatwiających odczytywanie i zapisywanie danych do strumienia danych. Niektóre z tych metod zawierają readBytes() i writeBytes(), readInt() i writeInt(), readFloat() i writeFloat(), readObject() i writeObject(), oraz readUTFBytes() i writeUTFBytes(). Te metody umożliwiają odczytanie danych ze strumienia danych jako zmienne określonych typów danych i zapisanie określonych typów danych bezpośrednio do binarnego strumienia danych. Na przykład, następujący kod odczytuje prostą tablicę ciągów i liczby zmiennoprzecinkowe i zapisuje każdy element do ByteArray. Organizacja tablic umożliwia kodowi wywołanie odpowiedniej metody ByteArray (writeUTFBytes() i writeFloat()) w celu zapisania danych. Powtarzający się wzór danych umożliwia odczytanie tablicy w pętli. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 157 Praca z tablicami bajtów // 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 Właściwość position Właściwość position zapisuje bieżącą pozycję wskaźnika indeksującego obiekt ByteArray podczas odczytywania i zapisywania. Początkowa wartość właściwości position to 0 (zero) zgodnie z następującym kodem: var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0 Podczas odczytywania i zapisywania do obiektu ByteArray użyte metody aktualizują właściwość position, tak aby wskazywała miejsce bezpośrednio po ostatnim zapisanym lub odczytanym bajcie. Na przykład, następujący kod zapisuje ciąg w obiekcie ByteArray, a następnie właściwość position wskazuje bajt bezpośrednio po łańcuchu w obiekcie 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 Podobnie, czynność odczytywania powoduje zwiększanie wartości właściwości position o liczbę odczytanych bajtów. 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! Właściwość position można ustawić na określone położenie w obiekcie ByteArray w celu odczytania lub zapisania przy tym przesunięciu. Właściwości bytesAvailable i length Właściwości length i bytesAvailable informują o długości obiektu ByteArray oraz liczbie znajdujących się w nim bajtów od położenia początkowego od końca. W następującym przykładzie przedstawiony jest sposób użycia tych właściwości. W przykładzie w obiekcie ByteArray zapisany jest ciąg tekstu String, który jest następnie odczytany jako kolejne bajty do czasu napotkania znaku „a” lub zakończenia (bytesAvailable <= 0). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 158 Praca z tablicami bajtów 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 } Właściwość endian Komputery mogą różnić się w sposobie zapisywania liczb wielobajtowych, tj. liczb wymagających do zapisania więcej niż jeden bajt pamięci. Liczba całkowita może na przykład zajmować w pamięci 4 bajty lub 32 bity. Niektóre komputery zapisują w pierwszej kolejności najbardziej znaczące bajty w najniższych adresach pamięci, inne natomiast najmniej znaczące bajty. Ten atrybut komputera lub kolejność bajtów określa się jako big endian (najbardziej znaczące bajty najpierw) lub little endian (najmniej znaczące bajty najpierw). Na przykład, liczba 0x31323334 będzie zapisana w następujący sposób zgodnie z kolejnością bajtów big endian i little endian, gdzie a0 przedstawia najniższy adres pamięci 4 bajtów, a a3 przedstawia najwyższy: 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 Właściwość endian klasy ByteArray umożliwia określenie kolejności bajtów dla przetwarzanych liczb wielobajtowych. Dopuszczalne wartości to "bigEndian" lub "littleEndian" - klasa Endian definiuje stałe BIG_ENDIAN i LITTLE_ENDIAN do ustawienia wartości endian za pomocą tych ciągów. Metody compress() i uncompress() Metoda compress() umożliwia kompresje obiektu ByteArray zgodnie z algorytmem kompresji określonego jako parametr. Metoda uncompress() umożliwia cofnięcie kompresji skompresowanego ByteArray zgodnie z algorytmem kompresji. Po wywołaniu metody compress() i uncompress() dla długości tablicy bajtów zostaje ustawiona nowa długość, a właściwość position zostaje ustawiona na koniec. Klasa CompressionAlgorithm definiuje stałe, które można używać w celu określenia algorytmu kompresji. AIR obsługuje algorytmy deflate i zlib. Algorytm kompresji deflate można stosować w wielu formatach kompresji np. zlib, gzip i wybranych implementacjach zip. Format danych skompresowanych zlib został opisany pod adresemhttp://www.ietf.org/rfc/rfc1950.txt, a algorytm kompresji deflate opisany jest pod adresem http://www.ietf.org/rfc/rfc1951.txt. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 159 Praca z tablicami bajtów W następującym przykładzie skompresowany jest obiekt ByteArray o nazwie bytes za pomocą algorytmu deflate: bytes.compress(CompressionAlgorithm.DEFLATE); W następującym przykładzie anulowana jest kompresja skompresowanego obiektu ByteArray za pomocą algorytmu deflate: bytes.uncompress(CompressionAlgorithm.DEFLATE); Odczytywanie i zapisywanie obiektów Metody readObject() i writeObject() odczytują obiekt i zapisują go do obiektu ByteArray zakodowanego w serializowanym formacie AMF (Action Message Format). Format AMF to protokół z informacjami na temat praw własności utworzony przez Adobe i stosowany przez różne klasy ActionScript 3.0, w tym Netstream, NetConnection, NetStream, LocalConnection oraz Shared Objects. Znacznik jednobajtowy opisuje typ zakodowanych danych występujących po nim. Format AMF korzysta z następujących 13 typów danych: 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 Zakodowane dane występują po typie znacznika, chyba że znacznik przedstawia pojedynczą dopuszczalną wartość, np. null lub true bądź false. W takim wypadku nie są kodowane żadne inne dane. Istnieją dwie wersje formatu AMF: AMF0 i AMF3. AMF 0 obsługuje wysyłanie złożonych obiektów poprzez odniesienie i umożliwia punktom końcowym przywrócenie relacji pomiędzy obiektami. AMF 3 uzupełnia AMF 0 poprzez przesłanie cech i ciągów jako odniesienie oprócz odniesienia do obiektów oraz poprzez obsługę nowych typów danych wprowadzonych w ActionScript 3.0. Właściwość ByteArray.objectEcodingokreśla wersję pliku AMF użytego w celu zakodowania danych obiektu. Klasa flash.net.ObjectEncoding określa stałe w celu określenia wersji AMF: ObjectEncoding.AMF0 i ObjectEncoding.AMF3. import flash.filesystem.*; import flash.utils.ByteArray; // Label component must be in Library import fl.controls.Label; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 160 Praca z tablicami bajtów 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(); } Metoda readObject() odczytuje obiekt w serializowanym formacie AMF z obiektu ByteArray i zapisuje go w obiekcie określonego typu. W następującym przykładzie odczytany jest plik order z pulpitu do obiektu ByteArray (inBytes), cofnięta zostanie kompresja i wywołana metoda readObject() w celu zapisania pliku w obiekcie XML orderXML. W tym przykładzie wykorzystana jest pętla for each() w celu dodania każdego węzła do obszaru tekstowego do wyświetlenia. W tym przykładzie wyświetlona jest również wartość właściwości objectEncoding razem z nagłówkiem treści w pliku order. import flash.filesystem.*; import flash.utils.ByteArray; // TextArea component must be in Library import fl.controls.TextArea; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 161 Praca z tablicami bajtów 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(); } Przykład ByteArray: odczytywanie pliku .zip W tym przykładzie przedstawiony jest sposób odczytywania pliku .zip zawierającego kilka plików różnego rodzaju. Następuje to poprzez pobranie istotnych danych z metadanych dla każdego pliku, rozpakowanie każdego pliku do obiektu ByteArray i zapisanie pliku na pulpicie. Ogólna struktura pliku .zip jest oparta o specyfikację PKWARE Inc. dostępną pod adresem http://www.pkware.com/documents/casestudies/APPNOTE.TXT. W pierwszej kolejności w archiwum pliku .zip występuje nagłówek pliku, a następnie nagłówek pliku i pary danych pliku dla każdego dodatkowego pliku. (Struktura nagłówka pliku jest opisana w dalszej części). Następnie plik .zip opcjonalnie zawiera rekord deskryptora danych (zazwyczaj po utworzeniu wyjściowego pliku zip w pamięci, a nie po zapisaniu go na dysk). Dalej znajdują się dodatkowe opcjonalne elementy: nagłówek deskryptora archiwum, rekord dodatkowych danych archiwum, struktura katalogu centralnego, rekord końca katalogu rekord lokalizatora katalogu centralnego Zip64 oraz rekord końca rekordu katalogu centralnego. W tym przykładzie kod jest zapisany wyłącznie w celu analizy plików zip, które nie zawierają folderów. Kod ten nie oczekuje rekordów deskryptora danych. Ignoruje wszystkie informacje występujące po danych ostatniego pliku. Format nagłówka pliku dla każdego pliku jest następujący: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 162 Praca z tablicami bajtów podpis nagłówka pliku 4 bajty wymagana wersja 2 bajty flaga bitowa ogólnego użytku 2 bajty metoda kompresji 2 bajty (8=DEFLATE; 0=UNCOMPRESSED) godzina ostatniej modyfikacji pliku 2 bajty data ostatniej modyfikacji pliku 2 bajty crc-32 4 bajty skompresowany rozmiar 4 bajty rozmiar bez kompresji 4 bajty długość nazwy pliku 2 bajty długość dodatkowego pola 2 bajty nazwa pliku zmienna dodatkowe pole zmienna Właściwe dane pliku znajdują się po nagłówku pliku. Mogą być one skompresowane bądź nie w zależności od flagi metody kompresji. Flaga ma wartość 0 (zero), jeśli dane pliku nie są skompresowane, wartość 8, jeśli dane są skompresowane za pomocą algorytmu DEFLATE lub inną wartość w przypadku innych algorytmów kompresji. Interfejs użytkownika w tym przykładzie składa się z etykiety i obszaru tekstowego (taFiles). Aplikacja zapisuje następujące informacje do obszaru tekstowego dla każdego pliku napotkanego w pliku .zip: nazwę pliku, skompresowany rozmiar i rozmiar bez kompresji. Na początku programu wykonywane są następujące zadania: • Importowanie wymaganych klas import flash.filesystem.*; import flash.utils.ByteArray; import flash.events.Event; • Definiowanie interfejsu użytkownika 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); • Definiowanie obiektu ByteArray bytes var bytes:ByteArray = new ByteArray(); • Definiowanie zmiennych w celu zapisania metadanych z nagłówka pliku TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 163 Praca z tablicami bajtów // 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; • Definiowanie obiektów File (zfile) i FileStream (zStream) w celu reprezentacji pliku .zip i określenie lokalizacji pliku .zip, z którego rozpakowywane są pliki — plik o nazwie „HelloAIR.zip” w katalogu pulpitu. // File variables for accessing .zip file var zfile:File = File.desktopDirectory.resolvePath("HelloAIR.zip"); var zStream:FileStream = new FileStream(); Program rozpoczyna się poprzez otwarcie pliku .zip w trybie odczytu. zStream.open(zfile, FileMode.READ); Następnie ustawiona zostaje właściwość endian obiektu bytes jako LITTLE_ENDIAN w celu wskazania, że kolejność bajtów pól numerycznych określa jako pierwsze bajty o najmniejszy znaczeniu. bytes.endian = Endian.LITTLE_ENDIAN; Następnie instrukcja while() rozpoczyna pętlę ciągnącą się do czasu, aż bieżące położenie w strumieniu plików będzie większe lub równe rozmiarowi pliku. while (zStream.position < zfile.size) { Pierwsza instrukcja w pętli odczytuje pierwsze 30 bajtów strumienia plików do obiektu bytes ByteArray. Pierwsze 30 bajtów tworzy pierwszą część nagłówka pliku o stałym rozmiarze. // read fixed metadata portion of local file header zStream.readBytes(bytes, 0, 30); Następnie kod odczytuje liczbę całkowitą (signature) z pierwszych bajtów 30-bajtowego nagłówka. Definicja formatu ZIP określa, że podpis dla każdego nagłówka pliku to wartość szesnastkowa 0x04034b50; jeśli podpis ma inną wartość, oznacza to, że kod został przeniesiony poza część pliku .zip i nie ma więcej plików do rozpakowania. W takim wypadku kod wychodzi bezpośrednio poza pętlę while i nie czeka na koniec tablicy bajtów. bytes.position = 0; signature = bytes.readInt(); // if no longer reading data files, quit if (signature != 0x04034b50) { break; } Kolejna część kodu odczytuje bajt nagłówka w położeniu przesunięcia 8 i zapisuje wartość w zmiennej compMethod. Ten bajt zawiera wartość wskazującą na metodę kompresji użytą do skompresowania tego pliku. Dozwolonych jest kilka metod kompresji, jednak w praktyce prawie wszystkie pliki .zip korzystają z algorytmu kompresji DEFLATE. Jeśli bieżący plik zostanie skompresowany przy użyciu metody DEFLATE, wówczas zmienna compMethod będzie miała wartość 8; jeśli plik zostanie zdekompresowany, zmienna compMethod będzie miała wartość 0. bytes.position = 8; compMethod = bytes.readByte(); // store compression method (8 == Deflate) TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 164 Praca z tablicami bajtów Za pierwszymi 30 bajtami znajduje się sekcja nagłówka o zmiennej długości, która zawiera nazwę pliku oraz dodatkowe pole (opcjonalnie). Zmienna offset zawiera rozmiar tej sekcji. Rozmiar jest obliczany poprzez dodanie długości nazwy pliku oraz długości pola dodatkowego, które są odczytywane przy przesunięciach 26 i 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 Następnie program odczytuje sekcję nagłówka pliku o zmiennej długości pod względem liczby bajtów zapisanych w zmiennej offset. // read variable length bytes between fixed-length header and compressed file data zStream.readBytes(bytes, 30, offset); Program odczytuje nazwę pliku z sekcji nagłówka o zmiennej długości, a następnie wyświetla nazwę w obszarze tekstowym wraz z rozmiarem pliku skompresowanego (programem zip) i nieskompresowanego (oryginalnego). 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'); W przykładzie przedstawiono odczytanie pozostałej części pliku ze strumienia pliku do bytes w celu określenia długości w pliku skompresowanym. W przykładzie następuje również zastąpienie nagłówka pliku w pierwszych 30 bajtach. Rozmiar skompresowany jest określony dokładnie, nawet jeśli plik nie jest skompresowany, ponieważ w tym przypadku wielkość pliku skompresowanego jest równa wielkości pliku nieskompresowanego. // read compressed file to offset 0 of bytes; for uncompressed files // the compressed and uncompressed size is the same zStream.readBytes(bytes, 0, compSize); Następnie w przykładzie dochodzi do dekompresji skompresowanego pliku oraz do wywołania funkcji outfile() w celu zapisania pliku w wyjściowym strumieniu pliku. Do funkcji outfile() przekazywana jest nazwa pliku oraz tablica bajtowa zawierająca dane pliku. if (compMethod == 8) // if file is compressed, uncompress { bytes.uncompress(CompressionAlgorithm.DEFLATE); } outFile(fileName, bytes); // call outFile() to write out the file Nawias zamykający wskazuje koniec pętli while oraz koniec kodu aplikacji, oprócz metody outFile(). Wykonywanie rozpoczyna się od pętli while i kontynuuje przetwarzanie kolejnych bajtów w pliku .zip — wyodrębniając inny plik lub kończąc przetwarzanie pliku .zip po przetworzeniu ostatniego pliku. } // end of while loop TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 165 Praca z tablicami bajtów Funkcja outfile() otwiera plik wyjściowy w trybie WRITE na pulpicie, nadając mu nazwę określoną przez parametr filename. Następnie zapisuje dane pliku z parametru data do wyjściowego strumienia pliku (outStream), a następnie zamyka plik. 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(); } 166 Rozdział 18: Praca z lokalnymi bazami danych SQL Środowisko Adobe AIR udostępnia funkcje tworzenia i pracy z lokalnymi bazami danych SQL. Środowisko wykonawcze zawiera mechanizm bazy danych SQL z obsługą wielu standardowych funkcji SQL i możliwością korzystania z systemu bazy danych SQLite typu open source. Lokalna baza danych SQL może służyć do zapisywania lokalnych, trwałych danych. Na przykład: może być używana do zapisywania danych aplikacji, ustawień użytkownika aplikacji, dokumentów lub innych typów danych, które aplikacja powinna zapisywać lokalnie. Dodatkowe informacje online na temat lokalnych baz danych SQL Więcej informacji na temat pracy z lokalnymi bazami danych SQL zawierają poniższe źródła: Podręczniki Szybki start (Adobe AIR Developer Connection) • Praca asynchroniczna z lokalną bazą danych SQL • Praca asynchroniczna z lokalną bazą danych SQL • Korzystanie z zaszyfrowanej bazy danych Skorowidz języka • SQLCollationType • SQLColumnNameStyle • SQLColumnSchema • SQLConnection • SQLError • SQLErrorEvent • SQLErrorOperation • SQLEvent • SQLIndexSchema • SQLMode • SQLResult • SQLSchema • SQLSchemaResult • SQLStatement • SQLTableSchema • SQLTransactionLockType • SQLTriggerSchema TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 167 Praca z lokalnymi bazami danych SQL • SQLUpdateEvent • SQLViewSchema Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „AIR SQL”) Informacje o lokalnych bazach danych SQL Środowisko Adobe AIR zawiera mechanizm relacyjnej bazy danych opartej na języku SQL, który działa w środowisku wykonawczym i zapisuje dane lokalnie w plikach bazy danych na komputerze, na którym działa aplikacja AIR (np. dysk twardy komputera). Baza danych działa lokalnie i pliki są zapisywane lokalnie, dlatego baza danych może być używana przez aplikację AIR bez względu na to, czy istnieje połączenie z siecią. Z tego względu mechanizm lokalnej bazy danych SQL w środowisku wykonawczym stanowi wygodny mechanizm do zapisywania trwałych, lokalnych danych aplikacji, przeznaczony przede wszystkim dla użytkowników posiadających doświadczenie z bazami SQL i bazami relacyjnymi. Zastosowania lokalnych baz danych SQL Lokalna baza danych SQL środowiska AIR może służyć do dowolnego celu, dla którego konieczne może być zapisanie danych aplikacji lokalnie na komputerze. Środowisko Adobe AIR zawiera kilka mechanizmów przeznaczonych do lokalnego zapisywania danych, a każdy charakteryzuje się osobnymi zaletami. Poniżej przedstawiono możliwe zastosowania lokalnej bazy danych SQL w aplikacji AIR: • W przypadku aplikacji zorientowanej na dane (np. książka adresowa) baza danych może służyć do zapisywania danych aplikacji głównej. • W przypadku aplikacji zorientowanej na dokumenty, w której użytkownicy tworzą dokumenty zapisywane oraz współużytkowane, każdy dokument może zostać zapisany jako plik bazy danych, w lokalizacji określonej przez użytkownika. (Należy jednak zwrócić uwagę, że dowolna aplikacja AIR będzie mogła otworzyć plik bazy danych, o ile nie będzie on zaszyfrowany. Zaleca się szyfrowanie dokumentów podlegających szczególnej ochronie). • W przypadku aplikacji sieciowej baza danych może służyć do zapisu lokalnej pamięci podręcznej danych aplikacji lub do tymczasowego zapisu danych, gdy nie istnieje połączenie z siecią. Możliwe jest utworzenie mechanizmu synchronizacji lokalnej bazy danych z sieciowym magazynem danych. • Dla każdej aplikacji baza danych może służyć do zapisania ustawień użytkownika aplikacji, np. opcji użytkownika lub informacji o aplikacji, takich jak wielkość i położenie okien. Informacje o bazach danych AIR i plikach bazy danych Pojedyncza lokalna baza danych SQL w środowisku Adobe AIR jest zapisana jako jeden plik w systemie plików. Środowisko wykonawcze zawiera mechanizm bazy danych SQL, który zarządza tworzeniem i strukturą plików bazy danych, a także manipulowaniem danymi i odzyskiwaniem danych z pliku bazy danych. Środowisko wykonawcze nie określa sposobu ani miejsca zapisu danych w systemie plików; zamiast tego każda baza danych jest zapisywana w całości w jednym pliku. Lokalizację pliku bazy danych określa się w systemie plików. Pojedyncza aplikacja AIR może uzyskiwać dostęp do jednej lub wielu osobnych baz danych (tj. do osobnych plików baz danych). Środowisko wykonawcze zapisuje każdą bazę danych jako osobny plik w systemie plików, dlatego możliwe jest dowolne umiejscowienie bazy danych poprzez określenie struktury aplikacji i ograniczeń dostępu do pliku w systemie TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 168 Praca z lokalnymi bazami danych SQL operacyjnym. Każdy użytkownik może korzystać z osobnego pliku bazy danych dla własnych danych lub możliwy jest dostęp do bazy danych przez wszystkich użytkowników aplikacji, w przypadku danych współużytkowanych. Dane są lokalne tylko względem pojedynczego komputera, dlatego dane nie są automatycznie współużytkowane przez użytkowników na różnych komputerach. Lokalny mechanizm bazy danych SQL nie umożliwia wykonywania instrukcji SQL dotyczących zdalnych lub serwerowych baz danych. Informacje o relacyjnych bazach danych Relacyjna baza danych to mechanizm przeznaczony do zapisywania (i pobierania) danych na komputerze. Dane są zorganizowane w tabelach: wiersze reprezentują rekordy lub pozycje, a kolumny (czasami nazywane „polami”) dzielą każdy rekord na osobne wartości. Na przykład: aplikacja książki adresowej może zawierać tabelę „znajomi”. Każdy wiersz w tej tabeli reprezentuje jednego znajomego zapisanego w bazie danych. Kolumny tabeli reprezentują dane, takie jak imię, nazwisko, data urodzenia itp. W wierszu każdego znajomego baza danych zawiera osobną wartość dla każdej kolumny. Relacyjne bazy danych zawierają dane złożone, a jeden element danych jest skojarzony lub powiązany z elementami innego typu. W relacyjnej bazie danych dane, dla których istnieje relacja „jeden do wielu” — w której jeden rekord może być powiązany z wieloma rekordami różnego typu — powinny być rozdzielone na różne tabele. Przykład: załóżmy, że wymagane jest, aby aplikacja książki telefonicznej zawierała wiele numerów telefonów dla każdego znajomego; to jest relacja „jeden do wielu”. Tabela „znajomi” będzie zawierała wszystkie dane osobowe dla każdego znajomego. Osobno tabela „numery telefonów” będzie zawierała wszystkie numery telefonów dla wszystkich znajomych. Oprócz danych dotyczących znajomych i numerów telefonów każda tabela może zawierać dane przeznaczone do śledzenia relacji między dwiema tabelami — w celu dopasowania rekordów poszczególnych osób do ich numerów telefonów. Te dane są określane jako klucz podstawowy — unikalny identyfikator, który odróżnia każdy wiersz w tabeli od innych wierszy w tej tabeli. Klucz podstawowy może być „kluczem naturalnym”, co oznacza, że jest to jeden z elementów danych, które w naturalny sposób odróżniają każdy rekord w tabeli. Jeśli wiadomo, że żadne osoby z tabeli „znajomi” nie mają takiej samej daty urodzenia, wówczas kolumna daty urodzenia może być używana jako klucz podstawowy (klucz naturalny) tabeli „znajomi”. Jeśli nie ma klucza naturalnego, można utworzyć osobną kolumnę klucza podstawowego, taką jak „id. znajomego” — będzie to sztuczna wartość, z której aplikacja korzysta w celu odróżniania wierszy. Za pomocą klucza podstawowego można skonfigurować relacje między wieloma tabelami. Na przykład: załóżmy, że tabela „znajomi” zawiera kolumnę „id. znajomego”, która zawiera unikalny numer dla każdego wiersza (znajomego). Powiązana tabela „numery telefonów” może zawierać dwie kolumny: jedną z id. znajomego, do którego należy numer telefonu, a drugą z rzeczywistym numerem telefonu. Dzięki temu niezależnie od liczby numerów telefonów, z których korzysta określona osoba, wszystkie te numery mogą być zapisane w tabeli „numery telefonów” i mogą być połączone z powiązanym znajomym za pomocą klucza podstawowego „id. znajomego”. Jeśli klucz podstawowy z jednej tabeli jest używany w tabeli powiązanej w celu określenia połączenia między rekordami, wówczas wartość w tabeli powiązanej jest określana jako klucz obcy. Mechanizm lokalnej bazy danych AIR — inaczej niż większość baz danych — nie umożliwia tworzenia ograniczeń dot. kluczy obcych. Są to ograniczenia, które powodują automatyczne sprawdzanie, czy wstawiony lub zaktualizowany klucz obcy ma odpowiadający wiersz w tabeli klucza podstawowego. Jednakże relacje kluczy obcych stanowią istotną część struktury relacyjnej bazy danych i powinny być używane w przypadku tworzenia relacji między tabelami w bazie danych. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 169 Praca z lokalnymi bazami danych SQL Informacje o języku SQL Język SQL (Structured Query Language) jest używany z relacyjnymi bazami danych w celu manipulowania danymi oraz w celu uzyskiwania danych. SQL jest językiem opisowym, a nie proceduralnym. Instrukcja SQL nie stanowi dla komputera instrukcji uzyskania danych — jest to opis wymaganego zestawu danych. Sposób uzyskiwania danych określa mechanizm bazy danych. Standardy języka SQL zostały określone przez instytut ANSI (American National Standards Institute). Lokalna baza danych SQL Adobe AIR obsługuje większą część standardu SQL-92. Szczegółowe opisy języka SQL obsługiwanego w środowisku Adobe AIR zawiera dodatek „Obsługa SQL w lokalnych bazach danych“ w dokumentacji Skorowidz języka i składników ActionScript 3.0. Informacje o klasach języka SQL W celu pracy z lokalnymi bazami danych SQL w języku ActionScript 3.0 należy korzystać z instancji następujących klas z pakietu flash.data: Klasa Opis flash.data.SQLConnection Udostępnia sposoby tworzenia i otwierania baz danych (plików baz danych), a także sposoby wykonywania operacji na poziomie bazy danych oraz do kontrolowania transakcji bazy danych. flash.data.SQLStatement Reprezentuje pojedynczą instrukcję SQL (pojedyncze zapytanie lub polecenie), która jest wykonywana na bazie danych — definiuje również tekst instrukcji i określa ustawienia wartości parametrów. flash.data.SQLResult Udostępnia sposób pobierania informacji dot. instrukcji lub wyników wykonania instrukcji, np. wiersze wyników z instrukcji SELECT, liczba wierszy objętych instrukcją UPDATE lub DELETE itd. W celu uzyskania schematów dotyczących struktury bazy danych należy użyć następujących klas z pakietu flash.data: Klasa flash.data.SQLSchemaResult Opis Służy jako kontener dla wyników schematu bazy danych wygenerowanych przez wywołanie metody SQLConnection.loadSchema(). flash.data.SQLTableSchema Udostępnia informacje opisujące pojedynczą tabelę w bazie danych. flash.data.SQLViewSchema Udostępnia informacje opisujące pojedynczy widok w bazie danych. flash.data.SQLIndexSchema Udostępnia informacje opisujące pojedynczą kolumnę tabeli lub widok w bazie danych. flash.data.SQLTriggerSchem a Udostępnia informacje opisujące pojedynczy wyzwalacz w bazie danych. Inne klasy z pakietu flash.data udostępniają stałe, które są używane z klasą SQLConnection oraz klasą SQLColumnSchema: Klasa Opis flash.data.SQLMode Definiuje zestaw stałych reprezentujących możliwe wartości parametru openMode metod SQLConnection.open() i SQLConnection.openAsync(). flash.data.SQLColumnNameStyle Definiuje zestaw stałych reprezentujących możliwe wartości właściwości SQLConnection.columnNameStyle. flash.data.SQLTransactionLockType Definiuje zestaw stałych reprezentujących możliwe wartości parametru option metody SQLConnection.begin(). flash.data.SQLCollationType Definiuje zestaw stałych reprezentujących możliwe wartości właściwości SQLColumnSchema.defaultCollationType, a także parametr defaultCollationType konstruktora SQLColumnSchema(). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 170 Praca z lokalnymi bazami danych SQL Ponadto poniższe klasy z pakietu flash.events reprezentują zdarzenia (oraz obsługujące stałe) używane przez użytkownika: Klasa Opis flash.data.SQLEvent Definiuje zdarzenia, które wywołuje instancja SQLConnection lub SQLStatement, gdy jakiekolwiek jej operacje zostaną pomyślnie wykonane. Z każdą operacją skojarzona jest stała typu zdarzenia zdefiniowana w klasie SQLEvent. flash.data.SQLErrorEvent Definiuje zdarzenie, które wywołuje instancja SQLConnection lub SQLStatement, gdy jakiekolwiek jej operacje spowodują błąd. flash.data.SQLUpdateEvent Definiuje zdarzenie, jakie wywołuje instancja SQLConnection, gdy dane tabeli w jednej z połączonych z nią baz danych ulegną zmianie w wyniku wykonania instrukcji SQL INSERT, UPDATE lub DELETE. Poniższe klasy z pakietu flash.errors udostępniają informacje o błędach działania baz danych: Klasa Opis flash.data.SQLError Udostępnia informacje o błędzie działania bazy danych, z uwzględnieniem operacji, która miała zostać wykonana oraz przyczyny niepowodzenia. flash.data.SQLErrorEvent Definiuje zestaw stałych reprezentujących możliwe wartości dla właściwości operation klasy SQLError — właściwość ta wskazuje operację bazy danych, która spowodowała błąd. Informacje o trybach wykonywania synchronicznego i asynchronicznego Podczas pisania kodu przeznaczonego do pracy z lokalną bazą danych SQL należy określić wykonanie operacji bazy danych w jednym z dwóch trybów: tryb wykonywania asynchronicznego i tryb wykonywania synchronicznego. Najczęściej przykłady kodu przedstawiają wykonywanie określonych operacji na dwa sposoby, dlatego możliwe jest wybranie sposobu, który najbardziej odpowiada określonym potrzebom. W trybie wykonywania asynchronicznego środowisko wykonawcze otrzymuje instrukcję i wówczas środowisko wywołuje zdarzenie, gdy żądana operacja zakończy się pomyślnie lub zakończy się niepowodzeniem. Najpierw mechanizm bazy danych musi otrzymać instrukcję dotyczącą wykonania operacji. Mechanizm działa w tle, a w tym czasie działa również aplikacja. Na koniec, gdy operacja powiedzie się (lub nie powiedzie), mechanizm bazy danych wywołuje błąd. Kod wywoływany przez zdarzenie powoduje wykonanie kolejnych operacji. Takie podejście ma znaczące zalety: środowisko wykonawcze wykonuje operacje bazy danych w tle podczas działania kodu aplikacji głównej. Jeśli wykonanie operacji bazy danych zajmuje pewną ilość czasu, wówczas aplikacja nadal działa. Najważniejsze jest to, że użytkownik może oddziaływać na aplikację i nie powoduje to efektu zamrożenia” ekranu. Jednakże kod operacji asynchronicznej może być znacznie bardziej złożony niż inne rodzaje kodu. Taka złożoność występuje przede wszystkim w przypadkach, gdy konieczne jest rozdzielenie wielu niezależnych operacji między różne metody detektora zdarzeń. Koncepcyjnie łatwiejsze jest kodowanie operacji jako pojedynczej sekwencji kroków — zestawu operacji synchronicznych — zamiast zestawu operacji podzielonych na kilka metod detektora zdarzeń. Oprócz asynchronicznych operacji na bazie danych środowisko Adobe AIR umożliwia również synchroniczne wykonywanie operacji na bazie danych. W trybie wykonywania synchronicznego operacje nie działają w tle. Zamiast tego działają w tej samej sekwencji wykonywania, w której działa cały kod aplikacji. Użytkownik zleca mechanizmowi bazy danych wykonanie operacji. Następnie kod jest wstrzymywany na czas działania mechanizmu bazy danych. Gdy operacja zostanie zakończona, następuje wznowienie wykonywania kodu od kolejnej linii. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 171 Praca z lokalnymi bazami danych SQL To, czy operacje są wykonywane w sposób synchroniczny czy asynchroniczny, jest określone na poziomie SQLConnection. W przypadku korzystania z pojedynczego połączenia z bazą danych nie ma możliwości wykonania jednych operacji w sposób synchroniczny, a innych w sposób asynchroniczny. To, czy instancja SQLConnection działa w trybie wykonywania synchronicznego czy asynchronicznego, określa się poprzez wywołanie metody SQLConnection w celu otwarcia bazy danych. Jeśli zostanie wywołana metoda SQLConnection.open(), połączenie działa w trybie wykonywania synchronicznego, a jeśli zostanie wywołana metoda SQLConnection.openAsync(), wówczas połączenie działa w trybie wykonywania asynchronicznego. Gdy instancja SQLConnection zostanie połączona z bazą danych za pomocą metody open() lub openAsync(), zostaje przypisana do trybu wykonywania synchronicznego lub asynchronicznego, chyba że nastąpi zamknięcie i ponowne otwarcie połączenia z bazą danych. Każdy tryb wykonywania ma pewne zalety. Większość aspektów każdego trybu jest podobna, jednak istnieją różnice, o których należy pamiętać podczas pracy z każdym trybem. Więcej informacji na ten temat oraz sugestie dotyczące pracy w każdym trybie zawiera sekcja „Korzystanie z synchronicznych i asynchronicznych operacji bazy danych” na stronie 192. Tworzenie i modyfikowanie bazy danych Zanim aplikacja będzie mogła dodać lub pobrać dane, konieczne jest utworzenie bazy danych zawierającej tabele, do których aplikacja będzie miała dostęp. W niniejszej sekcji opisano zadania tworzenia bazy danych, a także tworzenia struktury danych w bazie danych. Te zadania używane są rzadziej niż operacje wstawiania i pobierania danych, ale są konieczne dla większości aplikacji. Tworzenie bazy danych W celu utworzenia pliku bazy danych należy najpierw utworzyć instancję SQLConnection. Następnie należy wywołać jej metodę open(), aby otworzyć w trybie wykonywania asynchronicznego, lub metodę openAsync() w celu otwarcia w trybie wykonywania synchronicznego. Metody open() i openAsync() są używane do otwarcia połączenia z bazą danych. W przypadku wprowadzenia instancji File, która odwołuje się do nieistniejącej lokalizacji pliku dla parametru reference (parametr pierwszy), metoda open() lub openAsync() tworzy plik bazy danych w tej lokalizacji pliku, a następnie otwiera połączenie z nowo utworzoną bazą danych. Bez względu na to, czy w celu utworzenia bazy danych została wywołana metoda open(), czy metoda openAsync(), nazwa pliku bazy danych może być dowolną poprawną nazwą z dowolnym rozszerzeniem nazwy pliku. Jeśli metoda open() lub openAsync() zostanie wywołana z wartością null dla parametru reference, zostanie utworzona nowa baza danych (w pamięci), a nie plik bazy danych na dysku. Poniższy fragment kodu przedstawia sposób tworzenia pliku bazy danych (nowej bazy danych) w trybie wykonywania asynchronicznego. W tym przypadku plik bazy danych jest zapisany w katalogu zapisu aplikacji pod nazwą „DBSample.db”: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 172 Praca z lokalnymi bazami danych SQL 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); } W celu synchronicznego wykonywania operacji po otwarciu połączenia bazy danych za pomocą instancji SQLConnection należy wywołać metodę open(). Poniższy przykład przedstawia sposób tworzenia otwierania instancji SQLConnection, która wykonuje jej operacje synchronicznie: 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); } Tworzenie tabel bazy danych Utworzenie tabeli w bazie danych obejmuje wykonanie instrukcji SQL w tej bazie danych, z wykorzystaniem tego samego procesu, którego użyto w celu wykonania instrukcji SQL, takiej jak SELECT, INSERT, itp. W celu utworzenia tabeli należy zastosować instrukcję CREATE TABLE, która zawiera definicje kolumn i ograniczeń dla nowej tabeli. Więcej informacji na temat wykonywania instrukcji SQL zawiera sekcja „Praca z instrukcjami SQL” na stronie 175. Poniższy przykład demonstruje utworzenie tabeli o nazwie „employees” w istniejącym pliku bazy danych, przy wykorzystaniu trybu wykonywania asynchronicznego. W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn, która jest już połączona z bazą danych. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 173 Praca z lokalnymi bazami danych SQL 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); } Poniższy przykład demonstruje sposób utworzenia tabeli o nazwie „employees” w istniejącym pliku bazy danych, przy wykorzystaniu trybu wykonywania synchronicznego. W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn, która jest już połączona z bazą danych. 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); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 174 Praca z lokalnymi bazami danych SQL Manipulowanie danymi w bazie danych SQL Istnieją typowe zadania, jakie są wykonywane podczas pracy z lokalnymi bazami danych SQL. Do tych zadań należą: łączenie z bazą danych, dodawanie danych oraz pobieranie danych z tabel w bazie danych. Istnieją również pewne zagadnienia, o których należy pamiętać podczas wykonywania tych zadań, i dotyczą na przykład pracy z typami danych i obsługi błędów. Istnieją również pewne zadania dot. bazy danych, które są wykonywane rzadziej, ale często konieczne jest ich wykonanie zanim możliwe będzie wykonanie zadań typowych. Na przykład: zanim możliwe będzie połączenie z bazą danych i pobranie danych z tabeli konieczne jest utworzenie bazy danych oraz utworzenie struktury tabeli w bazie danych. Te mniej często wstępne zadania konfiguracji zostały omówione w sekcji „Tworzenie i modyfikowanie bazy danych” na stronie 171. Możliwe jest asynchroniczne wykonywanie operacji baz danych, co oznacza, że mechanizm bazy danych działa w tle i powiadamia użytkownika o tym, czy operacja zakończyła się pomyślnie czy niepomyślnie, poprzez wywołanie zdarzenia. Te operacje mogą być również wykonywane w sposób synchroniczny. W takim przypadku operacje bazy danych są wykonywane kolejno jedna po drugiej, a cała aplikacja (łącznie z operacjami aktualizowania ekranu) oczekuje na zakończenie operacji, dopiero wtedy wykonywany jest kolejny kod. Przykłady w niniejszej sekcji prezentują sposób wykonywania operacji w sposób synchroniczny i asynchroniczny. Więcej informacji o trybie wykonywania asynchronicznego i synchronicznego zawiera sekcja „Korzystanie z synchronicznych i asynchronicznych operacji bazy danych” na stronie 192. Połączenie z bazą danych Zanim możliwe będzie wykonanie jakichkolwiek operacji bazy danych najpierw należy nawiązać połączenie z plikiem bazy danych. Instancja SQLConnection służy do reprezentowania połączenia z jedną lub większą liczbą baz danych. Pierwsza baza danych, która zostanie połączona za pomocą instancji SQLConnection, jest określana jako „główna” baza danych. Ta baza danych zostanie połączona za pomocą metody open() (dla trybu wykonywania synchronicznego) lub za pomocą metody openAsync() (dla trybu wykonywania asynchronicznego). Jeśli baza danych zostanie otwarta za pomocą asynchronicznej operacji openAsync(), należy dokonać rejestracji dla zdarzenia open instancji SQLConnection w celu określenia czasu zakończenia operacji openAsync(). W celu ustalenia, czy operacja się nie powiodła, należy dokonać rejestracji zdarzenia error instancji SQLConnection. Poniższy przykład prezentuje sposób otwierania istniejącego pliku bazy danych dla wykonywania asynchronicznego. Plik bazy danych ma nazwę „DBSample.db” i znajduje się w katalogu zapisu aplikacji użytkownika. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 175 Praca z lokalnymi bazami danych SQL 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); } Poniższy przykład prezentuje sposób otwierania istniejącego pliku bazy danych dla wykonania synchronicznego. Plik bazy danych ma nazwę „DBSample.db” i znajduje się w katalogu zapisu aplikacji użytkownika. 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); } W wywołaniu metody openAsync() w przykładzie wykonania asynchronicznego oraz w wywołaniu metody open() w przykładzie wykonania synchronicznego drugi argument jest stałą SQLMode.UPDATE. Określenie stałej SQLMode.UPDATE dla drugiego parametru (openMode) powoduje, że środowisko wykonawcze wywołuje błąd, jeśli określony plik nie istnieje. Jeśli stała SQLMode.CREATE zostanie przekazana dla parametru openMode (lub jeśli parametr openMode pozostanie wyłączony), wówczas środowisko wykonawcze podejmie próbę utworzenia pliku bazy danych, pod warunkiem że określony plik nie istnieje. Jeśli jednak plik istnieje, to zostanie otwarty, tak jak gdyby została użyta metoda SQLMode.Update. Możliwe jest również wybranie stałej SQLMode.READ dla parametru openMode w celu otwarcia istniejącej bazy danych w trybie tylko do odczytu. W takim przypadku dane można pobrać z bazy danych, ale nie można ich dodawać, usuwać ani zmieniać. Praca z instrukcjami SQL Pojedyncza instrukcja SQL (zapytanie lub polecenie) jest reprezentowana w środowisku wykonawczym jako obiekt SQLStatement. W celu utworzenia i wykonania instrukcji SQL należy wykonać poniższe czynności: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 176 Praca z lokalnymi bazami danych SQL Utwórz instancję SQLStatement. Obiekt SQLStatement reprezentuje instrukcję SQL w aplikacji. var selectData:SQLStatement = new SQLStatement(); Określ bazę danych, której będzie dotyczyło zapytanie. W tym celu ustaw właściwość sqlConnection obiektu SQLStatement na instancję SQLConnection, która jest połączona z żądaną bazą danych. // A SQLConnection named "conn" has been created previously selectData.sqlConnection = conn; Określ rzeczywistą instrukcję SQL. Utwórz tekst instrukcji w postaci ciągu znaków, a następnie przypisz tekst do właściwości text instancji SQLStatement. selectData.text = "SELECT col1, col2 FROM my_table WHERE col1 = :param1"; Zdefiniuj funkcje w celu obsłużenia wyniku wykonanej operacji (tylko tryb wykonywania asynchronicznego). Użyj metody addEventListener() w celu zarejestrowania funkcji jako detektorów zdarzeń result i error instancji 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 } Możliwe jest również określenie metod detektorów za pomocą obiektu Responder. W takim przypadku należy utworzyć instancję Responder, a następnie powiązać z nią metody detektora. // 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 } Jeśli tekst instrukcji zawiera definicje, przypisz wartości do tych parametrów. W celu przypisania wartości parametru użyj właściwości parameters instancji SQLStatement — ta właściwość jest tablicą asocjacyjną. selectData.parameters[":param1"] = 25; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 177 Praca z lokalnymi bazami danych SQL Wykonaj instrukcję SQL. Wywołaj metodę execute() instancji SQLStatement. // using synchronous execution mode // or listener methods in asynchronous execution mode selectData.execute(); Ponadto: jeśli obiekt Responder jest używany zamiast detektorów zdarzeń w trybie wykonania asynchronicznego, wówczas należy przekazać instancję Responder do metody execute(). // using a Responder in asynchronous execution mode selectData.execute(-1, selectResponder); Przykłady prezentujące poszczególne kroki zawierają następujące tematy: „Pobieranie danych z bazy danych” na stronie 179 „Wstawianie danych” na stronie 185 „Zmiana i usuwanie danych” na stronie 188 Korzystanie z parametrów w instrukcjach Parametr instrukcji SQL umożliwia utworzenie instrukcji SQL wielokrotnego użytku. Jeśli używane są parametry instrukcji, wartości w instrukcji mogą ulec zmianie (np. wartości dodawane w instrukcji INSERT), ale podstawowy tekst instrukcji pozostaje niezmieniony. Dlatego użycie parametrów zapewnia potencjalnie wzrost wydajności, a także ułatwia kodowanie aplikacji. Informacje o parametrach instrukcji Często aplikacja wykorzystuje pojedynczą instrukcję SQL wielokrotnie w aplikacji, z niewielkimi odchyleniami. Na przykład: rozważmy aplikację do wyświetlania zasobów magazynowych, w której użytkownik może dodawać nowe elementy magazynowe do bazy danych. Kod aplikacji, który dodaje element magazynowy do bazy danych wykonuje instrukcję SQL INSERT, która w rzeczywistości dodaje dane do bazy danych. Jednak każde wykonanie instrukcji różni się nieznacznie od poprzedniego. Rzeczywiste wartości wprowadzane do tabeli są różne, ponieważ są właściwe dla pozycji magazynowej, która jest dodawana. W przypadku wielokrotnego korzystania z instrukcji SQL z różnymi wartościami najlepszym podejściem jest użycie instrukcji SQL, która zawiera parametry zamiast wartości literałowych w tekście SQL. Parametr jest elementem zastępczym w tekście instrukcji, który jest zastępowany rzeczywistą wartością przy każdym wykonaniu instrukcji. W celu korzystania z parametrów w instrukcji SQL należy utworzyć instancję SQLStatement w standardowy sposób. Dla rzeczywistej instrukcji SQL przypisanej do właściwości text należy użyć parametrów zamiast wartości literałowych. Następnie należy zdefiniować wartość dla każdego parametru poprzez ustawienie wartości elementu we właściwości parameters instancji SQLStatement. Właściwość parameters jest tablicą asocjacyjną, dlatego wartości należy ustawiać za pomocą poniższej składni: statement.parameters[parameter_identifier] = value; parameter_identifier jest ciągiem znaków, jeśli używany jest parametr nazwany, lub wartością całkowitą, jeśli używany jest parametr nienazwany. Korzystanie z parametrów nazwanych Parametr może być parametrem nazwanym. Parametr nazwany ma konkretną nazwę, z której korzysta baza danych w celu dopasowania wartości parametru do odpowiedniego elementu zastępczego w tekście instrukcji. Nazwa parametru zawiera znak „:” lub „@”, po którym następuje nazwa, jak w poniższych przykładach: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 178 Praca z lokalnymi bazami danych SQL :itemName @firstName Poniższy fragment kodu prezentuje zastosowanie nazwanych parametrów: 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(); Korzystanie z parametrów nienazwanych Zamiast korzystania z parametrów nazwanych możliwe jest korzystanie z parametrów nienazwanych. W celu użycia parametru nienazwanego należy do instrukcji SQL wprowadzić znak „?”. Do każdego parametru przypisany zostaje indeks liczbowy zgodnie z kolejnością parametrów w instrukcji, począwszy od indeksu 0 dla pierwszego parametru. Poniższy przykład prezentuje wersję poprzedniego przykładu z parametrami nienazwanymi: 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(); Zalety stosowania parametrów Stosowanie parametrów w instrukcjach SQL zapewnia następujące korzyści: Lepsza wydajność Instancja SQLStatement, w której stosowane są parametry, może zostać wykonana szybciej niż instancja, która dynamicznie tworzy tekst SQL za każdym razem, gdy jest wykonywana. Wzrost wydajności jest spowodowany tym, że instrukcja SQL jest przygotowywana jeden raz i następnie może być wykonywana wielokrotnie przy wykorzystaniu różnych wartości parametrów, bez potrzeby ponownej kompilacji. Jawne określanie typów danych Parametry służą do zastępowania wartości, które nie są znane w momencie konstruowania instrukcji SQL, przez wartości określonego typu. Korzystanie z parametrów to jedyny sposób na to, aby zapewnić klasę zapisu dla wartości przekazanej do bazy danych. Jeśli parametry nie są używane, wówczas środowisko wykonawcze podejmuje próbę konwersji wszystkich wartości z reprezentacji tekstowej na klasę zapisu na podstawie powinowactwa typu skojarzonej kolumny. Więcej informacji na temat klas zapisu i powinowactwa kolumn zawiera sekcja „Obsługa typów danych“ w dodatku „Obsługa SQL w lokalnych bazach danych“ w dokumentacji Skorowidz języka i składników ActionScript 3.0. Większe bezpieczeństwo Korzystanie z parametrów uniemożliwia stosowanie złośliwych technik, takich jak atak SQL inject. W przypadku ataku SQL inject użytkownik wprowadza kod SQL do lokalizacji dostępnej dla użytkownika (np. do pola wprowadzania danych). Jeśli kod aplikacji konstruuje instrukcję SQL poprzez bezpośrednią konkatenację danych wprowadzonych przez użytkownika do postaci tekstu SQL, wówczas kod SQL wprowadzony przez użytkownika jest wykonywany dla bazy danych. Poniższa lista prezentuje przykład konkatenacji danych wprowadzonych przez użytkownika na tekst SQL. Ta technika nie powinna być stosowana: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 179 Praca z lokalnymi bazami danych SQL // 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; Korzystanie z parametrów instrukcji zamiast konkatenowania wartości wprowadzanych przez użytkownika na tekst instrukcji zapobiega atakom typu SQL inject. Atak SQL inject nie jest możliwy, ponieważ wartości parametrów są traktowane jawnie jako podstawiane wartości i nie stają się one częścią literalnego tekstu instrukcji. Poniżej przedstawiono zalecaną alternatywę dla poprzedniego przykładu: // 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; Pobieranie danych z bazy danych Pobieranie danych z bazy danych jest procesem dwuetapowym. Najpierw należy wykonać instrukcję SQL SELECT, opisując zestaw danych żądany z bazy danych. Następnie należy uzyskać dostęp do pobranych danych i wyświetlić lub zmodyfikować je zgodnie z potrzebami. Wykonywanie instrukcji SELECT W celu pobrania istniejących danych z bazy danych należy skorzystać z instancji SQLStatement. Przypisz odpowiednią instrukcję SQL SELECT do właściwości text instancji, a następnie wywołaj metodę execute() instancji. Szczegółowe informacje na temat składni instrukcji SELECT zawiera dodatek „Obsługa SQL w lokalnych bazach danych“ w dokumentacji Skorowidz języka i składników ActionScript 3.0. Poniższy przykład prezentuje wykonanie instrukcji SELECT w celu uzyskania danych z tabeli o nazwie „products” przy wykorzystaniu trybu wykonania asynchronicznego: 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(); Poniższy przykład prezentuje wykonanie instrukcji SELECT w celu uzyskania danych z tabeli o nazwie „products” przy wykorzystaniu trybu wykonania asynchronicznego: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 180 Praca z lokalnymi bazami danych SQL 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 } Gdy kończy się wykonanie instrukcji w trybie wykonywania asynchronicznego, instrukcja SQLStatement wywołuje zdarzenie result (SQLEvent.RESULT), co oznacza pomyślne wykonanie instrukcji. I odwrotnie — jeśli obiekt Responder zostanie przekazany jako argument w wywołaniu metody execute(), wówczas następuje wywołanie funkcji modułu obsługi obiektu Responder. W trybie wykonywania asynchronicznego wykonywanie zostaje wstrzymane do czasu zakończenia operacji execute() — następnie jest kontynuowane od kolejnego wiersza kodu. Dostęp do danych wynikowych instrukcji SELECT Po zakończeniu wykonywania instrukcji SELECT kolejnym krokiem jest uzyskanie dostępu do pobranych danych. Każdy wiersz danych w zestawie wynikowym SELECT staje się instancją Object. Ten obiekt zawiera właściwości, których nazwy są zgodne z nazwami kolumn w zestawie wynikowym. Właściwości zawierają wartości z kolumn zestawu wynikowego. Przykład: załóżmy, że instrukcja SELECT określa zestaw wynikowy z trzema kolumnami o nazwach „itemId”, „itemName” i „price”. Dla każdego wiersza w zestawie wynikowym tworzona jest instancja Object z właściwościami o nazwach itemId, itemName i price. Te właściwości zawierają wartości z odpowiadających im kolumn. Poniższy fragment kodu stanowi kontynuację poprzedniego przykładu — dotyczy pobierania danych w trybie wykonywania asynchronicznego. Prezentuje sposób dostępu do uzyskanych danych za pomocą metody detektora zdarzeń wynikowych. 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. } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 181 Praca z lokalnymi bazami danych SQL Poniższy fragment kodu stanowi rozwinięcie poprzedniego przykładu — dotyczy pobierania danych w trybie wykonywania synchronicznego. Rozwija blok try..catch z poprzedniego przykładu wykonania synchronicznego, prezentując sposób dostępu do uzyskanych danych. 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. } Zgodnie z poprzednim fragmentem kodu obiekty wynikowe znajdują się w tablicy, która jest dostępna jako właściwość data instancji SQLResult. Jeśli stosowany jest tryb wykonania asynchronicznego z detektorem zdarzenia, to wówczas w celu uzyskania instancji SQLResult można wywołać metodę getResult() instancji SQLStatement. Po określeniu argumentu Responder w wywołaniu execute() następuje przekazanie instancji SQLResult jako argumentu funkcji obsługi wyników. W trybie wykonania synchronicznego należy wywołać metodę getResult() instancji SQLStatement w dowolnym momencie po wywołaniu metody execute(). W każdym z tych przypadków po uzyskaniu obiektu SQLResult możliwe jest uzyskanie dostępu do wierszy wyników za pomocą właściwości tablicy data. Poniższy fragment kodu definiuje instancję SQLStatement, której tekst jest instrukcją SELECT. Instrukcja pobiera wiersze zawierające wartości kolumn firstName i lastName z wszystkich wierszy tabeli o nazwie employees. W tym przykładzie prezentowany jest tryb wykonania asynchronicznego. Po zakończeniu wykonywania następuje wywołanie metody selectResult(), a dostęp do wierszy wynikowych jest uzyskiwany za pomocą metody SQLStatement.getResult(). Dane wynikowe są wyświetlane za pomocą metody trace(). W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn, która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została utworzona i zapełniona danymi. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 182 Praca z lokalnymi bazami danych SQL 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); } Poniższy fragment kodu prezentuje techniki podobne do poprzedniego fragmentu, ale w tym fragmencie zastosowano tryb wykonania synchronicznego. W przykładzie zdefiniowano instancję SQLStatement, której tekst jest instrukcją SELECT. Instrukcja pobiera wiersze zawierające wartości kolumn firstName i lastName z wszystkich wierszy tabeli o nazwie employees. Dostęp do wierszy wynikowych jest uzyskiwany za pomocą metody SQLStatement.getResult(). Dane wynikowe są wyświetlane za pomocą metody trace(). W tym przykładzie przyjęto, że istnieje instancja SQLConnection o nazwie conn, która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została utworzona i zapełniona danymi. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 183 Praca z lokalnymi bazami danych SQL 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); } Definiowanie typu danych wynikowych instrukcji SELECT Domyślnie każdy wiersz zwracany przez instrukcję SELECT jest tworzony jako instancja Object z właściwościami o nazwach pochodzących z kolumny zestawu wynikowego oraz z wartościami każdej kolumny jako wartościami właściwości skojarzonej z każdą kolumną. Jednak przed wykonaniem instrukcji SQL SELECT można ustawić właściwość itemClass instancji SQLStatement na klasę. Na skutek ustawienia właściwości itemClass każdy wiersz zwracany przez instrukcję SELECT jest tworzony jako instancja wyznaczonej klasy. Środowisko wykonawcze przypisuje wartości kolumn wynikowych do wartości właściwości poprzez dopasowanie nazw kolumn z zestawu wynikowego SELECT z nazwami właściwości z klasy itemClass. Każda klasa przypisana jako wartość właściwości itemClass musi zawierać konstruktor, który nie wymaga żadnych parametrów. Ponadto klasa musi mieć pojedynczą właściwość dla każdej kolumny zwróconej przez instrukcję SELECT. Jeśli nazwie kolumny z listy SELECT nie odpowiada nazwa właściwości w klasie itemClass, jest to traktowane jako błąd. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 184 Praca z lokalnymi bazami danych SQL Uzyskiwanie wyników SELECT w częściach Domyślnie wykonanie instrukcji SELECT powoduje pobranie wszystkich wierszy w postaci zestawu wynikowego jednocześnie. Po wykonaniu instrukcji zwykle następuje przetworzenie danych wynikowych, np. tworzenie obiektów lub wyświetlanie danych na ekranie. Jeśli instrukcja zwróci dużą liczbę wierszy, przetwarzanie wszystkich danych jednocześnie może bardzo obciążać komputer, co może powodować problemy z odświeżaniem interfejsu użytkownika. Istnieje możliwość zwiększenia subiektywnej wydajności aplikacji poprzez zdefiniowanie instrukcji dla środowiska wykonawczego dotyczącej zwrócenia określonej liczby wierszy jednocześnie. Zdefiniowanie takiej instrukcji może spowodować szybsze zwrócenie pierwszego zestawu wynikowego. Umożliwia także podział wierszy wyników na zestawy, dzięki czemu interfejs użytkownika zostaje zaktualizowany po przetworzeniu każdego zestawu wierszy. Stosowanie tej techniki jest zalecane wyłącznie w przypadku trybu wykonania asynchronicznego. W celu uzyskania wyników instrukcji SELECT w częściach należy określić wartość pierwszego parametru metody SQLStatement.execute() (parametr prefetch). Parametr prefetch określa liczbę wierszy do pobrania przy pierwszym wykonaniu instrukcji. Po wywołaniu metody execute() klasy SQLStatement należy określić wartość parametru prefetch — ta wartość będzie określała liczbę wierszy do pobrania: 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 Instrukcja wywołuje zdarzenie result, co oznacza, że pierwszy zestaw wierszy wynikowych jest już dostępny. Wynikowa właściwość data klasy SQLResult zawiera wiersze danych, a właściwość complete wskazuje, czy istnieją dodatkowe wiersze do pobrania. W celu pobrania dodatkowych wierszy wyników należy wywołać metodę next() klasy SQLStatement. Pierwszy parametr metody next() — podobnie jak w przypadku metody execute() — określa liczbę wierszy pobieranych przy następnym wywołaniu zdarzenia result. 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); } } } Klasa SQLStatement wywołuje zdarzenie result za każdym razem, gdy metoda next() zwraca kolejny zestaw wierszy wynikowych. W konsekwencji ta sama funkcja detektora może służyć do dalszego przetwarzania wyników (wywołań metody next()) do czasu pobrania wszystkich wierszy. Więcej informacji zawiera skorowidz języka, a w nim opisy metody SQLStatement.execute() (opis parametru prefetch) oraz metody SQLStatement.next(). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 185 Praca z lokalnymi bazami danych SQL Wstawianie danych Pobieranie danych z bazy danych obejmuje wykonanie instrukcji SQL INSERT. Po zakończeniu wykonywania instrukcji można uzyskać dostęp do klucza podstawowego nowo wstawionego wiersza, pod warunkiem że klucz został wygenerowany przez bazę danych. Wykonywanie instrukcji INSERT W celu dodania danych do tabeli bazy danych należy utworzyć i uruchomić instancję klasy SQLStatement, której tekst będzie instrukcją SQL INSERT. W poniższym przykładzie wykorzystano instancję klasy SQLStatement w celu dodania wiersza danych do istniejącej tabeli employees. Przykład prezentuje wstawianie danych w trybie wykonywania asynchronicznego. W tym przykładzie przyjęto, że istnieje instancja klasy SQLConnection o nazwie conn, która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została już utworzona. 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); } W poniższym przykładzie przedstawiono dodawanie wiersza danych do istniejącej tabeli employees przy użyciu trybu wykonywania synchronicznego. W tym przykładzie przyjęto, że istnieje instancja klasy SQLConnection o nazwie conn, która jest już połączona z bazą danych. Założono również, że tabela „pracownicy” została już utworzona. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 186 Praca z lokalnymi bazami danych SQL 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); } Pobieranie wygenerowanego przez bazę danych klucza podstawowego wstawionego wiersza Często po wstawieniu wiersza danych do tabeli kod musi poznać klucz podstawowy wygenerowany przez bazę danych lub wartość identyfikatora wiersza dla nowo wstawionego wiersza. Na przykład: po wstawieniu wiersza do jednej tabeli możliwe jest dodanie wierszy do tabeli powiązanej. W takim przypadku konieczne może być wstawienie wartości klucza podstawowego jako klucza obcego do powiązanej tabeli. Klucz podstawowy nowo wstawionego wiersza można uzyskać za pomocą obiektu SQLResult wygenerowanego na skutek wykonania instrukcji. Jest to ten sam obiekt, który jest używany w celu uzyskania dostępu do danych wynikowych po wykonaniu instrukcji SELECT. Zakończenie wykonywania instrukcji INSERT — podobnie jak w przypadku każdej instrukcji SQL — powoduje utworzenie w środowisku wykonawczym instancji klasy SQLResult. Dostęp do instancji klasy SQLResult uzyskuje się poprzez wywołanie metody getResult() obiektu SQLStatement, pod warunkiem że używany jest detektor zdarzeń lub używany jest tryb wykonywania synchronicznego. Jeśli stosowany jest tryb wykonywania asynchronicznego, a instancja klasy Responder zostanie przekazana do wywołania execute(), wówczas instancja klasy SQLResult zostanie przekazana jako argument do funkcji obsługi wyników. W każdym z tych przypadków instancja klasy SQLResult ma właściwość lastInsertRowID, która zawiera identyfikator wiersza wstawionego jako ostatni, jeśli wykonana została instrukcja SQL INSERT. Poniższy przykład prezentuje dostęp do klucza podstawowego wstawionego wiersza w trybie wykonywania asynchronicznego: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 187 Praca z lokalnymi bazami danych SQL 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 } Poniższy przykład prezentuje dostęp do klucza podstawowego wstawionego wiersza w trybie wykonywania synchronicznego: 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 } Identyfikator wiersza może być wartością kolumny wyznaczonej jako kolumna klucza podstawowego w definicji tabeli, zgodnie z poniższą formułą: • Jeśli tabela jest zdefiniowana z kolumną klucza podstawowego, którego powinowactwo (typ danych kolumny) to INTEGER, wówczas właściwość lastInsertRowID zawiera wartość, która została wstawiona do wiersza (lub zawiera wartość wygenerowaną przez środowisko wykonawcze, jeśli jest to kolumna AUTOINCREMENT). • Jeśli tabela jest zdefiniowana z wieloma kolumnami klucza podstawowego (klucz złożony) lub z jedną kolumną klucza podstawowego o powinowactwie innym niż INTEGER, wówczas w tle baza danych generuje wartość identyfikatora dla wiersza. Ta wygenerowana wartość jest wartością właściwości lastInsertRowID. • Wartość jest zawsze identyfikatorem wiersza wstawionego jako ostatni. Jeśli instrukcja INSERT spowoduje uruchomienie wyzwalacza, który wstawi wiersz, wówczas właściwość lastInsertRowID będzie zawierała identyfikator ostatniego wiersza wstawionego przez wyzwalacz, a nie wiersza wstawionego przez instrukcję INSERT. W konsekwencji — jeśli wymagane jest jawne zdefiniowanie kolumny klucza podstawowego, którego wartość będzie dostępna po wykonaniu polecenia INSERT za pośrednictwem właściwości SQLResult.lastInsertRowID, wówczas kolumna musi być zdefiniowana jako kolumna INTEGER PRIMARY KEY. Nawet jeśli tabela nie zawiera jawnej kolumny INTEGER PRIMARY KEY, równie dobrze w roli klucza podstawowego dla tabeli można zastosować identyfikator wiersza wygenerowany przez bazę danych i nie będzie to miało wpływu na definiowanie relacji z powiązanymi tabelami. Wartość kolumny identyfikatora wiersza może być dostępna w dowolnej instrukcji SQL — w tym celu należy użyć jednej z nazw kolumn specjalnych: ROWID, _ROWID_ lub OID. W powiązanej tabeli można utworzyć kolumnę klucza obcego i użyć wartości identyfikatora wiersza jako wartości kolumny klucza obcego, tak jak w każdej jawnie zadeklarowanej kolumnie INTEGER PRIMARY KEY. W takim przypadku, jeśli używany jest dowolny klucz podstawowy a nie klucz naturalny i jeśli dozwolone jest wygenerowanie wartości klucza podstawowego przez środowisko wykonawcze, wówczas to, czy kluczem podstawowym tabeli służącym do definiowania relacji klucza obcego między dwiema tabelami będzie kolumna INTEGER PRIMARY KEY czy identyfikator wiersza wygenerowany przez system stanowi niewielką różnicę. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 188 Praca z lokalnymi bazami danych SQL Więcej informacji o kluczach podstawowych i wygenerowanych identyfikatorach wierszy zawierają sekcje „CREATE TABLE” oraz „Wyrażenia” w dodatku „Obsługa SQL w lokalnych bazach danych” w dokumentacji Skorowidz języka i składników ActionScript 3.0. Zmiana i usuwanie danych Proces wykonywania innych operacji na danych jest taki sam, jak proces używany do wykonywania instrukcji SQL SELECT lub INSERT. Należy po prostu wprowadzić inną instrukcję SQL do właściwości text instancji klasy SQLStatement: • W celu zmiany istniejących danych w tabeli należy użyć instrukcji UPDATE. • W celu usunięcia jednego lub większej liczby wierszy danych z tabeli należy użyć instrukcji DELETE. Opisy instrukcji zawiera dodatek „Obsługa SQL w lokalnych bazach danych” w dokumentacji Skorowidz języka i składników ActionScript 3.0. Praca z wieloma bazami danych Metoda SQLConnection.attach() służy do otwierania połączenia z dodatkową bazą danych w instancji klasy SQLConnection, która zawiera już otwartą bazę danych. Dołączonej bazie danych nadaje się nazwę za pomocą parametru name w metodzie attach(). W przypadku pisania instrukcji do manipulowania tą bazą danych można użyć tej nazwy w przedrostku (stosując formę database-name.table-name) w celu określenia nazw dowolnych tabel w instrukcjach SQL, co stanowi dla środowiska wykonawczego informację o tym, że tabelę można znaleźć w nazwanej bazie danych. Istnieje możliwość wykonania pojedynczej instrukcji SQL, która będzie zawierała tabele z wielu baz danych połączonych z jedną instancją klasy SQLConnection. Jeśli transakcja jest tworzona w instancji klasy SQLConnection, ta transakcja ma zastosowanie do wszystkich instrukcji SQL, które są wykonywane za pomocą instancji klasy SQLConnection. Taka zależność jest prawdziwa niezależnie od tego, na której dołączonej bazie danych działa instrukcja. Możliwe jest również utworzenie wielu instancji klasy SQLConnection w aplikacji, a każda z tych instancji będzie połączona z jedną lub wieloma bazami danych. Jeśli jednak używanych jest wiele połączeń z tą samą bazą danych, należy pamiętać o tym, że transakcja bazy danych nie jest współużytkowana w instancjach klasy SQLConnection. W konsekwencji: jeśli wiele instancji klasy SQLConnection zostanie połączonych z jedną bazą danych, nie można oczekiwać, że zmiany danych z wszystkich połączeń będą stosowane w określony sposób. Na przykład: jeśli dwie instrukcje UPDATE lub DELETE zostaną uruchomione dla tej samej bazy danych za pośrednictwem różnych instancji SQLConnection, a po wykonaniu jednej operacji wystąpi błąd aplikacji, wówczas dane w bazie danych mogą pozostać w stanie pośrednim, którego odwrócenie nie będzie możliwe, co może wpływać na integralność bazy danych (a w konsekwencji aplikacji). Obsługa błędów bazy danych W ogólnym przypadku obsługa błędów bazy danych przebiega tak samo, jak w przypadku błędu środowiska wykonawczego. Wymagane jest napisanie kodu, który będzie przygotowany na błędy, jakie mogą wystąpić, oraz należy reagować na błędy, a nie pozostawiać tego środowisku wykonawczemu. Ogólnie możliwe błędy bazy danych mogą zostać podzielone na trzy kategorie: błędy połączenia, błędy składni SQL, oraz błędy naruszenia ograniczeń. Błędy połączenia Większość błędów baz danych to błędy połączenia, które mogą występować w każdej operacji. Istnieją strategie zapobiegania błędom połączeń, jednak rzadko dostępny jest prosty sposób odtwarzania po błędzie połączenia, gdy baza danych jest newralgiczną częścią aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 189 Praca z lokalnymi bazami danych SQL Większość błędów połączeń dotyczy sposobu oddziaływania środowiska wykonawczego z systemem operacyjnym, systemem plików i plikiem bazy danych. Na przykład: błąd połączenia występuje wówczas, gdy użytkownik nie ma uprawnienia do utworzenia pliku bazy danych w określonej lokalizacji w systemie plików. Poniższe strategie umożliwiają zapobieganie błędom połączeń: Korzystanie z osobnych plików bazy danych dla poszczególnych użytkowników Zamiast pojedynczego pliku bazy danych dla wszystkich użytkowników, którzy korzystają z aplikacji na pojedynczym komputerze, należy wyznaczyć dla każdego użytkownika osobny plik bazy danych. Plik należy zlokalizować w katalogu skojarzonym z kontem użytkownika. Na przykład: plik może znajdować się w katalogu zapisu aplikacji, w folderze dokumentów użytkownika, na pulpicie itp. Użytkownicy innych typów Aplikację należy przetestować z różnymi typami kont użytkowników na różnych systemach operacyjnych. Nie należy zakładać, że użytkownik ma uprawnienia administratora w komputerze. Ponadto nie należy przyjmować, że osoba, która zainstalowała aplikację to użytkownik, który korzysta z tej aplikacji. Różne lokalizacje plików Jeśli użytkownik ma możliwość określenia lokalizacji zapisu pliku bazy danych lub wyboru pliku do otwarcia, należy rozważyć różne lokalizacje plików, z których użytkownik będzie mógł korzystać. Ponadto należy rozważyć zdefiniowanie ograniczeń dotyczących miejsca zapisu (oraz miejsca otwierania) plików bazy danych. Na przykład: użytkownicy mogą mieć prawo do otwierania plików, które znajdują się w lokalizacji zapisu dla konta użytkownika. Jeśli wystąpi błąd połączenia, najprawdopodobniej wystąpi przy pierwszej próbie utworzenia lub otwarcia bazy danych. Oznacza to, że użytkownik nie może wykonać żadnych operacji dotyczących bazy danych w aplikacji. W przypadku określonych typów błędów, takich jak błędy dotyczące uprawnień i praw odczytu, jedną możliwą techniką odtworzenia jest skopiowanie pliku bazy danych do innej lokalizacji. Aplikacja może skopiować plik bazy danych do innej lokalizacji, w której użytkownik ma uprawnienia do tworzenia i zapisywania w plikach — wówczas należy korzystać z tej lokalizacji. Błędy składni Błąd składni występuje wówczas, gdy instrukcja SQL jest sformatowana niepoprawnie, a aplikacja podejmuje próbę wykonania instrukcji. Instrukcje SQL lokalnej bazy danych są tworzone jako ciągi znaków, dlatego kontrola składni SQL w czasie kompilacji nie jest możliwa. W celu sprawdzenia składni instrukcji SQL należy wykonać te instrukcje. Poniższe strategie umożliwiają zapobieganie błędom składni SQL: Dokładne testowanie wszystkich instrukcji SQL Jeśli jest to możliwe, podczas programowania aplikacji należy osobno testować instrukcje SQL przed umieszczeniem ich jako tekstu instrukcji w kodzie aplikacji. Ponadto należy stosować podejście testowania kodu, takie jak testowanie jednostek, w celu utworzenia zestawu testów, które będą sprawdzały każdą możliwą opcję i wariant w kodzie. Stosowanie parametrów instrukcji i unikanie konkatenacji (dynamiczne generowanie) SQL Stosowanie parametrów i unikanie dynamicznie tworzonych instrukcji SQL oznacza, że ten sam tekst instrukcji SQL będzie używany przy każdym wykonaniu instrukcji. W konsekwencji znacznie łatwiej jest testować własne instrukcje i ograniczać możliwe warianty. Jeśli konieczne jest dynamiczne wygenerowanie instrukcji SQL, należy zminimalizować ilość sekcji generowanych dynamicznie. Ponadto należy uważnie sprawdzać poprawność danych wprowadzanych przez użytkownika, aby upewnić się, że dane nie spowodują błędu składni. W celu odtworzenia po błędzie składni w aplikacji wymagana jest złożona logika, która będzie badała instrukcje SQL i naprawiała składnię. Na skutek przestrzegania powyższych instrukcji zapobiegania błędom składni kod będzie mógł identyfikować potencjalne błędy składni SQL (np. dane wprowadzone przez użytkownika użyte w instrukcji). W celu odtworzenia po błędzie składni należy pomóc użytkownikowi. Należy wskazać elementy do poprawy w celu poprawnego wykonania instrukcji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 190 Praca z lokalnymi bazami danych SQL Błędy naruszenia ograniczeń Błąd naruszenia ograniczenia występuje wówczas, gdy instrukcja INSERT lub UPDATE podejmuje próbę dodania danych do kolumny. Ten błąd występuje wówczas, gdy nowe dane naruszają jedno ze zdefiniowanych ograniczeń dla tabeli lub kolumny. Zestaw możliwych ograniczeń obejmuje: Ograniczenie unikalności Określa, że jedna kolumna nie może zawierać zduplikowanych wartości (we wszystkich wierszach tabeli). I odwrotnie — jeśli wiele kolumn jest połączonych ograniczeniem unikalności, wówczas kombinacja wartości z tych kolumn nie może być duplikowana. Innymi słowy: w przypadku unikalnej kolumny lub kolumn każdy wiersz musi być inny. Ograniczenie klucza podstawowego W przypadku danych, na które ograniczenie zezwala i na które nie zezwala, ograniczenie klucza podstawowego jest takie samo, jak ograniczenie unikalności. Ograniczenie „Not Null” Określa, że kolumna nie może zawierać wartości NULL, co oznacza, że każdy wiersz kolumny musi zawierać wartość. Ograniczenie Check Umożliwia określenie dowolnego ograniczenia dla jednej lub większej liczby tabel. Popularnym ograniczeniem Check jest reguła określająca, że wartość kolumny musi należeć do określonego zakresu (np. że wartość w kolumnie liczbowej musi być większa od 0). Inny typ ograniczenia Check określa relacje między wartościami kolumn (np. wartość kolumny musi być różna od wartości w innej kolumnie, w tym samym wierszu). Ograniczenie typu danych (powinowactwo kolumny) Środowisko wykonawcze wymusza typ danych dla wartości kolumn, a próba zapisania w kolumnie wartości innego typu powoduje błąd. Jednak w wielu warunkach wartości są konwertowane w taki sposób, aby były zgodne z typem danych zadeklarowanym dla kolumny. Więcej informacji zawiera sekcja „Praca z typami danych w bazie danych” na stronie 191. Środowisko wykonawcze nie narzuca ograniczeń na wartości kluczy obcych. Innymi słowy — wartości kluczy obcych nie muszą być zgodne z istniejącą wartością klucza podstawowego. Oprócz predefiniowanych typów ograniczeń mechanizm środowiska wykonawczego SQL obsługuje wyzwalacze. Wyzwalacz jest podobny do modułu obsługi zdarzeń. Jest to predefiniowany zestaw instrukcji, które są wykonywane w przypadku wystąpienia określonej operacji. Na przykład: możliwe jest zdefiniowanie wyzwalacza, który będzie działał wówczas, gdy dane zostaną wstawione lub usunięte z określonej tabeli. Jednym z możliwych zastosowań wyzwalacza jest sprawdzanie zmian danych i wywoływanie błędu w przypadku niespełnienia określonych warunków. Dzięki temu wyzwalacz może służyć temu samemu celowi, co ograniczenie, a strategie zapobiegania błędom i odtwarzania po błędach przekroczenia ograniczeń będą również miały zastosowanie do błędów wygenerowanych przez wyzwalacze. Jednak identyfikator błędu wygenerowanego przez wyzwalacz jest inny niż identyfikator błędu przekroczenia ograniczeń. Zestaw ograniczeń, który ma zastosowanie do określonej tabeli, jest określony podczas projektowania aplikacji. Świadome projektowanie ograniczeń ułatwia projektowanie aplikacji w taki sposób, aby zapobiegać błędom i odtwarzać po wystąpieniu błędów przekroczenia ograniczeń. Jednak przewidywanie i zapobieganie błędom przekroczenia ograniczeń jest trudne. Przewidywanie jest trudne, ponieważ błędy przekroczenia ograniczeń nie pojawiają się do czasu dodania danych aplikacji. Błędy naruszania ograniczeń występują w przypadku dodawania danych do bazy danych po jej utworzeniu. Te błędy często wynikają z relacji między nowymi danymi a danymi, które istnieją w bazie danych. Poniższe strategie umożliwiają zapobieganie wielu błędom ograniczeń: Uważne planowanie struktury i ograniczeń bazy danych Celem ograniczeń jest wymuszanie stosowania reguł aplikacji oraz ochrona integralności danych w bazie danych. Podczas planowania aplikacji należy rozważyć, strukturę bazy danych, która będzie obsługiwała aplikację. W ramach tego procesu należy określić reguły dla danych, np. to, czy niektóre wartości są wymagane, czy istnieje wartość domyślna, czy dozwolone są duplikaty wartości itp. Te reguły ułatwiają definiowanie ograniczeń dla bazy danych. Jawne określanie nazw kolumn Instrukcję INSERT można napisać bez jawnego określania kolumn, do których wprowadzane będą wartości, ale takie postępowanie wiąże się ze zbędnym ryzykiem. Jawne nazywanie kolumn, do TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 191 Praca z lokalnymi bazami danych SQL których będą wprowadzane wartości, umożliwia automatyczne generowanie wartości, kolumn z wartościami domyślnymi oraz kolumn, które mogą zawierać wartości NULL. Ponadto takie postępowanie gwarantuje, że do wszystkich kolumn NOT NULL wprowadzane będą jawne wartości. Korzystanie z wartości domyślnych Jeśli jest to możliwe, wówczas przy każdej okazji określania ograniczenia NOT NULL dla kolumny należy określić domyślną wartość w definicji kolumny. Kod aplikacji może również określać wartości domyślne. Na przykład: kod może sprawdzać, czy zmienna String ma wartość null, a także przypisywać wartość przed użyciem jej w celu ustawienia wartości parametru instrukcji. Sprawdzanie poprawności danych wprowadzanych przez użytkownika Dane wprowadzane przez użytkownika należy sprawdzać z wyprzedzeniem, aby zapewnić zgodność tych danych z limitami określonymi przez ograniczenia, szczególnie w przypadku ograniczeń NOT NULL i CHECK. Oczywiście sprawdzenie ograniczenia UNIQUE jest trudniejsze, ponieważ w celu sprawdzenia należałoby wykonać zapytanie SELECT aby określić, czy dane są unikalne. Stosowanie wyzwalaczy Istnieje możliwość napisania wyzwalacza, który będzie sprawdzał poprawność (a w razie możliwości zastępował) wprowadzone dane lub będzie wykonywał inne czynności w celu poprawienia niepoprawnych danych. Ten sposób sprawdzania poprawności i poprawiania może zapobiegać występowaniu błędów naruszania ograniczeń. W wielu przypadkach zapobieganie błędom naruszania ograniczeń jest dużo trudniejsze niż zapobieganie innym błędom. Na szczęście istnieje kilka strategii odtwarzania po wystąpieniu błędów naruszenia ograniczenia — strategie te obejmują sposoby, które nie powodują niestabilności aplikacji i nie powodują, że aplikacja staje się nie do użycia: Stosowanie algorytmów konfliktów Po zdefiniowaniu ograniczenia dla kolumny oraz utworzeniu instrukcji INSERT lub UPDATE istnieje możliwość określenia algorytmu konfliktu. Algorytm konfliktu definiuje operację, jaką wykonuje baza danych, gdy dojdzie do naruszenia ograniczenia. Istnieje kilka możliwych operacji, jakie może wykonać mechanizm bazy danych. Mechanizm bazy danych może zakończyć pojedynczą instrukcję lub całą transakcję. Może zignorować błąd. Może nawet usunąć stare dane i zastąpić je danymi, które kod próbuje zapisać. Więcej informacji zawiera sekcja „ ON CONFLICT (algorytmy konfliktów)” w dodatku „Obsługa SQL w lokalnych bazach danych” w dokumentacji Skorowidz języka i składników ActionScript 3.0. Udostępnianie informacji zwrotnych na temat korekt Zestaw ograniczeń, które mogą wpływać na określone polecenie SQL należy zidentyfikować z wyprzedzeniem. Dzięki temu możliwe jest przewidywanie błędów naruszenia ograniczeń, które może wywołać instrukcja. Dzięki tej wiedzy możliwe jest przygotowanie logiki aplikacji, która będzie reagowała na błąd naruszenia ograniczenia. Na przykład: załóżmy, że aplikacja zawiera formularz wprowadzania danych przeznaczony do wprowadzania nowych produktów. Jeśli kolumna nazwy produktu w bazie danych jest zdefiniowana z ograniczeniem UNIQUE, wówczas operacja wprowadzania wiersza nowego produktu do bazy danych może spowodować błąd naruszenia ograniczenia. W takim przypadku należy zaprojektować aplikację w taki sposób, aby przewidywała błąd naruszenia ograniczenia. Gdy wystąpi błąd, aplikacja ostrzega użytkownika, informując o tym, że określona nazwa produktu jest już używana. Aplikacja informuje również o konieczności wybrania innej nazwy. Inną możliwą reakcją jest zezwolenie użytkownikowi na wyświetlenie informacji o innym produkcie, o takiej samej nazwie. Praca z typami danych w bazie danych Podczas tworzenia tabeli w bazie danych instrukcja SQL przeznaczona do utworzenia tabeli definiuje powinowactwo lub typ danych dla każdej kolumny w tabeli. Możliwe jest pominięcie deklaracji powinowactwa, jednak dobrym rozwiązaniem jest jawne zadeklarowanie powinowactwa kolumny w instrukcjach SQL CREATE TABLE. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 192 Praca z lokalnymi bazami danych SQL Zwykle obiekt zapisany w bazie danych za pomocą instrukcji INSERT jest zwracany jako instancja tego samego typu danych po wykonaniu instrukcji SELECT. Jednak typ danych pobranej wartości może być inny w zależności od powinowactwa kolumny bazy danych, w której zapisana jest wartość. Gdy wartość jest zapisana w kolumnie, a jej typ danych nie jest zgodny z powinowactwem kolumny, wówczas baza danych podejmuje próbę konwersji wartości w celu dopasowania jej do powinowactwa kolumny. Na przykład: jeśli kolumna bazy danych jest zadeklarowana z powinowactwem NUMERIC, wówczas baza danych podejmuje próbę konwersji wstawionych danych na klasę zapisu liczb (INTEGER lub REAL) przed zapisaniem danych. Baza danych zgłasza błąd, jeśli nie ma możliwości konwersji danych. Zgodnie z tą regułą: jeśli ciąg znaków „12345” zostanie wstawiony do kolumny NUMERIC, wówczas przed zapisaniem w bazie danych ciąg znaków zostanie automatycznie przekonwertowany na wartość całkowitą 12345. W przypadku pobrania za pomocą instrukcji SELECT wartość zostanie zwrócona jako instancja typu danych liczbowych (np. Number), a nie jako instancja String. Najlepszym sposobem uniknięcia niepożądanej konwersji danych jest przestrzeganie dwóch reguł. Po pierwsze: należy zdefiniować każdą kolumnę z powinowactwem, które jest zgodne z typem danych, jakie mają być zapisywane w tej kolumnie. Po drugie: należy wstawiać tylko wartości, których typ danych jest zgodny ze zdefiniowanym powinowactwem. Przestrzeganie tych zasad przynosi dwie korzyści. Wstawiane dane nie będą nieoczekiwanie konwertowane (co wiąże się z możliwością utraty znaczenia). Ponadto pobierane dane są zwracane w oryginalnym typie danych. Więcej informacji o dostępnych typach powinowactwa kolumn oraz o stosowaniu typów danych w instrukcjach SQL zawiera sekcja „Obsługa typów danych” w dodatku „Obsługa SQL w lokalnych bazach danych” w dokumentacji Skorowidz języka i składników ActionScript 3.0. Korzystanie z synchronicznych i asynchronicznych operacji bazy danych W poprzedniej sekcji opisano typowe operacje bazy danych, takie jak pobieranie, wstawianie, aktualizowanie i usuwanie danych, a także tworzenie pliku bazy danych oraz tabel i innych obiektów w bazie danych. W przykładach przedstawiono sposób wykonywania tych operacji w sposób asynchroniczny i synchroniczny. Przypomnijmy, że w trybie wykonywania asynchronicznego należy określić instrukcję dla mechanizmu bazy danych, który wykona operację. Następnie mechanizm bazy danych będzie działał w tle przez czas działania aplikacji. Po zakończeniu operacji mechanizm bazy danych wywoła zdarzenie, które poinformuje o tym fakcie. Najważniejszą zaletą wykonywania asynchronicznego jest to, że środowisko wykonawcze wykonuje operacje bazy danych w tle, podczas gdy wykonywany jest kod aplikacji. Jest to szczególnie istotne wówczas, gdy aplikacja działa przez znaczny czas. Z drugiej strony: w trybie wykonywania synchronicznego operacje nie działają w tle. Użytkownik zleca mechanizmowi bazy danych wykonanie operacji. Kod jest wstrzymywany na czas działania mechanizmu bazy danych. Gdy operacja zostanie zakończona, następuje wznowienie wykonywania kodu od kolejnej linii. W przypadku korzystania z pojedynczego połączenia z bazą danych nie ma możliwości wykonywania jednych operacji w sposób synchroniczny, a innych w sposób asynchroniczny. Po otwarciu połączenia z bazą danych należy określić, czy klasa SQLConnection działa w trybie synchronicznym lub asynchronicznym. Jeśli zostanie wywołana metoda SQLConnection.open(), połączenie działa w trybie wykonywania synchronicznego, a jeśli zostanie wywołana metoda SQLConnection.openAsync(), wówczas połączenie działa w trybie wykonywania asynchronicznego. Gdy instancja SQLConnection zostanie połączona z bazą danych za pomocą metody open() lub openAsync(), zostaje przypisana do trybu wykonywania synchronicznego lub asynchronicznego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 193 Praca z lokalnymi bazami danych SQL Korzystanie z synchronicznych operacji bazy danych Różnica między kodem używanym do wykonywania i reagowania na operacje w trybie synchronicznym a kodem używanym w trybie asynchronicznym jest niewielka. Główne różnice między tymi podejściami są następujące. Pierwszą jest wykonywanie operacji, która jest uzależniona od innej operacji (np. wiersze wynikowe instrukcji SELECT lub klucz podstawowy wiersza dodawanego przez instrukcję INSERT). Drugą jest różnica w obsługiwaniu błędów. Pisanie kodu operacji synchronicznych Główną różnicą między wykonaniem synchronicznym i asynchronicznym jest to, że w trybie synchronicznym kod jest pisany jako seria kroków. W przypadku kodu asynchronicznego rejestrowane są detektory zdarzeń, a operacje często są rozdzielane między metody detektorów. Jeśli baza danych jest podłączana w trybie wykonywania synchronicznego, wówczas możliwe jest wykonanie kolejno serii operacji bazy danych za pomocą jednego bloku kodu. Poniższy przykład demonstruje tę technikę: 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(); Jak widać, te same metody są wywoływane w celu wykonania operacji bazy danych w trybie synchronicznym oraz asynchronicznym. Głównymi różnicami między tymi dwoma podejściami jest wykonywanie operacji, która jest uzależniona od innej operacji, a także obsługa błędów. Wykonywanie operacji, która jest uzależniona od innej operacji Jeśli używany jest tryb wykonywania synchronicznego, nie ma potrzeby pisania kodu, który będzie wykrywał zdarzenie w celu określenia, czy operacja została zakończona. Zamiast tego można przyjąć, że jeśli operacja w jednej linii kodu zakończy się pomyślnie, wykonywanie będzie kontynuowane od kolejnej linii kodu. W rezultacie w celu wykonania operacji, która jest uzależniona od powodzenia innej operacji, należy po prostu napisać zależny kod, który zostanie wykonany bezpośrednio po operacji, od której jest zależny. Na przykład: w celu zakodowania aplikacji w taki sposób, aby rozpoczęła transakcję, należy wykonać instrukcję INSERT, pobrać klucz podstawowy wstawionego wiersza, wstawić klucz podstawowy do innego wiersza w innej tabeli, a na koniec wykonać transakcję — kod można zapisać w postaci serii instrukcji. Poniższy przykład demonstruje te operacje: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 194 Praca z lokalnymi bazami danych SQL 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(); Obsługa błędów w wykonywaniu synchronicznym W trybie wykonywania synchronicznego nie ma potrzeby wykrywania zdarzenia błędu w celu określenia, czy operacja się nie powiodła. Zamiast tego należy otoczyć każdy kod, który może powodować błędy w zestawie bloków kodu try..catch..finally. Kod powodujący błędy należy umieścić w bloku try. Operacje, jakie powinny być wykonywane w odpowiedzi na każdy typ błędu należy zapisać w osobnych blokach catch. Każdy kod, który ma być wykonywany bez względu na powodzenie lub niepowodzenie (np. zamknięcie połączenia z bazą danych, które nie jest już wymagane) należy umieścić w bloku finally. W poniższym przykładzie zaprezentowano zastosowanie bloków try..catch..finally dla obsługi błędów. W tym przykładzie wykorzystano poprzedni przykład oraz dodano kod obsługi błędów: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 195 Praca z lokalnymi bazami danych SQL 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(); } Wyjaśnienie modelu wykonywania asynchronicznego Typowym zagadnieniem korzystania z trybu wykonywania asynchronicznego jest to, że nie ma możliwości uruchomienia instancji SQLStatement, jeśli wykonywana jest inna instancja klasy SQLStatement dla tego samego połączenia z bazą danych. W rzeczywistości założenie takiego działania jest niepoprawne. Podczas działania instancji klasy SQLStatement nie ma możliwości zmiany właściwości text instrukcji. Jeśli jednak używana jest osobna instancja klasy SQLStatement dla każdej innej instrukcji SQL, która ma zostać wykonana, wówczas należy wywołać metodę execute() klasy SQLStatement podczas wykonywania innej instancji SQLStatement i nie spowoduje to błędu. Podczas wykonywania operacji na bazie danych przy użyciu trybu wykonywania asynchronicznego każde połączenie z bazą danych (każda instancja SQLConnection) ma własną kolejkę lub listę operacji, które ma wykonywać. Środowisko wykonawcze wykonuje operacje w kolejności, w jakiej są dodawane do kolejki. Po utworzeniu instancji klasy SQLStatement i wywołaniu jej metody execute() ta operacja wykonania instrukcji zostaje dodana do kolejki połączenia. Jeśli żadna operacja nie jest aktualnie wykonywana na instancji klasy SQLConnection, wówczas wykonanie instrukcji rozpoczyna się w tle. Załóżmy, że w jednym bloku kodu utworzona zostaje inna instancja klasy TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 196 Praca z lokalnymi bazami danych SQL SQLStatement, a ponadto zostaje wywołana metoda execute() tej metody. Operacja wykonania drugiej instrukcji zostanie dodana do kolejki po pierwszej instrukcji. Gdy zakończy się wykonywanie pierwszej instrukcji, środowisko wykonawcze przechodzi do kolejnej operacji w kolejce. Przetwarzanie kolejnych operacji w kolejce odbywa się w tle, nawet jeśli zdarzenie result dla pierwszej operacji zostanie wywołane w głównym kodzie aplikacji. Poniższy kod prezentuje tę technikę: // 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. Istnienie istotny skutek automatycznego wykonywania przez bazę danych kolejnych instrukcji z kolejki. Jeśli instrukcja jest uzależniona od wyniku innej operacji, instrukcji nie można dodać do kolejki (innymi słowy: nie można wywołać jej metody execute()) do czasu zakończenia pierwszej operacji. Dzieje się tak, ponieważ po wywołaniu metody execute() drugiej instrukcji nie można zmienić właściwości text ani parameters instrukcji. W takim przypadku należy oczekiwać na zdarzenie wskazujące zakończenie pierwszej operacji — dopiero wówczas można uruchomić kolejną operację. Na przykład: jeśli wymagane jest wykonanie instrukcji w kontekście transakcji, instrukcja jest uzależniona od operacji otwarcia transakcji. Po wywołaniu metody SQLConnection.begin() w celu otwarcia transakcji należy odczekać, aż instancja klasy SQLConnection wywoła zdarzenie begin. Tylko wówczas można wywołać metodę execute() instancji klasy SQLStatement. W tym przykładzie najprostszym sposobem na zorganizowanie aplikacji w celu zapewnienia, że operacje są wykonywane poprawnie, jest utworzenie metody, która zostanie zarejestrowana jako detektor zdarzenia begin. Kod metody SQLStatement.execute() zostanie umieszczony w metodzie detektora. Korzystanie z szyfrowania w bazach danych SQL Wszystkie aplikacje Adobe AIR współużytkują ten sam lokalny mechanizm bazy danych. Dlatego każda aplikacja AIR może połączyć się z niezaszyfrowanym plikiem bazy danych oraz odczytywać i zapisywać w nim dane. Począwszy od wersji 1.5 środowisko Adobe AIR oferuje możliwość tworzenia zaszyfrowanych plików baz danych i łączenia się z takimi plikami. Aby połączyć się z zaszyfrowaną bazą danych, aplikacja musi podać prawidłowy klucz szyfrowania. Jeśli nie zostanie podany prawidłowy klucz szyfrowania (lub nie zostanie podany żaden klucz), aplikacja nie będzie mogła połączyć się z bazą. W takiej sytuacji aplikacja nie będzie mogła odczytywać danych z bazy ani zapisywać bądź zmieniać w niej danych. Aby korzystać z szyfrowanej bazy danych, należy utworzyć bazę jako zaszyfrowaną. Gdy zaszyfrowana baza danych będzie już istniała, możliwe będzie nawiązanie z nią połączenia. Można również zmienić klucz szyfrowania zaszyfrowanej bazy danych. Techniki pracy z zaszyfrowanymi bazami danych — z wyjątkiem operacji tworzenia takich baz i łączenia się z nimi — są takie same, jak w przypadku baz niezaszyfrowanych. W szczególności instrukcje SQL wykonywane są tak samo niezależnie od tego, czy baza danych jest zaszyfrowana. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 197 Praca z lokalnymi bazami danych SQL Zastosowania zaszyfrowanej bazy danych Szyfrowanie jest przydatne w sytuacjach, gdy chcemy ograniczyć dostęp do informacji przechowywanych w bazie danych. Funkcja szyfrowania baz danych oferowana przez środowisko Adobe AIR może być używana w kilku różnych celach. Poniżej przedstawiono przykłady sytuacji, w których celowe mogłoby okazać się użycie zaszyfrowanej bazy danych. • Przeznaczona tylko do odczytu pamięć podręczna na prywatne dane aplikacji pobrane z serwera. • Lokalny magazyn aplikacji przeznaczony na dane prywatne i synchronizowane z serwerem (dane są wysyłane do serwera i z niego ładowane). • Pliki zaszyfrowane jako format dokumentów tworzonych i edytowanych przez aplikację. Pliki mogą być prywatnymi plikami jednego użytkownika lub współużytkowane przez wszystkich użytkowników aplikacji. • Wszelkie inne zastosowania lokalnego magazynu danych, takie jak opisane w sekcji „Zastosowania lokalnych baz danych SQL” na stronie 167, gdy dane muszą być niedostępne dla osób mających dostęp do komputera lub plików bazy danych. Prawidłowe zdefiniowanie powodu, dla którego chcemy korzystać z zaszyfrowanej bazy danych, pomaga w podjęciu decyzji co do architektury aplikacji. W szczególności może mieć wpływ na sposób tworzenia, uzyskiwania lub przechowywania klucza szyfrowania dla bazy danych. Więcej informacji na temat tych zagadnień zawiera sekcja „Uwarunkowania szyfrowania bazy danych” na stronie 201. Alternatywnym dla bazy danych mechanizmem zapewnienia poufności danych jest użycie zaszyfrowanego magazynu lokalnego. Zaszyfrowany magazyn lokalny umożliwia przechowywanie pojedynczej wartości ByteArray przy użyciu klucza typu String. Dostęp do takiej wartości ma tylko ta aplikacja AIR, która ją zapisała, i tylko na komputerze, na którym wartość jest przechowywana. W przypadku zaszyfrowanego magazynu lokalnego nie ma potrzeby tworzenia własnego klucza szyfrowania. Z tego względu zaszyfrowany magazyn lokalny jest najprostszym mechanizmem przechowywania pojedynczej wartości lub zestawu wartości, które można w prosty sposób zakodować w obiekcie ByteArray. Zaszyfrowana baza danych najlepiej nadaje się do przechowywania większych zestawów danych, gdy pożądane jest przechowywanie danych w postaci strukturyzowanej i możliwość kierowania zapytań do bazy danych. Więcej informacji na temat korzystania z zaszyfrowanego magazynu lokalnego zawiera sekcja „Przechowywanie danych zaszyfrowanych” na stronie 217. Tworzenie zaszyfrowanej bazy danych Aby skorzystać z szyfrowania bazy danych, plik bazy danych należy zaszyfrować już na etapie jego tworzenia. Bazy danych utworzonej jako niezaszyfrowanej nie można później zaszyfrować. Podobnie, zaszyfrowanej bazy danych nie można później przekształcić w niezaszyfrowaną. W razie potrzeby można zmienić klucz szyfrowania zaszyfrowanej bazy danych. Szczegółowe informacje zawiera sekcja „Zmiana klucza szyfrowania bazy danych” na stronie 200. Jeśli istnieje już niezaszyfrowana baza danych, a chcemy skorzystać z szyfrowania bazy danych, można utworzyć nową zaszyfrowaną bazę danych i kopiować istniejącą strukturę tabel oraz dane do nowej bazy danych. Tworzenie zaszyfrowanej bazy danych odbywa się niemal identycznie jak tworzenie niezaszyfrowanej bazy danych, co opisano w sekcji „Tworzenie bazy danych” na stronie 171. Najpierw tworzymy instancję klasy SQLConnection reprezentującą połączenie z bazą danych. Bazę danych można utworzyć, wywołując metodę open() lub metodę openAsync() obiektu SQLConnection, jako lokalizację bazy danych wskazując plik, który jeszcze nie istnieje. Jedyna różnica występująca przy tworzeniu zaszyfrowanej bazy danych polega na konieczności podania wartości parametru encryptionKey (piątego parametru metody open() i szóstego parametru metody openAsync()). Poprawną wartością parametru encryptionKey jest obiekt ByteArray zawierający dokładnie 16 bajtów. W poniższym przykładzie zademonstrowano tworzenie zaszyfrowanej bazy danych otwieranej w trybie wykonywania asynchronicznego. W celu uproszczenia przykładu klucz szyfrowania został zapisany na stałe w kodzie aplikacji. Jednak w rzeczywistych zastosowaniach nie zaleca się stosowania tego rozwiązania, ponieważ nie jest ono bezpieczne. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 198 Praca z lokalnymi bazami danych SQL 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); } W poniższym przykładzie zademonstrowano tworzenie zaszyfrowanej bazy danych otwieranej w trybie wykonywania synchronicznego. W celu uproszczenia przykładu klucz szyfrowania został zapisany na stałe w kodzie aplikacji. Jednak w rzeczywistych zastosowaniach nie zaleca się stosowania tego rozwiązania, ponieważ nie jest ono bezpieczne. 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); } Przykład demonstrujący zalecany sposób generowania klucza szyfrowania zawiera sekcja „Przykład: Generowanie i używanie klucza szyfrowania” na stronie 202. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 199 Praca z lokalnymi bazami danych SQL Nawiązywanie połączenia z zaszyfrowaną bazą danych Podobnie jak w przypadku tworzenia zaszyfrowanej bazy danych, procedura otwierania połączenia z zaszyfrowaną bazą danych jest podobna do otwierania połączenia z bazą niezaszyfrowaną. Procedurę tę opisano bardziej szczegółowo w sekcji „Połączenie z bazą danych” na stronie 174. Należy użyć metody open() w celu otwarcia połączenia w trybie wykonywania synchronicznego lub metody openAsync() w celu otwarcia połączenia w trybie wykonywania asynchronicznego. Jedyna różnica polega na tym, że aby utworzyć zaszyfrowaną bazę danych, należy podać prawidłową wartość parametru encryptionKey (piątego parametru metody open() i szóstego parametru metody openAsync()). Jeśli podany klucz szyfrowania nie jest prawidłowy, zgłaszany jest błąd. W przypadku metody open() generowany jest wyjątek SQLError. W przypadku metody openAsync() obiekt SQLConnection wywołuje zdarzenie SQLErrorEvent, którego właściwość error zawiera obiekt SQLError. W obu przypadkach obiekt SQLError wygenerowany przez wyjątek ma właściwość errorID równą 3138. Ten identyfikator błędu odpowiada komunikatowi „Otwarty plik nie jest plikiem bazy danych”. Poniższy przykład ilustruje otwieranie zaszyfrowanej bazy danych w trybie wykonywania asynchronicznego. W celu uproszczenia przykładu klucz szyfrowania został zapisany na stałe w kodzie aplikacji. Jednak w rzeczywistych zastosowaniach nie zaleca się stosowania tego rozwiązania, ponieważ nie jest ono bezpieczne. 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); } } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 200 Praca z lokalnymi bazami danych SQL Poniższy przykład ilustruje otwieranie zaszyfrowanej bazy danych w trybie wykonywania synchronicznego. W celu uproszczenia przykładu klucz szyfrowania został zapisany na stałe w kodzie aplikacji. Jednak w rzeczywistych zastosowaniach nie zaleca się stosowania tego rozwiązania, ponieważ nie jest ono bezpieczne. 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); } } Przykład demonstrujący zalecany sposób generowania klucza szyfrowania zawiera sekcja „Przykład: Generowanie i używanie klucza szyfrowania” na stronie 202. Zmiana klucza szyfrowania bazy danych Klucz zaszyfrowanej bazy danych można zmienić już po jej utworzeniu. Aby zmienić klucz szyfrowania bazy danych, należy najpierw otworzyć połączenie z bazą danych, tworząc instancję klasy SQLConnection i wywołując jej metodę open() lub openAsync(). Po nawiązaniu połączenia z bazą danych należy wywołać metodę reencrypt(), przekazując jako jej argument nowy klucz szyfrowania. Podobnie jak w przypadku większości operacji na bazie danych, działanie metody reencrypt() jest różne w zależności od tego, czy połączenie z bazą danych jest nawiązane w trybie wykonywania synchronicznego, czy asynchronicznego. Jeśli do połączenia z bazą danych użyto metody open(), operacja reencrypt() działa asynchronicznie. Gdy operacja zostanie zakończona, następuje wznowienie wykonywania kodu od kolejnego wiersza: var newKey:ByteArray = new ByteArray(); // ... generate the new key and store it in newKey conn.reencrypt(newKey); Natomiast jeśli połączenie z bazą danych zostało otwarte przy użyciu metody openAsync(), operacja reencrypt() jest asynchroniczna. Wywołanie metody reencrypt() rozpoczyna proces ponownego szyfrowania. Po zakończeniu operacji obiekt SQLConnection wywołuje zdarzenie reencrypt. W celu wykrycia zakończenia operacji ponownego szyfrowania należy skorzystać z detektora zdarzeń: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 201 Praca z lokalnymi bazami danych SQL 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 } Operacja reencrypt() działa w ramach swojej własnej transakcji. Jeśli zostanie przerwana lub zakończy się niepowodzeniem (na przykład aplikacja zostanie zamknięta przed ukończeniem operacji), transakcja jest wycofywana. W takim wypadku w bazie danych nadal obowiązuje dotychczasowy klucz szyfrowania. Metoda reencrypt() nie umożliwia przekształcenie bazy danych w niezaszyfrowaną. Przekazanie do metody reencrypt()klucza szyfrowania o wartości null lub niebędącego 16-bajtowym obiektem ByteArray spowoduje błąd. Uwarunkowania szyfrowania bazy danych W sekcji „Zastosowania zaszyfrowanej bazy danych” na stronie 197 przedstawiono kilka przypadków, w których celowe byłoby użycie zaszyfrowanej bazy danych. Oczywiste jest, że w różnych zastosowaniach (przedstawionych oraz innych) obowiązują różne wymagania w zakresie poufności danych. Sposób włączenia mechanizmu szyfrowania do struktury aplikacji istotnie wpływa na skuteczność ochrony poufności danych w bazie. Na przykład, jeśli zaszyfrowana baza danych ma zapewniać poufność danych osobistych, nawet między różnymi użytkownikami tego samego komputera, to baza danych każdego użytkownika powinna mieć inny klucz szyfrowania. Aby uzyskać najwyższy poziom bezpieczeństwa, aplikacja może generować klucze na podstawie haseł wprowadzanych przez użytkowników. Powiązanie klucza szyfrowania z hasłem gwarantuje, że nawet jeśli inna osoba zdoła podszyć się pod konto użytkownika na komputerze, nadal nie będzie mieć dostępu do danych. Przeciwstawny skrajny przypadek to sytuacja, w której plik bazy danych powinien być czytelny dla wszystkich użytkowników naszej aplikacji, ale nie dla innych aplikacji. W takim przypadku każda zainstalowana kopia aplikacji musi mieć dostęp do współużytkowanego klucza szyfrowania. Budowę aplikacji, a w szczególności technikę generowania kluczy szyfrowania, można dopasować do wymaganego poziomu poufności danych aplikacji. Na poniższej liście przedstawiono propozycje rozwiązań odpowiadających różnym poziomom poufności danych: • Aby baza danych była dostępna dla każdego użytkownika mającego dostęp do aplikacji na dowolnym komputerze, należy użyć jednego klucza dostępnego dla wszystkich instancji aplikacji. Na przykład przy pierwszym uruchomieniu aplikacja może pobrać współużytkowany klucz szyfrowania z serwera, korzystając z bezpiecznego protokołu, np. SSL. Następnie aplikacja może zapisać klucz w szyfrowanym magazynie lokalnym i korzystać z niego w przyszłości. Alternatywnym rozwiązaniem jest szyfrowanie danych poszczególnych użytkowników na komputerze i synchronizowanie danych ze zdalnym magazynem danych, np. serwerem, w celu zapewnienia przenośności danych między komputerami. • Aby baza danych była dostępna dla jednego konkretnego użytkownika na dowolnym komputerze, należy wygenerować klucz szyfrowania na podstawie informacji znanej tylko użytkownikowi (np. hasła). W szczególności do generowania klucza nie należy używać wartości powiązanej z konkretnym komputerem (np. przechowywanej w szyfrowanym magazynie lokalnym). Alternatywnym rozwiązaniem jest szyfrowanie danych poszczególnych użytkowników na komputerze i synchronizowanie danych ze zdalnym magazynem danych, np. serwerem, w celu zapewnienia przenośności danych między komputerami. • Aby baza danych była dostępna tylko dla jednej konkretnej osoby na jednym konkretnym komputerze, należy wygenerować klucz na podstawie hasła i wygenerowanego modyfikatora. Zastosowanie tej techniki ilustruje „Przykład: Generowanie i używanie klucza szyfrowania” na stronie 202. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 202 Praca z lokalnymi bazami danych SQL Poniżej przedstawiono dodatkowe uwarunkowania dotyczące bezpieczeństwa, o których należy pamiętać, projektując aplikację korzystającą z zaszyfrowanej bazy danych. • System jest tylko tak bezpieczny, jak jego najsłabsze ogniwo. Jeśli klucz szyfrowania jest generowany na podstawie hasła wprowadzanego przez użytkownika, wskazane jest narzucenie minimalnej długości i złożoności hasła. Krótkie hasła składające się tylko z podstawowych znaków można szybko odgadnąć. • Kod źródłowy aplikacji AIR jest przechowywany na komputerze użytkownika w postaci zwykłego tekstu (w przypadku treści HTML) lub w formacie binarnym, który można jednak łatwo zdekompilować (w przypadku treści SWF). Ponieważ kod źródłowy jest dostępny, należy pamiętać o dwóch kwestiach: • Nigdy nie należy wpisywać klucza szyfrowania na stałe w kodzie aplikacji. • Należy zawsze zakładać, że osoba nieuprawniona będzie w stanie odtworzyć technikę użytą do wygenerowania klucza szyfrowania (np. generator liczb pseudolosowych lub konkretny algorytm mieszający). • W środowisku AIR do szyfrowania baz danych używany jest algorytm Advanced Encryption Standard (AES) z licznikiem w trybie CBC-MAC (CCM). Aby ten szyfr był bezpieczny, klucz wprowadzony przez użytkownika musi być połączony z wartością modyfikatora. Zastosowanie tej techniki ilustruje „Przykład: Generowanie i używanie klucza szyfrowania” na stronie 202. • Zaszyfrowanie bazy danych powoduje zaszyfrowanie wszystkich plików dyskowych używanych przez mechanizm serwera bazy danych w związku z daną bazą. Jednak mechanizm serwera bazy danych tymczasowo przechowuje pewne dane w pamięci podręcznej, aby przyspieszyć odczytywanie i zapisywanie danych w transakcjach. Wszystkie dane przechowywane w pamięci są niezaszyfrowane. Jeśli osoba nieuprawniona zdoła uzyskać dostęp do pamięci wykorzystywanej przez aplikację AIR, np. za pomocą debugera, to uzyska również dostęp do niezaszyfrowanych danych pochodzących z otwartej bazy. Przykład: Generowanie i używanie klucza szyfrowania Ta przykładowa aplikacja ilustruje jedną z technik generowania klucza szyfrowania. Aplikacja została zaprojektowana w taki sposób, aby zapewniała najwyższy poziom poufności i bezpieczeństwa danych użytkowników. Jednym z ważnych aspektów ochrony danych poufnych jest wymuszenie na użytkowniku wprowadzenia hasła za każdym razem, gdy aplikacja łączy się z bazą danych. Dlatego, co ilustruje omawiany przykład, aplikacja wymagająca tak wysokiego poziomu bezpieczeństwa nie powinna nigdy bezpośrednio przechowywać klucza szyfrowania bazy danych. Aplikacja składa się z dwóch części: klasy ActionScript generującej klucz szyfrowania (klasa EncryptionKeyGenerator) oraz prostego interfejsu użytkownika, który ilustruje zastosowanie tej klasy. Pełny kod źródłowy zawiera sekcja „Kompletny przykładowy kod ilustrujący generowanie i używanie klucza szyfrowania” na stronie 210. Użycie klasy EncryptionKeyGenerator w celu uzyskania bezpiecznego klucza szyfrowania W sekcji „Omówienie klasy EncryptionKeyGenerator” na stronie 204 szczegółowo opisano techniki używane przez klasę EncryptionKeyGenerator do generowania klucza szyfrowania dla bazy danych. Znajomość tych szczegółów nie jest jednak niezbędna do wykorzystania klasy EncryptionKeyGenerator w aplikacji. Aby użyć klasy EncryptionKeyGenerator we własnej aplikacji, należy postępować według poniższej procedury: 1 Klasa EncryptionKeyGenerator wchodzi w skład biblioteki podstawowej ActionScript 3.0 (as3corelib), będącej projektem Open Source. Pakiet as3corelib, wraz z kodem źródłowym i dokumentacją jest dostępny do pobrania. Ze strony projektu można również pobrać pliki SWC lub pliki z kodem źródłowym. 2 Umieść kod źródłowy klasy EncryptionKeyGenerator (lub plik SWC biblioteki as3corelib) w miejscu dostępnym i znanym w kodzie aplikacji. 3 W kodzie aplikacji dodaj instrukcję import w celu zaimportowania klasy EncryptionKeyGenerator. import com.adobe.air.crypto.EncryptionKeyGenerator; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 203 Praca z lokalnymi bazami danych SQL 4 Przed punktem kodu, w którym tworzona jest baza danych lub otwierane jest połączenie z bazą danych, dodaj kod tworzący instancję EncryptionKeyGenerator poprzez wywołanie konstruktora EncryptionKeyGenerator(). var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); 5 Uzyskaj hasło od użytkownika: var password:String = passwordInput.text; if (!keyGenerator.validateStrongPassword(password)) { // display an error message return; } Instancja klasy EncryptionKeyGenerator wykorzysta hasło jako podstawę dla klucza szyfrowania (co ilustruje następny krok). Instancja klasy EncryptionKeyGenerator testuje hasło pod kątem pewnych wymogów stawianych silnym hasłom. Jeśli test ten wypadnie niepomyślnie, zgłaszany jest błąd. W kodzie przykładowym widzimy, że możliwe jest sprawdzenie hasła zanim wystąpi ewentualny błąd; w tym celu należy wywołać metodę validateStrongPassword() obiektu EncryptionKeyGenerator. Ten sposób pozwala określić, czy hasło spełnia minimalne wymagania stawiane hasłom silnym, i uniknąć błędu. 6 Wygeneruj klucz szyfrowania na podstawie hasła: var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password); Metoda getEncryptionKey() generuje i zwraca klucz szyfrowania (16-bajtowy obiekt ByteArray). Uzyskany klucz może posłużyć do utworzenia nowej zaszyfrowanej bazy danych lub do otwarcia istniejącej bazy. Metoda getEncryptionKey() ma jeden parametr wymagany, którym jest hasło uzyskane w kroku 5. Uwaga: Aby utrzymać najwyższy poziom bezpieczeństwa i poufności danych, aplikacja musi wymagać od użytkownika wprowadzenia hasła za każdym razem, gdy nawiązuje połączenie z bazą danych. Nie należy bezpośrednio przechowywać hasła użytkownika lub klucza szyfrowania bazy danych. Stwarzałoby to zagrożenie dla poufności danych. Zamiast tego, tak jak ilustruje to omawiany przykład, aplikacja powinna generować klucz szyfrowania na podstawie hasła zarówno przy tworzeniu bazy danych, jak i każdorazowo przy nawiązywaniu połączenia z bazą. Do metody getEncryptionKey() można również przekazać drugi (opcjonalny) parametr overrideSaltELSKey. Klasa EncryptionKeyGenerator generuje wartość losową (tzw. modyfikator) wykorzystywaną jako część klucza szyfrowania. Aby możliwe było odtworzenie klucza szyfrowania, wartość modyfikatora jest przechowywana w zaszyfrowanym magazynie lokalnym aplikacji AIR. Domyślnie klasa EncryptionKeyGenerator używa konkretnego ciągu znaków jako klucza magazynu lokalnego. Choć jest to mało prawdopodobne, istnieje możliwość konfliktu między tym kluczem a innym kluczem używanym w aplikacji. Zamiast używać klucza domyślnego można zatem podać własny klucz zaszyfrowanego magazynu lokalnego. W takim wypadku własny klucz należy przekazać jako drugi parametr metody getEncryptionKey(), co zilustrowano poniżej: var customKey:String = "My custom ELS salt key"; var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password, customKey); 7 Utwórz lub otwórz bazę danych Mając do dyspozycji klucz zwrócony przez metodę getEncryptionKey(), kod może utworzyć nową zaszyfrowaną bazę danych lub podjąć próbę otwarcia istniejącej zaszyfrowanej bazy danych. W obu przypadkach używa się metody open() lub openAsync() klasy SQLConnection, tak jak opisano to w sekcjach „Tworzenie zaszyfrowanej bazy danych” na stronie 197 i „Nawiązywanie połączenia z zaszyfrowaną bazą danych” na stronie 199. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 204 Praca z lokalnymi bazami danych SQL Przykładowa aplikacja otwiera bazę danych w trybie wykonywania asynchronicznego. Kod konfiguruje odpowiednie detektory zdarzeń i wywołuje metodę openAsync(), przekazując klucz szyfrowania jako ostatni argument: conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, openError); conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); Metody detektorów zdarzeń wyrejestrowują detektory. Następnie wyświetlany jest komunikat o stanie informujący o tym, czy baza danych została utworzona, otwarta, czy też wystąpił błąd. W kodzie detektorów zdarzeń szczególną uwagę zwraca treść metody openError(). Instrukcja if w tej metodzie sprawdza, czy baza danych istnieje (co oznacza, że ma miejsce próba połączenia z istniejącą bazą danych) i czy identyfikator błędu jest równy stałej EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID. Jeśli oba te warunki są spełnione, prawdopodobnie hasło podane przez użytkownika jest nieprawidłowe. (Jednak spełnienie obu warunków może też oznaczać, że podany plik nie jest plikiem bazy danych). Oto kod sprawdzający identyfikator błędu: if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) { statusMsg.text = "Incorrect password!"; } else { statusMsg.text = "Error creating or opening database."; } Pełny kod przykładowych detektorów zdarzeń zawiera sekcja „Kompletny przykładowy kod ilustrujący generowanie i używanie klucza szyfrowania” na stronie 210. Omówienie klasy EncryptionKeyGenerator Znajomość wewnętrznego mechanizmu działania klasy EncryptionKeyGenerator nie jest niezbędna do wykorzystania tej klasy w celu utworzenia bezpiecznego klucza szyfrowania bazy danych. Procedurę użycia klasy wyjaśniono w sekcji „Użycie klasy EncryptionKeyGenerator w celu uzyskania bezpiecznego klucza szyfrowania” na stronie 202. Jednak dla wielu czytelników przydatne może okazać się zrozumienie technik zastosowanych w tej klasie. Na przykład możliwe jest zaadaptowanie klasy do nietypowych potrzeb lub wykorzystanie niektórych z zastosowanych w niej technik w sytuacjach, w których wymagany jest inny poziom poufności danych. Klasa EncryptionKeyGenerator wchodzi w skład biblioteki podstawowej ActionScript 3.0 (as3corelib), będącej projektem Open Source. Pakiet as3corelib wraz z kodem źródłowym i dokumentacją jest dostępny do pobrania. Możliwe jest także przeglądanie kodu źródłowego na stronie projektu lub pobranie go w celu przeanalizowania z pomocą niniejszych wyjaśnień. Gdy kod tworzy instancję klasy EncryptionKeyGenerator i wywołuje jej metodę getEncryptionKey(), podejmowany jest szereg działań zmierzających do zapewnienia dostępu do danych wyłącznie uprawnionemu użytkownikowi. Proces przebiega tak samo niezależnie od tego, czy klucz jest generowany na podstawie hasła przed utworzeniem bazy danych, czy też jest odtwarzany w celu otwarcia bazy danych. Uzyskanie i sprawdzenie poprawności silnego hasła W wywołaniu metody getEncryptionKey() kod aplikacji przekazuje hasło jako parametr. Hasło stanowi podstawę dla klucza szyfrowania. Wykorzystanie w kluczu informacji znanej tylko użytkownikowi gwarantuje, że dostęp do danych w bazie będzie miała wyłącznie osoba znająca hasło. Nawet jeśli inna osoba uzyska dostęp do konta użytkownika na komputerze, nie dostanie się do bazy danych, jeśli nie zna hasła. Aby uzyskać maksymalny poziom bezpieczeństwa, aplikacja nigdy nie przechowuje hasła. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 205 Praca z lokalnymi bazami danych SQL W przykładowej aplikacji passwordInput to nazwa instancji składnika TextInput, w której użytkownik wprowadza hasło. Zamiast bezpośrednio manipulować wartością text składnika, aplikacja kopiuje hasło do zmiennej o nazwie password. var password:String = passwordInput.text; Następnie przykładowa aplikacja tworzy instancję klasy EncryptionKeyGenerator i wywołuje metodę getEncryptionKey(), jako argument przekazując zmienną password: var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password); Pierwszym krokiem wykonywanym w klasie EncryptionKeyGenerator po wywołaniu metody getEncryptionKey() jest sprawdzenie, czy hasło wprowadzone przez użytkownika spełnia wymagania stawiane hasłom silnym. W tym przypadku hasło musi mieć długość od 8 do 32 znaków. Musi zawierać kombinację wielkich i małych liter oraz co najmniej jedną cyfrę lub symbol. Wyrażenie regularne sprawdzające zgodność z tymi wymogami jest zdefiniowane jako stała o nazwie STRONG_PASSWORD_PATTERN: private static const STRONG_PASSWORD_PATTERN:RegExp = /(?=^.{8,32}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/; Kod sprawdzający hasło znajduje się w metodzie validateStrongPassword() klasy EncryptionKeyGenerator. Oto wspomniany kod: public function vaidateStrongPassword(password:String):Boolean { if (password == null || password.length <= 0) { return false; } return STRONG_PASSWORD_PATTERN.test(password)) } Metoda getEncryptionKey() wywołuje metodę validateStrongPassword(), a jeśli hasło nie spełnia wymogów, generuje wyjątek. Metoda validateStrongPassword() jest metodą publiczną, a zatem istnieje możliwość sprawdzenia hasła bez wywoływania metody getEncryptionKey() i uniknięcia w ten sposób zgłoszenia błędu. Rozwinięcie hasła do 256 bitów Na dalszych etapach procesu hasło musi mieć długość 256 bitów. Kod jest napisany w taki sposób, że użytkownik nie musi wprowadzać hasła o długości dokładnie 256 bitów (32 znaków); w razie potrzeby dłuższe hasło jest tworzone przez powtórzenie znaków hasła użytkownika. Metoda getEncryptionKey() wywołuje metodę concatenatePassword() w celu uzyskania hasło o wymaganej długości. var concatenatedPassword:String = concatenatePassword(password); Oto kod metody concatenatePassword(): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 206 Praca z lokalnymi bazami danych SQL 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; } Jeśli hasło jest krótsze niż 256 bitów, jest konkatenowane samo ze sobą w celu uzyskania długości 256 bitów. Jeśli 256 nie jest dokładną wielokrotnością długości hasła, ostatnie powtórzenie jest skracane w celu uzyskania dokładnie tej liczby bitów. Generowanie lub pobieranie 256-bitowego modyfikatora Następnym krokiem jest uzyskanie 256-bitowej wartości modyfikatora, która na późniejszym etapie zostanie połączona z hasłem. Modyfikator (ang. salt, dosłownie „sól”, czyli przyprawa) to wartość losowa dodawana do wartości wprowadzonej przez użytkownika lub w inny sposób z nią łączona. Połączenie modyfikatora z hasłem gwarantuje, że nawet jeśli użytkownik w charakterze hasła poda zwykłe słowo występujące w słownikach, kombinacja hasło+modyfikator będzie wartością losową. Ta losowość chroni przed tzw. atakami słownikowymi, w których osoba atakująca próbuje odgadnąć hasło, próbując użyć kolejnych słów z listy. Ponadto wygenerowanie modyfikatora i zapisanie go w szyfrowanym magazynie lokalnym wiąże jego wartość z kontem użytkownika na komputerze, na którym znajduje się plik bazy danych. Jeśli aplikacja wywołuje metodę getEncryptionKey() po raz pierwszy, tworzona jest losowa 256-bitowa wartość modyfikatora. W przeciwnym razie modyfikator jest ładowany z szyfrowanego magazynu lokalnego. Modyfikator jest przechowywany w zmiennej o nazwie salt. W celu sprawdzenia, czy modyfikator został już utworzony, podejmowana jest próba załadowania go z szyfrowanego magazynu lokalnego: var salt:ByteArray = EncryptedLocalStore.getItem(saltKey); if (salt == null) { salt = makeSalt(); EncryptedLocalStore.setItem(saltKey, salt); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 207 Praca z lokalnymi bazami danych SQL W przypadku tworzenia nowego modyfikatora metoda makeSalt() generuje 256-bitową wartość losową. Ponieważ docelowo wartość ta ma być zapisana w szyfrowanym magazynie lokalnym, jest generowana jako obiekt ByteArray. Metoda makeSalt() używa metody Math.random() do wygenerowania wartości losowej. Metoda Math.random() nie umożliwia wygenerowania 256 bitów naraz. Dlatego zastosowano pętlę, w której metoda Math.random() wywoływana jest osiem razy. Za każdym razem generowana jest wartość losowa z przedziału od 0 do 4294967295 (maksymalna wartość typu uint). Typu uint użyto jako najdogodniejszego, ponieważ wartości tego typu mają dokładnie po 32 bity. Zapisanie ośmiu wartości uint w obiekcie ByteArray prowadzi do wygenerowania wartości 256bitowej. Oto kod metody 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; } Do zapisania modyfikatora w szyfrowanym magazynie lokalnym lub pobrania go z magazynu potrzebny jest klucz (ciąg znaków), pod którym modyfikator jest zapisany. Bez znajomości klucza nie można odczytać wartości modyfikatora. W tej sytuacji klucza szyfrowania nie dałoby się odtworzyć każdorazowo przy otwieraniu bazy danych. Domyślnie klasa EncryptionKeyGenerator używa wstępnie zdefiniowanego klucza magazynu, który jest zdefiniowany w stałej SALT_ELS_KEY. Zamiast używać klucza domyślnego, aplikacja może w wywołaniu metody getEncryptionKey() podać własny klucz magazynu. Domyślny lub podany przez aplikację klucz magazynu identyfikujący modyfikator jest przechowywany w zmiennej saltKey. Ta zmienna jest wykorzystywana w wywołaniach metod EncryptedLocalStore.setItem() i EncryptedLocalStore.getItem(), co ilustruje poprzedni listing kodu. Połączenie 256-bitowego hasła i modyfikatora przy użyciu operatora XOR Teraz dla kodu jest już dostępne i 256-bitowe hasło, i 256-bitowy modyfikator. Następnie wykonywana jest operacja XOR w celu połączenia modyfikatora ze skonkatenowanym hasłem w pojedynczą wartość. Wynikiem zastosowania tej techniki jest 256-bitowe hasło zawierające znaki z całego dostępnego zestawu. Znaki wynikowego hasła będą pochodzić z całego zestawu znaków, nawet jeśli hasło wprowadzone przez użytkownika zawierało w większości znaki alfanumeryczne. Ten dodatkowy czynnik losowy skutecznie powiększa zbiór możliwych haseł (utrudniając złamanie hasła), a jednocześnie eliminuje konieczność ręcznego wprowadzania długich i skomplikowanych ciągów znaków. Wynik operacji XOR jest zapisywany w zmiennej unhashedKey. Właściwa operacja bitowej różnicy symetrycznej (XOR) na dwóch wartościach wykonywana jest w metodzie xorBytes(): var unhashedKey:ByteArray = xorBytes(concatenatedPassword, salt); Bitowy operator XOR (^) działa na dwóch wartościach typu uint i zwraca wartość typu uint. (Wartości typu uint są 32bitowe). Argumenty przekazywane do metody xorBytes() należą do typu String (hasło) i ByteArray (modyfikator). Dlatego w kodzie zastosowano pętlę, która w każdym przebiegu wyodrębnia po 32 bity z każdego z argumentów przeznaczonych do wykonania operacji XOR. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 208 Praca z lokalnymi bazami danych SQL private function xorBytes(passwordString:String, salt:ByteArray):ByteArray { var result:ByteArray = new ByteArray(); for (var i:uint = 0; i < 32; i += 4) { // ... } return result; } Wewnątrz pętli wyodrębniane są pierwsze 32 bity (4 bajty) parametru passwordString. Te bity są wyodrębniane i konwertowane na wartość typu uint (o1) w dwóch etapach. Najpierw metoda charCodeAt() pobiera wartość liczbową każdego ze znaków. Następnie wartość znaku jest przesuwana na odpowiednią pozycję w ramach wartości uint przy użyciu operatora przesunięcia bitowego w lewo <<), a przesunięta wartość jest dodawana do o1. Na przykład pierwszy znak (i) staje się pierwszymi 8 bitami po zastosowaniu operatora przesunięcia bitowego w lewo (<<) o 24 bity i przypisaniu uzyskanej wartości do zmiennej o1. Drugi znak (i + 1) staje się drugą grupą 8 bitów po przesunięciu jego wartości w lewo o 16 bitów i dodaniu wyniku do o1. Wartości trzeciego i czwartego znaku są dodawane w ten sam sposób. // ... // 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); // ... Zmienna o1 zawiera teraz 32 bity z parametru passwordString. Następnie z parametru salt wyodrębniane są 32 bity poprzez wywołanie metody readUnsignedInt() tego parametru. Wyodrębnione 32 bity są zapisywane w zmiennej o2 typu uint. // ... salt.position = i; var o2:uint = salt.readUnsignedInt(); // ... Na koniec dwie wartości 32-bitowe (uint) są łączone za pomocą operatora XOR, a wynik jest zapisywany w obiekcie ByteArray o nazwie result. // ... var xor:uint = o1 ^ o2; result.writeUnsignedInt(xor); // ... Po zakończeniu pętli zwracany jest obiekt ByteArray zawierający wynik operacji XOR. // ... } return result; } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 209 Praca z lokalnymi bazami danych SQL Wymieszanie klucza Następnym krokiem po połączeniu skonkatenowanego hasła i modyfikatora jest dodatkowe zabezpieczenie wyniku poprzez wymieszanie go przy użyciu algorytmu mieszającego SHA-256. Wymieszanie wartości utrudnia potencjalnemu agresorowi odtworzenie sposobu, w jaki została utworzona. Na tym etapie w kodzie jest dostępny obiekt ByteArray o nazwie unhashedKey zawierający skonkatenowane hasło połączone z modyfikatorem. Projekt biblioteki podstawowej ActionScript 3.0 (as3corelib) obejmuje klasę SHA256 wchodząca w skład pakietu com.adobe.crypto. Metoda SHA256.hashBytes() wykonuje mieszanie na obiekcie ByteArray zgodnie z algorytmem SHA-256 i zwraca obiekt String zawierający 256-bitowy wynik mieszania w formie liczby szesnastkowej. W klasie EncryptionKeyGenerator klasa SHA256 jest używana do mieszania klucza: var hashedKey:String = SHA256.hashBytes(unhashedKey); Wyodrębnienie klucza szyfrowania z wyniku mieszania Klucz szyfrowania musi być obiektem ByteArray o długości dokładnie 16 bajtów (128 bitów). Wynik działania algorytmu mieszającego SHA-256 ma zawsze długość 256 bitów. Dlatego ostatnim etapem będzie wybranie z wyniku mieszania 128 bitów, które posłużą za faktyczny klucz szyfrowania. W klasie EncryptionKeyGenerator klucz jest skracany do 128 bitów w wyniku wywołania metody generateEncryptionKey(). Wynik tej metod jest zwracany jako wynik metody getEncryptionKey(): var encryptionKey:ByteArray = generateEncryptionKey(hashedKey); return encryptionKey; Kluczem szyfrowania nie musi być pierwsze 128 bitów. Równie dobrze można wybrać ciąg bitów rozpoczynający się w arbitralnie określonym punkcie, co drugi bit lub sekwencję bitów określoną w inny sposób. Ważne jest jedynie, aby wybrać 128 odrębnych bitów i za każdym razem używać tych samych 128 bitów. W prezentowanym przypadku metoda generateEncryptionKey() jako klucz szyfrowania wybiera ciąg bitów rozpoczynający się od 18. bajtu. Jak już wcześniej wspomniano, klasa SHA256 zwraca obiekt String zawierający 256bitowy wynik mieszania zapisany w postaci liczby szesnastkowej. Pojedynczy blok 128 bitów składa się ze zbyt wielu bajtów, aby można go było dodać do obiektu ByteArray w jednym kroku. Dlatego zastosowano pętlę for wyodrębniającą znaki z ciągu cyfr szesnastkowych, konwertującą je na wartości liczbowe i dodającą do obiektu ByteArray. Ciąg znaków będący wynikiem działania algorytmu SHA-256 ma długość 64 znaków. Ciąg 128 bitów odpowiada 32 znakom ciągu, a każdy znak reprezentuje 4 bity. Najmniejszą jednostką danych, jaką można dodać do obiektu ByteArray, jest jeden bajt (8 bitów), co odpowiada dwóm znakom w obiekcie String o nazwie hash. Dlatego pętla odlicza od 0 do 31 (32 znaki) z przyrostem 2 znaków. Wewnątrz pętli najpierw określana jest początkowa pozycja bieżącej pary znaków. Ponieważ wybrany zakres zaczyna się od znaku o indeksie 17 (18. bajtu), zmiennej position jest przypisywana bieżąca wartość iteratora (i) plus 17. Do wyodrębnienia dwóch znaków z bieżącej pozycji używana jest metoda substr(). Znaki te są przechowywane w zmiennej hex. Następnie za pomocą metody parseInt() ciąg znaków hex jest konwertowany na dziesiętną wartość całkowitą. Wartość ta jest zapisywana w zmiennej byte typu int. Na koniec wartość byte jest dodawana do obiektu ByteArray o nazwie result przy użyciu metody writeByte() tego obiektu. Po zakończeniu pętli obiekt ByteArray result zawiera 16 batów i jest gotowy do użycia w charakterze klucza szyfrowania bazy danych. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 210 Praca z lokalnymi bazami danych SQL 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; } Kompletny przykładowy kod ilustrujący generowanie i używanie klucza szyfrowania Poniżej przedstawiono kompletny kod aplikacji przykładowej „Generowanie i używanie klucza szyfrowania”. Kod składa się z dwóch części. W przykładzie zastosowano klasę EncryptionKeyGenerator do tworzenia klucza szyfrowania na podstawie hasła. Klasa EncryptionKeyGenerator wchodzi w skład biblioteki podstawowej ActionScript 3.0 (as3corelib), będącej projektem Open Source. Pakiet as3corelib, wraz z kodem źródłowym i dokumentacją jest dostępny do pobrania. Ze strony projektu można również pobrać pliki SWC lub pliki z kodem źródłowym. Plik FLA aplikacji zawiera kod źródłowy prostej aplikacji, która tworzy lub otwiera połączenie z zaszyfrowaną bazą danych. Plik FLA zawiera cztery składniki umieszczone na stole montażowym: Nazwa instancji Typ składnika Opis instructions Label Zawiera instrukcje dla użytkownika. passwordInput TextInput Pole wejściowe, w którym użytkownik wprowadza hasło. openButton Button Przycisk, który użytkownik klika po wprowadzeniu hasła. statusMsg Label Wyświetlane komunikaty o stanie (powodzenie lub niepowodzenie). Kod aplikacji jest zdefiniowany w klatce kluczowej będącej klatką nr 1 na głównej osi czasu. Kod aplikacji przedstawiono poniżej: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 211 Praca z lokalnymi bazami danych SQL 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; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 212 Praca z lokalnymi bazami danych SQL 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."; } } Strategie pracy z bazami danych SQL Poniżej przedstawiono różne sposoby, które umożliwiają aplikacji dostęp do lokalnej bazy danych SQL oraz pracę z tą bazą. Projekty aplikacji mogą być różne pod względem organizacji kodu aplikacji, kolejności i czasu wykonywania operacji itp. Wybrane techniki mogą mieć wpływ na łatwość projektowania aplikacji. Mogą również wpływać na łatwość modyfikowania aplikacji w przyszłych aktualizacjach. Mogą również wpływać na działanie aplikacji z perspektywy użytkownika. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 213 Praca z lokalnymi bazami danych SQL Dystrybucja wstępnie uzupełnionej bazy danych Jeśli w aplikacji używana jest lokalna baza danych SQL AIR, wówczas aplikacja oczekuje bazy danych z określoną strukturą tabel, kolumn itp. Niektóre aplikacje oczekują również na wstępne wprowadzenie pewnych danych do pliku bazy danych. Jednym sposobem zapewnienia poprawnej struktury bazy danych, jest utworzenie bazy danych w kodzie aplikacji. Po załadowaniu aplikacja sprawdza, czy w określonej lokalizacji istnieje plik bazy danych. Jeśli plik nie istnieje, wówczas aplikacja wykonuje zestaw komend w celu utworzenia pliku bazy danych, utworzenia struktury bazy danych oraz w celu wstępnego wprowadzenia danych do tabel. Kod, który tworzy bazę danych oraz jej tabele, jest często złożony. Często jest używany tylko jeden raz po zainstalowaniu aplikacji, ale powoduje zwiększenie wielkości i złożoności aplikacji. Zamiast programowego tworzenia bazy danych, struktury i danych można dystrybuować wstępnie wypełnioną bazę danych z aplikacją. W celu dystrybucji wstępnie zdefiniowanej bazy danych należy dołączyć plik bazy danych do pakietu aplikacji AIR. Plik bazy danych w pakunku — podobnie jak wszystkie pliki znajdujące się w pakiecie AIR — jest instalowany w katalogu aplikacji (katalog reprezentowany przez właściwość File.applicationDirectory). Jednak pliki w tym katalogu mogą być tylko odczytywane. Zastosowanie pliku z pakietu AIR jako „szablonowej” bazy danych. Przy pierwszym uruchomieniu aplikacji należy skopiować oryginalny plik bazy danych do katalogu zapisu aplikacji użytkownika (lub innej aplikacji), a następnie wykorzystać tę bazę danych w aplikacji. Zwiększanie wydajności bazy danych Kilka technik, jakie są wbudowane do środowiska Adobe AIR, umożliwia zwiększenie wydajności operacji bazy danych w aplikacji. Oprócz technik opisanych w tej sekcji zapisywana jest również instrukcja SQL, która także może wpłynąć na wydajność bazy danych. Często istnieje wiele sposobów pisania instrukcji SQL SELECT w celu pobrania określonego zestawu wyników. W niektórych przypadkach różne podejścia wymagają większego lub mniejszego wysiłku ze strony mechanizmu bazy danych. Ten aspekt poprawiana wydajności bazy danych, czyli projektowanie instrukcji SQL dla poprawy wydajności, nie został omówiony w dokumentacji Adobe AIR. Korzystanie z jednej instancji klasy SQLStatement dla każdej instrukcji SQL Przed wykonaniem instrukcji SQL środowisko wykonawcze przygotowuje (kompiluje) instrukcję w celu określenia kroków, jakie powinny zostać wykonane wewnętrznie w celu wykonania instrukcji. Po wywołaniu metody SQLStatement.execute() dla instancji klasy SQLStatement, która nie została wykonana poprzednio, instrukcja jest automatycznie przygotowywana zanim zostanie wykonana. Przy kolejnych wywołaniach metody execute() instrukcja jest nadal przygotowywana, pod warunkiem że właściwość SQLStatement.text nie została zmieniona. Dzięki temu jest wykonywana szybciej. W celu maksymalnego wykorzystania instrukcji wykonywanych wielokrotnie, jeśli wartości muszą zostać zmienione pomiędzy wykonywanymi instrukcjami, wówczas należy zastosować parametry instrukcji w celu dostosowania instrukcji. (Parametry instrukcji są określane za pomocą właściwości SQLStatement.parameters tablicy asocjacyjnej). W przypadku zmiany wartości parametrów instrukcji (w odróżnieniu od zmiany właściwości text instancji klasy SQLStatement) środowisko wykonawcze nie musi ponownie przygotowywać instrukcji. Więcej informacji na temat stosowania parametrów w instrukcjach zawiera sekcja „Korzystanie z parametrów w instrukcjach” na stronie 177. Przygotowanie i wykonanie instrukcji to operacja potencjalnie wymagająca, dlatego dobrym sposobem postępowania jest wstępne załadowanie danych, a następnie wykonanie innych instrukcji w tle. Najpierw należy załadować dane, których aplikacja potrzebuje na samym początku. Inne instrukcje należy wykonać po zakończeniu wstępnych operacji początkowych w aplikacji lub po wystąpieniu kolejnego momentu „bezczynności” w aplikacji. Na przykład: jeśli aplikacja w ogóle nie uzyskuje dostępu do bazy danych w celu wyświetlenia ekranu początkowego, należy poczekać na wyświetlenie tego ekranu, następnie otworzyć połączenie z bazą danych, a na koniec utworzyć instancje klasy TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 214 Praca z lokalnymi bazami danych SQL SQLStatement i uruchomić instancje, które mogą zostać uruchomione. Inny sposób: załóżmy, że uruchomiona aplikacja natychmiast wyświetla jakieś dane, np. wynik określonego zapytania. W takim przypadku należy uruchomić instancję SQLStatement dla tego zapytania. Po początkowym załadowaniu i wyświetleniu danych należy utworzyć instancje klasy SQLStatement dla innych operacji bazy danych, a jeśli to możliwe — wykonać inne instrukcje, które będą wymagane później. Jeśli instancja klasy SQLStatement jest używana ponownie, aplikacja powinna zachować odwołanie do instancji SQLStatement, gdy zostanie ona przygotowana. W celu zachowania odwołania do instancji należy zadeklarować zmienną jako zmienną o zasięgu klasy, a nie jako zmienną o zasięgu funkcji. Dobrym sposobem na to jest takie skonstruowanie aplikacji, aby instrukcja SQL była opakowana w pojedynczą klasę. Grupę instrukcji wykonywanych łącznie również można opakować w pojedynczą klasę. Zdefiniowanie instancji SQLStatement jako zmiennych należących do klasy powoduje, że będą one istniały tak długo, jak instancja klasy opakowującej będzie istniała w aplikacji. Wystarczy również zdefiniować zmienną zawierającą instancję SQLStatement na zewnątrz funkcji, dzięki czemu instancja zostanie zachowana w pamięci. Przykład: należy zadeklarować instancję SQLStatement jako zmienną klasy ActionScript lub jako zmienną (która nie jest funkcją) w pliku JavaScript. Następnie można ustawić wartości parametrów instrukcji i wywołać metodę execute() w celu rzeczywistego uruchomienia zapytania. Grupowanie wielu operacji w transakcji Załóżmy, że wykonywana jest duża liczba instrukcji SQL, które obejmują dodawanie lub zmianę danych (instrukcje INSERT lub UPDATE). Wykonanie wszystkich instrukcji w jawnej transakcji powoduje znaczny wzrost wydajności. Jeśli transakcja nie zostanie rozpoczęta jawnie, każda instrukcja będzie działała we własnej automatycznie tworzonej transakcji. Po zakończeniu wykonywania każdej transakcji (każdej instrukcji) środowisko wykonawcze zapisuje dane wynikowe do pliku bazy danych na dysku. Rozważmy jednak, co się stanie po jawnym utworzeniu transakcji i wykonaniu instrukcji w kontekście transakcji. Środowisko wykonawcze wykona wszystkie zmiany w pamięci, a następnie zapisze jednorazowo wszystkie zmiany w pliku bazy danych po wykonaniu transakcji. Zapisywanie danych na dysku zwykle zajmuje najwięcej czasu w operacji. W konsekwencji jednorazowe zapisanie na dysk zamiast zapisywania przy każdej instrukcji SQL może spowodować znaczny wzrost wydajności. Minimalizowanie przetwarzania w środowisku wykonawczym Korzystanie z poniższych technik może zapobiec wykonywaniu niepotrzebnej pracy przez mechanizm bazy danych oraz przyczynić się do wzrostu wydajności aplikacji: • Zawsze należy jawnie określać nazwy bazy danych wraz z nazwami tabel w instrukcji. (W przypadku głównej bazy danych należy stosować słowo „main”). Na przykład: SELECT employeeId FROM main.employees zamiast SELECT employeeId FROM employees. Jawne określanie nazw baz danych powoduje, że środowisko wykonawcze nie musi sprawdzać każdej bazy danych w celu odnalezienia określonej tabeli. Uniemożliwia również wybór błędnej bazy danych w środowisku wykonawczym. Należy przestrzegać tej reguły, nawet jeśli klasa SQLConnection jest połączona tylko z jedną bazą danych, ponieważ w tle klasa SQLConnection jest również połączona z tymczasową bazą danych, która jest dostępna za pośrednictwem instrukcji SQL. • Zawsze należy jawnie określać nazwy kolumn w instrukcjach SELECT i INSERT. • Należy dzielić wiersze zwracane przez instrukcję SELECT, która pobiera dużą liczbę wierszy: patrz „Uzyskiwanie wyników SELECT w częściach” na stronie 184. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 215 Praca z lokalnymi bazami danych SQL Unikanie zmian schematów Jeśli to możliwe, należy unikać zmian schematu (struktur tabel) bazy danych po dodaniu danych do tabel bazy danych. Normalnie struktura pliku bazy danych zawiera definicje tabeli na początku pliku. Po otwarciu połączenia z bazą danych środowisko wykonawcze ładuje te definicje. Dane dodane do tabel bazy danych są dodawane do pliku za definicjami tabel. Jednak zmiana schematu, taka jak dodanie kolumny do tabeli lub dodanie nowej tabeli, sprawia, że nowe dane definicji tabeli są mieszane z danymi tabeli w pliku bazy danych. Jeśli wszystkie dane definicji tabeli nie znajdują się na początku pliku bazy danych, otwieranie połączenia z bazą danych trwa dłużej, ponieważ środowisko wykonawcze odczytuje dane definicji tabeli z różnych części pliku. Jeśli konieczne jest dokonanie zmian schematu, po wykonaniu zmian można wywołać metodę SQLConnection.compact(). Ta metoda powoduje zmianę struktury pliku bazy danych, dzięki czemu dane definicji tabeli zostają umieszczone razem na początku pliku. Jednak operacja compact() może być wykonywana przez długi czas, szczególnie w przypadku dużych plików baz danych. Sprawdzone sposoby pracy z lokalnymi bazami danych SQL Poniżej przedstawiono listę sugerowanych technik, które mogą być używane w celu poprawy wydajności, bezpieczeństwa i łatwości obsługi aplikacji podczas pracy z lokalnymi bazami danych SQL. Dodatkowe techniki usprawniające działanie aplikacji bazodanowych zawiera sekcja „Zwiększanie wydajności bazy danych” na stronie 213. Wstępne tworzenie połączeń z bazą danych Nawet jeśli aplikacja nie wykonuje żadnych instrukcji przy pierwszym ładowaniu, należy utworzyć instancję obiektu SQLConnection i z wyprzedzeniem wywołać jego metodę open() lub openAsync() (np. po pierwszym uruchomieniu aplikacji), aby uniknąć opóźnień w czasie wykonywania instrukcji. Patrz „Połączenie z bazą danych” na stronie 174. Ponowne wykorzystanie połączeń z bazą danych Jeśli przez cały czas wykonywania aplikacji utrzymywane jest połączenie z bazą danych, należy zachować odwołanie do instancji SQLConnection i wykorzystywać je w całej aplikacji — jest to rozwiązanie lepsze niż zamykanie i ponowne otwieranie połączeń. Patrz „Połączenie z bazą danych” na stronie 174. Zalecane stosowanie trybu wykonywania asynchronicznego Podczas pisania kodu aplikacji kuszące może być synchroniczne wykonywanie operacji, ponieważ korzystanie z operacji synchronicznych często wymaga stosowania krótszego i mniej złożonego kodu. Jednak zgodnie z opisem w sekcji „Korzystanie z synchronicznych i asynchronicznych operacji bazy danych” na stronie 192 operacje synchroniczne powodują zmniejszenie wydajności, co dostrzegają użytkownicy i co wpływa na ich zadowolenie z użytkowania aplikacji. Ilość czasu przeznaczona na wykonanie jednej operacji jest uzależniona od operacji oraz od ilości danych, jakie biorą udział w operacji. Na przykład: instrukcja SQL INSERT, która dodaje tylko jeden wiersz do bazy danych, trwa krócej niż instrukcja SELECT, która pobiera tysiąc wierszy danych. Gdy jednak tryb synchroniczny jest używany do wykonywania wielu operacji, wówczas operacje są zwykle połączone ze sobą. Nawet jeśli czas wykonania jednej operacji jest krótki, działanie aplikacji zostaje wstrzymane do czasu wykonania wszystkich operacji synchronicznych. W rezultacie łączny czas wielu operacji może być tak długi, że spowoduje drastyczne wydłużenie czasu oczekiwania na odpowiedź aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 216 Praca z lokalnymi bazami danych SQL Jako standardowe podejście należy stosować aplikacje asynchroniczne — szczególnie w przypadku operacji, które obejmują duże liczby wierszy. W sekcji „Uzyskiwanie wyników SELECT w częściach” na stronie 184 opisano technikę dzielenia operacji przetwarzania dużych zestawów wyników instrukcji SELECT. Jednak ta technika może być stosowana tylko w trybie wykonywania asynchronicznego. Operacje synchroniczne powinny być stosowane tylko wówczas, gdy nie można uzyskać określonego działania za pomocą operacji asynchronicznych; po uwzględnieniu obniżenia wydajności, z którym będą musieli borykać się użytkownicy; oraz po przetestowaniu aplikacji i określeniu wpływu tych operacji na wydajność aplikacji. Wykonywanie asynchroniczne może wymagać bardziej złożonego kodowania. Jednak należy pamiętać o tym, że programista pisze kod tylko raz, a użytkownicy będą wielokrotnie korzystać z kodu działającego powoli lub szybko. W wielu przypadkach zastosowanie osobnej instancji klasy SQLStatement dla każdej wykonywanej instrukcji SQL umożliwia jednorazowe utworzenie kolejki z wielu operacji SQL, co sprawia, że kod asynchroniczny przypomina kod synchroniczny — pod względem sposobu jego pisania. Więcej informacji zawiera sekcja „Wyjaśnienie modelu wykonywania asynchronicznego” na stronie 195. Stosowanie osobnych instrukcji SQL i brak zmian właściwości text klasy SQLStatement Dla każdej instrukcji SQL, która jest wykonywana więcej niż jeden raz w aplikacji, należy utworzyć osobną instancję klasy SQLStatement. Ta instancja SQLStatement powinna być wykorzystywana przy każdym wykonaniu polecenia SQL. Przykład: załóżmy, że tworzona jest aplikacja, która zawiera cztery różne operacje SQL, które są wykonywane wiele razy. W takim przypadku należy utworzyć cztery osobne instancje klasy SQLStatement i wywołać metodę execute() w celu uruchomienia każdej instrukcji. Należy unikać podejścia odwrotnego, czyli użycia jednej instancji klasy SQLStatement dla wszystkich instrukcji SQL oraz ponownego definiowania właściwości text przed każdym wykonaniem instrukcji. Więcej informacji zawiera sekcja „Korzystanie z jednej instancji klasy SQLStatement dla każdej instrukcji SQL” na stronie 213. Stosowanie parametrów instrukcji Należy stosować parametry klasy SQLStatement — nigdy nie należy konkatenować danych wprowadzonych przez użytkownika do tekstu instrukcji. Korzystanie z parametrów sprawia, że aplikacja jest bardziej bezpieczna, ponieważ zapobiega ewentualnym atakom SQL inject. Umożliwia stosowanie obiektów w zapytaniach (zamiast stosowania samych wartości literałowych SQL). Sprawia również, że instrukcje działają bardziej wydajnie, ponieważ mogą być używane wielokrotnie bez konieczności ponownej kompilacji przy każdym wykonaniu. Więcej informacji zawiera sekcja „Korzystanie z parametrów w instrukcjach” na stronie 177. Stosowanie stałych dla nazw kolumn i parametrów Jeśli nie zostanie określona właściwość itemClass klasy SQLStatement, wówczas w celu uniknięcia błędów pisowni należy zdefiniować stałe String zawierające nazwy kolumn tabeli. Te stałe powinny być używane w tekście instrukcji oraz dla nazw właściwości podczas pobierania danych z obiektów wynikowych. Stałe powinny być również stosowane dla nazw parametrów. 217 Rozdział 19: Przechowywanie danych zaszyfrowanych Środowisko Adobe® AIR™ udostępnia trwały magazyn danych lokalnych każdej aplikacji AIR zainstalowanej na komputerze użytkownika. Magazyn taki umożliwia zapisywanie i pobieranie danych przechowywanych na lokalnym dysku twardym użytkownika w formacie zaszyfrowanym, którego inne aplikacje lub użytkownicy nie są w stanie w prosty sposób rozszyfrować. Dla każdej aplikacji AIR używany jest odrębny lokalny magazyn danych zaszyfrowanych i każda aplikacja AIR używa odrębnego magazynu dla każdego użytkownika. Uwaga: Poza szyfrowanym magazynem lokalnym środowisko AIR zapewnia również szyfrowanie dla treści zapisanej w bazach danych SQL. Szczegółowe informacje zawiera sekcja „Korzystanie z szyfrowania w bazach danych SQL” na stronie 196. Lokalny magazyn zaszyfrowany jest przydatny do przechowywania informacji, które muszą być zabezpieczone, takie jak poświadczenia logowania dla usług Web Service. Środowisko AIR do powiązania szyfrowanego magazynu lokalnego z każdą aplikacją i użytkownikiem używa interfejsu DPAPI w systemie Windows, KeyChain w systemie Mac OS oraz KeyRing lub KWallet w systemie Linux. Magazyn lokalny jest zaszyfrowany przy użyciu algorytmu 128-bitowego AES-CBC. Informacje o zaszyfrowanym magazynie lokalnym są dostępne tylko do treści aplikacji AIR w obszarze izolowanym bezpieczeństwa aplikacji. Metody statyczne setItem() i removeItem() klasy EncryptedLocalStore służą do zapisywania i pobierania danych z magazynu lokalnego. Dane są przechowywane w tabeli mieszania, w której kluczami są ciągi znaków, a właściwe dane mają postać tablic bajtów. Na przykład poniższy kod zapisuje ciąg znaków w zaszyfrowanym magazynie lokalnym: 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" Trzeci parametr metody setItem() — stronglyBound — jest opcjonalny. Gdy ten parametr jest ustawiony na true, zaszyfrowany magazyn lokalny zapewnia wyższy poziom bezpieczeństwa, ponieważ zapisane w nim elementy są powiązane z podpisem cyfrowym i bitami aplikacji AIR oraz z identyfikatorem wydawcy aplikacji: var str:String = "Bob"; var bytes:ByteArray = new ByteArray(); bytes.writeUTFBytes(str); EncryptedLocalStore.setItem("firstName", bytes, true); W przypadku elementu zapisanego z parametrem stronglyBound ustawionym na true późniejsze wywołania metody getItem() kończą się powodzeniem tylko wówczas, gdy wywołująca aplikacja AIR jest identyczna z aplikacją zapisującą (jeśli nie uległy zmianie żadne dane w plikach zapisanych w katalogu aplikacji). Jeśli wywołująca aplikacja AIR jest różna od aplikacji zapisującej, to aplikacja generuje wyjątek Error przy próbie wywołania metody getItem() dla elementu silnie powiązanego. W wypadku zmodyfikowania aplikacji nie będzie możliwe odczytanie silnie powiązanych danych zapisanych wcześniej w zaszyfrowanym magazynie lokalnym. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 218 Przechowywanie danych zaszyfrowanych Domyślnie aplikacja AIR nie może odczytywać zaszyfrowanego magazynu lokalnego innej aplikacji. Ustawienia stronglyBound zapewnia dodatkowe powiązanie (z bitami kodu aplikacji), które uniemożliwia potencjalnemu agresorowi odczytanie danych z zaszyfrowanego magazynu lokalnego aplikacji poprzez „podszycie się” pod identyfikator jej wydawcy. W wypadku zmodyfikowania aplikacji w taki sposób, że będzie używała innego certyfikatu podpisującego (przy użyciu podpisu migracji) zmodyfikowana wersja nie będzie mogła uzyskać dostępu do elementów w oryginalnym magazynie, nawet jeśli parametr stronglyBound był ustawiony na wartość false. Więcej informacji zawiera sekcja „Zmiana certyfikatów” na stronie 327. Istnieje możliwość usunięcia wartości z zaszyfrowanego magazynu lokalnego za pomocą metody EncryptedLocalStore.removeItem(), co ilustruje poniższy przykład: EncryptedLocalStore.removeItem("firstName"); Wywołanie metody EncryptedLocalStore.reset() umożliwia wyczyszczenie wszystkich danych z zaszyfrowanego magazynu lokalnego, co ilustruje poniższy przykład: EncryptedLocalStore.reset(); Aplikacja debugowana w środowisku AIR Debug Launcher (ADL) używa innego zaszyfrowanego magazynu lokalnego niż aplikacja zainstalowana. Zaszyfrowany magazyn lokalny może działać wolniej, jeśli objętość zapisanych danych przekracza 10 MB. Podczas odinstalowywania aplikacji AIR program odinstalowujący nie usuwa danych zapisanych w zaszyfrowanym magazynie lokalnym. Zaszyfrowany magazyn lokalny jest umieszczony w podkatalogu katalogu danych aplikacji użytkownika; ścieżka podkatalogu to Adobe/AIR/ELS/ z dodanym identyfikatorem aplikacji. 219 Rozdział 20: Informacje o środowisku HTML W środowisku Adobe®AIR™ wykorzystywany jest mechanizm WebKit (www.webkit.org), używany również w przeglądarce Safari, który służy do analizowania, definiowania układu oraz do renderowania treści HTML i JavaScript. Korzystanie z interfejsów API środowiska AIR w HTML jest opcjonalne. Zawartość obiektu HTMLLoader lub okna HTML można zaprogramować bezpośrednio w języku HTML lub JavaScript. Większość istniejących stron HTML i aplikacji powinna działać z niewielkimi zmianami (przy założeniu, że korzystają z funkcji HTML, CSS, DOM i JavaScript zgodnych z WebKit). Aplikacje AIR działają bezpośrednio na pulpicie, przy pełnym dostępie do systemu plików, dlatego model zabezpieczeń dla treści HTML jest bardziej wymagający niż model zabezpieczeń typowej przeglądarki internetowej. W środowisku AIR tylko treść ładowana z katalogu instalacyjnego aplikacji jest umieszczana w obszarze izolowanym aplikacji. Obszar izolowany aplikacji ma najwyższy poziom uprawnień i umożliwia dostęp do interfejsów API AIR. Środowisko AIR umieszcza inną zawartość w obszarach izolowanych na podstawie źródła zawartości. Pliki pobrane z systemu plików są wprowadzane do lokalnego obszaru izolowanego. Pliki pobrane z sieci przy użyciu protokołów http: lub https: przechodzą do obszaru izolowanego w zależności od domeny serwera zdalnego. Zawartość tych obszarów izolowanych (innych niż aplikacji) nie ma dostępu do żadnych interfejsów API AIR i działa tak, jak w typowej przeglądarce internetowej. W środowisku AIR wykorzystywany jest mechanizm WebKit (www.webkit.org), używany również w przeglądarce Safari oraz służy do analizowania, definiowania układu oraz do renderowania treści HTML i JavaScript. Wbudowane klasy obsługi i obiekty środowiska AIR udostępniają interfejs API przeznaczony dla funkcji tradycyjnie skojarzonych z aplikacjami pulpitu. Do tych funkcji należy odczytywanie i zapisywanie plików, a także zarządzanie oknami. Środowisko Adobe AIR dziedziczy również interfejsy API z odtwarzacza Adobe® Flash® Player, który udostępnia również funkcje, takie jak funkcje dźwiękowe i gniazda binarne. Treść HTML w środowisku AIR nie wyświetla plików SWF ani PDF, jeśli zastosowane są ustawienia alfa, skalowania i przezroczystości. Więcej informacji zawierają sekcje Zagadnienia dotyczące ładowania treści SWF lub PDF na stronie HTML i „Przezroczystość okna” na stronie 64. Przegląd środowiska HTML Środowisko Adobe AIR udostępnia kompletne środowisko JavaScript przypominające przeglądarkę, w którym dostępny jest moduł renderowania HTML, model obiektów dokumentu, a także interpreter JavaScript. Środowisko JavaScript jest reprezentowane przez klasę AIR HTMLLoader. W oknach HTML obiekt HTMLLoader zawiera całą treść HTML i w rezultacie znajduje się w obiekcie NativeWindow. W treści SWF klasa HTMLLoader, która rozszerza klasę Sprite, może zostać dodana do listy wyświetlania stołu montażowego w taki sam sposób, jak inne obiekty wyświetlane. Właściwości ActionScript™ klasy zostały opisane w sekcji „Wywoływanie skryptów w kontenerze HTML” na stronie 260, a także w dokumentacji Skorowidz języka Flex 3 ActionScript. Informacje o środowisku JavaScript i jego relacjach ze środowiskiem AIR Poniższy schemat ilustruje relacje między środowiskiem JavaScript a środowiskiem wykonawczym AIR. Schemat przedstawia tylko jedno okno rodzime, ale aplikacja AIR może zawierać wiele okien. (A pojedyncze okno może zawierać wiele obiektów HTMLLoader). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 220 Informacje o środowisku HTML AIR Run-time Environment NativeWindow HTMLLoader window JavaScript Environment window window body head htmlLoader native4Window runtime h1 div table p Środowisko JavaScript zawiera własne obiekty Document i Window. Kod JavaScript może oddziaływać ze środowiskiem wykonawczym AIR za pośrednictwem właściwości runtime, nativeWindow i htmlLoader. Kod ActionScript może oddziaływać ze środowiskiem JavaScript za pośrednictwem właściwości window obiektu HTMLLoader, który stanowi odwołanie do obiektu JavaScript Window. Ponadto obiekty ActionScript i JavaScript mogą wykrywać zdarzenia wywoływane przez obiekty AIR i JavaScript. Właściwość runtime zapewnia dostęp do klas API AIR, dzięki czemu umożliwia tworzenie nowych obiektów AIR, a także tworzenie członków klasy dostępu (zwanej również klasą statyczną). W celu uzyskania dostępu do interfejsu API AIR należy dodać nazwę klasy z pakietem do właściwości runtime. Na przykład: w celu utworzenia obiektu File należy użyć instrukcji: var file = new window.runtime.filesystem.File(); Uwaga: Pakiet SDK AIR udostępnia plik JavaScript AIRAliases.js, który definiuje bardziej wygodne aliasy dla najczęściej używanych klas AIR. Podczas importowania tego pliku można użyć krótszej nazwy air.Class zamiast nazwy window.runtime.package.Class. Przykład: obiekt File można utworzyć za pomocą metody new air.File(). Obiekt NativeWindow udostępnia właściwości przeznaczone do kontrolowania okna na pulpicie. Ze strony HTML można uzyskać dostęp do zawierającego obiektu NativeWindow za pomocą właściwości window.nativeWindow. Obiekt HTMLLoader udostępnia właściwości, metody i zdarzenia przeznaczone do kontrolowania sposobu ładowania i renderowania treści. Ze strony HTML można uzyskać dostęp do nadrzędnego obiektu HTMLLoader za pomocą właściwości window.htmlLoader. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 221 Informacje o środowisku HTML Ważne: Tylko strony zainstalowane jako część aplikacji zawierają właściwości htmlLoader, nativeWindow i runtime i tylko wówczas, gdy są ładowane jako dokument najwyższego poziomu. Te właściwości nie są dodawane podczas ładowania dokumentu do ramki lub ramki pływającej. (Dokument podrzędny może uzyskać dostęp do tych właściwości w dokumencie nadrzędnym, pod warunkiem że znajduje się w tym samym obszarze izolowanym. Na przykład: dokument załadowany w ramce może uzyskiwać dostęp do właściwości runtime dokumentu nadrzędnego za pomocą parent.runtime). Informacje o zabezpieczeniach Środowisko AIR wykonuje cały kod w obszarze izolowanym na podstawie domeny źródłowej. Treść aplikacji, która jest ograniczona do treści załadowanej z katalogu instalacyjnego aplikacji, jest umieszczana w obszarze izolowanym aplikacji. Dostęp do środowiska wykonawczego oraz interfejsów API AIR jest możliwy tylko dla kodu HTML i JavaScript działającego w tym obszarze izolowanym. Jednocześnie po zwróceniu wszystkich modułów obsługi dla zdarzenia load strony następuje zablokowanie najbardziej dynamicznego oceniania i wykonania kodu JavaScript w obszarze izolowanym aplikacji. Stronę aplikacji można odwzorować do nieaplikacyjnego obszaru izolowanego poprzez załadowanie strony do ramki lub ramki pływającej, a także ustawienie dla ramki atrybutów sandboxRoot i documentRoot właściwych dla AIR. Ustawienie wartości sandboxRoot na rzeczywistą domenę zdalną umożliwia zawartości z obszaru izolowanego na generowanie skryptów dla zawartości w danej domenie. Ten sposób odwzorowania stron może być bardzo użyteczny podczas ładowania treści zdalnej oraz wywoływania skryptów dla tej treści, np. w aplikacji mash-up. Innym sposobem umożliwiającym wymianę skryptów między treścią stanowiącą część aplikacji a treścią niebędącą częścią aplikacji, a także jedyną drogą udostępnienia treści niebędącej częścią aplikacji dostępu do interfejsów API środowiska AIR, jest utworzenie mostu obszaru izolowanego. Most nadrzędny-podrzędny umożliwia treści zawartej w podrzędnej ramce, ramce pływającej lub podrzędnym oknie na dostęp do wyznaczonych metod i właściwości zdefiniowanych w obszarze izolowanym aplikacji. I odwrotnie most podrzędny-nadrzędny umożliwia treści aplikacji dostęp do wyznaczonych metod i właściwości zdefiniowanych w obszarze izolowanym obiektu podrzędnego. Mosty obszarów izolowanych są definiowane przez właściwości parentSandboxBridge i childSandboxBridge obiektu window. Więcej informacji zawierają sekcje „Zabezpieczenia HTML” na stronie 31 i „Elementy ramek i ramek pływających HTML” na stronie 229. Informacje o wtyczkach i obiektach osadzonych Środowisko AIR obsługuje wtyczki Adobe® Acrobat®. W celu wyświetlania dokumentów PDF wymagany jest program Acrobat lub Adobe® Reader® 8.1 (lub wyższej wersji). Obiekt HTMLLoader udostępnia właściwość przeznaczoną do sprawdzania, czy system może wyświetlić plik PDF. Treść pliku SWF może również zostać wyświetlona w środowisku HTML, ale ta funkcja jest wbudowana w środowisko AIR i nie korzysta z zewnętrznych wtyczek. Żadne inne wtyczki Webkit nie są obsługiwane w AIR. Zobacz także „Zabezpieczenia HTML” na stronie 31 „Obszary izolowane HTML” na stronie 222 „Elementy ramek i ramek pływających HTML” na stronie 229 „Obiekt JavaScript Window” na stronie 228 „Obiekt XMLHttpRequest” na stronie 223 „Dodawanie treści w formacie PDF” na stronie 274 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 222 Informacje o środowisku HTML Rozszerzenia AIR i Webkit W środowisku Adobe AIR używany jest mechanizm Webkit, który jest również wykorzystywany w przeglądarce internetowej Safari. W środowisku AIR dostępnych jest kilka rozszerzeń klas środowiska wykonawczego i obiektów, a także rozszerzeń funkcji zabezpieczeń. Ponadto sam mechanizm Webkit dodaje funkcje niedostępne w standardach W3C dla HTML, CSS i JavaScript. W niniejszej sekcji omówiono tylko dodatki AIR oraz najbardziej istotne rozszerzenia Webkit; dodatkowa dokumentacja niestandardowych rozszerzeń dla HTML, CSS i JavaScript jest dostępna na stronie www.webkit.org oraz na stronie developer.apple.com. Informacje o standardach zawiera strona internetowa W3C. Mozilla udostępnia również istotne informacje ogólne na temat HTML, CSS i DOM (oczywiście mechanizmy Webkit i Mozilla nie są identyczne). Uwaga: Środowisko AIR nie obsługuje następujących standardowych i rozszerzonych funkcji WebKit: metoda print() obiektu JavaScript Window; wtyczki z wyjątkiem wtyczek dla programów Acrobat lub Adobe Reader 8.1+; skalowalna grafika wektorowa (SVG), właściwość CSS opacity. JavaScript w AIR Środowisko AIR wprowadza kilka zmian do typowego działania typowych obiektów JavaScript. Wiele z tych obiektów ma na celu ułatwianie zapisu bezpiecznych aplikacji w środowisku AIR. Jednocześnie te różnice w działaniu sprawiają, że wykonywanie w środowisku AIR niektórych wspólnych wzorców kodowania JavaScript i istniejących aplikacji sieci Web korzystających z tych wzorców, może być niezgodne z oczekiwaniami. Informacje na temat postępowania w przypadku takich problemów zawiera sekcja „Unikanie błędów JavaScript związanych z bezpieczeństwem” na stronie 237. Obszary izolowane HTML Środowisko AIR umieszcza treść do obszarów izolowanych w zależności od źródła treści. Reguły dotyczące obszarów izolowanych są spójne ze strategiami z tych samych źródeł implementowanymi przez większość przeglądarek sieci Web, a także z regułami dot. obszarów izolowanych, które są implementowane przez program Adobe Flash Player. Ponadto środowisko AIR udostępnia nowy typ obszaru izolowanego aplikacji, który może zawierać i chronić treść aplikacji. Więcej informacji na temat typów obszarów izolowanych, jakie można napotkać podczas programowania aplikacji AIR zawiera sekcja „Obszary izolowane” na stronie 28. Dostęp do środowiska wykonawczego oraz interfejsów API AIR jest możliwy tylko dla kodu HTML i JavaScript działającego w obszarze izolowanym aplikacji. Jednocześnie dynamiczna ocena i dynamiczne wykonywanie kodu JavaScript w różnych formach jest w znacznym stopniu ograniczone w obszarze izolowanym aplikacji z powodów związanych z bezpieczeństwem. Te ograniczenia obowiązują niezależnie od tego, czy aplikacja rzeczywiście ładuje informacje bezpośrednio z serwera. (Podejrzana może być nawet zawartość pliku, wklejane ciągi znaków oraz dane wprowadzane bezpośrednio przez użytkownika). Źródło treści w pliku określa obszar izolowany, do którego treść zostaje przekazana. Do obszaru izolowanego aplikacji wprowadzana jest tylko treść z katalogu aplikacji (katalog instalacyjny, do którego odwołuje się schemat URL app:). Zawartość ładowana z pliku systemowego jest umieszczana w obszarze izolowanym lokalnym z systemem plików oraz lokalnym zaufanym, co umożliwia dostęp i interakcje z zawartością w lokalnym obszarze z systemem plików, ale nie z zawartością zdalną. Zawartość ładowana z sieci jest umieszczana w zdalnym obszarze izolowanym odpowiadającym domenie źródła. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 223 Informacje o środowisku HTML Aby umożliwić aplikacji swobodne oddziaływanie z zawartością w zdalnym obszarze izolowanym, strona może zostać odwzorowana do tej samej domeny, do której odwzorowana została zawartość zdalna. Przykład: po napisaniu aplikacji, która wyświetla dane mapy z serwisu internetowego, możliwe jest odwzorowanie strony aplikacji, która ładuje i wyświetla treść z usługi, na domenę usługi. Atrybuty przeznaczone do odwzorowania stron na zdalny obszar izolowany oraz domenę to nowe atrybuty, które zostały dodane do elementów HTML ramek i ramek pływających. Aby umożliwić zawartości w nieaplikacyjnym obszarze izolowanym bezpieczne korzystanie z funkcji AIR, można ustawić most nadrzędnego obszaru izolowanego. Aby umożliwić treści aplikacji bezpieczne wywoływanie metod i dostęp do właściwości treści w innych obszarach izolowanych, należy skonfigurować most podrzędnego obszaru izolowanego. W tym przypadku bezpieczeństwo oznacza, że w treści zdalnej nie mogą przypadkowo powstać odwołania do obiektów, właściwości lub metod, które nie są jawnie udostępniane. Przez most mogą być przekazywane tylko proste typy danych, funkcje i anonimowe obiekty. Jednak należy unikać jawnego udostępniania potencjalnie niebezpiecznych funkcji. Jeśli na przykład udostępniono interfejs, który umożliwiał treści zdalnej odczytywanie i zapisywanie plików w dowolnym miejscu w systemie użytkownika, może to oznaczać, że treść zdalna może w znacznym stopniu zaszkodzić użytkownikowi. JavaScript eval(), funkcja Korzystanie z funkcji eval() po zakończeniu ładowania strony jest ograniczone do obszaru izolowanego aplikacji. Niektóre zastosowania są dozwolone, dzięki czemu dane w formacie JSON mogą być bezpiecznie analizowane, ale wynikowe instrukcje wykonywalne zawsze kończą się błędem. Sekcja „Ograniczenia kodu dotyczące treści różnych obszarów izolowanych” na stronie 33 zawiera opisy dozwolonych zastosowań funkcji eval(). Konstruktory funkcji W obszarze izolowanym aplikacji konstruktory funkcji mogą być używane zanim nastąpi zakończenie ładowania strony. Po zakończeniu wszystkich zdarzeń load strony nie ma możliwości tworzenia nowych funkcji. Ładowanie skryptów zewnętrznych Strony HTML w obszarze izolowanym aplikacji nie mogą korzystać ze znacznika script w celu ładowania plików JavaScript z zewnątrz katalogu aplikacji. Strona w aplikacji może załadować skrypt spoza katalogu aplikacji tylko wówczas, gdy strona została odwzorowana na nieaplikacyjny obszar izolowany. Obiekt XMLHttpRequest Środowisko AIR udostępnia obiekt XMLHttpRequest (XHR), z którego aplikacje mogą korzystać w celu wykonywania żądań danych. Poniższy przykład ilustruje proste żądanie dot. danych: 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); Środowisko AIR — w odróżnieniu od przeglądarki — umożliwia treści działającej w obszarze izolowanym aplikacji żądanie danych z dowolnej domeny. Wynikiem żądania XHR, który zawiera ciąg znaków JSON, mogą być dane, chyba że wynik zawiera również kod wykonywalny. Jeśli wynik żądania XHR zawiera instrukcje wykonywalne, zgłaszany jest błąd, a próba oceny kończy się niepowodzeniem. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 224 Informacje o środowisku HTML Aby zapobiec przypadkowemu wstrzykiwaniu kodu ze źródeł zdalnych, wywoływanie synchronicznego żądania XHR przed zakończeniem ładowania strony zwraca pusty wynik. Wywołanie asynchronicznych żądań XHR po załadowaniu strony zawsze zwraca wynik. Domyślnie środowisko AIR blokuje międzydomenowe żądania XMLHttpRequest w nieaplikacyjnych obszarach izolowanych. Okno nadrzędne w obszarze izolowanym aplikacji może zezwolić na żądania międzydomenowe w ramce podrzędnej zawierającej treść w nieaplikacyjnym obszarze izolowanym poprzez ustawienie dla atrybutu allowCrossDomainXHR (jest to atrybut dodany przez AIR) wartości true w zawierającym elemencie ramki lub ramki pływającej: <iframe id="mashup" src="http://www.example.com/map.html" allowCrossDomainXHR="true" </iframe> Uwaga: W razie potrzeby klasa AIR URLStream może również służyć do pobierania danych. W przypadku wywołania żądania XMLHttpRequest do serwera zdalnego z ramki lub ramki pływającej zawierającej treść aplikacji, która została odwzorowana do zdalnego obszaru izolowanego, należy się upewnić, że URL odwzorowania nie maskuje adresu serwera używanego w żądaniu XHR. Przykład: rozważmy poniższą definicję ramki pływającej, która odwzoruje treść aplikacji do zdalnego obszaru izolowanego, np. do domeny example.com: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/" allowCrossDomainXHR="true" </iframe> Atrybut sandboxRoot ponownie odwzorowuje główny adres URL adresu www.example.com, dlatego wszystkie żądania są ładowane z katalogu aplikacji, a nie z serwera zdalnego. Żądania są ponownie odwzorowywane niezależnie od tego, czy pochodzą ze strony nawigacji, czy z żądania XMLHttpRequest. Aby uniknąć przypadkowego zablokowania żądań danych w serwerze zdalnym, należy odwzorować sandboxRoot na podkatalog zdalnego adresu URL, a nie na katalog główny. Katalog nie musi istnieć. Przykład: aby umożliwić ładowanie żądań skierowanych do strony www.example.com z serwera zdalnego, a nie z serwera aplikacji, należy zmienić poprzednią ramkę pływającą na: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/" allowCrossDomainXHR="true" </iframe> W takim przypadku tylko treść z podkatalogu air jest ładowana lokalnie. Więcej informacji na temat odwzorowania obszaru izolowanego zawierają sekcje „Elementy ramek i ramek pływających HTML” na stronie 229 oraz „Zabezpieczenia HTML” na stronie 31. Obiekt Canvas Obiekt Canvas definiuje interfejs API przeznaczony do rysowania kształtów geometrycznych, takich jak linie, łuki, elipsy i wielokąty. W celu korzystania z API canvas należy najpierw dodać element canvas do dokumentu, a następnie rysować w obiekcie za pomocą API JavaScript Canvas. Pod innymi względami obiekt Canvas działa jak obraz. Poniższy przykład rysuje trójkąt za pomocą obiektu Canvas: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 225 Informacje o środowisku 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> Więcej informacji na temat API Canvas zawiera dokumentacja Safari JavaScript Reference firmy Apple. Niedawno w projekcie Webkit rozpoczęto zmiany API Canvas w celu standaryzacji wersji roboczej HTML 5 zaproponowanej przez grupę WHATWG (Web Hypertext Application Technology Working Group) i W3C. W rezultacie część dokumentacji Safari JavaScript Reference może być niezgodna z wersją obiektu canvas dostępną w środowisku AIR. Pliki cookie W aplikacjach AIR tylko zawartość w zdalnych obszarach izolowanych (zawartość ładowana ze źródeł http: i https:) może korzystać z plików cookie (właściwość document.cookie). W obszarze izolowanym aplikacji interfejsy API AIR udostępniają inne sposoby zapisu danych trwałych (np. klasy EncryptedLocalStore i FileStream). Obiekt Clipboard Interfejs API Clipboard WebKit jest sterowany przez następujące zdarzenia: copy, cut i paste. Obiekt event przekazywany w tych zdarzeniach zapewnia dostęp do schowka za pośrednictwem właściwości clipboardData. Poniższe metody obiektu clipboardData służą do zapisywania i odczytywania danych schowka: Metoda Opis clearData(mimeType) Czyści dane schowka. Należy ustawić parametr mimeType na typ MIME danych do wyczyszczenia. getData(mimeType) Pobiera dane schowka. Ta metoda może zostać wywołana wyłącznie w module obsługi dla zdarzenia paste. Należy ustawić parametr mimeType na typ MIME danych do zwrócenia. setData(mimeType, data) Kopiowanie tekstu do schowka. Należy ustawić parametr mimeType na typ MIME danych. Kod JavaScript poza obszarem izolowanym aplikacji może uzyskiwać dostęp do schowka wyłącznie za pośrednictwem tych zdarzeń. Jednak zawartość w obszarze izolowanym aplikacji może uzyskiwać dostęp do schowka systemowego bezpośrednio za pomocą klasy AIR Clipboard. Przykład: możliwe jest użycie następującej instrukcji w celu pobrania danych tekstowych ze schowka: var clipping = air.Clipboard.generalClipboard.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY); Poprawne typy danych MIME: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 226 Informacje o środowisku HTML Typ MIME Wartość Tekst "text/plain" HTML "text/html" URL "text/uri-list" Bitmapa "image/x-vnd.adobe.air.bitmap" Lista plików "application/x-vnd.adobe.air.file-list" Ważne: Dostęp do danych plików zawartych w skryptach ma tylko treść z obszaru izolowanego aplikacji. Jeśli treść nieaplikacyjna podejmuje próbę uzyskania dostępu do obiektu pliku ze schowka, zgłoszony zostaje błąd zabezpieczeń. Więcej informacji na temat korzystania ze schowka zawiera sekcja „Kopiowanie i wklejanie” na stronie 150 oraz sekcja Using the Pasteboard from JavaScript (Apple Developer Center). Przeciąganie i upuszczanie Gesty przeciągania i upuszczania do kodu HTML i na zewnątrz tego kodu powodują powstanie następujących zdarzeń DOM: dragstart, drag, dragend, dragenter, dragover, dragleave i drop. Obiekt zdarzenia przekazywany w tych zdarzeniach zapewnia dostęp do przeciągniętych danych za pośrednictwem właściwości dataTransfer. Właściwość dataTransfer odwołuje się do obiektu, który udostępnia te same metody, co obiekt clipboardData skojarzony ze zdarzeniem clipboard. Na przykład: można użyć następującej funkcji w celu pobrania danych tekstowych ze zdarzenia drop: function onDrop(dragEvent){ return dragEvent.dataTransfer.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY); } Obiekt dataTransfer zawiera następujące ważne elementy: Element Opis clearData(mimeType) Czyści dane. Należy ustawić parametr mimeType na typ MIME reprezentacji danych przeznaczonych do wyczyszczenia. getData(mimeType) Pobiera przeciągnięte dane. Ta metoda może zostać wywołana wyłącznie w module obsługi dla zdarzenia drop. Należy ustawić parametr mimeType na typ MIME danych do pobrania. setData(mimeType, data) types Ustawia dane do przeciągnięcia. Należy ustawić parametr mimeType na typ MIME danych. Tablica ciągów znaków zawierająca typy MIME wszystkich danych aktualnie dostępnych w obiekcie dataTransfer. effectsAllowed Określa, czy dane przeciągane mogą być kopiowane, przenoszone, łączone lub czy możliwe jest wykonywanie kombinacji tych czynności. Właściwość effectsAllowed w module obsługi należy ustawić na zdarzenie dragstart. dropEffect Określa dozwolone efekty przeciągania, które są obsługiwane przez cel przeciągania. Należy ustawić właściwość dropEffect w module obsługi na zdarzenie dragEnter. Podczas przeciągania kursor zmienia się w celu wskazania efektu, jaki będzie miało zwolnienie przycisku myszy. Jeśli nie określono wartości dropEffect, wybierany jest efekt metody effectsAllowed. Efekt kopiowania ma priorytet wyższy niż efekt przeciągania, który ma priorytet wyższy od efektu łączenia. Użytkownik może za pomocą klawiatury zmodyfikować domyślną właściwość. Więcej informacji na temat dodawania funkcji obsługi operacji przeciągania i upuszczania do aplikacji AIR zawiera sekcja „Przeciąganie i upuszczanie” na stronie 134 oraz sekcja Using the Drag-and-Drop from JavaScript (Apple Developer Center). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 227 Informacje o środowisku HTML Właściwości innerHTML i outerHTML Środowisko AIR definiuje ograniczenia dotyczące korzystania z właściwości innerHTML i outerHTML dla treści działającej w obszarze izolowanym aplikacji. Przed zdarzeniem ładowania strony, a także podczas działania modułów obsługi zdarzeń ładowania, korzystanie z właściwości innerHTML i outerHTML jest nieograniczone. Jednak po załadowaniu strony można korzystać tylko z właściwości innerHTML lub outerHTML w celu dodawania do dokumentu treści statycznych. Wszelkie instrukcje w ciągu znaków przypisanym do właściwości innerHTML lub outerHTML, które dotyczą kodu wykonywalnego, są ignorowane. Na przykład: w przypadku dołączenia atrybutu wywołania zdarzenia do definicji elementu detektor zdarzenia nie jest dodawany. I podobnie — osadzone znaczniki <script> również są ignorowane. Więcej informacji zawiera sekcja „Zabezpieczenia HTML” na stronie 31. Metody Document.write() i Document.writeln() Przed wystąpieniem zdarzenia loadstrony stosowanie metod write() i writeln() w obszarze izolowanym aplikacji nie jest ograniczone. Jednak po załadowaniu strony wywołanie dowolnej z tych metod nie powoduje wyczyszczenia strony ani utworzenia nowej. W nieaplikacyjnym obszarze izolowanym, jak w większości przeglądarek internetowych, wywołanie metody document.write() lub writeln() po zakończeniu ładowania strony powoduje wyczyszczenie bieżącej strony i otwarcie nowej, pustej. Document.designMode, właściwość Aby umożliwić edycję wszystkich elementów w dokumencie, należy ustawić dla właściwości document.designMode wartość on. Wbudowane funkcje obsługi edytora obsługują edytowanie, kopiowanie, wklejanie oraz przeciąganie i upuszczanie tekstu. Ustawienie dla właściwości designMode wartości on jest równoważne ustawieniu właściwości contentEditable elementu body na wartość true. Właściwość contentEditable może być używana w większości elementów HTML w celu określenia w dokumencie sekcji dostępnych do edycji. Dodatkowe informacje zawiera sekcja „Atrybut contentEditable HTML” na stronie 232. Zdarzenia unload (dla obiektów body i frameset) W znaczniku frameset lub body najwyższego poziomu okna (łącznie z głównym oknem aplikacji) nie należy używać zdarzenia unload w celu reagowania na zamykane okno (lub aplikację). Zamiast tego należy użyć zdarzenia exiting obiektu NativeApplication (w celu wykrycia zamykania aplikacji). Lub należy użyć zdarzenia closing obiektu NativeWindow (w celu wykrycia zamykania okna). Przykład: poniższy kod JavaScript wyświetla komunikat ("Goodbye."), gdy użytkownik zamyka aplikację: var app = air.NativeApplication.nativeApplication; app.addEventListener(air.Event.EXITING, closeHandler); function closeHandler(event) { alert("Goodbye."); } Jednak skrypty mogą pomyślnie odpowiadać na zdarzenie unload wywołane poprzez nawigowanie w ramce, ramce pływającej lub w treści w oknie najwyższego poziomu. Uwaga: Te ograniczenia mogą zostać usunięte w przyszłych wersjach środowiska Adobe AIR. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 228 Informacje o środowisku HTML Obiekt JavaScript Window Obiekt Window pozostaje globalnym obiektem w kontekście wykonywania kodu JavaScript. W obszarze izolowanym aplikacji środowisko AIR dodaje nowe właściwości do obiektu JavaScript Window w celu zapewnienia dostępu do wbudowanych klas AIR, a także ważnych obiektów obsługiwanych. Ponadto niektóre metody i właściwości działają różnie w zależności od tego, czy znajdują się w obszarze izolowanym aplikacji, czy nie. Window.runtime, właściwość Właściwość runtime umożliwia tworzenie instancji oraz korzystanie z wbudowanych klas środowiska wykonawczego z obszaru izolowanego aplikacji. Do tych klas należą interfejsy API AIR i Flash Player (ale nie należy np. struktura Flex). Na przykład: poniższa instrukcja tworzy obiekt pliku AIR: var preferencesFile = new window.runtime.flash.filesystem.File(); Plik AIRAliases.js dostępny w pakiecie SDK AIR zawiera definicje aliasów, które umożliwiają skrócenie takich odwołań. Na przykład: jeśli plik AIRAliases.js zostanie zaimportowany na stronę, wówczas obiekt File może zostać utworzony za pomocą poniższej instrukcji: var preferencesFile = new air.File(); Właściwość window.runtime jest zdefiniowana tylko dla treści w obszarze izolowanym aplikacji oraz tylko dla dokumentu nadrzędnego strony w ramkach i ramkach pływających. Patrz „Korzystanie z pliku AIRAliases.js” na stronie 241. Właściwość Window.nativeWindow Właściwość nativeWindow udostępnia odwołanie do podstawowego rodzimego obiektu window. Za pomocą tej właściwości można pisać skrypty dot. funkcji okien oraz właściwości, takich jak położenie na ekranie, wielkość i widoczność. Ta właściwość służy również do obsługi zdarzeń window, takich jak zamykanie, zmiana wielkości i przenoszenie. Na przykład: poniższa instrukcja zamyka okno: window.nativeWindow.close(); Uwaga: Funkcje sterowania oknami udostępnione przez obiekt NativeWindow zastępują funkcje udostępnione przez obiekt JavaScript Window. W takich przypadkach możliwe jest korzystanie z dowolnej metody. Właściwość window.nativeWindow jest zdefiniowana tylko dla treści w obszarze izolowanym aplikacji oraz tylko dla dokumentu nadrzędnego strony w ramkach i ramkach pływających. Właściwość Window.htmlLoader Właściwość htmlLoader udostępnia odwołanie do obiektu AIR HTMLLoader, który zawiera treść HTML. Za pomocą tej właściwości można tworzyć skrypty określające wygląd i działanie środowiska HTML. Na przykład: za pomocą właściwości htmlLoader.paintsDefaultBackground można określić, czy element sterowania będzie miał domyślne białe tło: window.htmlLoader.paintsDefaultBackground = false; Uwaga: Obiekt HTMLLoader ma właściwość window, która odwołuje się do obiektu JavaScript Window treści HTML, jaką zawiera. Za pomocą tej właściwości można uzyskać dostęp do środowiska JavaScript za pośrednictwem odwołania do zawierającego obiektu HTMLLoader. Właściwość window.htmlLoader jest zdefiniowana tylko dla treści w obszarze izolowanym aplikacji oraz tylko dla dokumentu nadrzędnego strony w ramkach i ramkach pływających. Właściwości Window.parentSandboxBridge i Window.childSandboxBridge Właściwości parentSandboxBridge i childSandboxBridge umożliwiają zdefiniowanie połączenia między ramką nadrzędną i podrzędną. Więcej informacji zawiera sekcja „Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych” na stronie 249. Funkcje Window.setTimeout() i Window.setInterval() Środowisko AIR definiuje ograniczenia dotyczące korzystania z funkcji setTimeout() i setInterval() w obszarze izolowanym aplikacji. Poprzez wywołanie funkcji setTimeout() lub setInterval() nie można zdefiniować kodu, jaki powinien zostać wywołany, w postaci ciągu znaków. W tym celu należy użyć odwołania do funkcji. Więcej informacji zawiera sekcja „setTimeout() i setInterval()” na stronie 239. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 229 Informacje o środowisku HTML Funkcja Window.open() Metoda open() wywołana przez kod działający w nieaplikacyjnym obszarze izolowanym otwiera okno tylko wówczas, gdy zostaje wywołana w wyniku interakcji użytkownika (np. kliknięcia lub naciśnięcia klawisza). Ponadto przed tytułem okna umieszczony zostaje tytuł aplikacji (dzięki czemu okna otwierane przez treści zdalne nie uosabiają okien otwieranych przez aplikację). Więcej informacji zawiera sekcja „Ograniczenia dotyczące wywoływania metody window.open() JavaScript” na stronie 35. Obiekt air.NativeApplication Obiekt NativeApplication udostępnia informacje o stanie aplikacji, wywołuje kilka ważnych zdarzeń na poziomie aplikacji oraz udostępnia użyteczne funkcje przeznaczone do kontrolowania działania aplikacji. Pojedyncza instancja obiektu NativeApplication jest tworzona automatycznie i można do niej uzyskać dostęp przez właściwość NativeApplication.nativeApplication zdefiniowaną przez klasę. Aby uzyskać dostęp do obiektu z kodu JavaScript można użyć kodu: var app = window.runtime.flash.desktop.NativeApplication.nativeApplication; Lub jeśli zaimportowano skrypt AIRAliases.js, można użyć krótszej formy: var app = air.NativeApplication.nativeApplication; Dostęp do obiektu NativeApplication można uzyskać tylko z obszaru izolowanego aplikacji. Sekcja „Praca z informacjami o środowisku wykonawczym i systemie operacyjnym” na stronie 301 opisuje szczegółowo obiekt NativeApplication. Schemat URL JavaScript Wykonywanie kodu zdefiniowanego w schemacie JavaScript URL (np. href="javascript:alert('Test')") jest blokowane w obszarze izolowanym aplikacji. Nie jest zgłaszany żaden błąd. Rozszerzenia HTML Środowiska AIR i WebKit definiują kilka niestandardowych elementów i atrybutów HTML, między innymi: „Elementy ramek i ramek pływających HTML” na stronie 229 „Element Canvas HTML” na stronie 231 „Moduły obsługi zdarzeń elementów HTML” na stronie 232 Elementy ramek i ramek pływających HTML Środowisko AIR dodaje nowe atrybuty do elementów ramek i ramek pływających treści w obszarze izolowanym aplikacji: sandboxRoot, atrybut Atrybut sandboxRoot określa alternatywną, nieaplikacyjną domenę dla pliku określonego przez atrybut src ramki. Plik jest ładowany do nieaplikacyjnego obszaru izolowanego, który odpowiada danej domenie. Skrypty treści pliku i treści ładowanej z określonej domeny mogą odwoływać się do siebie wzajemnie. Ważne: Jeśli wartość sandboxRoot zostanie zmieniona na podstawowy adres URL domeny, wówczas wszystkie żądania z domeny zostaną załadowane z katalogu aplikacji, a nie z serwera zdalnego (niezależnie od tego, czy żądanie wynikło z nawigacji na stronie, jest żądaniem XMLHttpRequest lub wynikło z innego sposobu ładowania treści). Atrybut documentRoot Atrybut documentRoot określa katalog lokalny, z którego ładowane są adresy URL wskazujące na pliki w lokalizacji określonej przez sandboxRoot. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 230 Informacje o środowisku HTML Podczas odczytywania adresów URL w atrybucie src ramki lub w treści załadowanej do ramki część adresu URL zgodna z wartością określoną w sandboxRoot jest zastępowana wartością określoną w documentRoot. W poniższym znaczniku ramki: <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/"/> kod child.html jest ładowany z podkatalogu sandbox folderu instalacyjnego aplikacji. Względne adresy URL w child.html są odczytywane na podstawie katalogu sandbox. Pliki z serwera zdalnego www.example.com/air nie są dostępne w ramce, ponieważ środowisko AIR podejmuje próby załadowania tych plików z katalogu app:/sandbox/. Atrybut allowCrossDomainXHR Aby umożliwić treści z ramki wysyłanie żądań XMLHttpRequest do dowolnej domeny zdalnej, należy dołączyć kod allowCrossDomainXHR="allowCrossDomainXHR" do ramki otwierającej. Domyślnie treść nieaplikacyjna może wysyłać takie żądania tylko do własnej domeny źródłowej. Istnieją poważne ograniczenia dot. zabezpieczeń związanych z zezwoleniem na stosowanie międzydomenowych żądań XHR. Kod na stronie może wymieniać dane w dowolnej domenie. Jeśli treści złośliwe zostaną wstrzyknięte do strony, zagrożone będą wszystkie dane dostępne dla kodu znajdujące się w bieżącym obszarze izolowanym. Międzydomenowe żądania XHR można umożliwić wyłącznie dla stron tworzonych i kontrolowanych i tylko wówczas, gdy międzydomenowe ładowanie danych jest naprawdę niezbędne. Ponadto należy uważnie sprawdzić wszystkie dane zewnętrzne ładowane przez stronę, aby zapobiec wstrzykiwaniu kodu lub innym formom ataku. Ważne: Jeśli atrybut allowCrossDomainXHR został dołączony do elementu ramki lub ramki pływającej, międzydomenowe żądania XHR są możliwe (chyba że wartość jest równa „0” lub rozpoczyna się od liter „f” albo „n”). Na przykład: ustawienie dla allowCrossDomainXHR wartości "deny" nadal umożliwia międzydomenowe żądania XHR. Jeśli żądania międzydomenowe mają być zabronione, należy pozostawić atrybut poza deklaracją elementu. Atrybut ondominitialize Określa moduł obsługi zdarzenia dominitialize ramki. To zdarzenie jest właściwe dla środowiska AIR i uruchamiane jest po utworzeniu obiektów window lub document ramki, ale przed analizowaniem skryptów lub utworzeniem elementów dokumentów. Ramka wywołuje zdarzenie dominitialize odpowiednio wcześnie w sekwencji ładowania, aby skrypt na każdej stronie podrzędnej mógł odwoływać się do obiektów, zmiennych i funkcji dodawanych do dokumentu podrzędnego przez moduł obsługi dominitialize. Strona nadrzędna musi znajdować się w tym samym obszarze izolowanym co podrzędna — wówczas może bezpośrednio dodawać albo uzyskiwać dostęp do obiektów w dokumencie podrzędnym. Jednak dokument nadrzędny w obszarze izolowanym aplikacji może utworzyć most (obszaru podrzędnego) w celu nawiązania komunikacji z treścią w obszarze izolowanym. Poniższe przykłady ilustrują użycie znacznika iframe w środowisku AIR: Umieszczanie dokumentu child.html w zdalnym obszarze izolowanym bez odwzorowania do rzeczywistej domeny na serwerze zdalnym: <iframe src="http://localhost/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://localhost/air/"/> Umieszczanie dokumentu child.html w zdalnym obszarze izolowanym i zezwolenie na generowanie żądań XMLHttpRequest tylko do strony www.example.com: <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/"/> Umieszczanie dokumentu child.html w zdalnym obszarze izolowanym i zezwolenie na generowanie żądań XMLHttpRequest tylko do domeny zdalnej: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 231 Informacje o środowisku HTML <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/" allowCrossDomainXHR="allowCrossDomainXHR"/> Umieszczenie dokumentu child.html w lokalnym obszarze izolowanym z systemem plików: <iframe src="file:///templates/child.html" documentRoot="app:/sandbox/" sandboxRoot="app-storage:/templates/"/> Umieszczenie dokumentu child.html w zdalnym obszarze izolowanym za pomocą zdarzenia dominitialize w celu ustawienia mostu obszaru izolowanego: <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> Poniższy dokument child.html ilustruje, jak treść dokumentu podrzędnego może uzyskać dostęp do mostu obszaru izolowanego dokumentu nadrzędnego: <html> <head> <script> document.write(window.parentSandboxBridge.testProperty); </script> </head> <body></body> </html> Więcej informacji zawierają sekcje „Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych” na stronie 249 i „Zabezpieczenia HTML” na stronie 31. Element Canvas HTML Definiuje obszar rysowania do użytku z interfejsem API Webkit Canvas. Komendy graficzne nie mogą być określane w znaczniku. W celu rysowania w obszarze roboczym (canvas) należy wywołać metody rysowania canvas za pośrednictwem JavaScript. <canvas id="drawingAtrium" style="width:300px; height:300px;"></canvas> Więcej informacji zawiera sekcja „Obiekt Canvas” na stronie 224. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 232 Informacje o środowisku HTML Moduły obsługi zdarzeń elementów HTML Obiekty DOM w AIR i Webkit wywołują niektóre zdarzenia niedostępne w standardowym modelu zdarzeń DOM. W poniższej tabeli przedstawiono powiązane atrybuty zdarzeń, za pomocą których można określać moduły obsługi dla tych zdarzeń: Nazwa atrybutu wywołania Opis zwrotnego oncontextmenu Wywoływany przy wywołaniu menu kontekstowego, np. poprzez kliknięcie prawym przyciskiem myszy lub kliknięcie z wciśniętym klawiszem Command w zaznaczonym tekście. oncopy Wywoływany w przypadku kopiowania zaznaczenia elementu. oncut Wywoływany w przypadku wycinania zaznaczenia elementu. ondominitialize Wywoływany, gdy tworzony jest model DOM dokumentu załadowanego do ramki lub ramki pływającej, ale przed utworzeniem elementów DOM i przed analizowaniem skryptów. ondrag Wywoływany przy przeciąganiu elementu. ondragend Wywoływany po zakończeniu przeciągania. ondragenter Wywoływany, gdy gest przeciągania sięga do wnętrza granic elementu. ondragleave Wywoływany, gdy gest przeciągania sięga na zewnątrz granic elementu. ondragover Wywoływany w sposób ciągły, gdy gest przeciągania znajduje się w granicach elementu. ondragstart Wywoływany przy rozpoczęciu gestu przeciągania. ondrop Wywoływany po zwolnieniu gestu przeciągania nad elementem. onerror Wywoływany w przypadku błędu podczas ładowania elementu. oninput Wywoływany, gdy tekst zostanie wprowadzony do elementu formularza. onpaste Wywoływany, gdy pozycja została wklejona do elementu. onscroll Wywołany podczas przewijania treści przewijanego elementu. onsearch Wywoływany podczas kopiowania elementu (? Apple docs correct ?) onselectstart Wywoływany po rozpoczęciu zaznaczania. Atrybut contentEditable HTML Atrybut contentEditable można dodać do dowolnego elementu HTML, aby umożliwić użytkownikom edytowanie treści elementu. Poniższy przykładowy kod HTML ustawia cały dokument jako dostępny do edycji, z wyjątkiem pierwszego elementu p: <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> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 233 Informacje o środowisku HTML Uwaga: Jeśli właściwość document.designMode ma wartość on, wówczas wszystkie elementy w dokumencie są dostępne do edycji, bez względu na ustawienie contentEditable w poszczególnych elementach. Jednak ustawienie właściwości designMode na off, nie uniemożliwia edytowania elementów, dla których właściwość contentEditable ma wartość true. Dodatkowe informacje zawiera sekcja „Document.designMode, właściwość” na stronie 227. Rozszerzenia CSS WebKit obsługuje kilka rozszerzonych właściwości CSS. W poniższej tabeli przedstawiono rozszerzone właściwości, które są obsługiwane. WebKit udostępnia również inne niestandardowe właściwości, ale nie są one w pełni obsługiwane w AIR, ponieważ są nadal tworzone przez WebKit lub dlatego, że są to funkcje eksperymentalne, które zostaną usunięte w przyszłości. Nazwa właściwości CSS Wartości Opis -webkit-border-horizontal-spacing Nieujemna jednostka długości Określa poziomy składnik krawędzi. -webkit-border-vertical-spacing Nieujemna jednostka długości Określa pionowy składnik krawędzi. -webkit-line-break after-white-space, normal Określa regułę podziału wierszy dla tekstu w języku chińskim, japońskim i koreańskim (CJK). -webkit-margin-bottom-collapse collapse, discard, separate Określa sposób zwijania dolnego marginesu komórki tabeli. -webkit-margin-collapse collapse, discard, separate Określa sposób zwijania górnego i dolnego marginesu komórki tabeli. -webkit-margin-start Dowolna jednostka długości. Szerokość marginesu początkowego. W przypadku tekstu pisanego od lewej do prawej ta właściwość zastępuje margines lewy. W przypadku tekstu pisanego od prawej do lewej ta właściwość zastępuje margines prawy. -webkit-margin-top-collapse collapse, discard, separate Określa sposób zwijania górnego marginesu komórki tabeli. -webkit-nbsp-mode normal, space Definiuje działanie spacji nierozdzielających w zawartej treści. -webkit-padding-start Dowolna jednostka długości. Określa szerokość dopełnienia początkowego. W przypadku tekstu pisanego od lewej do prawej ta właściwość zastępuje dopełnienie z lewej. W przypadku tekstu pisanego od prawej do lewej ta właściwość zastępuje dopełnienie z prawej. -webkit-rtl-ordering logical, visual Zastępuje domyślny sposób obsługi tekstu mieszanego: pisanego od lewej do prawej i od prawej do lewej. -webkit-text-fill-color Dowolny nazwany kolor lub wartość liczbowa koloru Określa kolor wypełnienia tekstu. -webkit-text-security circle, disc, none, square Określa kształt zastępujący znaki w polu wprowadzania hasła. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 234 Informacje o środowisku HTML Nazwa właściwości CSS Wartości Opis -webkit-user-drag • auto — działanie domyślne Zastępuje domyślne działanie przeciągania. • element — przeciągany jest cały element • none — element nie może być przeciągany -webkit-user-modify read-only, read-write, read-writeplaintext-only Określa, czy możliwa jest edycja treści elementu. -webkit-user-select • auto — działanie domyślne Określa, czy użytkownik może zaznaczyć treść elementu. • none — element nie może zostać zaznaczony • text — w elemencie możliwe jest zaznaczenie tylko tekstu Więcej informacji zawiera dokumentacja Apple Safari CSS Reference (http://developer.apple.com/documentation/AppleApplications/Reference/SafariCSSRef/). 235 Rozdział 21: Programowanie w językach HTML i JavaScript Istnieje wiele unikalnych zagadnień programowania w procesie tworzenia aplikacji Adobe® AIR™ za pomocą HTML i JavaScript. Niniejsze informacje są istotne niezależnie od tego, czy tworzona jest aplikacja AIR w formacie HTML czy w formacie SWF, która uruchamia kod HTML i JavaScript za pomocą klasy HTMLLoader (lub składnika mx:HTML Flex™ ). Informacje o klasie HTMLLoader Klasa HTMLLoader środowiska Adobe AIR definiuje obiekt wyświetlany, który może w aplikacji AIR wyświetlać treść HTML. Aplikacje w formacie SWF mogą dodawać element sterowania HTMLLoader do istniejącego okna lub tworzyć okno HTML, które automatycznie zawiera obiekt HTMLLoader z metodą HTMLLoader.createRootWindow(). Do obiektu HTMLLoader dostęp można uzyskać za pomocą właściwości window.htmlLoader JavaScript z załadowanej strony HTML. Ładowanie treści HTML z adresu URL Poniższy kod ładuje adres URL do obiektu HTMLLoader (dodaje obiekt HTMLLoader jako obiekt potomny stołu montażowego lub innego kontenera obiektu wyświetlanego w celu wyświetlenia treści HTML w aplikacji): 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); Obie właściwości width i height obiektu HTMLLoader domyślnie ustawione są na wartość 0. Programista ustawia te wymiary podczas dodawania obiektu HTMLLoader na stół montażowy. W czasie ładowania strony obiekt HTMLLoader wywołuje kilka zdarzeń. Zdarzeń tych można użyć do określenia, kiedy bezpieczna jest interakcja z załadowaną stroną. Zdarzenia opisane zostały w rozdziale „Obsługa zdarzeń powiązanych z HTML” na stronie 254. Programista może także renderować tekst HTML za pomocą klasy TextField, ale jej możliwości są ograniczone. Klasa TextField programu Adobe® Flash® Player obsługuje podzestaw znaczników HTML, jednak ze względu na ograniczenia rozmiaru ograniczone zostały jej możliwości. (Klasa HTMLLoader zawarta w środowisku Adobe AIR jest niedostępna w programie Flash Player). Ładowanie treści HTML z ciągu znaków Metoda loadString() obiektu HTMLLoader ładuje ciąg znaków treści HTML do obiektu HTMLLoader: var html:HTMLLoader = new HTMLLoader(); var htmlStr:String = "<html><body>Hello <b>world</b>.</body></html>"; html.loadString(htmlStr); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 236 Programowanie w językach HTML i JavaScript Domyślnie treść załadowana za pomocą metody loadString() jest umieszczana w nieaplikacyjnym obszarze izolowanym o następujących cechach: • Obszar izolowany ma dostęp z sieci do ładowanej treści (ale nie z systemu plików). • Obszar izolowany nie może ładować danych za pomocą XMLHttpRequest. • Właściwość window.location ma wartość "about:blank". • Treść nie może mieć dostępu do właściwości window.runtime (analogicznie treść w dowolnym nieaplikacyjnym obszarze izolowanym może). W środowisku AIR 1.5 klasa HTMLLoader zawiera właściwość placeLoadStringContentInApplicationSandbox. Jeśli ta właściwość ma wartość true dla obiektu HTMLLoader, treść załadowana za pomocą metody loadString() jest umieszczona w obszarze izolowanym aplikacji. (Wartością domyślną jest false). Daje to dostęp treści załadowanej za pomocą metody loadString() do właściwości window.runtime oraz do wszystkich interfejsów API środowiska AIR. Jeśli dla tej właściwości zostanie ustawiona wartość true, należy upewnić się, że źródło danych dla ciągu znaków użyte w wywołaniu metody loadString() jest zaufane. Instrukcje kodu w ciągu znaków HTML są wykonywane z pełnymi uprawnieniami aplikacji, jeśli ta właściwość ma wartość true. Tę właściwość należy ustawić na wartość true tylko wtedy, gdy użytkownik ma pewność, że ciąg znaków nie zawiera szkodliwego kodu. W aplikacjach skompilowanych za pomocą programu AIR 1.0 SDK lub AIR 1.1 SDK treść załadowana za pomocą metody loadString() jest umieszczana w obszarze izolowanym aplikacji. Ważne reguły zabezpieczeń podczas używania kodu HTML w aplikacjach AIR Pliki instalowane z aplikacją AIR mają dostęp do interfejsu API środowiska AIR. Ze względów bezpieczeństwa treść z innych źródeł nie ma tego dostępu. Na przykład: ograniczenie to uniemożliwia treści ze zdalnej domeny (np. http://example.com) na odczyt treści z katalogu pulpitu użytkownika (lub gorzej). Ponieważ istnieją luki bezpieczeństwa, które mogą zostać wykorzystane przez wywołanie funkcji eval() (i powiązane interfejsy API), domyślnie treść zainstalowana z aplikacją została ograniczona przed używaniem tych metod. Jednak niektóre środowiska Ajax używają funkcji eval() i powiązanych interfejsów API. Aby poprawnie zbudować treść do pracy w aplikacji AIR, należy wziąć pod uwagę reguły ograniczeń bezpieczeństwa dla treści z różnych źródeł. Treść z różnych źródeł umieszczana jest w oddzielnych klasyfikacjach bezpieczeństwa nazywanych obszarami izolowanymi (patrz „Obszary izolowane” na stronie 28). Domyślnie treść instalowana z aplikacją instalowana jest w obszarze izolowanym nazywanym obszarem izolowanym aplikacji, co daje jej dostęp do interfejsów API środowiska AIR. Obszar izolowany aplikacji jest zazwyczaj najbezpieczniejszym obszarem izolowanym z ograniczeniami zaprojektowanymi do zapobiegania wykonania niezaufanego kodu. Środowisko wykonawcze umożliwia załadowanie treści zainstalowanej z aplikacją do obszaru izolowanego innego niż obszar izolowany aplikacji. Treść w nieaplikacyjnym obszarze izolowanym działa w środowisku bezpieczeństwa podobnym do środowiska typowej przeglądarki internetowej. Na przykład: kod w nieaplikacyjnym obszarze izolowanym może użyć funkcji eval() i powiązanych metod (ale w tym samym czasie dostęp do interfejsów API środowiska AIR jest niedozwolony). Środowisko wykonawcze zawiera różne sposoby na bezpieczną komunikację treści z innych obszarów izolowanych (np. bez udostępniania interfejsów API środowiska AIR dla treści nieaplikacyjnej). Szczegóły zawiera sekcja „Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych” na stronie 249. Jeśli wywołany zostanie kod, którego użycie zostało ograniczone ze względów bezpieczeństwa, środowisko wykonawcze zgłosi błąd JavaScript o treści podobnej do następującej: „Naruszenie zabezpieczeń środowiska wykonawczego Adobe AIR dla kodu JavaScript w obszarze izolowanym zabezpieczeń aplikacji”. Aby uniknąć tego błędu, należy zastosować praktyki kodowania opisane w kolejnej sekcji — „Unikanie błędów JavaScript związanych z bezpieczeństwem” na stronie 237. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 237 Programowanie w językach HTML i JavaScript Więcej informacji zawiera sekcja „Zabezpieczenia HTML” na stronie 31. Unikanie błędów JavaScript związanych z bezpieczeństwem Jeśli wywołany zostanie kod, którego użycie zostało ograniczone ze względu na ograniczenia bezpieczeństwa, środowisko wykonawcze zgłosi błąd JavaScript o następującej treści: „Naruszenie zabezpieczeń środowiska wykonawczego Adobe AIR dla kodu JavaScript w obszarze izolowanym zabezpieczeń aplikacji”. Aby uniknąć tego błędu, należy zastosować poniższe praktyki kodowania. Przyczyny błędów JavaScript związanych z bezpieczeństwem Dostęp kodu wykonywanego w obszarze izolowanym aplikacji jest ograniczony dla większości operacji, które dotyczą interpretacji i wykonania ciągów znaków po uruchomieniu zdarzenia load dokumentu i zakończenia działania dowolnego modułu obsługi zdarzeń load. Próba użycia poniższych typów instrukcji JavaScript, które interpretują i wykonują potencjalnie niebezpieczne ciągi znaków generują błędy JavaScript: • Funkcja eval() • setTimeout() i setInterval() • Konstruktor funkcji Ponadto poniższe typy instrukcji JavaScript zakończą się niepowodzeniem bez generowania niebezpiecznego błędu JavaScript: • Adresy URL javascript: • Wywołania zwrotne zdarzenia przypisane za pomocą atrybutu onevent w instrukcjach innerHTML i outerHTML • Ładowanie plików JavaScript spoza katalogu instalacyjnego aplikacji • document.write() i document.writeln() • Synchroniczne XMLHttpRequests przed zdarzeniem load lub w czasie działania modułu obsługi zdarzenia load • Dynamicznie utworzone elementy skryptu Uwaga: W niektórych ograniczonych przypadkach obliczenie wartości dla ciągów znaków jest dozwolone. (Więcej informacji zawiera sekcja „Ograniczenia kodu dotyczące treści różnych obszarów izolowanych” na stronie 33). Firma Adobe przechowuje listę środowisk Ajax, które wspierają obsługę bezpiecznych obszarów izolowanych aplikacji na stronie http://www.adobe.com/go/airappsandboxframeworks_pl. Poniższe sekcje wyjaśniają w jaki sposób ponownie napisać skrypty, aby uniknąć niebezpiecznych błędów JavaScript i cichych błędów dla kodu działającego w obszarze izolowanym aplikacji. Odwzorowywanie treści aplikacji w różnych obszarach izolowanych W większości przypadków programista może ponownie napisać lub zmienić strukturę aplikacji w celu uniknięcia błędów JavaScript związanych z bezpieczeństwem. Jeśli jednak ponowne napisanie lub zmiana struktury nie jest możliwa, treść aplikacji można załadować do innego obszaru izolowanego za pomocą techniki opisanej w sekcji „Ładowanie treści aplikacji do nieaplikacyjnego obszaru izolowanego” na stronie 250. Jeśli treść również musi mieć dostęp do interfejsów API środowiska AIR, należy wówczas utworzyć most obszaru izolowanego w sposób opisany w sekcji „Konfigurowanie interfejsu mostu obszaru izolowanego” na stronie 251. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 238 Programowanie w językach HTML i JavaScript Funkcja eval() W obszarze izolowanym aplikacji funkcja eval() może być używana jedynie przed zdarzeniem load strony lub w czasie działania modułu obsługi zdarzeń load. Po załadowaniu strony wywołanie funkcji eval() nie spowoduje wykonania kodu. Jednak w poniższych przypadkach można ponownie napisać kod, aby uniknąć użycia funkcji eval(). Przypisywanie właściwości do obiektu Zamiast przekształcać ciąg znaków w celu utworzenia akcesora właściwości: eval("obj." + propName + " = " + val); do dostępu do właściwości należy użyć notacji z nawiasami: obj[propName] = val; Tworzenie funkcji ze zmiennymi dostępnymi kontekstowo Zastąp instrukcje w następujący sposób: function compile(var1, var2){ eval("var fn = function(){ this."+var1+"(var2) }"); return fn; } na: function compile(var1, var2){ var self = this; return function(){ self[var1](var2) }; } Tworzenie obiektu z użyciem nazwy klasy jako parametru w postaci ciągu znaków Rozważmy hipotetyczną klasę JavaScript zdefiniowaną za pomocą poniższego kodu: var CustomClass = { Utils: { Parser: function(){ alert('constructor') } }, Data: { } }; var constructorClassName = "CustomClass.Utils.Parser"; Najprostszym sposobem na utworzenie instancji będzie użycie funkcji eval(): var myObj; eval('myObj=new ' + constructorClassName +'()') Można jednak uniknąć wywołania funkcji eval() przez przekształcenie każdego składnika o danej nazwie klasy i utworzenie nowego obiektu za pomocą notacji z nawiasami: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 239 Programowanie w językach HTML i 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; } Aby utworzyć instancję, użyj: try{ var Parser = getter(constructorClassName); var a = new Parser(); }catch(e){ alert(e); } setTimeout() i setInterval() Zastąp ciąg znaków przekazany jako funkcja modułu obsługi odwołaniem funkcji lub obiektem. Na przykład: zastąp instrukcję: setTimeout("alert('Timeout')", 10); na: setTimeout(alert('Timeout'), 10); Lub jeśli funkcja wymaga, aby obiekt this był ustawiony przez obiekt wywołujący, zastąp instrukcję: this.appTimer = setInterval("obj.customFunction();", 100); na następującą: var _self = this; this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100); Konstruktor funkcji Wywołanie new Function(param, body) można zastąpić dołączoną deklaracją funkcji lub użyć go wyłącznie przed obsługą zdarzenia load strony. Adresy URL javascript: Kod zdefiniowany w łączu za pomocą schematu URL javascript: jest ignorowany w obszarze izolowanym aplikacji. Nie jest generowany żaden niebezpieczny błąd JavaScript. Łącza można zastąpić za pomocą adresów URL javascript: w sposób przedstawiony poniżej: <a href="javascript:code()">Click Me</a> na: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 240 Programowanie w językach HTML i JavaScript <a href="#" onclick="code()">Click Me</a> Wywołania zwrotne zdarzenia przypisane za pomocą atrybutu onevent w instrukcjach innerHTML i outerHTML Korzystając z instrukcji innerHTML lub outerHTML do dodawania elementów do modelu DOM dokumentu, dowolne wywołania zwrotne zdarzenia przypisanego w instrukcji (np. onclick lub onmouseover) zostaną zignorowane. Nie zostanie wygenerowany żaden błąd dotyczący bezpieczeństwa. Zamiast tego można przypisać atrybut id do nowych elementów i ustawić funkcje wywołania zwrotnego dla modułu obsługi zdarzeń za pomocą metody addEventListener(). Na przykład: dany element docelowy w dokumencie: <div id="container"></div> Zastępuje instrukcje: document.getElementById('container').innerHTML = '<a href="#" onclick="code()">Click Me.</a>'; na: document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>'; document.getElementById('smith').addEventListener("click", function() { code(); }); Ładowanie plików JavaScript spoza katalogu instalacyjnego aplikacji Ładowanie plików skryptu spoza obszaru izolowanego aplikacji jest niedozwolone. Nie zostanie wygenerowany żaden błąd dotyczący bezpieczeństwa. Wszystkie pliki skryptu, które uruchamiane są w obszarze izolowanym aplikacji, muszą być zainstalowane w katalogu aplikacji. Aby użyć zewnętrznych skryptów na stronie, należy odwzorować stronę w innym obszarze izolowanym. Patrz „Ładowanie treści aplikacji do nieaplikacyjnego obszaru izolowanego” na stronie 250. document.write() i document.writeln() Wywołania metod document.write() lub document.writeln() są ignorowane po obsłużeniu zdarzenia load strony. Nie zostanie wygenerowany żaden błąd dotyczący bezpieczeństwa. Alternatywnym rozwiązaniem jest załadowanie nowego pliku lub zastąpienie treści dokumentu przy pomocy technik manipulowania DOM. Synchroniczne XMLHttpRequests przed zdarzeniem load lub w czasie działania modułu obsługi zdarzenia load Synchroniczne XMLHttpRequests zainicjowane przed zdarzeniem load strony lub w czasie działania modułu obsługi zdarzeń load nie zwracają żadnej treści. Asynchroniczne XMLHttpRequests można zainicjować, ale nie zwrócą żadnej treści dopóki nie zostanie zakończone zdarzenie load. Po obsłużeniu zdarzenia load synchroniczne XMLHttpRequests działają zwyczajnie. Dynamicznie utworzone elementy skryptu Dynamicznie utworzone elementy skryptu, np. elementy utworzone z właściwością innerHTML lub za pomocą metody document.createElement(), są ignorowane. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 241 Programowanie w językach HTML i JavaScript Dostęp do klas API środowiska AIR z JavaScript Poza standardowymi i rozszerzonymi elementami środowiska Webkit, kod HTML i JavaScript może uzyskać dostęp do klas hosta dostarczonych przez środowisko wykonawcze. Klasy te umożliwiają dostęp do zaawansowanych funkcji dostarczanych przez środowisko AIR, w tym: • Dostęp do systemu plików • Użycie lokalnych baz danych SQL • Sterowanie menu aplikacji i okien • Dostęp do gniazd do pracy w sieci • Użycie klas i obiektów zdefiniowanych przez użytkownika • Możliwości dźwiękowe Na przykład: interfejs API pliku AIR zawiera klasę File, która znajduje się w pakiecie flash.filesystem. Obiekt File w języku JavaScript można utworzyć w sposób następujący: var myFile = new window.runtime.flash.filesystem.File(); Obiekt runtime jest specjalnym obiektem JavaScript dostępnym dla treści HTML uruchomionej w obszarze izolowanym aplikacji w środowisku AIR. Umożliwia dostęp do klas środowiska wykonawczego z kodu JavaScript. Właściwość flash obiektu runtime zapewnia dostęp do pakietu flash. Z kolei właściwość flash.filesystem obiektu runtime zapewnia dostęp do pakietu flash.filesystem (pakiet ten zawiera klasę File). Pakiety są sposobem na organizowanie klas używanych w kodzie ActionScript. Uwaga: Właściwość runtime nie jest automatycznie dodawana do obiektów okna dla stron załadowanych do ramki lub ramki pływającej. Jednak tak długo, jak dokumenty podrzędne są w obszarze izolowanym aplikacji, element podrzędny ma dostęp do właściwości runtime elementu nadrzędnego. Ponieważ struktura pakietu klas środowiska wykonawczego będzie wymagała od programistów wpisywania długich ciągów znaków kodu JavaScript w celu dostępu do każdej klasy (np. window.runtime.flash.desktop.NativeApplication), plik AIRAliases.js programu AIR SDK umożliwia łatwiejszy dostęp do klas środowiska wykonawczego (np. przez proste wpisanie air.NativeApplication). Klasy interfejsu API środowiska AIR omawiane są wszędzie w podręczniku. Pozostałe klasy interfejsu API programu Flash Player, które mogą zainteresować programistów HTML, zostały opisane w podręczniku Skorowidz języka Adobe AIR dla programistów HTML. ActionScript jest językiem używanym w treści SWF (Flash Player). Jednak składnia języków JavaScript i ActionScript jest podobna. (Oba są oparte na wersjach języka ECMAScript). Wszystkie klasy wbudowane dostępne są w obu językach: JavaScript (w treści HTML) i ActionScript (w treści SWF). Uwaga: Kod JavaScript nie może korzystać z klas Dictionary, XML i XMLList, które dostępne są w języku ActionScript. Korzystanie z pliku AIRAliases.js Klasy środowiska wykonawczego zorganizowane są w strukturę pakietu w następujący sposób: • window.runtime.flash.desktop.NativeApplication • window.runtime.flash.desktop.ClipboardManager • window.runtime.flash.filesystem.FileStream • window.runtime.flash.data.SQLDatabase TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 242 Programowanie w językach HTML i JavaScript Zawarty w programie AIR SDK plik AIRAliases.js dostarcza definicje „aliasów”, które umożliwiają dostęp do klas środowiska wykonawczego, redukując ilość znaków koniecznych do wpisania. Na przykład: do klas wymienionych powyżej dostęp można uzyskać, wpisując po prostu: • air.NativeApplication • air.Clipboard • air.FileStream • air.SQLDatabase Lista ta jest krótkim podzbiorem klas w pliku AIRAliases.js. Pełna lista klas i funkcji poziomu pakietu zawarta została w podręczniku Skorowidz języka Adobe AIR dla programistów HTML. Poza często używanymi klasami środowiska wykonawczego plik AIRAliases.js zawiera aliasy dla często używanych funkcji poziomu pakietu: window.runtime.trace(), window.runtime.flash.net.navigateToURL() i window.runtime.flash.net.sendToURL(), do których utworzono aliasy air.trace(), air.navigateToURL() oraz air.sendToURL(). Aby użyć pliku AIRAliases.js, należy umieścić odwołanie script na stronie HTML: <script src="AIRAliases.js"></script> W razie konieczności należy dostosować odwołanie src. Ważne: Należy zauważyć, że przykładowy kod JavaScript w niniejszej dokumentacji zakłada, że plik AIRAliases.js został dołączony do strony HTML. Informacje o adresach URL w środowisku AIR W treści HTML działającej w środowisku AIR można korzystać z dowolnego z następujących schematów URL w definiujących atrybutach src dla znaczników img, frame, iframe i script, w atrybucie href znacznika link lub gdziekolwiek indziej, gdzie można wprowadzić adres URL. Schemat URL Opis Przykład file Ścieżka względna wobec katalogu głównego systemu plików. file:///c:/AIR Test/test.txt app Ścieżka względna wobec katalogu głównego zainstalowanej aplikacji. app:/images app-storage Ścieżka względna wobec katalog zapisu aplikacji. Dla każdej zainstalowanej aplikacji środowisko AIR definiuje unikalny katalog zapisu aplikacji, który jest miejscem użytecznym do zapisu danych charakterystycznych dla danej aplikacji. app-storage:/settings/prefs.xml http Standardowe żądanie HTTP. http://www.adobe.com https Standardowe żądanie HTTPS. https://secure.example.com Więcej informacji na temat korzystania ze schematów URL w środowisku AIR zawiera sekcja „Korzystanie ze schematów URL środowiska AIR w adresach URL” na stronie 308. Wiele z interfejsów API środowiska AIR, łącznie z klasami File, Loader, URLStream i Sound, używa obiektu URLRequest, a nie ciągu znaków zawierającego adres URL. Sam obiekt URLRequest inicjalizowany jest za pomocą ciągu znaków, który może używać dowolnego z tych samych schematów URL. Na przykład: poniższa instrukcja tworzy obiekt URLRequest, którego można użyć, aby wysłać żądanie strony głównej firmy Adobe: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 243 Programowanie w językach HTML i JavaScript var urlReq = new air.URLRequest("http://www.adobe.com/"); Więcej informacji o obiektach URLRequest zawiera rozdział „Żądania URL i praca w sieci” na stronie 307. Udostępnianie obiektów ActionScript dla kodu JavaScript Kod JavaScript na stronie HTML załadowanej przez obiekt HTMLLoader może wywoływać klasy, obiekty i funkcje zdefiniowane w kontekście wywołania ActionScript za pomocą właściwości window.runtime, window.htmlLoader i window.nativeWindowstrony HTML. Programista może także udostępniać obiekty i funkcje języka ActionScript dla kodu JavaScript, tworząc odwołania do nich w kontekście wywołania JavaScript. Podstawowy przykład dostępu obiektów JavaScript z kodu ActionScript Poniższy przykład ilustruje, w jaki sposób dodać właściwości odnoszące się do obiektów ActionScript do globalnego obiektu okna strony 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; } Treść HTML (w pliku o nazwie test.html) załadowana do obiektu HTMLLoader w poprzednim przykładzie może uzyskać dostęp do właściwości foo i metody helloFromJS() zdefiniowanej w nadrzędnym pliku SWF: <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> Podczas dostępu do kontekstu JavaScript ładującego dokumentu można użyć zdarzenia htmlDOMInitialize, aby utworzyć obiekty w sekwencji tworzenia strony, zanim jakikolwiek skrypt zdefiniowany na stronie będzie mógł uzyskać do nich dostęp. Jeśli programista poczeka na zdarzenie complete, tylko skrypty strony, które uruchomione zostaną po zdarzeniu load strony, będą mogły uzyskać dostęp do dodanych obiektów. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 244 Programowanie w językach HTML i JavaScript Udostępnianie definicji klas dla kodu JavaScript Aby udostępnić klasy ActionScript aplikacji dla kodu JavaScript, programista może przypisać załadowaną treść HTML do domeny aplikacji zawierającej definicje klas. Domenę aplikacji kontekstu wykonania JavaScript można ustawić za pomocą właściwości runtimeApplicationDomain obiektu HTMLLoader. Na przykład: aby ustawić domenę aplikacji na domenę główną aplikacji, należy ustawić właściwość runtimeApplicationDomain na ApplicationDomain.currentDomain, co ilustruje poniższy kod: html.runtimeApplicationDomain = ApplicationDomain.currentDomain; Po ustawieniu właściwości runtimeApplicationDomain kontekst JavaScript współużytkuje definicje klas z przypisaną domeną. Aby utworzyć instancję klasy niestandardowej w języku JavaScript, należy odwołać się do definicji klasy za pomocą właściwości window.runtime i użyć operatora new: var customClassObject = new window.runtime.CustomClass(); Treść HTML musi pochodzić ze zgodnej domeny zabezpieczeń. Jeśli treść HTML znajduje się w innej domenie zabezpieczeń niż przypisana domena aplikacji, strona w zamian użyje domyślnej domeny aplikacji. Na przykład: jeśli z Internetu załadowana zostanie zdalna strona, nie będzie możliwe przypisanie ApplicationDomain.currentDomain jako domeny aplikacji dla strony. Usuwanie detektorów zdarzeń Jeśli do obiektów spoza bieżącej strony (łącznie z obiektami środowiska wykonawczego, obiektami w załadowanej treści SWF, a nawet obiektami JavaScript działającymi na innych stronach), dodane zostaną detektory zdarzeń JavaScript, należy je zawsze usunąć w czasie wyładowania strony. W przeciwnym wypadku detektor zdarzeń wywoła zdarzenie do funkcji modułu obsługi, która już nie istnieje. Jeśli się tak stanie, wyświetlony następujący komunikat podobny do następującego: „Aplikacja podjęła próbę utworzenia odwołania do obiektu JavaScript na stronie HTML, która nie jest już załadowana”. Usunięcie niepotrzebnych detektorów zdarzeń umożliwia także środowisku AIR odzyskanie powiązanej pamięci. Więcej informacji zawiera sekcja „Usuwanie detektorów zdarzeń ze stron HTML, które nawigują” na stronie 258. Dostęp do modelu DOM HTML i obiektów JavaScript z kodu ActionScript Po wywołaniu zdarzenia complete przez obiekt HTMLLoader programista ma dostęp do wszystkich obiektów modelu DOM (obiektowy model dokumentu) HTML strony. Obiekty, do których można uzyskać dostęp, zawierają elementy wyświetlane (np. obiekty div i p na stronie), a także zmienne i funkcje JavaScript. Zdarzenie complete odpowiada zdarzeniu load strony JavaScript. Nie należy przekształcać ani tworzyć elementów, zmiennych i funkcji modelu DOM, zanim nie zostanie wywołane zdarzenie complete. Jeśli jest to możliwe, należy poczekać na zdarzenie complete przed dostępem do modelu DOM HTML. Na przykład: rozważmy następującą stronę HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 245 Programowanie w językach HTML i JavaScript <html> <script> foo = 333; function test() { return "OK."; } </script> <body> <p id="p1">Hi.</p> </body> </html> Prosta strona HTML definiuje zmienną JavaScript o nazwie foo oraz funkcję JavaScript o nazwie test(). Obie są właściwościami obiektu globalnego window strony. Obiekt window.document zawiera element o nazwie P (z ID p1), do którego dostęp można uzyskać za pomocą metody getElementById(). Po załadowaniu strony (gdy obiekt HTMLLoader wywoła zdarzenie complete) możliwy jest dostęp do każdego z tych obiektów za pomocą języka ActionScript, co ilustruje poniższy kod 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. } Aby uzyskać dostęp do treści elementu HTML, należy użyć właściwości innerHTML. Na przykład: poprzedni kod używa wywołania html.window.document.getElementById("p1").innerHTML w celu pobrania treści elementu HTML o nazwie p1. Możliwe jest również ustawienie właściwości strony HTML z kodu ActionScript. Na przykład: poniższy przykład ustawia na stronie treść elementu p1 oraz wartość zmiennej JavaScript foo za pomocą odwołania do zawierającego je obiektu HTMLLoader: html.window.document.getElementById("p1").innerHTML = "Goodbye"; html.window.foo = 66; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 246 Programowanie w językach HTML i JavaScript Osadzanie treści SWF w kodzie HTML W aplikacji AIR treść SWF można osadzić w treści HTML tak, jak przy użyciu przeglądarki. Treść SWF można osadzić za pomocą znacznika object, znacznika embed lub obu. Uwaga: Częstą praktyką w programowaniu stron internetowych jest użycie obu znaczników object i embed w celu wyświetlenia treści SWF na stronie HTML. Ta praktyka nie przynosi korzyści w środowisku AIR. W treści można użyć samego znacznika object w standardzie W3C, aby został on wyświetlony w środowisku AIR. W razie konieczności w tym samym czasie można nadal wspólnie używać znaczników object i embed dla treści HTML, która jest również wyświetlana w przeglądarce. Poniższy przykład ilustruje użycie znacznika object HTML w celu wyświetlenia pliku SWF w treści HTML. Plik SWF ładowany jest z katalogu aplikacji, ale możliwe jest użycie dowolnego schematu URL obsługiwanego przez środowisko AIR. (Lokalizacja, z której ładowany jest plik SWF, wskazuje obszar izolowany zabezpieczeń, w którym środowisko AIR umieszcza treść). <object type="application/x-shockwave-flash" width="100%" height="100%"> <param name="movie" value="app:/SWFFile.swf"></param> </object> Można użyć również skryptu, aby załadować treść dynamicznie. Poniższy przykład tworzy węzeł object, aby wyświetlić plik SWF określony w parametrze urlString. Przykład dodaje węzeł jako element podrzędny strony z ID określonym w parametrze 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> Korzystanie z bibliotek ActionScript na stronie HTML Środowisko AIR rozszerza element script HTML tak, że strona może importować klasy ActionScript do skompilowanego pliku SWF. Na przykład: aby zaimportować bibliotekę o nazwie myClasses.swf umieszczoną w podkatalogu lib głównego folderu aplikacji, należy umieścić poniższy znacznik script w pliku HTML: <script src="lib/myClasses.swf" type="application/x-shockwave-flash"></script> Ważne: Atrybut type biblioteki musi mieć wartość type="application/x-shockwave-flash", aby biblioteka została poprawnie załadowana. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 247 Programowanie w językach HTML i JavaScript Jeśli treść SWF została skompilowana do pliku SWF programu Flash Player 10 lub środowiska AIR 1.5, należy wówczas ustawić przestrzeń nazw XML pliku deskryptora aplikacji na przestrzeń nazw środowiska AIR 1.5. Więcej informacji zawiera sekcja „Definiowanie właściwości w pliku deskryptora aplikacji” na stronie 46. W czasie pakowania pliku AIR należy dołączyć także katalog lib i plik myClasses.swf. Dostęp do zaimportowanych klas za pomocą właściwości runtime obiektu Window JavaScript: var libraryObject = new window.runtime.LibraryClass(); Jeśli klasy w pliku SWF zostały zorganizowane w pakiety, należy dołączyć także nazwę pakietu. Na przykład: jeśli definicja klasy LibraryClass znajduje się w pakiecie o nazwie utilities, instancję klasy należy utworzyć za pomocą następującej instrukcji: var libraryObject = new window.runtime.utilities.LibraryClass(); Uwaga: Aby skompilować bibliotekę SWF ActionScript w celu użycia jako części strony HTML w środowisku AIR, należy użyć kompilatora acompc. Narzędzie acompc jest częścią programu Flex 3 SDK i zostało opisane w dokumentacji programu Flex 3 SDK. Dostęp do modelu DOM HTML i obiektów JavaScript z zaimportowanego pliku ActionScript Aby uzyskać dostęp do obiektów na stronie HTML z kodu ActionScript pliku SWF zaimportowanego na stronę z użyciem znacznika <script>, należy przekazać odwołanie do obiektu JavaScript (np. window lub document) do funkcji zdefiniowanej w kodzie ActionScript. Do dostępu do obiektu JavaScript (lub innych obiektów, do których dostęp można uzyskać przez przekazanie odwołania) służy odwołanie w funkcji. Na przykład: rozważmy następującą stronę 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> Prosta strona HTML zawiera zmienną JavaScript o nazwie num oraz funkcję JavaScript o nazwie getStatus(). Obie są właściwościami obiektu window strony. Obiekt window.document zawiera element o nazwie P (z ID p1). Strona ładuje plik ActionScript „ASLibrary.swf”, który zawiera klasę ASClass. Klasa ASClass definiuje funkcję o nazwie accessDOM(), która wyświetla wartości obiektów JavaScript. Metoda accessDOM() przyjmuje jako argument obiekt Window JavaScript. Za pomocą odwołania Window można uzyskać dostęp do innych obiektów na stronie łącznie ze zmiennymi, funkcjami i elementami DOM, co ilustruje poniższa definicja: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 248 Programowanie w językach HTML i 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. } } Możliwe jest pobranie i ustawienie właściwości strony HTML z zaimportowanej klasy ActionScript. Na przykład: poniższa funkcja ustawia na stronie treść elementu p1 oraz wartość zmiennej JavaScript foo: public function modifyDOM(window:*):void { window.document.getElementById("p1").innerHTML = "Bye"; window.foo = 66; Konwertowanie obiektów Date i RegExp Oba języki JavaScript i ActionScript definiują klasy Date i RegExp, ale obiekty tych typów nie są automatycznie konwertowane między dwoma kontekstami wykonania. Obiekty Date i RegExp należy przekonwertować na odpowiedni typ przed użyciem ich do ustawienia właściwości lub parametrów funkcji w drugim kontekście wykonania. Na przykład: poniższy kod ActionScript konwertuje obiekt Date JavaScript o nazwie jsDate na obiekt Date ActionScript: var asDate:Date = new Date(jsDate.getMilliseconds()); Poniższy kod ActionScript konwertuje obiekt RegExp JavaScript o nazwie jsRegExp na obiekt RegExp 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); Manipulowanie szablonem strony HTML z kodu ActionScript Po wywołaniu zdarzenia complete przez obiekt HTMLLoader programista może kontrolować i manipulować stylami CSS na stronie. Na przykład: rozważmy następujący prosty dokument HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 249 Programowanie w językach HTML i 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> Po załadowaniu przez obiekt HTMLLoader tej treści możliwe jest manipulowanie stylami CSS na stronie za pomocą tablicy cssRules tablicy window.document.styleSheets, co ilustruje poniższy przykład: 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"; } Kod dostosowuje style CSS tak, aby wynikowy dokument HTML wyświetlony został w sposób następujący: Należy pamiętać, że kod może dodawać style do strony po wywołaniu przez obiekt HTMLLoader zdarzenia complete. Treść odwołująca się do skryptów w różnych bezpiecznych obszarach izolowanych Model zabezpieczeń środowiska wykonawczego izoluje kod o różnym pochodzeniu. Dzięki treści odwołującej się do skryptów w różnych bezpiecznych obszarach izolowanych programista może zezwolić treści z jednego bezpiecznego obszaru izolowanego na dostęp do wybranych właściwości i metod z innego obszaru izolowanego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 250 Programowanie w językach HTML i JavaScript Bezpieczne obszary izolowane środowiska AIR i kod JavaScript Środowisko AIR wymusza regułę tego samego pochodzenia, która zapobiega interakcji kodu z jednej domeny z treścią innej domeny. Wszystkie pliki umieszczane są w obszarze izolowanym w oparciu o ich pochodzenie. Treść z obszaru izolowanego aplikacji nie może naruszyć zasady tego samego pochodzenia ani treść odwołująca się do skryptów załadowana spoza katalogu instalacyjnego aplikacji. Jednak środowisko AIR zapewnia kilka technik, które umożliwiają użycie nieaplikacyjnej treści odwołującej się do skryptów. Jedna technika korzysta z ramek lub ramek pływających, aby odwzorować treść aplikacji na inny obszar izolowany zabezpieczeń. Wszystkie strony załadowane z obszaru izolowanego aplikacji działają tak, jakby zostały załadowane ze zdalnej domeny. Na przykład: dzięki odwzorowaniu treści aplikacji na domenę example.com treść może odwoływać się do skryptów ze stron załadowanych z domeny example.com. Ponieważ ta technika umieszcza treść aplikacji w innym obszarze izolowanym, kod w tej treści również nie jest dłużej przedmiotem ograniczeń wykonania kodu w ciągach znaków, dla których wyznaczana jest wartość. Tej techniki odwzorowywania obszaru izolowanego można używać do złagodzenia ograniczeń nawet, jeśli nie jest wymagane odwoływanie się do skryptów zdalnej treści. Odwzorowanie treści w ten sposób możne być szczególnie użyteczne podczas pracy z jednym z wielu środowisk JavaScript lub istniejącym kodem, który opiera się na obliczaniu wartości dla ciągów. Należy jednak uwzględnić i zabezpieczyć się przed dodatkowym ryzykiem związanym z niezaufaną treścią, która może zostać wstrzyknięta i wykonana, gdy treść uruchamiana jest poza obszarem izolowanym aplikacji. W tym samym czasie treść odwzorowana na inny obszar izolowany traci dostęp do interfejsu API środowiska AIR, dlatego technika odwzorowywania obszaru izolowanego nie może być używana do udostępniania funkcjonalności środowiska AIR dla kodu wykonywanego poza obszarem izolowanym aplikacji. Inna technika odwoływania się do skryptu umożliwia tworzenie interfejsu nazywanego mostem obszaru izolowanego między treścią z nieaplikacyjnego obszaru izolowanego a jego dokumentem nadrzędnym w obszarze izolowanym aplikacji. Most umożliwia treści dokumentu podrzędnego na dostęp do właściwości i metod zdefiniowanych przez dokument nadrzędny, dostęp dokumentu nadrzędnego do właściwości i metod zdefiniowanych przez dokument podrzędny lub obie możliwości. W końcu możliwe jest również wykonanie międzydomenowych żądań XMLHttpRequest z obszaru izolowanego aplikacji i (opcjonalnie) z innych obszarów izolowanych. Więcej informacji zawiera sekcja „Elementy ramek i ramek pływających HTML” na stronie 229, „Zabezpieczenia HTML” na stronie 31 i „Obiekt XMLHttpRequest” na stronie 223. Ładowanie treści aplikacji do nieaplikacyjnego obszaru izolowanego Aby umożliwić treści aplikacji bezpieczne odwoływanie się do skryptów treści załadowanej spoza katalogu instalacyjnego aplikacji, można użyć elementów frame lub iframe w celu załadowania treści aplikacji do tego samego obszaru izolowanego zabezpieczeń co zewnętrzna treść. Jeśli odwoływanie się do skryptów zdalnej treści nie jest konieczne, ale nadal istnieje potrzeba ładowania strony aplikacji spoza obszaru izolowanego aplikacji, można użyć tej samej techniki, określając jako domenę początkową http://localhost/ lub inną bezpieczną wartość. Środowisko AIR dodaje nowe atrybuty sandboxRoot i documentRoot do elementu ramki, które umożliwiają określanie, czy plik aplikacji załadowany do ramki powinien być odwzorowywany w nieaplikacyjnym obszarze izolowanym. Pliki, których ścieżka wskaże adres poniżej adresu URL sandboxRoot załadowane zostaną z katalogu określonego w atrybucie documentRoot. Ze względów bezpieczeństwa treść aplikacji załadowana w ten sposób traktowana jest tak, jakby rzeczywiście została załadowana z adresu URL określonego we właściwości sandboxRoot. Właściwość sandboxRoot określa adres URL w celu użycia do określania obszaru izolowanego i domeny, w której umieszczana jest treść ramki. Należy użyć schematów URL: file:, http: lub https:. Jeśli określony zostanie względny adres URL, treść pozostanie w obszarze izolowanym aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 251 Programowanie w językach HTML i JavaScript Właściwość documentRoot określa katalog, z którego ładowana jest treść ramki. Należy użyć schematów URL: file:, app: lub app-storage:. Poniższy przykład odwzorowuje treść zainstalowaną w podkatalogu sandbox aplikacji w celu uruchomienia w zdalnym obszarze izolowanym oraz domenie www.example.com: <iframe src="http://www.example.com/local/ui.html" sandboxRoot="http://www.example.com/local/" documentRoot="app:/sandbox/"> </iframe> Strona ui.html może załadować plik javascript z lokalnego folderu sandbox za pomocą następujących znaczników script: <script src="http://www.example.com/local/ui.js"></script> Może załadować także treść z katalogu na zdalnym serwerze za pomocą znacznika script, co ilustruje poniższy przykład: <script src="http://www.example.com/remote/remote.js"></script> Adres URL określony we właściwości sandboxRoot będzie maskował każdą treść dla tego samego adresu URL na zdalnym serwerze. W powyższym przykładzie nie jest możliwy dostęp do żadnej zdalnej treści na stronie www.example.com/local/ (ani do żadnego jej podkatalogu), ponieważ środowisko AIR ponownie odwzorowuje żądanie na lokalny katalog aplikacji. Żądania są ponownie odwzorowywane niezależnie od tego czy kierowane są z elementów nawigacji strony (XMLHttpRequest) czy zostały utworzone przez inne środki ładowania treści. Konfigurowanie interfejsu mostu obszaru izolowanego Mostu obszaru izolowanego można używać, gdy treść w obszarze izolowanym aplikacji musi mieć dostęp do właściwości lub metod zdefiniowanych przez treść w nieaplikacyjnym obszarze izolowanym lub gdy nieaplikacyjna treść musi mieć dostęp do właściwości i metod zdefiniowanych przez treść w obszarze izolowanym aplikacji. Most należy utworzyć z właściwościami childSandboxBridge i parentSandboxBridge obiektu window dla każdego dokumentu podrzędnego. Tworzenie mostu obszaru izolowanego elementu podrzędnego Właściwość childSandboxBridge umożliwia podrzędnemu dokumentowi udostępnianie interfejsu dla treści w dokumencie nadrzędnym. Aby udostępnić interfejs, należy ustawić właściwość childSandbox na funkcję lub obiekt w dokumencie podrzędnym. Programista może następnie uzyskać dostęp do obiektu lub funkcji z treści dokumentu nadrzędnego. Poniższy przykład przedstawia, w jaki sposób skrypt uruchomiony w dokumencie podrzędnym może udostępniać obiekt zawierający funkcję i właściwość swojemu dokumentowi nadrzędnemu: var interface = {}; interface.calculatePrice = function(){ return ".45 cents"; } interface.storeID = "abc" window.childSandboxBridge = interface; Jeśli treść dokumentu podrzędnego załadowana została do ramki pływającej, do której przypisany został identyfikator „child”, dostęp do interfejsu można uzyskać z treści elementu nadrzędnego, odczytując właściwość childSandboxBridge ramki: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 252 Programowanie w językach HTML i JavaScript var childInterface = document.getElementById("child").contentWindow.childSandboxBridge; air.trace(childInterface.calculatePrice()); //traces ".45 cents" air.trace(childInterface.storeID)); //traces "abc" Tworzenie mostu obszaru izolowanego elementu nadrzędnego Właściwość parentSandboxBridge umożliwia nadrzędnemu dokumentowi udostępnianie interfejsu dla treści w dokumencie podrzędnym. Aby udostępnić interfejs, dokument nadrzędny ustawia właściwość parentSandbox dokumentu podrzędnego na funkcję lub obiekt zdefiniowany w dokumencie nadrzędnym. Programista może następnie uzyskać dostęp do obiektu lub funkcji z treści dokumentu podrzędnego. Poniższy przykład przedstawia, w jaki sposób skrypt uruchomiony w ramce nadrzędnej może udostępniać obiekt zawierający funkcję dokumentowi podrzędnemu: var interface = {}; interface.save = function(text){ var saveFile = air.File("app-storage:/save.txt"); //write text to file } document.getElementById("child").contentWindow.parentSandboxBridge = interface; Za pomocą tego interfejsu treść w ramce podrzędnej może zapisać tekst do pliku o nazwie save.txt, ale nie będzie miała żadnego innego rodzaju dostępu do systemu plików. Treść elementu podrzędnego może wywołać funkcję save w następujący sposób: var textToSave = "A string."; window.parentSandboxBridge.save(textToSave); Treść aplikacji powinna udostępniać innym obszarom izolowanym najwęższy możliwy interfejs. Nieaplikacyjna treść powinna być rozważana jako niegodna zaufania, ponieważ może być narażona na wprowadzenie przypadkowego lub złośliwego kodu. Należy przydzielić odpowiednie zabezpieczenia, aby zapobiec niewłaściwemu użyciu interfejsu udostępnionego za pomocą mostu obszaru izolowanego. Dostęp do mostu obszaru izolowanego elementu nadrzędnego podczas ładowania strony Aby skrypt w dokumencie podrzędnym uzyskał dostęp do mostu obszaru izolowanego dokumentu nadrzędnego, most musi zostać skonfigurowany przed uruchomieniem skryptu. Obiekty okna, ramki i ramki pływającej wywołują zdarzenie dominitialize, gdy utworzony zostanie model DOM nowej strony, ale przez przetworzeniem skryptów lub dodaniem elementów DOM. Zdarzenia dominitialize można użyć do utworzenia mostu w sekwencji tworzenia strony dostatecznie wcześnie, aby wszystkie skrypty w dokumencie podrzędnym mogły uzyskać do niego dostęp. Poniższy przykład ilustruje, w jaki sposób utworzyć most obszaru izolowanego dokumentu nadrzędnego w odpowiedzi na zdarzenie dominitialize wywołane z ramki podrzędnej: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 253 Programowanie w językach HTML i 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> Poniższy dokument child.html ilustruje, jak treść dokumentu podrzędnego może uzyskać dostęp do mostu obszaru izolowanego dokumentu nadrzędnego: <html> <head> <script> document.write(window.parentSandboxBridge.testProperty); </script> </head> <body></body> </html> Aby wykryć zdarzenie dominitialize podrzędnego okna, a nie ramki, należy dodać detektor do nowego podrzędnego obiektu okna utworzonego za pomocą funkcji window.open(): var childWindow = window.open(); childWindow.addEventListener("dominitialize", engageBridge()); childWindow.document.location = "http://www.example.com/air/child.html"; W tym przypadku nie ma możliwości odwzorowania treści aplikacji do nieaplikacyjnego obszaru izolowanego. Ta technika jest użyteczna tylko gdy dokument child.html ładowany jest spoza katalogu aplikacji. Treść aplikacji nadal można odwzorować w oknie na nieaplikacyjny obszar izolowany, ale najpierw należy załadować stronę pośrednią, która sama używa ramek, aby załadować dokument podrzędny i odwzorować go na pożądany obszar izolowany. Jeśli do tworzenia okna używana jest funkcja createRootWindow() klasy HTMLLoader, nowe okno nie będzie dokumentem podrzędnym dokumentu, z którego wywoływana jest funkcja createRootWindow(). Dlatego nie można utworzyć mostu obszaru izolowanego z okna wywołującego do treści nieaplikacyjnej załadowanej do nowego okna. Zamiast tego należy użyć ładowania strony pośredniej w nowym oknie, które samo korzysta z ramek do ładowania dokumentu podrzędnego. Most można utworzyć z dokumentu nadrzędnego nowego okna do dokumentu podrzędnego załadowanego do ramki. 254 Rozdział 22: Obsługa zdarzeń powiązanych z HTML System obsługi zdarzeń umożliwia programistom określanie reakcji na czynności użytkownika i zdarzenia systemowe w wygodny sposób. Model zdarzeń Adobe® AIR™ jest nie tylko wygodny, ale również zgodny ze standardami. Zgodnie ze specyfikacją Document Object Model (DOM) Level 3 Events Specification, która jest branżowym standardem architektury obsługi zdarzeń, model zdarzeń stanowi wydajne i intuicyjne w obsłudze narzędzie dla programistów. HTMLLoader, zdarzenia Obiekt HTMLLoader wywołuje następujące zdarzenia Adobe® ActionScript® 3.0: Zdarzenie Opis htmlDOMInitialize Wywoływane po utworzeniu dokumentu HTML, ale przed analizą skryptów oraz przed dodaniem węzłów DOM do strony. complete Wywoływane po utworzeniu DOM HTML w odpowiedzi na operację ładowania, natychmiast po zdarzeniu onload na stronie HTML. htmlBoundsChanged Wywoływane przy zmianie jednej lub obydwu właściwości: contentWidth i contentHeight. locationChange Wywoływane po zmianie właściwości location obiektu HTMLLoader. scroll Wywoływane za każdym razem, gdy mechanizm HTML zmieni położenie przewijania. Zdarzenia scroll mogą występować z powodu nawigacji do odsyłaczy kotwiczących (odsyłacze #) na stronie lub z powodu wywołań metody window.scrollTo(). Wprowadzenie tekstu do obszaru tekstu wejściowego lub do obszaru tekstowego również może spowodować wywołanie zdarzenia scroll. uncaughtScriptException Wywoływane w przypadku wystąpienia wyjątku JavaScript w module HTMLLoader, gdy wyjątek nie zostanie wychwycony w kodzie JavaScript. Dla zdarzenia JavaScript (takiego jak onClick) można również zarejestrować funkcję ActionScript. Szczegółowe informacje zawiera sekcja „Obsługa zdarzeń DOM za pomocą kodu ActionScript” na stronie 254. Obsługa zdarzeń DOM za pomocą kodu ActionScript Istnieje możliwość zarejestrowania funkcji ActionScript w celu reagowania na zdarzenia JavaScript. Weźmy na przykład pod uwagę następującą treść HTML: <html> <body> <a href="#" id="testLink">Click me.</a> </html> Możliwe jest zarejestrowanie funkcji ActionScript jako modułu obsługi dla dowolnego zdarzenia na stronie. Na przykład: poniższy kod dodaje funkcję clickHandler() jako detektor zdarzenia onclick elementu testLink na stronie HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 255 Obsługa zdarzeń powiązanych z 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!"); } Możliwe jest również użycie metody addEventListener() w celu zarejestrowania dla tych zdarzeń. Na przykład: możliwe jest zastąpienie metody completeHandler() z poprzedniego przykładu następującym kodem: function completeHandler(event:Event):void { var testLink:Object = html.window.document.getElementById("testLink"); testLink.addEventListener("click", clickHandler); } Gdy detektor odwołuje się do konkretnego elementu DOM, dobrą metodą jest oczekiwanie na wywołanie zdarzenia complete przez obiekt nadrzędny HTMLLoader, a dopiero potem dodanie detektorów zdarzeń. Strony HTML często ładują wiele plików i wówczas model DOM HTML nie zostaje w pełni zbudowany do czasu załadowania i przeanalizowania wszystkich plików. Obiekt HTMLLoader wywołuje zdarzenie complete po utworzeniu wszystkich elementów. Reagowanie na niewychwycone wyjątki JavaScript Rozważmy poniższy kod HTML: <html> <head> <script> function throwError() { var x = 400 * melbaToast; } </script> </head> <body> <a href="#" onclick="throwError()">Click me.</a> </html> Zawiera on funkcję JavaScript throwError(), która odwołuje się do nieznanej zmiennej melbaToast: var x = 400 * melbaToast; Gdy operacja JavaScript napotka niedozwoloną operację, która nie zostanie wychwycona w kodzie JavaScript za pomocą struktury try/catch, wówczas obiekt HTMLLoader zawierający stronę wywołuje zdarzenie HTMLUncaughtScriptExceptionEvent. Dla tego zdarzenia można zarejestrować moduł obsługi, jak w poniższym przykładzie: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 256 Obsługa zdarzeń powiązanych z 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); } } W kodzie JavaScript to samo zdarzenie można obsługiwać za pomocą właściwości 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> Moduł obsługi zdarzenia htmlErrorHandler() anuluje domyślne zachowanie zdarzenia (domyślnie zdarzenie wysyła komunikat o błędzie JavaScript jako wynik działania aplikacji AIR) i generuje własny komunikat wyjściowy. Wartością wyjściową jest wartość exceptionValue obiektu HTMLUncaughtScriptExceptionEvent. Wartością wyjściową są właściwości poszczególnych obiektów z tablicy stackTrace: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 257 Obsługa zdarzeń powiązanych z HTML exceptionValue: ReferenceError: Can't find variable: melbaToast sourceURL: app:/test.html line: 5 function: throwError sourceURL: app:/test.html line: 10 function: onclick Obsługa zdarzeń środowiska wykonawczego za pomocą JavaScript Klasy środowiska wykonawczego obsługują moduły obsługi zdarzeń za pomocą metody addEventListener(). W celu dodania funkcji modułu obsługi dla zdarzenia należy wywołać metodę addEventListener() obiektu, który wywołał zdarzenie, udostępniając typ zdarzenia i funkcję obsługi. Na przykład: w celu wykrycia zdarzenia closing wywołanego, gdy użytkownik kliknął przycisk zamknięcia okna na pasku tytułu, należy użyć poniższej instrukcji: window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing); Tworzenie funkcji modułu obsługi zdarzeń Poniższy kod tworzy przykładowy plik HTML, który wyświetla informacje o pozycji w oknie głównym. Funkcja modułu obsługi o nazwie moveHandler() wykrywa zdarzenie move (zdefiniowane przez klasę NativeWindowBoundsEvent) okna głównego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 258 Obsługa zdarzeń powiązanych z 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> Gdy użytkownik przesunie okno, w obszarze tekstowym pojawią się nowe pozycje X i Y okna: Należy zauważyć, że obiekt zdarzenia został przekazany jako argument do metody moveHandler(). Parametr zdarzenia umożliwia funkcji modułu obsługi sprawdzenie obiektu zdarzenia. W tym przykładzie właściwość type obiektu zdarzenia służy do zgłoszenia, czy zdarzenie jest zdarzeniem move. Usuwanie detektorów zdarzeń Do usuwania zbędnych detektorów zdarzeń służy metoda removeEventListener(). Usuwanie detektorów, które nie będą używane, jest bardzo dobrym sposobem postępowania. Do wymaganych parametrów należą eventName i listener i są to te same parametry, jak parametry wymagane dla metody addEventListener(). Usuwanie detektorów zdarzeń ze stron HTML, które nawigują Jeśli treść HTML służy do nawigacji lub treść HTML jest usuwana, ponieważ okno (w której się znajduje) zostało zamknięte, wówczas detektory zdarzeń, które odwołują się do obiektów na niezaładowanej stronie, nie są automatycznie usuwane. Gdy obiekt wywoła zdarzenie dla modułu obsługi, który został już usunięty z pamięci, zostanie wyświetlony następujący komunikat podobny do następującego: „Aplikacja podjęła próbę utworzenia odwołania do obiektu JavaScript na stronie HTML, która nie jest już załadowana”. W celu uniknięcia tego błędu należy usunąć detektory zdarzeń JavaScript ze strony HTML przed jej dezaktywacją. W przypadku nawigacji na stronie (w obiekcie HTMLLoader) należy usunąć detektor zdarzeń podczas zdarzenia unload obiektu window. Na przykład: poniższy kod JavaScript usuwa detektor zdarzenia uncaughtScriptException: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 259 Obsługa zdarzeń powiązanych z HTML window.onunload = cleanup; window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException); function cleanup() { window.htmlLoader.removeEventListener('uncaughtScriptException', uncaughtScriptExceptionHandler); } Aby zapobiec występowaniu błędu podczas zamykania okna, które zawiera treść HTML, należy wywołać funkcję czyszczenia w odpowiedzi na zdarzenie closing obiektu NativeWindow (window.nativeWindow). Na przykład: poniższy kod JavaScript usuwa detektor zdarzenia uncaughtScriptException: window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup); function cleanup() { window.htmlLoader.removeEventListener('uncaughtScriptException', uncaughtScriptExceptionHandler); } Aby zapobiec temu błędowi, można również usunąć detektor zdarzenia, gdy tylko zostanie uruchomiony. Przykład: poniższy kod JavaScript tworzy okno html poprzez wywołanie metody createRootWindow() klasy HTMLLoader, a następnie dodaje detektor dla zdarzenia complete. Gdy zostanie wywołany moduł obsługi zdarzenia complete, usuwa on własny detektor zdarzeń za pomocą funkcji 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")); Usuwanie zbędnych detektorów zdarzeń umożliwia również modułowi czyszczenia pamięci odzyskanie pamięci skojarzonej z tymi detektorami. Sprawdzanie dostępności detektorów zdarzeń Metoda hasEventListener() umożliwia sprawdzenie dostępności detektora zdarzenia w obiekcie. 260 Rozdział 23: Wywoływanie skryptów w kontenerze HTML Klasa HTMLLoader działa jako kontener treści HTML w środowisku Adobe® AIR™. Ta klasa udostępnia wiele właściwości i metod dziedziczonych od klasy Sprite, które służą do kontrolowania zachowania i wyglądu obiektu na liście wyświetlania ActionScript® 3.0. Ponadto klasa definiuje właściwości i metody, np. dla zadań, takich jak ładowanie i oddziaływanie z treścią HTML oraz zarządzanie historią. Klasa HTMLHost definiuje zestaw domyślnych zachowań dla obiektu HTMLLoader. Podczas tworzenia obiektu HTMLLoader nie jest udostępniana żadna implementacja klasy HTMLHost. Dlatego gdy treść HTML uruchamia jedno z domyślnych zachowań, takie jak zmiana lokalizacji okna lub tytuł okna, nic się nie dzieje. Klasę HTMLHost można rozszerzyć, aby zdefiniować zachowania wymagane dla aplikacji. Domyślna implementacja klasy HTMLHost jest dostępna dla okien HTML tworzonych przez środowisko AIR. Domyślną implementację klasy HTMLHost można przypisać do innego obiektu HTMLLoader poprzez ustawienie właściwości htmlHost obiektu — w tym celu należy użyć nowego obiektu HTMLHost utworzonego z parametrem defaultBehavior o wartości true. Właściwości wyświetlania obiektów HTMLLoader Obiekt HTMLLoader dziedziczy właściwości wyświetlania od klasy Sprite programu Adobe® Flash® Player. Te właściwości umożliwiają na przykład zmianę wielkości, przesunięcie, ukrycie i zmianę koloru. Możliwe jest także zastosowanie efektów zaawansowanych, takich jak filtry, maski, skalowanie i rotacje. Podczas stosowania efektów należy rozważyć ich wpływ na czytelność obiektów wyświetlanych. W przypadku zastosowania niektórych efektów nie będzie możliwości wyświetlenia treści SWF i PDF załadowanej do strony HTML. Okna HTML zawierają obiekt HTMLLoader, który renderuje treść HTML. Ten obiekt jest ograniczony do obszaru okna, dlatego zmiana wymiarów, położenia, rotacji lub współczynnika skali nie zawsze powoduje uzyskanie pożądanych wyników. Podstawowe właściwości wyświetlania Podstawowe właściwości wyświetlania obiektu HTMLLoader umożliwiają umieszczenie obiektu sterowania w jego nadrzędnym obiekcie wyświetlanym w celu ustawienia wielkości oraz w celu wyświetlenia lub ukrycia elementu sterowania. Tych właściwości nie należy zmieniać dla obiektu HTMLLoader okna HTML. Do właściwości podstawowych należą: Właściwość Uwagi x, y Ustawia obiekt w jego kontenerze nadrzędnym. width, height Zmienia rozmiary obszaru wyświetlania. visible Kontroluje widoczność obiektu oraz jego treści. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 261 Wywoływanie skryptów w kontenerze HTML Poza oknem HTML właściwości width i height obiektu HTMLLoader mają domyślnie wartość 0. Właściwości width i height należy zmienić zanim załadowana treść HTML zostanie wyświetlona. Treść HTML zostanie narysowana zgodnie z rozmiarem HTMLLoader i wyświetlona zgodnie z właściwościami HTML i CSS treści. Zmiana wielkości obiektu HTMLLoader powoduje ponowne ułożenie jego zawartości. Podczas ładowania treści do nowego obiektu HTMLLoader (z właściwością width równą 0) kuszące może być ustawienie wartości width i height wyświetlanego obiektu HTMLLoader za pomocą właściwości contentWidth i contentHeight. Ta technika działa dla stron, które mają odpowiednią minimalną szerokość po wyświetleniu zgodnie z regułami strumienia HTML i CSS. Jeśli jednak dla obiektu HTMLLoader nie określono odpowiedniej szerokości, wówczas niektóre strony są wyświetlane jako stosunkowo długie i wąskie. Uwaga: Po zmianie właściwości width i height obiektu HTMLLoader wartości scaleX i scaleY nie ulegają zmianie, jak w przypadku większości innych typów obiektów wyświetlanych. Przezroczystość obiektu HTMLLoader Właściwość paintsDefaultBackground obiektu HTMLLoader, która ma domyślnie wartość true, określa, czy obiekt HTMLLoader jest rysowany z nieprzezroczystym tłem. Jeśli właściwość paintsDefaultBackground ma wartość false, wówczas tło jest przezroczyste. Kontener obiektu wyświetlanego lub inne obiekty wyświetlane poniżej obiektu HTMLLoader są widoczne za elementami widocznymi na pierwszym planie treści HTML. Jeśli element body lub inny element treści HTML określa kolor tła (np. za pomocą style="backgroundcolor:gray"), wówczas tło tej części HTML jest nieprzezroczyste i wyświetlane w określonym kolorze. Jeśli właściwość opaqueBackground obiektu HTMLLoader oraz obiektu paintsDefaultBackground ma wartość false, wówczas kolor ustawiony dla właściwości opaqueBackground będzie widoczny. Uwaga: Możliwe jest użycie przezroczystej grafiki w formacie PNG w celu utworzenia tła o różnych współczynnikach alfa dla elementów w dokumencie HTML. Ustawianie stylu przezroczystości elementu HTML nie jest obsługiwane. Skalowanie treści HTMLLoader Nie należy zmieniać skali obiektu HTMLLoader powyżej wartości współczynnika 1.0. Tekst w treści HTMLLoader jest renderowana z określoną rozdzielczością i po zwiększeniu skali widoczne będą poszczególne piksele obiektu HTMLLoader. Aby zapobiec skalowaniu obiektu HTMLLoader oraz jego treści podczas zmiany wielkości okna, należy ustawić właściwość scaleMode stołu montażowego na StageScaleMode.NO_SCALE. Zagadnienia dotyczące ładowania treści SWF lub PDF na stronie HTML Treść SWF i PDF wczytana do obiektu HTMLLoader nie jest wyświetlana w następujących okolicznościach: • W przypadku zmiany skali obiektu HTMLLoader na współczynnik inny niż 1.0. • Jeśli właściwość alpha obiektu HTMLLoader zostanie ustawiona na wartość inną niż 1.0. • W przypadku obrócenia treści obiektu HTMLLoader. Treść pojawia się ponownie po usunięciu niezgodnego ustawienia właściwości i usunięciu filtrów aktywnych. Uwaga: Środowisko wykonawcze nie może wyświetlać treści SWF lub PDF w oknach przezroczystych. Więcej informacji na temat ładowania tych typów nośników do obiektu HTMLLoader zawiera sekcja „Osadzanie treści SWF w kodzie HTML” na stronie 246 oraz „Dodawanie treści w formacie PDF” na stronie 274. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 262 Wywoływanie skryptów w kontenerze HTML Zaawansowane właściwości wyświetlania Klasa HTMLLoader dziedziczy kilka metod, które mogą być używane w celu tworzenia efektów specjalnych. W ogólnym wypadku dla tych efektów obowiązują ograniczenia, gdy są używane z wyświetlanymi obiektami HTMLLoader, ale mogą być użyteczne dla przejść lub innych tymczasowych efektów. Na przykład: jeśli wyświetlane jest okno dialogowe w celu gromadzenia danych wprowadzonych przez użytkownika można zmniejszyć ostrość wyświetlania okna głównego do czasu zamknięcia okna dialogowego. I podobnie — można również spowodować znikanie podczas zamykania okna. Do zaawansowanych właściwości wyświetlania należą: Właściwość Ograniczenia alpha Może zmniejszać czytelność treści HTML. filters W oknie HTML efekty zewnętrzne są mocowane do krawędzi okna. graphics Kształty rysowane za pomocą polecenia graphics mogą pojawiać się poniżej treści HTML, łącznie z domyślnym tłem. Właściwość paintsDefaultBackground musi mieć wartość false — tylko wówczas narysowane kształty będą widoczne. opaqueBackground Nie powoduje zmiany koloru domyślnego tła. Właściwość paintsDefaultBackground musi mieć wartość false — tylko wówczas ta warstwa koloru będzie widoczna. rotation Narożniki prostokątnego obszaru HTMLLoader mogą być przymocowane do krawędzi okna. Treść SWF i PDF ładowana do treści HTML nie jest wyświetlana. scaleX, scaleY W przypadku współczynników skali większych niż 1 mogą być widoczne piksele zrenderowanego obrazu. Treść SWF i PDF ładowana do treści HTML nie jest wyświetlana. transform Może zmniejszać czytelność treści HTML. Wyświetlana treść HTML może być przymocowana do krawędzi okna. Treść SWF i PDF ładowana do treści HTML nie jest wyświetlana, jeśli właściwość transform obejmuje rotacje, skalowanie i pochylanie. Poniższy przykład ilustruje sposób ustawiania tablicy filters w celu zmniejszenia ostrości całego wyświetlanego obszaru HTML: 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; Przewijanie treści HTML Klasa HTMLLoader zawiera następujące właściwości, które umożliwiają kontrolowanie przewijania treści HTML: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 263 Wywoływanie skryptów w kontenerze HTML Właściwość Opis contentHeight Wysokość treści HTML w pikselach. contentWidth Szerokość treści HTML w pikselach. scrollH Pozycja przewijania w poziomie treści HTML w obiekcie HTMLLoader. scrollV Pozycja przewijania w pionie treści HTML w obiekcie HTMLLoader. Poniższy kod ustawia właściwość scrollV w taki sposób, że treść HTML jest przewijana do dołu strony: 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; } Obiekt HTMLLoader nie zawiera poziomych ani pionowych pasków przewijania. Paski przewijania można zaimplementować w języku ActionScript. Można również użyć metody HTMLLoader.createRootWindow() w celu utworzenia okna, które zawiera obiekt HTMLLoader z paskami przewijania (patrz „Tworzenie okien z przewijaną treścią HTML” na stronie 272). Dostęp do listy historii HTML W miarę ładowania nowych stron do obiektu HTMLLoader środowisko wykonawcze tworzy listę historii dla obiektu. Lista historii odpowiada obiektowi window.history na stronie HTML. Klasa HTMLLoader zawiera następujące właściwości i metody, które umożliwiają pracę z listą historii HTML: Element klasy Opis historyLength Całkowita długość listy historii, łącznie z pozycjami w nawigacji „do przodu” i „do tyłu”. historyPosition Bieżąca pozycja na liście historii. Pozycje historii przed tą pozycją reprezentują nawigację „do tyłu”, a pozycje po tej pozycji reprezentują nawigację „do przodu”. getHistoryAt() Zwraca obiekt URLRequest odpowiadający pozycji historii w określonej pozycji na liście historii. historyBack() Jeśli to możliwe, nawiguje do tyłu na liście historii. historyForward() Jeśli to możliwe, nawiguje do przodu na liście historii. historyGo() Przechodzi o wskazaną liczbę kroków w przeglądarce historii. Wartość dodatnia powoduje nawigację do przodu, wartość ujemna — nawigację do tyłu. Nawigacja do zera powoduje ponowne załadowanie strony. Określenie pozycji poza końcem powoduje przejście na koniec listy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 264 Wywoływanie skryptów w kontenerze HTML Pozycje na liście historii są zapisywane jako obiekty typu HistoryListItem. Klasa HistoryListItem ma następujące właściwości: Właściwość Opis isPost Wartość true, jeśli strona HTML zawiera dane POST. originalUrl Oryginalny adres URL strony HTML przed przekierowaniami. title Tytuł strony HTML. url Adres URL strony HTML. Ustawianie agenta użytkownika używanego podczas ładowania treści HTML Klasa HTMLLoader zawiera właściwość userAgent, co umożliwia ustawienie ciągu znaków agenta użytkownika używanego przez klasę HTMLLoader. Ustawia właściwość userAgent obiektu HTMLLoader przed wywołaniem metody load(). Jeśli ta właściwość zostanie ustawiona dla instancji HTMLLoader, wówczas właściwość userAgent klasy URLRequest przekazanej do metody load()nie będzie używana. Domyślnego agenta użytkownika używanego przez wszystkie obiekty HTMLLoader w domenie aplikacji można ustawić poprzez ustawienie właściwości URLRequestDefaults.userAgent. Statyczne właściwości URLRequestDefaults mają zastosowanie jako domyślne dla wszystkich obiektów URLRequest, nie tylko dla obiektów URLRequest używanych z metodą load() obiektów HTMLLoader. Ustawienie właściwości userAgent obiektu HTMLLoader zastępuje domyślne ustawienie URLRequestDefaults.userAgent. Jeśli wartość agenta użytkownika nie zostanie ustawiona dla właściwości userAgent obiektu HTMLLoader lub dla właściwości URLRequestDefaults.userAgent, wówczas będzie używana domyślna wartość agenta użytkownika AIR. Ta domyślna wartość może być różna w zależności od systemu operacyjnego środowiska wykonawczego (np. Mac OS lub Windows), języka środowiska wykonawczego, wersji środowiska wykonawczego, co przedstawiono w poniższych dwóch przykładach: • "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0" • "Mozilla/5.0 (Windows; U; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0" Ustawianie kodowania znaków do użytku z treścią HTML Strona HTML może określać kodowanie znaków, z jakiego korzysta, łącznie ze znacznikiem meta jak poniżej: meta http-equiv="content-type" content="text/html" charset="ISO-8859-1"; Aby zapewnić stosowanie określonego kodowania znaków, należy zmienić ustawienie strony, ustawiając właściwość textEncodingOverride obiektu HTMLLoader: var html:HTMLLoader = new HTMLLoader(); html.textEncodingOverride = "ISO-8859-1"; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 265 Wywoływanie skryptów w kontenerze HTML Należy określić kodowanie znaków dla treści HTMLLoader, jakie będzie używane wówczas, gdy strona HTML nie określi ustawienia za pomocą właściwości textEncodingFallback obiektu HTMLLoader: var html:HTMLLoader = new HTMLLoader(); html.textEncodingFallback = "ISO-8859-1"; Właściwość textEncodingOverride zastępuje ustawienie na stronie HTML. Właściwość textEncodingOverride i ustawienie na stronie HTML zastępują właściwość textEncodingFallback. Przed załadowaniem treści HTML należy ustawić właściwość textEncodingOverride lub właściwość textEncodingFallback. Definiowanie interfejsów użytkownika w stylu przeglądarki dla treści HTML Język JavaScript udostępnia kilka interfejsów API przeznaczonych do kontrolowania okna, w którym wyświetlana jest treść HTML. W środowisku AIR te interfejsy API mogą być zastępowane poprzez implementowanie niestandardowej klasy HTMLHost. Informacje o rozszerzaniu klasy HTMLHost Na przykład: jeśli aplikacja prezentuje wiele obiektów HTMLLoader w interfejsie z kartami, wówczas programista może chcieć, aby zmiany tytułów na ładowanych stronach HTML powodowały zmiany etykiet kart, a nie tytułu głównego okna. I podobnie — kod może reagować na wywołanie metody window.moveTo() poprzez przeniesienie obiektu HTMLLoader do kontenera nadrzędnego obiektu wyświetlanego; poprzez przeniesienie okna, które zawiera obiekt HTMLLoader; poprzez niewykonanie żadnej operacji lub poprzez wykonanie zupełnie innej operacji. Klasa AIR HTMLHost kontroluje następujące właściwości i metody JavaScript: • window.status • window.document.title • window.location • window.blur() • window.close() • window.focus() • window.moveBy() • window.moveTo() • window.open() • window.resizeBy() • window.resizeTo() Utworzenie obiektu HTMLLoader za pomocą metody new HTMLLoader() nie powoduje aktywacji właściwości i metod JavaScript z listy. Klasa HTMLHost udostępnia domyślną implementację tych interfejsów API JavaScript w stylu przeglądarki. Możliwe jest również rozszerzenie klasy HTMLHost w celu dostosowania zachowania. W celu utworzenia obiektu HTMLHost obsługującego zachowanie domyślne należy ustawić dla parametru defaultBehaviors wartość true w konstruktorze HTMLHost: var defaultHost:HTMLHost = new HTMLHost(true); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 266 Wywoływanie skryptów w kontenerze HTML Po utworzeniu okna HTML w środowisku AIR za pomocą metody createRootWindow() klasy HTMLLoader następuje automatyczne przypisanie instancji HTMLHost obsługującej domyślne zachowania. Zachowanie obiektu hosta można zmienić poprzez przypisanie innej implementacji HTMLHost do właściwości htmlHost obiektu HTMLLoader lub przypisanie wartości null w celu wyłączenia tych funkcji. Uwaga: Środowisko AIR przypisuje domyślny obiekt HTMLHost do początkowego okna tworzonego dla aplikacji AIR opartej na HTML oraz do dowolnych okien utworzonych przez domyślną implementację metody window.open() JavaScript. Przykład: rozszerzanie klasy HTMLHost Poniższy przykład prezentuje sposób dostosowania wpływu, jaki obiekt HTMLLoader wywiera na interfejs użytkownika, poprzez rozszerzenie klasy HTMLHost: 1 Utwórz plik Flash dla środowiska AIR. Ustaw klasę document tego pliku jako CustomHostExample, a następnie zapisz plik pod nazwą CustomHostExample.fla. 2 Utwórz plik ActionScript o nazwie CustomHost.as, który zawiera klasę rozszerzającą klasę HTMLHost (podklasa). Ta klasa przesłania niektóre metody nowej klasy w celu obsługi zmian w ustawieniach powiązanych z interfejsem użytkownika. Na przykład: klasa CustomHost definiuje zachowania wywołanej metody window.open() i zmiany właściwości window.document.title. Wywołania metody window.open() powodują otwieranie strony HTML w nowym oknie, a zmiany właściwości window.document.title (łącznie z ustawieniem elementu <title> strony HTML) powodują ustawienie tytułu tego okna. 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, TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 267 Wywoływanie skryptów w kontenerze HTML 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; } 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 Utwórz inny plik ActionScript o nazwie CustomHostExample.as, który będzie zawierał klasę document dla aplikacji. Ta klasa tworzy obiekt HTMLLoader i ustawia jego właściwość host na instancję klasy CustomHost zdefiniowaną w poprzednim kroku: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 268 Wywoływanie skryptów w kontenerze 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; } } } W celu przetestowania tego kodu należy dołączyć do katalogu aplikacji plik HTML o następującej treści: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 269 Wywoływanie skryptów w kontenerze 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> Obsługa zmian właściwości window.location W celu obsługiwania zmian adresu URL strony HTML należy przesłonić metodę locationChange(). Metoda locationChange() jest wywoływana, gdy kod JavaScript na stronie zmieni wartość window.location. Poniższy przykład ładuje żądany adres URL: override public function updateLocation(locationURL:String):void { htmlLoader.load(new URLRequest(locationURL)); } Uwaga: Za pomocą właściwości htmlLoader obiektu HTMLHost można tworzyć odwołania do bieżącego obiektu HTMLLoader. Obsługa wywołań JavaScript do funkcji window.moveBy(), window.moveTo(), window.resizeTo(), window.resizeBy() W celu obsługiwania zmian krawędzi treści HTML należy przesłonić metodę set windowRect(). Metoda set windowRect() jest wywoływana, gdy kod JavaScript na stronie wywoła metodę window.moveBy(), window.moveTo(), window.resizeTo() lub metodę window.resizeBy(). Poniższy przykład aktualizuje krawędzie okna na pulpicie: override public function set windowRect(value:Rectangle):void { htmlLoader.stage.nativeWindow.bounds = value; } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 270 Wywoływanie skryptów w kontenerze HTML Obsługa wywołań JavaScript do funkcji window.open() W celu obsługiwania wywołań metody window.open() z kodu JavaScript należy przesłonić metodę createWindow(). Implementacje metody createWindow() są odpowiedzialne za tworzenie i zwracanie nowego obiektu HTMLLoader. Zwykle obiekt HTMLLoader jest wyświetlany w nowym oknie, ale tworzenie okna nie jest wymagane. Poniższy przykład ilustruje sposób implementacji funkcji createWindow() za pomocą metody HTMLLoader.createRootWindow() w celu utworzenia okna i obiektu HTMLLoader. Można również osobno utworzyć obiekt NativeWindow i dodać obiekt HTMLLoader do stołu montażowego okna. 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; } Uwaga: Ten przykład przypisuje niestandardową implementację HTMLHost do dowolnych nowych okien utworzonych za pomocą metody window.open(). W razie potrzeby można również użyć innej implementacji lub ustawić dla właściwości htmlHost wartość null dla nowych okien. Obiekt przekazany jako parametr do metody createWindow() jest obiektem HTMLWindowCreateOptions. Klasa HTMLWindowCreateOptions zawiera właściwości, które zgłaszają wartości ustawione w ciągu znaków parametru features w wywołaniu metody window.open(): Właściwość klasy HTMLWindowCreateOptions Odpowiadające ustawienie w ciągu znaków funkcji w wywołaniu metody window.open() z kodu JavaScript fullscreen fullscreen height height locationBarVisible location menuBarVisible menubar resizeable resizable scrollBarsVisible scrollbars statusBarVisible status toolBarVisible toolbar width width x left lub screenX y top lub screenY Klasa HTMLLoader nie implementuje wszystkich funkcji, które mogą być określone w ciągu znaków tej funkcji. W razie potrzeby aplikacja musi udostępniać paski przewijania, paski lokalizacji, paski menu, paski stanu oraz paski narzędzi. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 271 Wywoływanie skryptów w kontenerze HTML Inne argumenty metody window.open() JavaScript są obsługiwane przez system. Implementacja metody createWindow() nie powinna ładować treści w obiekcie HTMLLoader ani ustawiać tytułu okna. Obsługa wywołań JavaScript do funkcji window.close() W celu obsługiwania wywołań metody window.close() z kodu JavaScript należy przesłonić metodę windowClose(). Poniższy przykład zamyka okno pulpitu po wywołaniu metody window.close(): override public function windowClose():void { htmlLoader.stage.nativeWindow.close(); } Wywołania metody window.close() z kodu JavaScript nie muszą zamykać okna zawierającego. Można na przykład usunąć obiekt HTMLLoader z listy wyświetlania, pozostawiając okno otwarte (okno może zawierać inną treść), jak w poniższym kodzie: override public function windowClose():void { htmlLoader.parent.removeChild(htmlLoader); } Obsługa zmian właściwości window.status W celu obsługiwania zmian JavaScript dotyczących wartości window.status należy przesłonić metodę updateStatus(). W poniższym przykładzie polecenie trace dotyczy wartości stanu: override public function updateStatus(status:String):void { trace(status); } Żądany stan jest przekazywany jako ciąg znaków do metody updateStatus(). Obiekt HTMLLoader nie udostępnia paska stanu. Obsługa zmian właściwości window.document.title W celu obsługiwania zmian JavaScript dotyczących wartości window.document.title należy przesłonić metodę updateTitle(). Poniższy przykład zmienia tytuł okna i dołącza do tytułu ciąg znaków „Sample”: override public function updateTitle(title:String):void { htmlLoader.stage.nativeWindow.title = title + " - Sample"; } Jeśli właściwość document.title jest ustawiona na stronie HTML, wówczas żądany tytuł jest przekazywany jako ciąg znaków do metody updateTitle(). Zmiany właściwości document.title nie muszą powodować zmiany tytułu okna zawierającego obiekt HTMLLoader. Można na przykład zmienić inny element interfejsu, taki jak pole tekstowe. Obsługa wywołań JavaScript do funkcji window.blur() i window.focus() W celu obsługi wywołań metod window.blur() i window.focus() w kodzie JavaScript należy przesłonić metody windowBlur() i windowFocus(), co przedstawiono w poniższym przykładzie: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 272 Wywoływanie skryptów w kontenerze 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); } Uwaga: Środowisko AIR nie udostępnia interfejsu API przeznaczonego do dezaktywowania okna lub aplikacji. Tworzenie okien z przewijaną treścią HTML Klasa HTMLLoader zawiera statyczną metodę HTMLLoader.createRootWindow(), która umożliwia otwarcie nowego okna (reprezentowanego przez obiekt NativeWindow), które zawiera obiekt HTMLLoader oraz definiuje niektóre ustawienia interfejsu użytkownika dla okna. Metoda przyjmuje cztery parametry, które umożliwiają zdefiniowanie interfejsu użytkownika: Parametr Opis visible Wartość logiczna, która określa, czy okno jest początkowo widoczne (true) czy niewidoczne (false). windowInitOptions Obiekt NativeWindowInitOptions. Klasa NativeWindowInitOptions definiuje opcje inicjowania dla obiektu NativeWindow, łącznie z następującymi ustawieniami: określa, czy możliwe jest maksymalizowanie, minimalizowanie i zmiana wielkości okna; określa, czy okno ma karnację systemową czy niestandardową; określa, czy okno jest przezroczyste czy nieprzezroczyste (dla okien bez karnacji systemowej); określa również typ okna. scrollBarsVisible Określa, czy paski przewijania są dostępne (true) czy niedostępne (false). bounds Obiekt Rectangle definiujący pozycję i wielkość nowego okna. Na przykład: poniższy kod korzysta z metody HTMLLoader.createRootWindow() w celu utworzenia okna z treścią HTMLLoader, która korzysta z pasków przewijania: 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(); Uwaga: Okna utworzone poprzez bezpośrednie wywołanie metody createRootWindow() w kodzie JavaScript pozostają niezależne od otwieranych okien HTML. Na przykład właściwości JavaScript opener i parent Window mają wartość null. Jeśli jednak metoda createRootWindow() zostanie wywołana bezpośrednio poprzez przesłonięcie metody createWindow() HTMLHost wywołaniem metody createRootWindow(), wówczas właściwości opener i parent będą odwoływały się do otwieranego okna HTML. Tworzenie podklas klasy HTMLLoader W celu tworzenia nowych zachowań można tworzyć podklasy klasy HTMLLoader. Na przykład: można utworzyć podklasę, która definiuje domyślne detektory zdarzeń dla zdarzeń HTMLLoader (np. zdarzeń wywoływanych podczas renderowania HTML lub gdy użytkownik kliknie odsyłacz). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 273 Wywoływanie skryptów w kontenerze HTML Poniższy przykład rozszerza klasę HTMLHost w celu udostępnienia zachowania normalnego przy wywołaniu metody window.open() JavaScript. W przykładzie następnie zdefiniowano podklasę klasy HTMLLoader, która korzysta z niestandardowej implementacji klasy 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 } } Poniższy przykład definiuje podklasę klasy HTMLLoader, która przypisuje obiekt MyHTMLHost do jego właściwości htmlHost: package { import flash.html.HTMLLoader; import MyHTMLHost; import HTMLLoader; public class MyHTML extends HTMLLoader { public function MyHTML() { super(); htmlHost = new MyHTMLHost(); } } } Szczegółowe informacje na temat klasy HTMLHost oraz metody HTMLLoader.createRootWindow(), które wykorzystano w tym przykładzie, zawiera sekcja „Definiowanie interfejsów użytkownika w stylu przeglądarki dla treści HTML” na stronie 265. 274 Rozdział 24: Dodawanie treści w formacie PDF Aplikacje działające w środowisku Adobe® AIR™ mogą renderować nie tylko treść w formatach SWF i HTML, ale również treść w formacie PDF. Aplikacje AIR renderują treść PDF przy użyciu klasy HTMLLoader, mechanizmu WebKit oraz wtyczki Adobe® Reader® do przeglądarki. W aplikacji AIR treść PDF może być wyświetlana na całej wysokości i szerokości okna aplikacji lub jako fragment interfejsu. Wtyczka Adobe Reader do przeglądarki steruje wyświetlaniem plików PDF w aplikacji AIR, tak że modyfikacje pasków narzędzi programu Reader (np. zmiana położenia, zakotwiczenia i widoczności) są zachowywane w następnych sesjach wyświetlania plików PDF, zarówno w aplikacji AIR, jak i w przeglądarce. Ważne: Aby móc renderować treść PDF w środowisku AIR, użytkownik musi mieć zainstalowany program Adobe Reader lub Adobe® Acrobat® w wersji 8.1 lub wyższej. Wykrywanie możliwości dotyczących treści PDF Jeśli użytkownik nie ma zainstalowanego programu Adobe Reader lub Adobe Acrobat w wersji 8.1 lub wyższej, treść PDF nie będzie wyświetlana w aplikacji AIR. Aby wykryć, czy użytkownik może renderować treść PDF, należy sprawdzić wartość właściwości HTMLLoader.pdfCapability. Ta właściwość przyjmuje wartość równą jednej ze stałych klasy HTMLPDFCapability: Stała Opis HTMLPDFCapability.STATUS_OK Wykryto wymaganą wersję (8.1 lub wyższą) programu Adobe Reader i treść PDF może być ładowana do obiektu HTMLLoader. HTMLPDFCapability.ERROR_INSTALLED_READER_NOT_FOUND Nie wykryto żadnej wersji programu Adobe Reader. Obiekt HTMLLoader nie może wyświetlać treści PDF. HTMLPDFCapability.ERROR_INSTALLED_READER_TOO_OLD Wykryto program Adobe Reader, ale jego wersja jest zbyt stara. Obiekt HTMLLoader nie może wyświetlać treści PDF. HTMLPDFCapability.ERROR_PREFERRED_READER_TOO_OLD Wykryto wymaganą wersję (8.1 lub wyższą) programu Adobe Reader, ale wersja programu Adobe Reader skonfigurowana do obsługi treści PDF jest starsza niż Reader 8.1. Obiekt HTMLLoader nie może wyświetlać treści PDF. W systemie Windows, jeśli w systemie użytkownika jest już uruchomiony program Adobe Acrobat lub Adobe Reader w wersji 7.x lub wyższej, używana będzie uruchomiona wersja, nawet jeśli jest także zainstalowana nowsza wersja obsługująca ładowanie treści PDF. W tym przypadku, jeśli właściwość pdfCampability ma wartość HTMLPDFCapability.STATUS_OK, to przy próbie załadowania treści PDF w aplikacji AIR starsza wersja programu Acrobat lub Reader wyświetli alert (i nie zostanie wygenerowany wyjątek w aplikacji AIR). Jeśli taka sytuacja może wystąpić u użytkowników, wskazane jest przekazanie im instrukcji, aby zamykali program Acrobat na czas pracy z aplikacją. Taka instrukcja może być wyświetlana np. wówczas, gdy treść PDF nie zostanie załadowana w dopuszczalnym czasie. W systemie Linux środowisko AIR wyszukuje program Adobe Reader w zmiennej środowiskowej PATH wyeksportowanej przez użytkownika (jeśli zawiera polecenie acroread) oraz w katalogu /opt/Adobe/Reader. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 275 Dodawanie treści w formacie PDF Poniższy kod wykrywa, czy użytkownik może wyświetlać treść PDF w aplikacji AIR, a jeśli nie, wyświetla kod błędu odpowiadający obiektowi błędu HTMLPDFCapability. if(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK) { trace("PDF content can be displayed"); } else { trace("PDF cannot be displayed. Error code:", HTMLLoader.pdfCapability); } Ładowanie treści PDF Można dodać treść PDF do aplikacji AIR, tworząc instancję klasy HTMLLoader, ustawiając jej wymiary i podając ścieżkę do pliku PDF. Poniższy przykład ładuje plik PDF z witryny zewnętrznej. W obiekcie URLRequest ścieżkę przykładową należy zastąpić ścieżką do dostępnego zewnętrznego pliku PDF. 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); Można również ładować treść z adresów URL plików oraz adresów URL charakterystycznych dla środowiska AIR, takich jak app oraz app-storage. Na przykład poniższy kod ładuje plik test.pdf z podkatalogu PDF katalogu aplikacji: app:/js_api_reference.pdf Więcej informacji o schematach adresów URL charakterystycznych dla środowiska AIR zawiera sekcja „Korzystanie ze schematów URL środowiska AIR w adresach URL” na stronie 308. Wywoływanie skryptów w treści PDF Istnieje możliwość użycia skryptów JavaScript do sterowania treścią PDF, tak jak w przypadku strony sieci Web w przeglądarce. Rozszerzenia JavaScript programu Acrobat oferują m.in. następujące możliwości: • Sterowanie nawigacją i powiększeniem strony. • Przetwarzanie formularzy w dokumencie. • Sterowanie zdarzeniami multimedialnymi. Kompletne, szczegółowe informacje na temat rozszerzeń JavaScript dla programu Adobe Acrobat są dostępne w serwisie Adobe Acrobat Developer Connection pod adresem http://www.adobe.com/devnet/acrobat/javascript.html. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 276 Dodawanie treści w formacie PDF Podstawy komunikacji HTML-PDF Skrypt JavaScript na stronie HTML może wysłać komunikat do skryptu JavaScript w treści PDF, wywołując metodę postMessage() obiektu DOM reprezentującego treść PDF. Rozważmy na przykład następującą osadzoną treść PDF: <object id="PDFObj" data="test.pdf" type="application/pdf" width="100%" height="100%"/> Poniższy kod JavaScript w zawierającej PDF treści HTML wysyła komunikat do kodu JavaScript w pliku PDF: pdfObject = document.getElementById("PDFObj"); pdfObject.postMessage(["testMsg", "hello"]); Plik PDF może zawierać kod JavaScript odbierający komunikat. Kod JavaScript można dodawać do plików PDF w różnych kontekstach, w szczególności w kontekście dokumentu, folderu, strony, pola i partii wsadowej. Tutaj omawiamy wyłącznie kontekst dokumentu, w którym zdefiniowane są skrypty wykonywane podczas otwierania dokumentu PDF. Plik PDF może dodać właściwość messageHandler do obiektu hostContainer. Właściwość messageHandler jest obiektem definiującym funkcje obsługi reagujące na komunikaty. Na przykład w poniższym kodzie zdefiniowano funkcję obsługi komunikatów odbieranych przez plik PDF z jego kontenera (czyli z treści HTML, w której jest osadzony plik PDF): this.hostContainer.messageHandler = {onMessage: myOnMessage}; function myOnMessage(aMessage) { if(aMessage[0] == "testMsg") { app.alert("Test message: " + aMessage[1]); } else { app.alert("Error"); } } Kod JavaScript na stronie HTML może wywołać metodę postMessage() obiektu PDF zawartego na stronie. Wywołanie tej metody powoduje wysłanie komunikatu ("Hello from HTML") do kodu JavaScript na poziomie dokumentu w pliku PDF: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 277 Dodawanie treści w formacie 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> Bardziej zaawansowany przykład oraz informacje na temat użycia programu Acrobat 8 w celu dodania kodu JavaScript do pliku PDF zawiera dokument Wywoływanie skryptów w treści PDF ze środowiska Adobe AIR. Wywoływanie skryptów w treści PDF z kodu ActionScript Kod ActionScript (w treści SWF) nie może bezpośrednio komunikować się z kodem JavaScript w treści PDF. Jednak kod ActionScript może komunikować się z kodem JavaScript na stronie HTML załadowanej do obiektu HTMLLoader, który z kolei ładuje treść PDF, a ten kod JavaScript może już komunikować się z kodem JavaScript w załadowanym pliku PDF. Więcej informacji zawiera sekcja „Programowanie w językach HTML i JavaScript” na stronie 235. Znane ograniczenia treści PDF w środowisku AIR Treść PDF w środowisku Adobe AIR podlega następującym ograniczeniom: • Treść PDF nie jest wyświetlana w oknie (obiekcie NativeWindow), który jest przezroczysty (którego właściwość transparent jest ustawiona na true). • Kolejność wyświetlania pliku PDF różni się od kolejności wyświetlania pozostałych obiektów wyświetlanych w aplikacji AIR. Mimo że treść PDF jest prawidłowo obcinana zgodnie z kolejnością wyświetlania treści HTML, zawsze będzie znajdować się nad treścią należącą do kolejności wyświetlania aplikacji AIR. • Treść PDF nie jest wyświetlana w oknie wyświetlanym w trybie pełnoekranowym (gdy właściwość displayState obiektu Stage ma wartość StageDisplayState.FULL_SCREEN lub StageDisplayState.FULL_SCREEN_INTERACTIVE). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 278 Dodawanie treści w formacie PDF • Jeśli pewne właściwości wizualne obiektu HTMLLoader, które zawierają dokument PDF, zostaną zmienione, dokument PDF stanie się niewidoczny. Te właściwości obejmują właściwości filters, alpha, rotation i scaling. Zmiana tych właściwości spowoduje wyrenderowanie pliku PDF, który będzie niewidoczny do momentu przywrócenia wartości domyślnych właściwości. Dzieje się tak również wówczas, gdy zostaną zmienione wspomniane właściwości kontenerów obiektu wyświetlanego zawierającego obiekt HTMLLoader. • Treść PDF jest widoczna jedynie wtedy, gdy właściwość scaleMode obiektu Stage obiektu NativeWindow zawierającego treść PDF jest ustawiona na wartość StageScaleMode.NO_SCALE. W przypadku ustawienia na dowolną inną wartość, treść PDF nie jest widoczna. • Klikanie łączy do treści w pliku PDF powoduje zmianę pozycji przewinięcia treści PDF. Klikanie łączy do treści poza plikiem PDF przekierowuje obiekt HTMLLoader zawierający plik PDF (nawet jeśli celem łącza jest nowe okno). • Procedury komentowania w plikach PDF nie działają w środowisku AIR. 279 Rozdział 25: Korzystanie z mechanizmów Digital Rights Management Serwer Adobe® Flash® Media Rights Management Server (FMRMS) umożliwia wydawcom multimediów rozpowszechnianie treści, w szczególności plików FLV i MP4, oraz pobieranie za nie od konsumentów opłat w postaci bezpośredniej (opłaty użytkowników) albo pośredniej (zyski z reklam). Wydawcy rozpowszechniają multimedia jako zaszyfrowane pliki FLV, które można pobierać i odtwarzać w programie Adobe® Media Player™ lub dowolnej aplikacji AIR, która korzysta z interfejsu API mechanizmu Digital Rights Management (DRM). Serwer FMRMS stwarza wydawcom treści możliwość udzielania licencji na podstawie tożsamości użytkownika w celu ochrony treści przy użyciu poświadczeń użytkownika. Konsument chce na przykład obejrzeć program telewizyjny, ale nie chce oglądać towarzyszących mu reklam. Aby uniknąć reklam, konsument rejestruje się i płaci dostawcy treści. Następnie użytkownik uzyskuje dostęp do programu przy użyciu uzyskanych poświadczeń i ogląda program bez reklam. Z kolei inny konsument chce oglądać treść w trybie offline, podczas podróży, bez dostępu do Internetu. Po zarejestrowaniu się i wniesieniu opłaty za usługę wyższej jakości użytkownik uzyska poświadczenia uwierzytelniania pozwalające na pobranie programu z witryny sieci Web wydawcy. Następnie użytkownik przez określony czas ma prawo do oglądania treści w trybie offline. Treść także jest zabezpieczona poświadczeniami użytkownika i nie może być udostępniana innym użytkownikom. Gdy użytkownik próbuje odtworzyć plik zaszyfrowany przy użyciu mechanizmu DRM, aplikacja nawiązuje kontakt z serwerem FMRMS, który z kolei nawiązuje kontakt z systemem wydawcy za pośrednictwem interfejsu dostawcy usług (SPI, ang. service provider interface) w celu uwierzytelnienia użytkownika i pobrania licencji — kuponu, który określa, czy użytkownik ma prawo uzyskać dostęp do treści, a jeśli tak, to na jak długo. Kupon określa również, czy użytkownik może korzystać z treści w trybie offline, a jeśli tak, to przez jak długi okres. Poświadczenia użytkownika są niezbędne do ustalenia praw dostępu do zaszyfrowanej treści. Mechanizm licencjonowania na podstawie tożsamości obsługuje także dostęp anonimowy. Na przykład dostęp anonimowy umożliwia dostawcy rozpowszechnianie treści z reklamami lub bezpłatne udostępnianie aktualnych treści przez określoną liczbę dni. W takiej sytuacji materiały archiwalne mogą być uznawane za treść o większej wartości, dostępną po wniesieniu opłaty i przedstawieniu poświadczeń. Dostawca treści może także określić i narzucić ograniczenia dotyczące typu i wersji odtwarzacza, za pomocą którego może być odtwarzania treść. W niniejszym rozdziale opisano techniki, które pozwolą aplikacji AIR na odtwarzanie treści zaszyfrowanej przy użyciu mechanizmu DRM. Nie jest konieczna znajomość sposobów szyfrowania treści przy użyciu mechanizmu DRM, ale przyjęto założenie, że aplikacja ma dostęp do tak zaszyfrowanej treści i komunikuje się z serwerem FMRMS w celu uwierzytelnienia użytkownika i pobrania kuponu. Omówienie serwera FMRMS, w tym procedury tworzenia zasad, zawiera dokumentacja dołączona do serwera FMRMS. Informacje na temat programu Adobe Media Player można znaleźć w Pomocy do programu Adobe Media Player dostępnej w tym programie. Dodatkowe informacje o mechanizmach DRM dostępne w Internecie Więcej informacji na temat mechanizmów Digital Rights Management można znaleźć w następujących źródłach: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 280 Korzystanie z mechanizmów Digital Rights Management Skorowidz języka • AuthenticationMethod • DRMAuthenticationCompleteEvent • DRMAuthenticationErrorEvent • DRMAuthenticateEvent • DRMContentData • DRMErrorEvent • DRMManager • DRMPlaybackTimeWindow • DRMStatusEvent • DRMVoucher • LoadVoucherSetting • NetStream Artykuły i przykłady na stronie Adobe Developer Connection • Adobe AIR Developer Connection for Flash (wyszukaj „digital rights management” lub „drm”) Omówienie przepływu pracy z zaszyfrowanym plikiem FLV Istnieją cztery typu zdarzeń, które mogą być wywoływane, gdy aplikacja AIR próbuje odtwarzać plik zaszyfrowany przy użyciu mechanizmu DRM: StatusEvent, DRMAuthenticateEvent, DRMErrorEvent i DRMStatusEvent. Aby obsługiwać takie pliki, aplikacja powinna dodać detektory zdarzeń związanych z mechanizmem DRM. Poniżej przedstawiono przepływ pracy, w ramach którego aplikacja AIR pobiera i odtwarza treść zaszyfrowaną przy użyciu mechanizmu DRM: 1 Aplikacja, korzystając z obiektu NetStream, próbuje odtworzyć plik FLV lub MP4. Jeśli treść jest zaszyfrowana, w kodzie jest wywoływane zdarzenie events.StatusEventDRM.encryptedFLV, które informuje, że plik FLV jest zaszyfrowany. Uwaga: Jeśli aplikacja nie powinna odtwarzać pliku zaszyfrowanego przy użyciu mechanizmu DRM, może wykrywać zdarzenie statusu wywoływane po napotkaniu zaszyfrowanej treści, a następnie poinformować użytkownika, że plik nie jest obsługiwany, i zamknąć połączenie. 2 Jeśli plik jest zaszyfrowany anonimowo, tj. wszyscy użytkownicy mogą wyświetlać treść bez konieczności wprowadzania poświadczeń uwierzytelniających, aplikacja AIR przechodzi do ostatniego kroku tego przepływu pracy. Jeśli jednak plik wymaga licencji powiązanej z tożsamością, tj. wymagane są poświadczenia użytkownika, wówczas obiekt NetStream wywołuje obiekt DRMAuthenticateEvent. Użytkownik musi podać poświadczenia uwierzytelniające, aby możliwe było rozpoczęcie odtwarzania. 3 Aplikacja AIR musi udostępniać mechanizm pytania o wymagane poświadczenia. Właściwości usernamePrompt, passwordPrompt i urlPrompt klasy DRMAuthenticationEvent, udostępniane przez serwer treści, mogą posłużyć do przekazania użytkownikowi końcowemu informacji o wymaganych danych. Właściwości te można wykorzystać do budowania interfejsu użytkownika, który pozwoli użytkownikowi wprowadzić poświadczenia. Na przykład ciąg usernamePrompt może zawierać informację mówiącą, że nazwa użytkownika musi mieć postać adresu e-mail. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 281 Korzystanie z mechanizmów Digital Rights Management Uwaga: Środowisko AIR nie udostępnia domyślnego interfejsu do wczytywania od użytkownika poświadczeń uwierzytelniających. Twórca aplikacji musi opracować interfejs użytkownika i obsługiwać zdarzenia DRMAuthenticateEvent. Jeśli aplikacja nie udostępnia detektora zdarzeń reagującego na obiekty DRMAuthenticateEvent, obiekt zaszyfrowany przy użyciu mechanizmu DRM pozostaje w stanie „oczekiwania na poświadczenia” i treść jest niedostępna. 4 Gdy aplikacja uzyska poświadczenia użytkownika, przekazuje je za pomocą metody setDRMAuthenticationCredentials() do obiektu NetStream. Sygnalizuje w ten sposób obiektowi NetStream, że powinien podjąć próbę uwierzytelnienia użytkownika przy następnej okazji. Środowisko AIR przekazuje następnie poświadczenia do serwera FMRMS celem uwierzytelnienia. Jeśli użytkownik został uwierzytelniony, aplikacja przechodzi do następnego kroku. Jeśli uwierzytelnienie nie powiedzie się, obiekt NetStream wywołuje nowy obiekt DRMAuthenticateEvent, a aplikacja wraca do kroku 3. Proces jest powtarzany w nieskończoność. Aplikacja powinna zapewnić mechanizm wykrywania i ograniczania wielokrotnie powtarzanych prób uwierzytelnienia. Na przykład aplikacja powinna pozwalać użytkownikowi na anulowanie próby, a tym samym zamknięcie połączenia NetStream. 5 Po uwierzytelnieniu użytkownika lub jeśli stosowane jest szyfrowanie anonimowe, podsystem DRM pobiera kupon. Kupon służy do sprawdzania, czy użytkownik jest uprawniony do wyświetlania treści. Informacje zawarte w kuponie mogą mieć zastosowanie zarówno do użytkowników uwierzytelnionych, jak i anonimowych. Na przykład zarówno uwierzytelnieni, jak i anonimowi użytkownicy mogą mieć dostęp do treści przez określony czas zanim treść utraci ważność; podobnie, obie kategorie użytkowników mogą nie mieć dostępu do treści, ponieważ jej dostawca nie obsługuje danej wersji aplikacji wyświetlającej. Jeśli nie wystąpił błąd i pomyślnie zweryfikowano uprawnienia użytkownika do wyświetlenia treści, obiekt NetStream wywołuje obiekt DRMStatusEvent, a aplikacja AIR rozpoczyna odtwarzanie. Obiekt DRMStatusEvent zawiera pokrewne informacje z kuponu, które identyfikują zasady i uprawnienia użytkownika. Na przykład są to informacje określające, czy treść może być udostępniana w trybie offline, lub termin ważności kuponu, po którym treści nie można już oglądać. Aplikacja na podstawie tych danych może poinformować użytkownika o obowiązujących go zasadach. Na przykład aplikacja może na pasku stanu wyświetlić pozostałą liczbę dni, przez jaką użytkownik będzie jeszcze mieć uprawnienia do wyświetlania treści. Jeśli użytkownik jest uprawniony do dostępu w trybie offline, kupon jest umieszczany w pamięci podręcznej, a zaszyfrowana treść jest pobierana na komputer użytkownika i udostępniana przez czas równy okresowi dzierżawy w trybie offline. Właściwość detail obiektu zdarzenia zawiera tekst „DRM.voucherObtained”. Aplikacja decyduje o miejscu lokalnego przechowywania treści udostępnianej w trybie offline. W środowisku AIR 1.5 można także wstępnie załadować kupony, korzystając z klasy DRMManager. Błędy związane z mechanizmem DRM powodują, że aplikacja wywołuje obiekt zdarzenia DRMErrorEvent. Środowisko AIR obsługuje niepowodzenia uwierzytelniania występujące w metodzie setDRMAuthenticationCredentials() obiektu NetStream, ponownie wywołując obiekt DRMAuthenticationEvent. Wszystkie inne obiekty zdarzeń powinny być jawnie obsługiwane przez aplikację. Dotyczy to także przypadków, w których użytkownik wprowadza poprawne poświadczenia, ale kupon chroniący zaszyfrowaną treść ogranicza dostęp do niej. Na przykład uwierzytelniony użytkownik może nie mieć dostępu do treści, ponieważ nie zapłacił za uprawnienia. Taka sytuacja wystąpi, gdy dwóch użytkowników zarejestrowanych u tego samego wydawcy multimediów spróbuje uzyskać dostęp do treści, za którą zapłacił tylko jeden z nich. Aplikacja powinna poinformować użytkownika o błędzie, np. ograniczeniu dostępu do treści, oraz zaproponować alternatywny sposób postępowania, np. przedstawić procedurę rejestracji i wniesienia opłaty za prawo do wyświetlenia treści. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 282 Korzystanie z mechanizmów Digital Rights Management Wstępne ładowanie kuponów w celu odtwarzania bez połączenia Możliwe jest wstępne ładowanie kuponów wymaganych do odtwarzania treści zabezpieczonej przy użyciu mechanizmu DRM. Wstępnie załadowane kupony umożliwiają użytkownikom wyświetlanie treści niezależnie do tego, czy w danej chwili mają aktywne połączenie z Internetem. (Oczywiście do samego wstępnego załadowania kuponu połączenie z Internetem jest wymagane). Do wstępnego ładowania kuponów służy metoda preloadEmbeddedMetadata() klasy NetStream oraz klasa DRMManager środowiska AIR 1.5. Poniżej przedstawiono kolejne etapy procedury wstępnego ładowania kuponu dla pliku multimedialnego chronionego mechanizmem DRM: 1 Pobierz i zapisz plik multimedialny. (Metadane DRM można wstępnie ładować wyłącznie z plików zapisanych lokalnie). 2 Utwórz obiekty NetConnection i NetStream, tworząc implementacje funkcji wywołania zwrotnego onDRMContentData() i onPlayStatus() w obiekcie klienckim NetStream. 3 Utwórz obiekt NetStreamPlayOptions i przypisz właściwości stream adres URL lokalnego pliku multimedialnego. 4 Wywołaj metodę preloadEmbeddedMetadata() obiektu NetStream, przekazując do niej obiekt NetStreamPlayOptions wskazujący plik multimedialny do przeanalizowania. 5 Jeśli plik multimedialny zawiera metadane DRM, wywoływana jest funkcja wywołania zwrotnego onDRMContentData(). Metadane są przekazywane do tej funkcji jako obiekt DRMContentData. 6 Użyj obiektu DRMContentData do uzyskania kuponu, korzystając z metody loadVoucher() klasy DRMManager. Jeśli właściwość authenticationMethod obiektu DRMContentData ma wartość userNameAndPassword, należy uwierzytelnić użytkownika na serwerze zarządzania uprawnieniami przed załadowaniem kuponu. Właściwości serverURL i domain obiektu DRMContentData można przekazać do metody authenticate() klasy DRMManager razem z poświadczeniami użytkownika. 7 Po zakończeniu analizowania pliku wywoływana jest funkcja wywołania zwrotnego onPlayStatus(). Jeśli funkcja onDRMContentData() nie została wywołana, plik nie zawiera metadanych potrzebnych do uzyskania kuponu (i możliwe, że nie jest zabezpieczony przy użyciu mechanizmu DRM). Poniższy przykładowy kod ilustruje sposób wstępnego ładowania kuponu dla lokalnego pliku multimedialnego: 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; TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 283 Korzystanie z mechanizmów Digital Rights Management 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 ); 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 { TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 284 Korzystanie z mechanizmów Digital Rights Management 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(); } } } Elementy i zdarzenia klasy NetStream związane z mechanizmem DRM Klasa NetStream udostępnia jednokierunkowe połączenie strumieniowe między programem Flash Player lub aplikacją AIR a serwerem Flash Media Server lub lokalnym systemem plików. (Klasa NetStream obsługuje także stopniowe pobieranie). Obiekt NetStream jest kanałem wewnątrz obiektu NetConnection. W aplikacji AIR klasa NetStream wywołuje cztery zdarzenia związane z mechanizmem DRM: Zdarzenie Opis drmAuthenticate To zdarzenie, zdefiniowane w klasie DRMAuthenticateEvent, jest wywoływane, gdy obiekt NetStream spróbuje odtworzyć treść zaszyfrowaną przy użyciu mechanizmu DRM, która wymaga uwierzytelnienia przy użyciu poświadczeń użytkownika. Właściwości tego zdarzenia to m.in. header, usernamePrompt, passwordPrompt oraz urlPrompt; właściwości te umożliwiają odczytywanie i ustawianie poświadczeń użytkownika. To zdarzenie jest wywoływane cyklicznie, dopóki obiekt NetStream nie odbierze poprawnych poświadczeń użytkownika. drmError To zdarzenie jest zdefiniowane w klasie DRMErrorEvent i wywoływane, gdy obiekt NetStream próbuje odtworzyć plik zaszyfrowany przy użyciu mechanizmu DRM i napotka błąd związany z tym mechanizmem. Przykładowo, obiekt zdarzenia błędu DRM jest wywoływany w razie niepowodzenia w uwierzytelnianiu użytkownika. Powodem może być niezakupienie przez użytkownika praw do wyświetlania treści lub brak obsługi aplikacji wyświetlającej przez dostawcę treści. drmStatus To zdarzenie jest zdefiniowane w klasie DRMStatusEvent i wywoływane, gdy rozpoczyna się odtwarzanie treści zaszyfrowanej przy użyciu mechanizmu DRM (gdy użytkownik został uwierzytelniony i ma uprawnienia do odtworzenia treści). Obiekt DRMStatusEvent zawiera informacje powiązane z kuponem informacyjnym, np. o możliwości udostępniania treści w trybie offline lub terminie ważności kuponu, po którym treści nie będzie już można wyświetlać. status To zdarzenie jest zdefiniowane w klasie events.StatusEvent i wywoływane tylko wtedy, gdy aplikacja próbuje odtworzyć treść zaszyfrowaną przy użyciu mechanizmu DRM poprzez wywołanie metody NetStream.play(). Wartość właściwości status to „DRM.encryptedFLV”. Klasa NetStream zawiera następujące metody związane z mechanizmem DRM: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 285 Korzystanie z mechanizmów Digital Rights Management Metoda Opis resetDRMVouchers() Usuwa wszystkie buforowane lokalnie dane kuponów związane z mechanizmem DRM. Aby użytkownik mógł uzyskać dostęp do zaszyfrowanej treści, aplikacja musi ponownie pobrać kupony. Na przykład, poniższy kod usuwa wszystkie kupony z buforu: NetStream.resetDRMVouchers(); setDRMAuthenticationCredentials() Przekazuje zestaw poświadczeń uwierzytelniających, w szczególności nazwę użytkownika, hasło i typ uwierzytelniania, do obiektu NetStream celem uwierzytelnienia. Poprawne typy uwierzytelniania to "drm" i "proxy". W przypadku typu uwierzytelniania "drm" podane poświadczenia są uwierzytelniane na serwerze FMRMS. W przypadku typu uwierzytelniania "proxy" poświadczenia są uwierzytelniane na serwerze proxy i muszą być zgodne z wymaganiami tego serwera. Opcja proxy umożliwia aplikacji uwierzytelnianie użytkownika na serwerze proxy, jeśli w danej organizacji takie uwierzytelnienie jest obowiązkowe, aby użytkownik mógł uzyskać dostęp do Internetu. O ile nie jest używane uwierzytelniania anonimowe, po uwierzytelnieniu na serwerze proxy użytkownik wciąż musi uwierzytelnić się na serwerze FMRMS, aby uzyskać kupon i odtworzyć treść. Aplikacja może po raz drugi wywołać metodę setDRMAuthenticationcredentials() z opcją "drm", aby uwierzytelnić użytkownika na serwerze FMRMS. preloadEmbeddedMetadata() Analizuje lokalny plik multimedialny w poszukiwaniu osadzonych metadanych. Po znalezieniu metadanych związanych z mechanizmem DRM środowisko AIR wywołuje funkcję wywołania zwrotnego onDRMContentData(). Ponadto obiekt NetStream wywołuje funkcje wywołania zwrotnego onDRMContentData() i onPlayStatus() w wyniku wywołania metody preloadEmbeddedMetaData(). Funkcja onDRMContentData() jest wywoływana po napotkaniu w pliku multimedialnym metadanych mechanizmu DRM. Funkcja onPlayStatus() jest wywoływana po zakończeniu analizowania całego pliku. Funkcje onDRMContentData() i onPlayStatus() muszą być zdefiniowane w obiekcie client przypisanym do instancji klasy NetStream. W wypadku użycia tego samego obiektu NetStream od wstępnego ładowania kuponów i odtwarzania treści, należy przed rozpoczęciem odtwarzania poczekać na wywołanie funkcji onPlayStatus() wygenerowane przez metodę preloadEmbeddedMetaData(). W poniższym kodzie użytkownik jest uwierzytelniany przy użyciu nazwy użytkownika ("administrator"), hasła ("password") i typu "drm". Metoda setDRMAuthenticationCredentials() musi udostępnić poświadczenia zgodne z poświadczeniami znanymi dostawcy treści i zaakceptowanymi przez niego (są to te same poświadczenia użytkownika, które uprawniają do wyświetlania treści). W przykładzie pominięto kod odtwarzający wideo i weryfikujący połączenie ze strumieniem wideo. 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"); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 286 Korzystanie z mechanizmów Digital Rights Management Korzystanie z klasy DRMStatusEvent Obiekt NetStream wywołuje obiekt DRMStatusEvent, gdy pomyślnie rozpocznie się odtwarzanie treści chronionej przez mechanizm DRM (tj. po zweryfikowaniu kuponu, uwierzytelnieniu użytkownika i potwierdzeniu jego uprawnień do wyświetlania treści). Obiekt DRMStatusEvent jest także wywoływany w przypadku użytkowników anonimowych, którym zezwolono na dostęp. Kupon jest sprawdzany w celu zweryfikowania, czy użytkownik anonimowy, który nie wymaga uwierzytelnienia, ma prawo odtwarzać treść. Odmowa dostępu dla użytkowników anonimowych może wynikać z wielu różnych przyczyn. Na przykład użytkownik anonimowy może nie mieć dostępu do treści, która utraciła ważność. Obiekt DRMStatusEvent zawiera informacje powiązane z kuponem informacyjnym, np. o możliwości udostępniania treści w trybie offline lub terminie ważności kuponu, po którym treści nie będzie już można wyświetlać. Aplikacja może na podstawie tych danych poinformować użytkownika o obowiązujących go zasadach i uprawnieniach. Właściwości klasy DRMStatusEvent Klasa DRMStatusEvent zawiera następujące właściwości: Właściwość Opis contentData Obiekt DRMContentData zawierający metadane DRM osadzone w treści. detail Ciąg znaków opisujący kontekst zdarzenia statusu. W przypadku mechanizmu DRM 1.0 jedyną poprawną wartością jest ciąg znaków DRM.voucherObtained. isAnonymous Wskazuje, czy treść szyfrowana przy użyciu mechanizmu DRM jest dostępna dla użytkowników bez konieczności podawania poświadczeń uwierzytelniających (true), czy też nie jest w ten sposób dostępna (false). Wartość false oznacza, że użytkownik musi podać nazwę użytkownika i hasło zgodne z danymi, jakie zna i jakich oczekuje dostawca treści. isAvailableOffline Określa, czy treść zaszyfrowana przy użyciu mechanizmu DRM może być udostępniana w trybie offline (true), czy nie (false). Aby treść chroniona przy użyciu mechanizmu DRM była dostępna w trybie offline, jej kupon musi być zapisany w pamięci podręcznej na komputerze lokalnym użytkownika. isLocal Wskazuje, czy kupon potrzebny do odtworzenia treści jest buforowany lokalnie. offlineLeasePeriod Pozostała liczba dni, przez jaką treść może być wyświetlana w trybie offline. policies Obiekt niestandardowy może zawierać niestandardowe właściwości związane z mechanizmem DRM. voucher Obiekt DRMVoucher. voucherEndDate Bezwzględna data, w której kupon traci ważność, a treść przestaje być dostępna do wyświetlania. Tworzenie funkcji obsługi zdarzenia DRMStatusEvent W poniższym przykładzie tworzona jest funkcja obsługi zdarzeń, która wyświetla informacje o statusie treści DRM dla obiektu NetStream, z którego pochodzi zdarzenie. Tę funkcję obsługi zdarzeń należy dodać do obiektu NetStream, który wskazuje na treść zaszyfrowaną przy użyciu mechanizmu DRM. function drmStatusEventHandler(event:DRMStatusEvent):void { trace(event); } function drmStatusEventHandler(event:DRMStatusEvent):void { trace(event); } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 287 Korzystanie z mechanizmów Digital Rights Management Korzystanie z klasy DRMAuthenticateEvent Obiekt DRMAuthenticateEvent jest wywoływany, gdy obiekt NetStream spróbuje odtworzyć treść zaszyfrowaną przy użyciu mechanizmu DRM, która wymaga uwierzytelnienia przy użyciu poświadczeń użytkownika. Funkcja obsługi zdarzenia DRMAuthenticateEvent jest odpowiedzialna za uzyskanie od użytkownika wymaganych poświadczeń (nazwy, hasła i typu) oraz przekazanie ich wartości do metody NetStream.setDRMAuthenticationCredentials() w celu sprawdzenia poprawności. Każda aplikacja AIR musi udostępniać mechanizm uzyskiwania poświadczeń od użytkownika. Aplikacja może na przykład udostępnić użytkownikowi prosty interfejs użytkownika służący do wprowadzania wartości nazwy użytkownika i hasła oraz opcjonalnie typu. Aplikacja AIR powinna także udostępniać mechanizm obsługi wielokrotnie powtarzanych prób uwierzytelniania i ograniczania liczby takich prób. Właściwości klasy DRMAuthenticateEvent Klasa DRMAuthenticateEvent zawiera następujące właściwości: Właściwość Opis authenticationType Określa, czy podane poświadczenia są przeznaczone do uwierzytelniania na serwerze FMRMS ("drm"), czy na serwerze proxy ("proxy"). Opcja "proxy" umożliwia aplikacji uwierzytelnianie użytkownika na serwerze proxy, jeśli w danej organizacji takie uwierzytelnienie jest obowiązkowe, aby użytkownik mógł uzyskać dostęp do Internetu. O ile nie jest używane uwierzytelniania anonimowe, po uwierzytelnieniu na serwerze proxy użytkownik wciąż musi uwierzytelnić się na serwerze FMRMS, aby uzyskać kupon i odtworzyć treść. Aplikacja może po raz drugi wywołać metodę setDRMAuthenticationcredentials() z opcją "drm", aby uwierzytelnić użytkownika na serwerze FMRMS. header Nagłówek zaszyfrowanego pliku treści udostępniony przez serwer. Zawiera informacje o kontekście zaszyfrowanej treści. netstream Obiekt NetStream, który zainicjował to zdarzenie. passwordPrompt Monit o hasło udostępniony przez serwer. Jest to ciąg znaków, który może zawierać instrukcję dotyczącą wymaganego hasła. urlPrompt Udostępniony przez serwer monit o adres URL. Ciąg może zawierać lokalizację, do której wysyłana jest nazwa użytkownika i hasło. usernamePrompt Monit o nazwę użytkownika udostępniony przez serwer. Jest to ciąg znaków, który może zawierać instrukcję dotyczącą wymaganej nazwy użytkownika. Na przykład dostawca treści może wymagać nazwy użytkownika w postaci adresu e-mail. Tworzenie funkcji obsługi zdarzenia DRMAuthenticateEvent W poniższym przykładzie tworzona jest funkcja obsługi zdarzenia, która przekazuje zestaw zakodowanych na stałe poświadczeń uwierzytelniających do obiektu NetStream, z którego pochodzi zdarzenia. (W przykładzie pominięto kod odtwarzający wideo i weryfikujący połączenie ze strumieniem wideo). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 288 Korzystanie z mechanizmów Digital Rights Management 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"); } Tworzenie interfejsu służącego do uzyskiwania poświadczeń od użytkownika Jeśli treść DRM wymaga uwierzytelnienia użytkownika, aplikacja AIR zazwyczaj musi uzyskać poświadczenia uwierzytelniające użytkownika za pośrednictwem interaktywnego interfejsu użytkownika. Korzystanie z klasy DRMErrorEvent Środowisko AIR wywołuje obiekt DRMErrorEvent, gdy obiekt NetStream — próbując odtworzyć plik zaszyfrowany przy użyciu mechanizmu — napotka błąd związany z mechanizmem DRM. W wypadku niepoprawnych poświadczeń użytkownika obiekt DRMAuthenticateEvent jest wywoływany cyklicznie, dopóki użytkownik nie wprowadzić poprawnych poświadczeń lub aplikacja AIR odmówi podejmowania następnych prób. Aplikacja powinna wykrywać wszelkie inne zdarzenia błędów DRM, aby być w stanie reagować na takie błędy. Nawet jeśli użytkownik wprowadzić poprawne poświadczenia, nadal może nie mieć uprawnień do wyświetlania treści, jeśli wynika to z warunków określonych w kuponie DRM. Przykładem jest sytuacja, w której użytkownik próbuje wyświetlić treść w nieuprawnionej aplikacji, tj. aplikacji niezatwierdzonej przez wydawcę treści zaszyfrowanej. W takim wypadku wywoływany jest obiekt DRMErrorEvent. Zdarzenia błędów mogą być także wywoływane, jeśli treść jest uszkodzona lub wersja aplikacji różni się od określonej w kuponie. Aplikacja musi zapewniać odpowiedni mechanizm obsługi błędów. Właściwości klasy DRMErrorEvent W poniższej tabeli wymieniono błędu zgłaszane przez obiekt DRMErrorEvent: Główny kod błędu Poboczny kod błędu Szczegóły błędu 1001 nieużywany Uwierzytelnienie użytkownika nie powiodło się. 1002 nieużywany Serwer Flash Media Rights Management Server (FMRMS) nie obsługuje protokołu Secure Sockets Layer (SSL). 1003 nieużywany Treść utraciła ważność i nie jest już dostępna do wyświetlania. 1004 nieużywany Niepowodzenie autoryzacji użytkownika. Taka sytuacja może wystąpić np. gdy użytkownik nie zakupił treści i nie ma prawa do oglądania jej. 1005 nieużywany Server URL Opis Nie można połączyć się z serwerem. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 289 Korzystanie z mechanizmów Digital Rights Management Główny kod błędu Poboczny kod błędu Szczegóły błędu 1006 nieużywany Wymagana jest aktualizacja klienta, tzn. serwer Flash Media Rights Management Server (FMRMS) wymaga nowego klienckiego mechanizmu DRM. 1007 nieużywany Ogólne niepowodzenie wewnętrzne. 1008 Szczegółowy kod błędu deszyfrowania Nieprawidłowy klucz licencji. 1009 nieużywany Treść FLV jest uszkodzona. 1010 nieużywany 1011 nieużywany Wersja aplikacji nie jest zgodna z określoną w zasadach. 1012 nieużywany Weryfikacja kuponu skojarzonego z zaszyfrowaną treścią nie powiodła się, co świadczy o możliwym uszkodzeniu treści. 1013 nieużywany Kupon skojarzony z zaszyfrowaną treści nie został pomyślnie zapisany. 1014 nieużywany Weryfikacja integralności nagłówka pliku FLV nie powiodła się, co świadczy o możliwym uszkodzeniu treści. Główny kod błędu Poboczny identyfikator błędu 3300 Kod błędu serwera Adobe Policy Server Aplikacja wykryła niepoprawny kupon skojarzony z treścią. 3301 nieużywany Uwierzytelnienie użytkownika nie powiodło się. 3302 nieużywany Protokół Secure Sockets Layer (SSL) nie jest obsługiwany przez serwer Flash Media Rights Management Server (FMRMS). 3303 nieużywany Treść utraciła ważność i nie jest już dostępna do wyświetlania. 3304 nieużywany Niepowodzenie autoryzacji użytkownika. Ten błąd może wystąpić nawet jeśli użytkownik jest uwierzytelniony, np. jeśli użytkownik nie zakupił praw do wyświetlania treści. 3305 nieużywany 3306 nieużywany Wymagana jest aktualizacja klienta, tzn. serwer Flash Media Rights Management Server (FMRMS) wymaga nowego klienckiego mechanizmu DRM. 3307 nieużywany Ogólne wewnętrzne niepowodzenie mechanizmu DRM. 3308 Szczegółowy kod błędu deszyfrowania Nieprawidłowy klucz licencji. 3309 nieużywany Treść wideo w formacie Flash jest uszkodzona. publisherID:applicationID Szczegóły błędu Server URL Opis Identyfikator aplikacji służącej do wyświetlania różni się od identyfikatora aplikacji obsługiwanej przez dostawcę treści. Opis Nie można połączyć się z serwerem. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 290 Korzystanie z mechanizmów Digital Rights Management Główny kod błędu Poboczny identyfikator błędu Szczegóły błędu Opis 3310 nieużywany publisherID:applicationID Identyfikator aplikacji służącej do wyświetlania różni się od identyfikatora aplikacji obsługiwanej przez dostawcę treści. Innymi słowy, aplikacja wyświetlająca nie jest obsługiwana przez dostawcę treści. 3311 nieużywany min=x:max=y Wersja aplikacji nie jest zgodna z określoną w kuponie. 3312 nieużywany Weryfikacja kuponu skojarzonego z zaszyfrowaną treścią nie powiodła się, co świadczy o możliwym uszkodzeniu treści. 3313 nieużywany Kupon skojarzony z zaszyfrowaną treści nie został pomyślnie zapisany w składnicy Microsafe. 3314 nieużywany Weryfikacja integralności nagłówka pliku FLV nie powiodła się, co świadczy o możliwym uszkodzeniu treści. 3315 nieużywany Zdalne odtwarzanie treści chronionej przez mechanizm DRM nie jest dozwolone. 3316 nieużywany Brak modułu AdobeCP. 3317 nieużywany Ładowanie modułu AdobeCP nie powiodło się. 3318 nieużywany Znaleziono niekompatybilną wersję modułu AdobeCP. 3319 nieużywany Brak punktu wejścia modułu AdobeCP w interfejsie API. 3320 nieużywany Moduł AdobeCP nie został uwierzytelniony. Tworzenie funkcji obsługi zdarzenia DRMErrorEvent W poniższym przykładzie tworzona jest funkcja obsługi zdarzenia dla obiektu NetStream, z którego zdarzenie pochodzi. Jest wywoływana, gdy obiekt NetStream napotka błąd przy próbie odtwarzania treści zaszyfrowanej przy użyciu mechanizmu DRM. Zazwyczaj po napotkaniu błędu aplikacja wykonuje szereg działań porządkowych, informuje użytkownika o błędzie i proponuje opcje jego rozwiązania. private function drmErrorEventHandler(event:DRMErrorEvent):void { trace(event.toString()); } Korzystanie z klasy DRMManager Klasa DRMManager służy do zarządzania kuponami i sesjami serwera uprawnień DRM w aplikacji AIR. Klasa DRMManager jest dostępna w środowisku AIR w wersji 1.5 i wyższych. Zarządzanie kuponami TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 291 Korzystanie z mechanizmów Digital Rights Management Za każdym razem, gdy użytkownik odtwarza z sieci (online) plik multimedialny zabezpieczony mechanizmem DRM, środowisko AIR pobiera i zapisuje w lokalnym buforze kupon licencji niezbędny do wyświetlenia treści. Jeśli aplikacja zapisze plik lokalnie, a kupon zezwala na odtwarzanie w trybie bez połączenia, wówczas użytkownik może wyświetlać treść nawet wtedy, gdy połączenie z serwerem uprawnień DRM jest niedostępne. Korzystając z klasy DRMManager i metody preloadEmbeddedMetadata() obiektu NetStream, można wstępnie zapisać kupon w buforze, aby aplikacja nie musiała inicjować odtwarzania w celu uzyskania licencji potrzebnej do wyświetlania treści. Na przykład aplikacja może pobrać plik multimedialny i uzyskać kupon, gdy użytkownik jeszcze ma połączenie. Aby wstępnie załadować kupon, należy pobrać obiekt DRMContentData za pomocą metody preloadEmbeddedMetadata() obiektu NetStream. Obiekt DRMContentData zawiera adres URL i domenę serwera uprawnień DRM, który może udostępnić licencję, oraz opisuje, czy wymagane jest uwierzytelnienie użytkownika. Na podstawie tej informacji można wywołać metodę loadVoucher() klasy DRMManager w celu uzyskania kuponu i zapisania go w buforze. Procedurę wstępnego ładowania kuponów opisano bardziej szczegółowo w sekcji „Wstępne ładowanie kuponów w celu odtwarzania bez połączenia” na stronie 282. Zarządzanie sesją Klasy DRMManager można także użyć do uwierzytelnienia użytkownika na serwerze uprawnień DRM i do zarządzania sesjami trwałymi. Wywołanie metody authenticate() klasy DRMManager umożliwia nawiązanie sesji z serwerem uprawnień DRM. Po pomyślnym uwierzytelnieniu klasa DRMManager wywołuje obiekt DRMAuthenticationCompleteEvent. Ten obiekt zawiera token sesji. Token można zapisać w celu nawiązywania w przyszłości sesji bez konieczności ponownego wprowadzania poświadczeń konta przez użytkownika. Aby nawiązać nową uwierzytelnioną sesję, należy przekazać token do metody setAuthenticationToken(). (Termin ważności tokenu i inne jego atrybuty są określone przez ustawienia na serwerze generującym token. Struktura danych tokenu nie jest przeznaczona do interpretacji przez kod aplikacji AIR i może ulec zmianie w przyszłych wersjach środowiska AIR). Tokeny uwierzytelniania można przenosić na inne komputery. Aby chronić tokeny, można przechowywać je w zaszyfrowanym magazynie lokalnym środowiska AIR. Więcej informacji można znaleźć w sekcji „Przechowywanie danych zaszyfrowanych” na stronie 217. Zdarzenia DRMStatus Klasa DRMManager wywołuje obiekt DRMStatusEvent po pomyślnym zakończeniu wywołania metody loadVoucher(). Jeśli uzyskano kupon, właściwość detail obiektu zdarzenia ma wartość: „DRM.voucherObtained”, a właściwość voucher zawiera obiekt DRMVoucher. Jeśli kupon nie został uzyskany, właściwość detail także ma wartość „DRM.voucherObtained”; jednak właściwość voucher jest wówczas równa null. Nieuzyskanie kuponu może wynikać np. z przypisania właściwości LoadVoucherSetting wartości localOnly i braku lokalnie buforowanego kuponu. Jeśli wywołanie metody loadVoucher() nie zostanie pomyślnie zakończone, prawdopodobnie z powodu błędu uwierzytelniania lub komunikacji, klasa DRMManager wywoła obiekt zdarzenia DRMErrorEvent. Zdarzenia DRMAuthenticationComplete Klasa DRMManager wywołuje obiekt DRMAuthenticationCompleteEvent, gdy użytkownik zostanie pomyślnie uwierzytelniony w wyniku wywołania metody authenticate() . TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 292 Korzystanie z mechanizmów Digital Rights Management W środowisku AIR 1.5 obiekt DRMAuthenticationCompleteEvent zawiera token wielokrotnego użytku, który można wykorzystać do zachowywania uwierzytelnienie użytkownika między sesjami aplikacji. W celu ponownego nawiązania sesji token należy przekazać do metody setAuthenticationToken() klasy DRMManager. (Atrybuty tokenu, takie jak jego termin ważności, ustawia twórca tokenu. Środowisko AIR nie udostępnia wywołań API służących do analizowania atrybutów tokenu). Zdarzenia DRMAuthenticationError Klasa DRMManager wywołuje obiekt DRMAuthenticationErrorEvent, gdy nie powiedzie się uwierzytelnienie użytkownika poprzez wywołanie metody authenticate() lub setAuthenticationToken(). Korzystanie z klasy DRMContentData Obiekt DRMContentData zawiera właściwości metadanych pliku multimedialnego chronionego za pomocą mechanizmu DRM. Właściwości obiektu DRMContentData zawierają informacje potrzebne do uzyskania kuponu licencji służącego do wyświetlania treści. 293 Rozdział 26: Uruchamianie aplikacji i opcje zamykania W tej sekcji omówione zostały opcje i warunki uruchomienia zainstalowanej aplikacji Adobe® AIR™ oraz opcje i warunki zamknięcia uruchomionej aplikacji. Wywołanie aplikacji Aplikacja AIR zostaje wywołana, gdy użytkownik (lub system operacyjny): • Uruchomi aplikację z pulpitu. • Użyje aplikacji jako polecenia z poziomu wiersza poleceń. • Otworzy typ pliku, dla którego aplikacja stanowi domyślną aplikację podczas otwierania. • (W systemie Mac OS X) kliknie ikonę aplikacji na pasku zadań (bez względu, czy aplikacja jest aktualnie uruchomiona). • Uruchomi aplikację za pomocą instalatora (na zakończenie procesu nowej instalacji lub po dwukrotnym kliknięciu pliku AIR już zainstalowanej aplikacji). • Rozpocznie aktualizację aplikacji AIR, gdy zainstalowana wersja poinformuje o automatycznym przeprowadzaniu aktualizacji (poprzez uwzględnienie deklaracji <customUpdateUI>true</customUpdateUI> w pliku deskryptora aplikacji). • Przejdzie na stronę internetową z identyfikatorem Flash lub do aplikacji wywołującej metodę com.adobe.air.AIR launchApplication() określającą informacje identyfikacyjne dla aplikacji AIR. (Deskryptor aplikacji musi także zawierać deklarację <allowBrowserInvocation>true</allowBrowserInvocation>, aby wywołanie zakończyło się powodzeniem). Patrz „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. Każdorazowo po wywołaniu aplikacji AIR, aplikacja ta wywołuje obiekt InvokeEvent typu invoke za pomocą obiektu singletonowego NativeApplication. Aby aplikacja miała czas na zainicjowanie i zarejestrowanie detektora zdarzeń, zdarzenia invoke są dodawane do kolejki, a nie pomijane. Po zarejestrowaniu detektora dostarczane są wszystkie zdarzenia z kolejki. Uwaga: Po wywołaniu aplikacji za pomocą funkcji wywołania z przeglądarki obiekt NativeApplication wywołuje wyłącznie zdarzenie invoke, gdy aplikacja nie została wcześniej uruchomiona. Patrz „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. Aby odebrać zdarzenia invoke, należy wywołać metodę addEventListener()obiektu NativeApplication (NativeApplication.nativeApplication). Po zarejestrowaniu detektora dla zdarzenia invoke odebrane są również wszystkie zdarzenia invoke mające miejsce przed rejestracją. Zdarzenia invoke z kolejki są wywoływane pojedynczo w krótkich odstępach czasu po zwróceniu wywołaniaaddEventListener(). Jeśli nowe zdarzenie invoke pojawi się w tym procesie, może zostać wywołane przed jednym lub większą liczbą zdarzeń z kolejki. Kolejka zdarzeń umożliwia obsługę dowolnych zdarzeń invoke mających miejsce przed wykonaniem kodu inicjowania. Należy pamiętać, że po późniejszym dodaniu detektora zdarzeń w czasie wykonywania (po inicjalizacji aplikacji), dalej będą odbierane wszystkie zdarzenia invoke mające miejsce od czasu uruchomienia aplikacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 294 Uruchamianie aplikacji i opcje zamykania Zostaje uruchomiona wyłącznie jedna instancja aplikacji AIR. Gdy już uruchomiona aplikacja jest wywołana ponownie, AIR wywołuje nowe zdarzenie invoke dla działającej instancji. Do zadań aplikacji AIR należy odpowiadane na zdarzenie invoke i wykonanie odpowiedniej czynności (np. otwarcie nowego okna dokumentu). Obiekt InvokeEventzawiera wszystkie argumenty przekazane do aplikacji oraz katalog, z którego aplikacja została wywołana. Jeśli aplikacja została wywołana poprzez powiązanie z typem pliku, pełna ścieżka do pliku jest zawarta w argumentach wiersza poleceń. Podobnie, jeśli aplikacja została wywołana poprzez aktualizację aplikacji, zawarta jest pełna ścieżka do zaktualizowanego pliku AIR. Jeśli w pojedynczej operacji zostanie otwartych wiele plików, w systemie Mac OS X zostanie wywołany jeden obiekt InvokeEvent. Każdy z plików jest zawarty w tablicy arguments. W systemach Windows i Linux dla każdego pliku zostanie wywołany osobny obiekt InvokeEvent. Aplikacja może obsługiwać zdarzenia invokepoprzez zarejestrowanie detektora z obiektem NativeApplication: NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvokeEvent); air.NativeApplication.nativeApplication.addEventListener(air.InvokeEvent.INVOKE, onInvokeEvent); Oraz poprzez zdefiniowanie detektora zdarzeń: var arguments:Array; var currentDir:File; public function onInvokeEvent(invocation:InvokeEvent):void { arguments = invocation.arguments; currentDir = invocation.currentDirectory; } Przechwytywanie argumentów wiersza poleceń Argumenty wiersza poleceń powiązane z wywołaniem aplikacji AIR są dostarczone w zdarzeniu invokewywołanym przez obiekt. Właściwość InvokeEvent.arguments zawiera tablicę przekazaną przez system operacyjny podczas wywoływania aplikacji AIR. Jeśli argumenty zawierają względne ścieżki pliku, można zazwyczaj je rozwiązać poprzez użycie właściwości currentDirectory. Argumenty przekazane do programu AIR są traktowane jako ciągi ograniczone spacjami, chyba że zostaną ujęte w podwójne cudzysłowy: Argumenty Tablica tick tock {tick,tock} tick "tick tock" {tick,tick tock} "tick" “tock” {tick,tock} \"tick\" \"tock\" {"tick","tock"} Właściwość InvokeEvent.currentDirectory zawiera obiekt File reprezentujący katalog, z którego została uruchomiona aplikacja. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 295 Uruchamianie aplikacji i opcje zamykania Gdy aplikacja zostaje wywołana, ponieważ otwarty został plik, którego typ jest zarejestrowany przez aplikację, własna ścieżka do pliku jest zawarta jako łańcuch w argumentach wiersza poleceń. (Aplikacja odpowiada za zaczynanie i wykonywanie zamierzonej czynności w pliku). Podobnie, po zaprogramowaniu aplikacji do automatycznej aktualizacji (a nie za pomocą standardowego interfejsu użytkownika aktualizacji AIR), natywna ścieżka pliku AIR zostaje uwzględniona po dwukrotnym kliknięciu pliku AIR zawierającego aplikację ze zgodnym identyfikatorem aplikacji. Dostęp do pliku można uzyskać za pomocą metody resolve() obiektu FilecurrentDirectory: if((invokeEvent.currentDirectory != null)&&(invokeEvent.arguments.length > 0)){ dir = invokeEvent.currentDirectory; fileToOpen = dir.resolvePath(invokeEvent.arguments[0]); } Należy również zatwierdzić argument jako ścieżkę pliku. Przykład: dziennik zdarzeń wywołania Następujący przykład przedstawia sposób rejestracji detektorów i obsługi zdarzeń invoke. W przykładzie zapisane zostają wszystkie zdarzenia wywołania i wyświetlony zostaje bieżący katalog oraz argumenty wiersza poleceń. Uwaga: Aby utworzyć poniższy przykład za pomocą programu Adobe® Flash® CS3 Professional lub Adobe® Flash® CS4 Professional, najpierw należy utworzyć plik Flash (Adobe AIR). W panelu ustawień ActionScript 3.0 (Plik > Ustawienia publikowania... > przycisk Ustawienia) wprowadź nazwę InvokeEventLogExample w polu Klasa dokumentu. Zapisz plik FLA z nazwą InvokeEventLogExample.fla. Następnie utwórz plik ActionScript w tym samym folderze. Do pliku ActionScript wprowadź następujący kod, a następnie zapisz plik z nazwą 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(); logEvent("Invoke event received: " + now); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 296 Uruchamianie aplikacji i opcje zamykania 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); } } } Uruchamianie podczas logowania Aplikację AIR można ustawić, tak aby aplikacja była automatycznie uruchamiana podczas logowania użytkownika poprzez ustawienie NativeApplication.nativeApplication.startAtLogin=true. Po ustawieniu aplikacja zostaje automatycznie uruchomiona za każdym razem podczas logowania użytkownika. Aplikacja jest uruchamiania w ten sposób do czasu zmiany ustawienia na wartość false. Ustawienia można zmieniać ręcznie poprzez system operacyjny lub aplikacja zostanie odinstalowana. Uruchamianie podczas logowania to ustawienie środowiska wykonawczego. Uwaga: Aplikacja nie jest uruchamiana w momencie uruchomienia systemu. Zostaje uruchomiona podczas logowania użytkownika. To ustawienie zastosuje się wyłącznie do bieżącego użytkownika. Ponadto aplikacja musi być zainstalowana, aby dla właściwości startAtLogin można było ustawić wartość true. Jeśli właściwość zostanie ustawiona, gdy aplikacja nie jest zainstalowana (np. podczas uruchamiania za pomocą ADL), generowany jest wyjątek. Wywołanie z przeglądarki Za pomocą funkcji wywoływania z przeglądarki strona internetowa może uruchomić z przeglądarki zainstalowaną aplikację AIR. Wywołanie z przeglądarki może być wykonane wyłącznie, gdy plik deskryptora aplikacji ustawia dla właściwości allowBrowserInvocation wartość true: <allowBrowserInvocation>true</allowBrowserInvocation> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 297 Uruchamianie aplikacji i opcje zamykania Więcej informacji na temat pliku deskryptora aplikacji znajduje się w temacie „Definiowanie ustawień aplikacji AIR” na stronie 45. Gdy aplikacja jest wywołana za pomocą przeglądarki, obiekt aplikacji NativeApplication wywołuje obiekt BrowserInvokeEvent. Aby odebrać zdarzenia BrowserInvokeEvent, należy wywołać metodę addEventListener()obiektu NativeApplication (NativeApplication.nativeApplication) w aplikacji AIR. Po zarejestrowaniu detektora dla zdarzenia BrowserInvokeEvent odebrane są również wszystkie zdarzenia BrowserInvokeEvent mające miejsce przed rejestracją. Te zdarzenia są wywołanie po zwróceniu wywołania addEventListener(), ale niekoniecznie przed innymi zdarzeniami BrowserInvokeEvent, które mogą być odebrane po rejestracji. Umożliwia to obsługę zdarzeń BrowserInvokeEvent, które mają miejsce przed wykonaniem kodu inicjalizacji (np. kiedy aplikacja została początkowo wywołana z przeglądarki). Należy pamiętać, że po późniejszym dodaniu detektora zdarzeń w czasie wykonywania (po inicjalizacji aplikacji), dalej będą odbierane wszystkie zdarzenia BrowserInvokeEvent mające miejsce od czasu uruchomienia aplikacji. W obiekcie BrowserInvokeEvent znajdują się następujące właściwości: Właściwość Opis arguments Tablica argumentów (ciągów) przekazywanych do aplikacji. isHTTPS Określa, czy treść w przeglądarce korzysta ze schematu https URL (true) bądź z niego nie korzysta (false). isUserEvent Określa, czy wywołanie z przeglądarki spowodowało zdarzenie użytkownika (np. kliknięcie myszy). W przypadku wersji AIR 1.0 dla tej właściwości ustawiona jest zawsze wartość true; w aplikacji AIR dla funkcji wywołania z przeglądarki wymagane jest zdarzenie użytkownika. sandboxType Typ obszaru izolowanego dla treści w przeglądarce. Zdefiniowane poprawne wartości są takie same, co wartości użyte we właściwości Security.sandboxType i mogą to być: • Security.APPLICATION — Treść znajduje się w obszarze izolowanym aplikacji. • Security.LOCAL_TRUSTED — Treść znajduje się w lokalnym obszarze izolowanym z systemem plików. • Security.LOCAL_WITH_FILE — Treść znajduje się w lokalnym obszarze izolowanym z systemem plików. securityDomain • Security.LOCAL_WITH_NETWORK — Treść znajduje się w lokalnym obszarze izolowanym z obsługą sieci. • Security.REMOTE — Treść znajduje się zdalnej domenie (sieci). Domena zabezpieczeń treści w przeglądarce, np."www.adobe.com" lub "www.example.org". Ta właściwość jest ustawiona wyłącznie dla treści w zdalnym obszarze zabezpieczeń (dla treści z domeny sieci). Nie jest ustawiona dla treści w lokalnym lub aplikacyjnym obszarze zabezpieczeń. Jeśli korzysta się z funkcji wywoływania z przeglądarki, należy uwzględnić kwestie zabezpieczeń. W przypadku uruchomienia aplikacji AIR ze strony internetowej, dane mogą być przesyłane za pomocą właściwości arguments obiektu BrowserInvokeEvent. Należy zachować ostrożność podczas korzystania z tych danych w operacjach wrażliwych np. interfejsy API ładowania pliku lub kodu. Poziom ryzyka zależy od sposobu wykorzystania danych przez aplikację. Jeśli wyłącznie określona strona sieci Web ma wywołać aplikację, aplikacja powinna sprawdzić wartość właściwości securityDomain obiektu BrowserInvokeEvent. Od strony sieci Web wywołującej aplikację można również wymagać użycia protokołów HTTP, które można określić poprzez sprawdzenie wartościisHTTPS obiektu BrowserInvokeEvent. Aplikacja powinna zatwierdzić przekazywane dane. Na przykład, jeśli aplikacja oczekuje na przekazanie do niej adresów URL do określonej domeny, powinna zatwierdzić, że adresy URL naprawdę wskazują na tę domenę. Dzięki temu możliwe jest zapobiegnięcie wysłania wrażliwych danych pod niewłaściwe adresy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 298 Uruchamianie aplikacji i opcje zamykania Żadna aplikacja nie powinna korzystać z argumentów BrowserInvokeEvent, które mogą odwoływać się do lokalnych zasobów: Na przykład, aplikacja nie powinna tworzyć obiektów File w oparciu o ścieżkę przekazaną z przeglądarki. Jeśli oczekiwane jest przekazywanie ścieżek zdalnych z przeglądarki, aplikacja powinna sprawdzić, czy ścieżki nie używają protokołu file:// zamiast zdalnego protokołu. Więcej informacji na temat wywoływania aplikacji z przeglądarki znajduje się w temacie „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. Zamykanie aplikacji Najszybszym sposobem na zamknięcie aplikacji jest wywołanie metody NativeApplication.nativeApplication.exit(); ten sposób działa dobrze, jeśli aplikacja użytkownika nie zawiera żadnych danych do zapisania lub zewnętrznych zasobów do czyszczenia. Wywołanie metody exit() zamyka wszystkie okna, a następnie zamyka aplikację. Jednak, aby okna i inne komponenty mogły przerywać proces zamykania, np. w celu zapisania ważnych danych, należy wywołać odpowiednie zdarzenia ostrzegawcze przed wywołaniem metody exit(). Kolejnym ułatwieniem podczas zamykania aplikacji jest podanie jednej ścieżki wykonania bez względu na sposób rozpoczęcia procesu zamykania. Użytkownik (lub system operacyjny) może wyzwolić zamknięcie aplikacji poprzez: • Zamknięcie ostatniego okna aplikacji, gdy właściwość NativeApplication.nativeApplication.autoExit na wartość true. • Wybranie polecenia zamknięcia systemu operacyjnego; na przykład gdy użytkownik wybierze polecenie zamknięcia aplikacji z menu domyślnego. Taka sytuacja ma miejsce jedynie w systemach Mac OS; systemy Windows i Linux nie zapewniają aplikacji polecenia zamknięcia za pośrednictwem karnacji systemu. • Wyłączenie komputera. Kiedy polecenie zamknięcia jest przekazane poprzez system operacyjny na jeden z tych sposobów, obiekt NativeApplication wywołuje zdarzenie exiting. Jeśli żaden z detektorów nie anuluje zdarzenia exiting, wszystkie otwarte okna zostaną zamknięte. Każde okno wywołuje zdarzenie closing, a następnie close. Jeśli dowolne okno anuluje zdarzenie closing, proces zamykania zostaje przerwany. Jeśli kolejność zamykania okien stanowi problem dla aplikacji, należy wywołać zdarzenie exiting z obiektu NativeApplication i samemu zamknąć okna w odpowiedniej kolejności. Może to mieć znaczenie, na przykład w przypadku okna dokumentu z paletami narzędzi. Taka sytuacja może być niekorzystna, jeśli system zamknie palety, a użytkownik będzie chciał anulować polecenie zamknięcia w celu zapisania danych. W systemie Windows zdarzenie exiting ma miejsce wyłącznie po zamknięciu ostatniego okna (kiedy właściwość autoExitobiektu NativeApplication ma wartość true). Aby zapewnić takie same ustawienia na wszystkich platformach, bez względu czy kolejność zamykania jest inicjowana za pośrednictwem karnacji systemu operacyjnego, polecenia menu lub logikę aplikacji, należy przestrzegać następujących zalecanych sposobów zamykania aplikacji: 1 Zawsze należy wywołać zdarzenie exiting za pomocą obiektu NativeApplication przed wywołaniem metody exit()w kodzie aplikacji i sprawdzić, czy inny komponent aplikacji nie anuluje zdarzenia. public function applicationExit():void { var exitingEvent:Event = new Event(Event.EXITING, false, true); NativeApplication.nativeApplication.dispatchEvent(exitingEvent); if (!exitingEvent.isDefaultPrevented()) { NativeApplication.nativeApplication.exit(); } } TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 299 Uruchamianie aplikacji i opcje zamykania 2 Wywołaj zdarzenie aplikacji exiting z obiektu NativeApplication.nativeApplication i w module obsługi zamknąć wszystkie okna (wywołując najpierw zdarzenie closing). Wykonaj wszystkie niezbędne zadania czyszczenia, takie jak zapisanie danych aplikacji, usuwanie plików tymczasowych, po zamknięciu wszystkich okien. Podczas czyszczenia należy stosować wyłącznie synchroniczne metody, aby zapewnić, że zostaną zakończone przed zamknięciem aplikacji. Jeśli kolejność zamykania okien nie ma znaczenia, można wówczas przejść do tablicy NativeApplication.nativeApplication.openedWindows zamknąć kolejno każde okno. Jeśli kolejność maznaczenie, należy skorzystać z metody zamykania okien w odpowiedniej kolejności. 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 Okna powinny zawsze obsługiwać własne zadania oczyszczania poprzez wywoływanie własnych zdarzeń closing. 4 W aplikacji należy użyć wyłącznie jednego detektora zdarzeń exiting, ponieważ moduły obsługi wywołane wcześniej, nie wiedzą, czy kolejne moduły będą anulować zdarzenie exiting (nierozsądnie jest opierać się tylko na kolejności wykonywania). Zobacz także „Definiowanie ustawień aplikacji AIR” na stronie 45 „Prezentacja niestandardowego interfejsu użytkownika służącego do aktualizacji aplikacji” na stronie 333 300 Rozdział 27: Odczytywanie ustawień aplikacji W czasie wykonywania możliwe jest odczytywanie właściwości pliku deskryptora aplikacji oraz identyfikatora wydawcy aplikacji. Ustawia się je jako właściwości applicationDescriptor i publisherID obiektu NativeApplication. Odczytywanie pliku deskryptora aplikacji Istnieje możliwość odczytania pliku deskryptora aktualnie uruchomionej aplikacji, jako obiektu XML, poprzez pobranie właściwości applicationDescriptor obiektu NativeApplication, co przedstawiono poniżej: var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor; Deskryptor aplikacji można odczytać jako obiekt XML (E4X), co ilustruje poniższy przykład: 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; Więcej informacji zawiera sekcja „Struktura pliku deskryptora aplikacji” na stronie 45. Pobieranie identyfikatorów aplikacji i wydawcy Identyfikator aplikacji i wydawcy łącznie jednoznacznie identyfikują aplikację AIR. Identyfikator aplikacji określa się w elemencie <id> deskryptora aplikacji. Identyfikator wydawcy jest wyznaczany na podstawie certyfikatu, którym był podpisany pakiet instalacyjny AIR. Identyfikator aplikacji można odczytać z właściwości id obiektu NativeApplication, co ilustruje poniższy kod: trace(NativeApplication.nativeApplication.applicationID); Identyfikator wydawcy można odczytać z właściwości publisherID obiektu NativeApplication: trace(NativeApplication.nativeApplication.publisherID); Uwaga: Gdy aplikacja AIR jest uruchomiona w środowisku ADL, nie ma identyfikatora wydawcy, chyba że przypisano jej tymczasowo taki identyfikator za pomocą znacznika -pubID w wierszu komend ADL. Identyfikator wydawcy dla zainstalowanej aplikacji można też odczytać z pliku META-INF/AIR/publisherid, który znajduje się w katalogu instalacyjnym aplikacji. Więcej informacji zawiera sekcja „Informacje o identyfikatorach wydawców AIR” na stronie 325. 301 Rozdział 28: Praca z informacjami o środowisku wykonawczym i systemie operacyjnym W tej sekcji omówiono metody zarządzania przypisaniami typów plików w systemie operacyjnym, wykrywania aktywności użytkownika i pobierania informacji o środowisku wykonawczym Adobe® AIR™ z poziomu aplikacji AIR. Zarządzanie skojarzeniami plików Skojarzenia między aplikacją a typem pliku muszą być zadeklarowane w deskryptorze aplikacji. W procesie instalacji instalator aplikacji AIR kojarzy tę aplikację jako domyślną aplikację otwierającą ze wszystkimi zadeklarowanymi typami plików, chyba że dla danego typu pliku jest już przypisana inna aplikacja domyślna. W procesie instalacji aplikacji AIR nie są zmieniane istniejące skojarzenia z typami plików. Aby przejąć skojarzenie z innej aplikacji, należy wywołać metodę NativeApplication.setAsDefaultApplication() w czasie wykonywania. Do dobrych praktyk należy sprawdzanie w momencie uruchamiania aplikacji, czy oczekiwane skojarzenia plików są zdefiniowane. Wynika to z faktu, że instalator aplikacji AIR nie przesłania istniejących skojarzeń z plikami, a ponadto skojarzenia w systemie użytkownika mogą ulegać zmianie w dowolnym momencie. Gdy typ pliku jest skojarzony z inną aplikacją, dobrym zwyczajem jest zapytanie użytkownika o zgodę przed wymuszeniem zmiany tego skojarzenia. Poniższe metody klasy NativeApplication umożliwiają zarządzanie skojarzeniami plików. Parametrem każdej z tych metod jest rozszerzenie plików określające ich typ: Metoda Opis isSetAsDefaultApplication() Zwraca wartość true, jeśli aplikacja AIR jest obecnie skojarzona z określonym typem plików. setAsDefaultApplication() Tworzy skojarzenie między aplikacją AIR a operacją otwierania plików danego typu. removeAsDefaultApplication() Usuwa skojarzenie między aplikacją AIR a typem plików. getDefaultApplication() Zwraca ścieżkę aplikacji, która jest obecnie skojarzona z typem plików. Środowisko AIR może zarządzać tylko tymi skojarzeniami z typami plików, które zostały pierwotnie zadeklarowane w deskryptorze aplikacji. Nie można uzyskać informacji o skojarzeniach niezadeklarowanych typów plików, nawet jeśli użytkownik ręcznie utworzył skojarzenie między danym typem plików a aplikacją. Wywołanie którejkolwiek z metod do zarządzania skojarzeniami typów plików dla typu niezadeklarowanego w deskryptorze aplikacji spowoduje wygenerowanie wyjątku w czasie wykonywania. Informacje o deklarowaniu typów plików w deskryptorze aplikacji zawiera sekcja „Deklarowanie skojarzeń typów plików” na stronie 53. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 302 Praca z informacjami o środowisku wykonawczym i systemie operacyjnym Pobieranie wersji środowiska wykonawczego i poziomu poprawek Obiekt NativeApplication ma właściwość runtimeVersion wskazującą na wersję środowiska wykonawczego, w którym działa aplikacja (jest to ciąg znaków, np. "1.0.5"). Obiekt NativeApplication ma także właściwość runtimePatchLevel wskazującą na poziom poprawek środowiska wykonawczego (jest to liczba, np. 2960). Właściwości te zostały wykorzystane w poniższym kodzie: trace(NativeApplication.nativeApplication.runtimeVersion); trace(NativeApplication.nativeApplication.runtimePatchLevel); Wykrywanie możliwości środowiska AIR W przypadku pliku powiązanego z aplikacją Adobe AIR właściwość Security.sandboxType jest ustawiona na wartość zdefiniowaną przez stałą Security.APPLICATION. Aplikacja może ładować treść (która może, ale nie musi zawierać wywołań API charakterystycznych dla środowiska AIR) w zależności od tego, czy plik znajduje się w obszarze izolowanym zabezpieczeń środowiska Adobe AIR, co ilustruje poniższy kod: if (Security.sandboxType == Security.APPLICATION) { // Load SWF that contains AIR APIs } else { // Load SWF that does not contain AIR APIs } Wszystkie zasoby, które nie są instalowane razem z aplikacją AIR, są przypisywane do tych samych obszarów izolowanych, do których byłyby przypisane przez program Adobe® Flash® Player w przeglądarce sieci Web. Zasoby zdalne są umieszczane w obszarach izolowanych odpowiednio do ich domen źródłowych, a zasoby lokalne są umieszczane w obszarze izolowanym lokalnym z obsługą sieci, lokalnym z systemem plików lub lokalnym zaufanym. Aby ustalić, czy treść jest wykonywana w środowisku wykonawczym (a nie w odtwarzaczu Flash Player uruchomionym w przeglądarce), można sprawdzić, czy wartość właściwości statycznej Capabilities.playerType jest równa "Desktop". Więcej informacji zawiera sekcja „Zabezpieczenia w środowisku AIR” na stronie 24. Monitorowanie obecności użytkownika Obiekt NativeApplication wywołuje dwa zdarzenia, które pomagają w określeniu, czy użytkownik aktywnie korzysta z komputera. Jeśli w okresie zdefiniowanym przez właściwość NativeApplication.idleThreshold nie zostanie wykryta aktywność myszy lub klawiatury, obiekt NativeApplication wywołuje zdarzenie userIdle. Gdy ponownie zajdzie zdarzenie związane z aktywnością klawiatury lub myszy, obiekt NativeApplication wywoła zdarzenie userPresent. Okres idleThreshold jest mierzony w sekundach, a jego wartość domyślna to 300 (5 minut). Właściwość NativeApplication.nativeApplication.lastUserInput zawiera liczbę sekund od ostatniego przejawu aktywności użytkownika. Poniższe wiersze kodu ustawiają próg bezczynności na 2 minuty i wykrywają zdarzenia userIdle i userPresent: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 303 Praca z informacjami o środowisku wykonawczym i systemie operacyjnym 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"); }); Uwaga: Między każdymi dwoma zdarzeniami userPresent wywoływane jest tylko jedno zdarzenie userIdle. 304 Rozdział 29: Monitorowanie połączeń sieciowych Środowisko Adobe® AIR™ udostępnia mechanizmy wykrywania zmian w połączeniach sieciowych komputera, na którym jest zainstalowana aplikacja AIR. Informacje takie są użyteczne, jeśli aplikacja korzysta z danych uzyskiwanych z sieci. Ponadto aplikacja może sprawdzić dostępność usługi sieciowej. Wykrywanie zmian w połączeniach sieciowych Aplikacja AIR może działać w środowiskach, w których stan połączeń sieciowych będzie zmienny lub niestabilny. Aby ułatwić zarządzanie połączeniami z zasobami sieciowymi w ramach aplikacji, środowisko AIR wysyła zdarzenie zmiany stanu sieci za każdym razem, gdy połączenie sieciowe stanie się dostępne lub niedostępne. Obiekt NativeApplication wywołuje zdarzenie zmiany stanu sieci. Aby zareagować na to zdarzenie, należy dodać detektor: NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange); Oraz zdefiniować funkcję obsługi zdarzenia: function onNetworkChange(event:Event) { //Check resource availability } Zdarzenie Event.NETWORK_CHANGE nie oznacza każdej zmiany w aktywności sieci, a jedynie zmianę stanu połączenia sieciowego. Środowisko AIR nie próbuje interpretować znaczenia zmiany stanu połączenia sieciowego. Komputer pracujący w sieci może mieć wiele połączeń rzeczywistych i wirtualnych, a zatem utrata połączenia nie musi być równoznaczna z utratą dostępu do zasobu. Z drugiej strony, nowe połączenia nie gwarantują lepszej dostępności zasobu. Niekiedy nowe połączenie może nawet zablokować dostęp do zasobów, które były wcześniej dostępne (na przykład w wypadku połączenia z siecią VPN). Co do zasady, jedynym sposobem sprawdzenia, czy aplikacja może połączyć się z zasobem zdalnym, jest podjęcie próby takiego połączenia. Dlatego architektura monitorowania usług w pakiecie air.net udostępnia aplikacjom AIR oparty na zdarzeniach mechanizm reagowania na zmiany w połączeniach sieciowych z określonym hostem. Uwaga: Architektura monitorowania usług wykrywa, czy serwer w sposób akceptowalny reaguje na żądanie. Nie gwarantuje to jednak pełnej łączności. Skalowalne usługi Web Service często korzystają z mechanizmów buforowania i równoważenia ruchu, które przekierowują ruch do klastra serwerów sieci Web. W takiej sytuacji dostawcy usług zapewniają tylko częściową diagnostykę łączności sieciowej. Podstawy monitorowania usług Architektura monitorowania usług, odrębna od architektury AIR, rezyduje w pliku servicemonitor.swc. Aby skorzystać z tej architektury, należy uwzględnić plik servicemonitor.swc w procesie budowania. Ważne: Aby użyć klas w programie Adobe® Flash® CS3 Professional, należy przeciągnąć składnik ServiceMonitorShim z panelu Składniki do Biblioteki, a następnie dodać poniższą instrukcję import do kodu w języku ActionScript 3.0: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 305 Monitorowanie połączeń sieciowych import air.net.*; Aby skorzystać z tych klas w programie Adobe® Flash® CS4 Professional: 1 Wybierz polecenie Plik > Ustawienia publikowania. 2 Kliknij przycisk Ustawienia dla ActionScript 3.0. Wybierz ścieżkę biblioteki. 3 Kliknij przycisk Przejdź do pliku SWC i wyszukaj plik Adobe Flash CS4/AIK1.1/frameworks/libs/air/servicemoniter.swc. 4 Kliknij przycisk OK. 5 Dodaj poniższą instrukcję importowania do kodu w języku ActionScript 3.0: import air.net.*; Klasa ServiceMonitor implementuje architekturę monitorowania usług sieciowych i udostępnia podstawową funkcjonalność dla monitorów usług. Domyślnie instancja klasy ServiceMonitor wywołuje zdarzenia dotyczące połączeń sieciowych. Obiekt ServiceMonitor wywołuje te zdarzenia, gdy instancja jest tworzona, oraz za każdym razem, gdy środowisko Adobe AIR wykryje zmianę stanu połączeń sieciowych. Ponadto możliwe jest ustawienie właściwości pollInterval instancji klasy ServiceMonitor w taki sposób, aby stan połączeń był sprawdzany co zadaną liczbę milisekund, niezależnie od zdarzeń zmiany stanu połączeń sieciowych. Obiekt ServiceMonitor nie sprawdza połączeń sieciowych, zanim nie zostanie wywołana metoda start(). Klasa URLMonitor, będąca podklasą klasy ServiceMonitor, wykrywa zmiany w połączeniach HTTP dla określonego obiektu URLRequest. Klasa SocketMonitor, która również jest podklasą klasy ServiceMonitor, wykrywa zmiany w łączności z określonym hostem na określonym porcie. Wykrywanie połączeń HTTP Klasa URLMonitor określa, czy możliwe jest wysyłanie żądań HTTP do określonego adresu na port 80 (typowy port używany w komunikacji HTTP). W poniższym kodzie użyto instancji klasy URLMonitor w celu wykrywania zmian w łączności z witryną firmy 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); } Wykrywanie połączeń z gniazdami Aplikacje AIR mogą także używać połączeń z gniazdami do realizacji łączności w modelu aktywnym (ang. push). Zapory i routery sieciowe zazwyczaj ze względów bezpieczeństwa uniemożliwiają komunikację sieciową przez nieupoważnione porty. Dlatego programiści muszą brać pod uwagę fakt, że użytkownik nie zawsze może nawiązać połączenie przez gniazdo. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 306 Monitorowanie połączeń sieciowych Podobnie jak w przykładzie użycia klasy URLMonitor, w poniższym kodzie wykorzystano instancję klasy SocketMonitor do wykrywania zmian łączności z gniazdem w porcie 6667 (jest to typowy port dla komunikacji 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); } 307 Rozdział 30: Żądania URL i praca w sieci Nowe funkcje Adobe AIR dotyczące określania żądań URL nie są dostępne dla treści SWF działającej w przeglądarce. Te funkcje są dostępne tylko dla treści w bezpiecznym obszarze izolowanym aplikacji. Sekcja opisuje funkcje URLRequest w środowisku wykonawczym, a ponadto omawia sposób, w jaki interfejs API zmienia treść AIR. Pozostałe informacje na temat korzystania z możliwości pracy w sieci i komunikacji języka Adobe® ActionScript® 3.0 zawiera podręcznik Programowanie w języku Adobe ActionScript 3.0. Korzystanie z klasy URLRequest Klasa URLRequest umożliwia bardzo łatwe definiowanie ciągów adresów URL. Środowisko AIR dodaje nowe właściwości do klasy URLRequest, ale są one dostępne tylko dla treści AIR działającej w obszarze izolowanym aplikacji. Treść w środowisku wykonawczym może definiować adresy URL przy użyciu nowych schematów URL (oprócz schematów standardowych, takich jak file i http). Właściwości klasy URLRequest Klasa URLRequest zawiera następujące właściwości, które są dostępne dla treści zawartej tylko w obszarze izolowanym aplikacji AIR: Właściwość Opis followRedirects Określa, czy śledzone są przekierowania (true — wartość domyślna) czy nie (false). Obsługiwana tylko w środowisku wykonawczym. manageCookies Określa, czy stos protokołu HTTP zarządza plikami cookie (true — wartość domyślna) lub nie (false) w danym żądaniu. Obsługiwana tylko w środowisku wykonawczym. authenticate Określa, czy dla danego żądania będą obsługiwane żądania uwierzytelniania (true). Obsługiwana tylko w środowisku wykonawczym. Domyślnie żądania są uwierzytelniane — to może powodować wyświetlanie okna dialogowego uwierzytelniania, jeśli serwer wymaga wyświetlania referencji. Możliwe jest również ustawienie nazwy i hasła użytkownika — patrz „Określanie ustawień domyślnych klasy URLRequest” na stronie 308. cacheResponse Określa, czy dane pomyślnej odpowiedzi powinny zostać zapisane w pamięci podręcznej dla danego żądania. Obsługiwana tylko w środowisku wykonawczym. Domyślnie odpowiedź jest zapisywana w pamięci podręcznej (true). useCache Określa, czy wymagane jest sprawdzenie lokalnej pamięci podręcznej zanim klasa URLRequest pobierze dane. Obsługiwana tylko w środowisku wykonawczym. Ustawienie domyślne (true) określa używanie lokalnej wersji danych z pamięci podręcznej, jeśli są tam dostępne. userAgent Określ ciąg znaków użytkownik-agent, który powinien być używany w żądaniu HTTP. Poniższe właściwości obiektu URLRequest mogą być ustawione (według zawartości) w dowolnym obszarze izolowanym (nie tylko bezpiecznym obszarze izolowanym aplikacji AIR): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 308 Żądania URL i praca w sieci Właściwość Opis contentType Typ zawartości MIME dowolnych danych wysyłanych za pomocą żądania URL. data Obiekt zawierający dane, które będą przesyłane razem z żądaniem URL. digest Bezpieczne „streszczenie” w pliku zapisanym w pamięci podręcznej w celu śledzenia pamięci podręcznej programu Adobe® Flash® Player. method Kontroluje metodę żądania HTTP, np. GET lub POST. (Zawartość działająca w domenie zabezpieczeń aplikacji AIR może określać ciągi znaków inne niż "GET" lub "POST" jako właściwość method. Dozwolona jest dowolna komenda HTTP, a metoda "GET" jest metodą domyślną. Patrz „Zabezpieczenia w środowisku AIR” na stronie 24). requestHeaders Tablica nagłówków HTTP, które mają być dołączone do żądania HTTP. url Określa żądany adres URL. Uwaga: Klasa HTMLLoader zawiera powiązane właściwości przeznaczone dla ustawień dotyczących treści ładowanej przez obiekt HTMLLoader. Szczegółowe informacje zawiera sekcja „Informacje o klasie HTMLLoader” na stronie 235. Określanie ustawień domyślnych klasy URLRequest Klasa URLRequestDefaults umożliwia definiowanie ustawień domyślnych dla obiektów URLRequest. Na przykład: poniższy kod ustawia domyślne wartości dla właściwości manageCookies i useCache: URLRequestDefaults.manageCookies = false; URLRequestDefaults.useCache = false; air.URLRequestDefaults.manageCookies = false; air.URLRequestDefaults.useCache = false; Klasa URLRequestDefaults zawiera metodę setLoginCredentialsForHost(), która umożliwia określenie domyślnej nazwy użytkownika oraz hasła, które będą używane dla określonego hosta. Host, zdefiniowany w parametrze hostname metody, może być domeną, np. "www.example.com", lub domeną i numerem portu, np."www.example.com:80". Nazwy "example.com", "www.example.com" oraz "sales.example.com" stanowią unikalne nazwy różnych hostów. Te referencje są używane tylko wówczas, gdy serwer tego wymaga. Jeśli użytkownik został już uwierzytelniony (na przykład użył okna dialogowego uwierzytelniania), wówczas nie ma możliwości zmiany użytkownika uwierzytelnionego poprzez wywołanie metody setLoginCredentialsForHost(). Na przykład: poniższy kod ustawia domyślną nazwę użytkownika i hasło dla strony www.example.com: URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X"); air.URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X"); Każda właściwość ustawień URLRequestDefaults dotyczy tylko domeny aplikacji treści ustawiającej właściwość. Jednak metoda setLoginCredentialsForHost() ma zastosowanie do treści we wszystkich domenach aplikacji w aplikacji AIR. Dzięki temu aplikacja może zarejestrować się w hoście, a ponadto cała treść aplikacji może zostać zarejestrowana przy użyciu określonych referencji. Więcej informacji zawiera opis klasy URLRequestDefaults w dokumentacji Skorowidz języka i składników ActionScript 3.0 (http://www.adobe.com/go/learn_air_aslr_pl). Korzystanie ze schematów URL środowiska AIR w adresach URL Standardowe schematy URL, takie jak poniższy, są dostępne podczas definiowania adresów URL w każdym obszarze izolowanym w środowisku AIR: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 309 Żądania URL i praca w sieci http: i https: Należy je używać w taki sposób, jakby były używane w przeglądarce sieci Web. file: Służy do określania ścieżki względnej do katalogu głównego systemu plików. Na przykład: file:///c:/AIR Test/test.txt W przypadku definiowania adresów URL dla zawartości działającej w obszarze izolowanym aplikacji można również używać następujących schematów: app: Służy do określania ścieżki względnej dla katalogu głównego zainstalowanej aplikacji (katalog, który zawiera plik deskryptora zainstalowanej aplikacji). Przykład: poniższa ścieżka wskazuje na podkatalog resources katalogu zainstalowanej aplikacji: app:/resources W przypadku działania w aplikacji ADL katalog resource aplikacji to katalog, który zawiera plik deskryptora aplikacji. app-storage: Służy do określania ścieżki względnej do katalogu zapisu aplikacji. Dla każdej zainstalowanej aplikacji program AIR definiuje unikalny katalog zapisu aplikacji (dla każdego użytkownika), który jest miejscem użytecznym do zapisu danych charakterystycznych dla danej aplikacji. Na przykład: poniższa ścieżka wskazuje na plik prefs.xml w podkatalogu settings katalogu zapisu aplikacji: app-storage:/settings/prefs.xml Lokalizacja katalogu zapisu aplikacji jest uzależniona od nazwy użytkownika, identyfikatora aplikacji i identyfikatora wydawcy: • W systemie Mac OS: /Users/nazwa użytkownika/Library/Preferences/id_aplikacji.id_wydawcy/Local Store/ Na przykład: /Users/babbage/Library/Preferences/com.example.TestApp.02D88EEED35F84C264A183921344EEA353 A629FD.1/Local Store • W systemie Windows: w katalogu Documents and Settings: nazwa użytkownika/Application Data/id_aplikacji.id_wydawcy/Local Store/ Na przykład: C:\Documents and Settings\babbage\Application Data\com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Local Store • W systemie Linux: w katalogu /home/nazwa użytkownika/.appdata/id_aplikacji.id_wydawcy/Local Store/ Na przykład: /home/babbage/.appdata/com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Loc al Store Adres URL (i właściwość url) dla obiektu File utworzonego w katalogu File.applicationStorageDirectory korzysta ze schematu URL app-storage, co przedstawiono poniżej: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 310 Żądania URL i praca w sieci 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: Schematu mailto można używać w obiektach URLRequest przekazywanych do funkcji navigateToURL(). Więcej informacji zawiera sekcja „Otwieranie adresu URL w domyślnej przeglądarce internetowej systemu” na stronie 310. Korzystanie ze schematów URL w środowisku AIR Istnieje możliwość użycia obiektu URLRequest, który będzie korzystał z dowolnego ze schematów URL w celu zdefiniowania żądania URL dla pewnej liczby innych obiektów, takich jak FileStream lub Sound. Możliwe jest także użycie tych schematów w treści HTML działającej w środowisku AIR; na przykład: te schematy mogą być używane w atrybucie src znacznika img. Jednak możliwe jest używanie tych schematów URL właściwych dla środowiska AIR (app: i app-storage:) w treści w bezpiecznym obszarze izolowanym aplikacji. Więcej informacji zawiera sekcja „Zabezpieczenia w środowisku AIR” na stronie 24. Zabronione schematy URL Niektóre interfejsy API umożliwiają uruchamianie treści w przeglądarce sieci Web. Z uwagi na bezpieczeństwo stosowanie takich interfejsów API w środowisku AIR jest zabronione. Lista zabronionych schematów jest uzależniona od obszaru izolowanego kodu, który korzysta z interfejsu API. Szczegółowe informacje zawiera sekcja „Otwieranie adresu URL w domyślnej przeglądarce internetowej systemu” na stronie 310 . Zmiany klasy URLStream Klasa URLStream zapewnia możliwość pobierania danych z adresów URL (w trybie ograniczonego dostępu). W środowisku wykonawczym klasa URLStream zawiera nowe zdarzenie: httpResponseStatus. W przeciwieństwie do zdarzenia httpStatus zdarzenie httpResponseStatus jest wprowadzane przed danymi odpowiedzi. Zdarzenie httpResponseStatus (zdefiniowane w klasie HTTPStatusEvent) zawiera właściwość responseURL — jest to adres URL, z którego została zwrócona odpowiedź, a także właściwość responseHeaders, która jest tablicą obiektów URLRequestHeader reprezentujących nagłówki odpowiedzi zwrócone w odpowiedzi. Otwieranie adresu URL w domyślnej przeglądarce internetowej systemu Funkcja navigateToURL() służy do otwierania adresu URL w domyślnej przeglądarce internetowej systemu. Dla obiektu URLRequest przekazywanego jako parametr request funkcji używana jest tylko właściwość url. var url = "http://www.adobe.com"; var urlReq = new air.URLRequest(url); air.navigateToURL(urlReq); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 311 Żądania URL i praca w sieci Uwaga: Podczas używania funkcji navigateToURL() środowisko wykonawcze traktuje obiekt URLRequest, który używa metody POST (której właściwość method jest ustawiona na wartość URLRequestMethod.POST), tak jakby korzystał z metody GET. Jeśli używana jest funkcja navigateToURL(), wówczas dozwolone są schematy URL obszaru izolowanego kodu wywołującego funkcję navigateToURL(). Niektóre interfejsy API umożliwiają uruchamianie treści w przeglądarce sieci Web. Z uwagi na bezpieczeństwo stosowanie takich interfejsów API w środowisku AIR jest zabronione. Lista zabronionych schematów jest uzależniona od obszaru izolowanego kodu, który korzysta z interfejsu API. (Szczegółowe informacje na temat obszarów izolowanych zawiera sekcja „Zabezpieczenia w środowisku AIR” na stronie 24). Obszar izolowany aplikacji Dozwolone są następujące schematy. Należy ich używać w taki sposób, jakby były używane w przeglądarce sieci Web. • http: • https: • file: • mailto: — AIR kieruje te żądania do zarejestrowanej aplikacji poczty elektronicznej systemu • app: • app-storage: Wszystkie inne schematy URL są zabronione. Zdalny obszar izolowany Dozwolone są następujące schematy. Należy ich używać w taki sposób, jakby były używane w przeglądarce sieci Web. • http: • https: • mailto: — AIR kieruje te żądania do zarejestrowanej aplikacji poczty elektronicznej systemu Wszystkie inne schematy URL są zabronione. Lokalny obszar izolowany z systemem plików Dozwolone są następujące schematy. Należy je używać w taki sposób, jakby były używane w przeglądarce sieci Web. • file: • mailto: — AIR kieruje te żądania do zarejestrowanej aplikacji poczty elektronicznej systemu Wszystkie inne schematy URL są zabronione. Lokalny obszar izolowany z obsługą sieci Dozwolone są następujące schematy. Należy ich używać w taki sposób, jakby były używane w przeglądarce sieci Web. • http: • https: • mailto: — AIR kieruje te żądania do zarejestrowanej aplikacji poczty elektronicznej systemu Wszystkie inne schematy URL są zabronione. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 312 Żądania URL i praca w sieci Lokalny zaufany obszar izolowany Dozwolone są następujące schematy. Należy je używać w taki sposób, jakby były używane w przeglądarce sieci Web. • file: • http: • https: • mailto: — AIR kieruje te żądania do zarejestrowanej aplikacji poczty elektronicznej systemu Wszystkie inne schematy URL są zabronione. 313 Rozdział 31: Komunikacja między aplikacjami Klasa LocalConnection umożliwia komunikację między aplikacjami Adobe® AIR™ oraz między aplikacjami AIR a treścią SWF działającą w przeglądarce. W metodzie connect() klasy LocalConnection do identyfikacji aplikacji służy parametr connectionName. W treści działającej w obszarze izolowanym zabezpieczeń aplikacji AIR (treści zainstalowanej z aplikacją AIR) w miejsce domeny treści SWF działającej w przeglądarce używany jest ciąg znaków app#, po którym następuje identyfikator aplikacji, kropka (.), oraz identyfikator wydawcy aplikacji AIR (zdefiniowany w pliku deskryptora aplikacji). Na przykład właściwość connectionName dla aplikacji o identyfikatorze com.example.air.MyApp, connectionName i identyfikatorze wydawcy B146A943FBD637B68C334022D304CEA226D129B4 ma wartość "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4:connectionName". (Więcej informacji zawierają sekcje Definiowanie podstawowych informacji o aplikacji oraz „Pobieranie identyfikatorów aplikacji i wydawcy” na stronie 300). Aby zezwolić innej aplikacji AIR na komunikowanie się z naszą aplikacją przez połączenie lokalne, należy wywołać metodę allowDomain() obiektu LocalConnection z nazwą domeny połączenia lokalnego. W przypadku aplikacji AIR ta nazwa domeny jest tworzona na podstawie identyfikatorów aplikacji i wydawcy, na tej samej zasadzie, co ciąg znaków połączenia. Na przykład, jeśli wysyłająca aplikacja AIR ma identyfikator aplikacji com.example.air.FriendlyApp oraz identyfikator wydawcy 214649436BD677B62C33D02233043EA236D13934, wówczas ciąg znaków domeny zezwalający tej aplikacji na nawiązywanie połączeń ma postać: app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934. Uwaga: Gdy aplikacja jest uruchomiona w środowisku ADL (lub w narzędziu programistycznym, takim jak Flash CS3, Flex Builder lub Dreamweaver), identyfikator wydawcy jest równy null i musi zostać pominięty w ciągu znaków domeny. W przypadku aplikacji uruchamianej po zainstalowaniu ciąg znaków musi zawierać identyfikator wydawcy. Możliwe jest przypisanie tymczasowego identyfikatora wydawcy przy użyciu argumentów w wierszu komend ADL. Tymczasowy identyfikator wydawcy umożliwia sprawdzenie, czy ciąg znaków połączenia i nazwa domeny są prawidłowo sformatowane. 314 Rozdział 32: Dystrybucja, instalowanie i uruchamianie aplikacji AIR Aplikacje AIR są dystrybuowane w postaci jednego pliku instalacyjnego AIR, który zawiera kod aplikacji i wszystkie zasoby. Ten plik można dystrybuować na dowolny ze standardowych sposobów, np. jako dane do pobrania przez pocztę e-mail lub nośnik fizyczny, taki jak CD-ROM. Użytkownik może zainstalować aplikację poprzez dwukrotne kliknięcie pliku AIR. Możliwe jest także skorzystanie z funkcji instalacji bezproblemowej, dzięki której użytkownicy mogą zainstalować aplikację AIR (oraz w razie potrzeby środowisko Adobe® AIR™) poprzez kliknięcie jednego odsyłacza na stronie sieci Web. Przed dystrybucją plik instalacyjny AIR należy spakować i podpisać certyfikatem podpisującym kod oraz kluczem prywatnym. Elektroniczne podpisanie pliku instalacyjnego zapewnia, że aplikacja nie została zmodyfikowana od momentu podpisania. Ponadto jeśli certyfikat cyfrowy został wydany przez zaufany ośrodek certyfikacji, użytkownicy mogą potwierdzić tożsamość wydawcy i autora podpisu. Plik AIR zostaje podpisany, gdy aplikacja jest pakowana za pomocą narzędzia ADT (AIR Developer Tool). Informacje o sposobie pakowania aplikacji do pliku AIR za pomocą aktualizacji środowiska AIR dla programu Flash zawiera sekcja „Tworzenie plików aplikacji AIR i plików instalatora” na stronie 17. Informacje o sposobie pakowania aplikacji do pliku AIR za pomocą programu Adobe® AIR™ SDK zawiera sekcja „Pakowanie pliku instalacyjnego aplikacji AIR za pomocą narzędzia AIR Developer Tool (ADT)” na stronie 360. Instalowanie i uruchamianie aplikacji AIR z pulpitu Plik AIR można po prostu wysłać do odbiorcy. Na przykład: można wysłać plik jako załącznik e-mail lub jako odsyłacz do strony internetowej. Gdy użytkownik pobierze aplikację AIR, powinien wykonać poniższe czynności w celu zainstalowania aplikacji: 1 Kliknij dwukrotnie plik AIR. Środowisko Adobe AIR musi być już zainstalowane w komputerze. 2 W oknie instalacji pozostaw ustawienia domyślne i kliknij przycisk kontynuowania. W systemie Windows środowisko AIR automatycznie wykonuje następujące operacje: • Instaluje aplikację w katalogu Program Files • Tworzy skrót pulpitowy dla aplikacji • Tworzy skrót w menu Start • Dodaje pozycję dotyczącą aplikacji do obszaru Dodaj/Usuń Programy w panelu sterowania W systemie Mac OS domyślnie aplikacja jest dodawana do katalogu Applications. Jeśli aplikacja jest już zainstalowana, instalator umożliwia wybór: można otworzyć istniejącą wersję aplikacji lub zaktualizować wersję do wersji z pobranego pliku AIR. Instalator identyfikuje aplikację, korzystając z jej identyfikatora oraz z identyfikatora wydawcy w pliku AIR. 3 Po zakończeniu instalowania kliknij przycisk Zakończ. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 315 Dystrybucja, instalowanie i uruchamianie aplikacji AIR W celu zainstalowania zaktualizowanej wersji aplikacji w systemie Mac OS użytkownik powinien mieć odpowiednie uprawnienia dostępu do zainstalowania w katalogu aplikacji. W systemach Windows i Linux użytkownik musi mieć uprawnienia administratora. Aplikacja może również zainstalować nową wersję za pośrednictwem kodu ActionScript lub kodu JavaScript. Więcej informacji zawiera sekcja „Aktualizowanie aplikacji AIR” na stronie 331. Po zainstalowaniu aplikacji AIR użytkownik powinien kliknąć dwukrotnie ikonę aplikacji w celu jej uruchomienia — tak samo jak w przypadku każdej innej aplikacji. • W systemie Windows kliknij dwukrotnie ikonę aplikacji (zainstalowana na pulpicie lub w folderze) albo wybierz aplikację z menu Start. • W systemie Linux kliknij dwukrotnie ikonę aplikacji (zainstalowana wcześniej na pulpicie lub w folderze) albo wybierz aplikację z menu aplikacji. • W systemie Mac OS kliknij dwukrotnie aplikację w folderze, w którym została zainstalowana. Domyślnym katalogiem instalowania jest katalog /Applications. Funkcja AIR instalacji bezproblemowej umożliwia zainstalowanie aplikacji AIR poprzez kliknięcie odsyłacza na stronie internetowej. Funkcje wywołania przeglądarki AIR umożliwiają użytkownikowi uruchomienie zainstalowanej aplikacji AIR poprzez kliknięcie odsyłacza na stronie internetowej. Te funkcje zostały opisane w poniższej sekcji. Instalowanie i uruchamianie aplikacji AIR ze strony internetowej Funkcja instalacji bezproblemowej umożliwia osadzenie pliku SWF na stronie internetowej, dzięki czemu użytkownik może zainstalować aplikację AIR z przeglądarki. Jeśli środowisko wykonawcze nie jest zainstalowane, wówczas funkcja instalacji bezproblemowej instaluje środowisko wykonawcze. Funkcja instalacji bezproblemowej umożliwia zainstalowanie aplikacji AIR bez zapisywania pliku AIR na komputerze. Pakiet AIR SDK zawiera plik badge.swf, który umożliwia łatwe korzystanie z funkcji instalacji bezproblemowej. Szczegółowe informacje zawiera sekcja „Korzystanie z pliku badge.swf w celu zainstalowania aplikacji” na stronie 316. Demonstrację użycia funkcji instalacji bezproblemowej zawiera artykuł do przykładu Dystrybuowanie aplikacji AIR za pośrednictwem sieci WWW (http://www.adobe.com/go/learn_air_qs_seamless_install_pl). Informacje o dostosowywaniu pliku badge.swf instalacji bezproblemowej Oprócz korzystania z pliku badge.swf udostępnionego w SDK możliwe jest również utworzenie własnego pliku SWF do użytku na stronie przeglądarki. Niestandardowy plik SWF może wchodzić w interakcje ze środowiskiem wykonawczym na następujące sposoby: • Może zainstalować aplikację AIR. Patrz „Instalowanie aplikacji AIR z przeglądarki” na stronie 321. • Może sprawdzić, czy konkretna aplikacja AIR została zainstalowana. Patrz „Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana” na stronie 320. • Może sprawdzić, czy zainstalowane jest środowisko wykonawcze. Patrz „Sprawdzanie, czy środowisko wykonawcze jest zainstalowane” na stronie 319. • Może uruchomić zainstalowaną aplikację AIR w systemie użytkownika. Patrz „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 316 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Wszystkie te funkcje stają się dostępne po wywołaniu interfejsów API w pliku SWF, który znajduje się w witrynie adobe.com: air.swf. W niniejszej sekcji opisano sposób używania i dostosowywania pliku badge.swf, a także sposób wywołania interfejsów API air.swf z własnego pliku SWF. Ponadto plik SWF działający w przeglądarce może komunikować się z działającą aplikacją AIR za pomocą klasy LocalConnection. Więcej informacji zawiera sekcja „Komunikacja między aplikacjami” na stronie 313. Ważne: Funkcje opisane w tej sekcji (a także interfejsy API w pliku air.swf) wymagają zainstalowania w przeglądarce internetowej w systemie Windows lub Mac OS aktualizacji nr 3 programu Adobe® Flash® Player 9. W systemie Linux funkcja instalacji bezproblemowej wymaga programu Flash Player 10 (wersja 10,0,12,36 lub nowsza). Możliwe jest napisanie kodu w celu sprawdzenia zainstalowanej wersji programu Flash Player, a także udostępnienie alternatywnego interfejsu dla użytkownika, jeśli wymagana wersja programu Flash Player nie jest zainstalowana. Na przykład: jeśli zainstalowana jest starsza wersja programu Flash Player, można udostępnić odsyłacz do wersji pliku AIR przeznaczonej do pobrania (zamiast używania pliku badge.swf lub interfejsu API air.swf w celu zainstalowania aplikacji). Korzystanie z pliku badge.swf w celu zainstalowania aplikacji Pakiet AIR SDK zawiera plik badge.swf, który umożliwia łatwe korzystanie z funkcji instalacji bezproblemowej. Plik badge.swf może zainstalować środowisko wykonawcze i aplikację AIR za pośrednictwem odsyłacza na stronie internetowej. Plik badge.swf oraz jego kod źródłowy są dostępne do dystrybucji na stronie internetowej. Instrukcje dostępne w tej sekcji udostępniają informacje na temat ustawiania parametrów pliku badge.swf udostępnionego przez Adobe. Ta sekcja zawiera również kod źródłowy pliku badge.swf, który może być dostosowywany. Osadzanie pliku badge.swf na stronie internetowej 1 Zlokalizuj poniższe pliki, dostępne w katalogu samples/badge pakietu AIR SDK, a następnie dodaj je do serwera sieci Web. • badge.swf • default_badge.html • AC_RunActiveContent.js 2 Otwórz plik default_badge.html w edytorze tekstu. 3 Na stronie default_badge.html, w funkcji AC_FL_RunContent() JavaScript, dostosuj definicje parametru FlashVars dla następujących parametrów: Parametr Opis appname Nazwa aplikacji wyświetlana przez plik SWF, gdy środowisko wykonawcze nie jest zainstalowane. appurl (Wymagane). Adres URL pliku AIR, który ma zostać pobrany. Należy użyć adresu URL bezwzględnego, a nie względnego. airversion (Wymagane). Dla wersji 1.0 środowiska wykonawczego, należy ustawić tę wartość na 1.0. imageurl Adres URL obrazu (opcjonalnie) do wyświetlenia w identyfikatorze. buttoncolor Kolor przycisku pobierania (określony jako wartość szesnastkowa, na przykład: FFCC00). messagecolor Kolor komunikatu tekstowego wyświetlanego poniżej przycisku, gdy środowisko wykonawcze nie zostało zainstalowane (określony jako wartość szesnastkowa, na przykład FFCC00). 4 Minimalna wielkość pliku badge.swf to 217 pikseli szerokości i 180 pikseli wysokości. Dostosuj wartości parametrów width i height funkcji AC_FL_RunContent() w celu dostosowania ich do własnych potrzeb. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 317 Dystrybucja, instalowanie i uruchamianie aplikacji AIR 5 Zmień nazwę pliku default_badge.html i dostosuj jego kod (albo dołącz go do innej strony HTML). Możliwa jest także edycja i ponowna kompilacja pliku badge.swf. Szczegółowe informacje zawiera sekcja „Modyfikowanie pliku badge.swf” na stronie 317. Instalowanie aplikacji AIR za pośrednictwem odsyłacza instalacji bezproblemowej ze strony internetowej Po dodaniu do strony odsyłacza do instalacji bezproblemowej użytkownik może zainstalować aplikację AIR poprzez kliknięcie odsyłacza w pliku SWF. 1 W przeglądarce internetowej, w której jest zainstalowany program Flash Player (wersja 9 z aktualizacją 3 lub nowszą w systemach Windows i Mac OS albo wersja 10 w systemie Linux), przejdź na stronę HTML. 2 Na stronie internetowej kliknij odsyłacz w pliku badge.swf. • Jeśli zainstalowano środowisko wykonawcze, przejdź do kolejnego kroku. • Jeśli środowisko wykonawcze nie zostało zainstalowane, pojawi się okno dialogowe z zapytaniem o to, czy wymagane jest zainstalowanie środowiska. Zainstaluj środowisko wykonawcze (patrz „Instalacja środowiska Adobe AIR” na stronie 1), a następnie przejdź do kolejnego kroku. 3 W oknie instalacji pozostaw ustawienia domyślne i kliknij przycisk kontynuowania. W systemie Windows środowisko AIR automatycznie wykonuje następujące operacje: • Instaluje aplikację w katalogu c:\Program Files\ • Tworzy skrót pulpitowy dla aplikacji • Tworzy skrót w menu Start • Dodaje pozycję dotyczącą aplikacji do obszaru Dodaj/Usuń Programy w panelu sterowania W systemie Mac OS instalator dodaje aplikację do katalogu Applications (na przykład do katalogu /Applications w systemie Mac OS). W systemie Linux środowisko AIR automatycznie wykonuje następujące operacje: • Instaluje aplikację w katalogu /opt. • Tworzy skrót pulpitowy dla aplikacji • Tworzy skrót w menu Start • Dodaje wpis aplikacji do systemowego menedżera pakietów. 4 Wybierz żądane opcje, a następnie kliknij przycisk Instaluj. 5 Po zakończeniu instalowania kliknij przycisk Zakończ. Modyfikowanie pliku badge.swf Pakiet AIR SDK udostępnia pliki źródłowe dla pliku badge.swf. Te pliki znajdują się w folderze samples/badge pakietu SDK: Pliki źródłowe Opis badge.fla Plik źródłowy Flash, który służy do kompilowania pliku badge.swf. Wynikiem kompilacji pliku badge.fla jest plik SWF 9 (który można załadować w programie Flash Player). AIRBadge.as Klasa ActionScript 3.0, która definiuje klasę podstawową używaną w pliku badge.fla. W celu zmiany interfejsu pliku badge.fla można użyć programu Flash CS3 lub Flash CS4. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 318 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Funkcja konstruktora AIRBadge() zdefiniowana w klasie AIRBadge ładuje plik air.swf dostępny na stronie http://airdownload.adobe.com/air/browserapi/air.swf. Plik air.swf zawiera kod, który umożliwia korzystanie z funkcji instalacji bezproblemowej. Metoda onInit() (w klasie AIRBadge) zostaje wywołana po pomyślnym załadowaniu pliku air.swf: 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; } } Kod ustawia dla globalnej zmiennej _air główną klasę załadowanego pliku air.swf. Klasa zawiera następujące metody publiczne, do których plik badge.swf uzyskuje dostęp w celu wywołania funkcji instalacji bezproblemowej: Metoda Opis getStatus() Określa, czy na komputerze zainstalowane jest środowisko wykonawcze (lub czy może zostać zainstalowane). Szczegółowe informacje zawiera sekcja „Sprawdzanie, czy środowisko wykonawcze jest zainstalowane” na stronie 319. installApplication() Instaluje określoną aplikację na komputerze użytkownika. Szczegółowe informacje zawiera sekcja „Instalowanie aplikacji AIR z przeglądarki” na stronie 321. • url — ciąg znaków definiujący adres URL. Należy użyć adresu URL bezwzględnego, a nie względnego. • runtimeVersion — ciąg znaków oznaczający wersję środowiska wykonawczego (np. "1.0.M6") wymaganego do zainstalowania aplikacji. • arguments — argumenty, jakie zostaną przekazane do aplikacji, jeśli zostanie uruchomiona po zainstalowaniu. Aplikacja jest uruchamiana po zainstalowaniu, jeśli element allowBrowserInvocation ma wartość true w pliku deskryptora aplikacji. (Więcej informacji na temat pliku deskryptora aplikacji zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45). Jeśli aplikacja zostanie uruchomiona w wyniku bezproblemowej instalacji z przeglądarki (użytkownik wybrał opcję uruchomienia po instalacji), wówczas obiekt NativeApplication aplikacji wywołuje zdarzenie BrowserInvokeEvent tylko po przekazaniu argumentów. Należy rozważyć, czy dane przekazywane do aplikacji nie spowodują zagrożenia. Szczegółowe informacje zawiera sekcja „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 319 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Ustawienia url i runtimeVersion są przekazywane do pliku SWF za pośrednictwem ustawień FlashVars na stronie HTML kontenera. Jeśli aplikacja zostanie uruchomiona bezpośrednio po zainstalowaniu, można skorzystać z komunikacji LocalConnection, aby wywołana zainstalowana aplikacja skontaktowała się z plikiem badge.swf. Szczegółowe informacje zawiera sekcja „Komunikacja między aplikacjami” na stronie 313. Możliwe jest również wywołanie metody getApplicationVersion() pliku air.swf w celu sprawdzenia, czy aplikacja jest zainstalowana. Tę metodę można wywołać przed zainstalowaniem aplikacji lub po uruchomieniu instalowania. Szczegółowe informacje zawiera sekcja „Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana” na stronie 320. Ładowanie pliku air.swf Możliwe jest utworzenie własnego pliku SWF, który będzie korzystał z interfejsów API pliku air.swf w celu interakcji ze środowiskiem wykonawczym i aplikacjami AIR ze strony internetowej w przeglądarce. Plik air.swf jest dostępny na stronie http://airdownload.adobe.com/air/browserapi/air.swf. W celu utworzenia odwołania do interfejsów API air.swf z pliku SWF należy załadować plik air.swf do tej samej domeny aplikacji, co plik SWF. Poniższy kod stanowi przykład ładowania pliku air.swf do domeny aplikacji ładującego pliku SWF: 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; } Po załadowaniu pliku air.swf (gdy obiekt contentLoaderInfo obiektu Loader wywoła zdarzenie init) można wywołać dowolny interfejs API pliku air.swf. Te interfejsy API zostały opisane w poniższych sekcjach: • „Sprawdzanie, czy środowisko wykonawcze jest zainstalowane” na stronie 319. • „Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana” na stronie 320. • „Instalowanie aplikacji AIR z przeglądarki” na stronie 321. • „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. Uwaga: Plik badge.swf, dostępny w pakiecie AIR SDK, automatycznie ładuje plik air.swf. Patrz „Korzystanie z pliku badge.swf w celu zainstalowania aplikacji” na stronie 316. Instrukcje w niniejszej sekcji dotyczą tworzenia własnego pliku SWF, który ładuje plik air.swf. Sprawdzanie, czy środowisko wykonawcze jest zainstalowane Plik SWF może sprawdzić, czy środowisko wykonawcze jest zainstalowane — w tym celu należy wywołać metodę getStatus() w pliku air.swf załadowanym ze strony http://airdownload.adobe.com/air/browserapi/air.swf. Szczegółowe informacje zawiera sekcja „Ładowanie pliku air.swf” na stronie 319. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 320 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Po załadowaniu pliku air.swf plik SWF może wywołać metodę getStatus() pliku air.swf, jak w poniższym kodzie: var status:String = airSWF.getStatus(); Metoda getStatus() zwraca jeden z następujących ciągów znaków w zależności od statusu środowiska wykonawczego na komputerze: Ciąg znaków Opis "available" Środowisko wykonawcze może zostać zainstalowane na tym komputerze, ale aktualnie nie jest zainstalowane. "unavailable" Środowisko wykonawcze nie może zostać zainstalowane na komputerze. "installed" Środowisko wykonawcze jest już zainstalowane na komputerze. Metoda getStatus() generuje błąd, jeśli w przeglądarce nie jest zainstalowana wymagana wersja programu Flash Player (wersja 9 z aktualizacją 3 lub nowszą w systemach Windows i Mac OS albo wersja 10 w systemie Linux). Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana Plik SWF może sprawdzić, czy zainstalowana jest aplikacja AIR (ze zgodnym identyfikatorem aplikacji i wydawcy) — w tym celu musi wywołać metodę getApplicationVersion() w pliku air.swf załadowanym ze strony http://airdownload.adobe.com/air/browserapi/air.swf. Szczegółowe informacje zawiera sekcja „Ładowanie pliku air.swf” na stronie 319. Po załadowaniu pliku air.swf plik SWF może wywołać metodę getApplicationVersion() pliku air.swf, jak w poniższym kodzie: 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. } } Metoda getApplicationVersiom() ma następujące parametry: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 321 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Parametry Opis appID Identyfikator aplikacji. Szczegółowe informacje zawiera sekcja „Definiowanie tożsamości aplikacji” na stronie 48. pubID Identyfikator wydawcy dla aplikacji. Szczegółowe informacje zawiera sekcja „Informacje o identyfikatorach wydawców AIR” na stronie 325. callback Funkcja wywołania zwrotnego, która służy jako funkcja modułu obsługi. Metoda getApplicationVersion() działa asynchronicznie, a po wykryciu zainstalowanej wersji (lub braku zainstalowanej wersji) wywoływana jest ta metoda wywołania zwrotnego. Definicja metody wywołania zwrotnego musi zawierać jeden parametr — ciąg znaków — który określa wersję zainstalowanej aplikacji. Jeśli aplikacja nie została zainstalowana, do funkcji przekazywana jest wartość null, co ilustruje poprzedni fragment kodu. Metoda getApplicationVersion() generuje błąd, jeśli w przeglądarce nie jest zainstalowana wymagana wersja programu Flash Player (wersja 9 z aktualizacją 3 lub nowszą w systemach Windows i Mac OS albo wersja 10 w systemie Linux). Instalowanie aplikacji AIR z przeglądarki Plik SWF może zainstalować aplikację AIR poprzez wywołanie metody installApplication() w pliku air.swf załadowanym ze strony http://airdownload.adobe.com/air/browserapi/air.swf. Szczegółowe informacje zawiera sekcja „Ładowanie pliku air.swf” na stronie 319. Po załadowaniu pliku air.swf plik SWF może wywołać metodę installApplication() pliku air.swf, jak w poniższym kodzie: var url:String = "http://www.example.com/myApplication.air"; var runtimeVersion:String = "1.0"; var arguments:Array = ["launchFromBrowser"]; // Optional airSWF.installApplication(url, runtimeVersion, arguments); Metoda installApplication() zainstaluje określoną aplikację na komputerze użytkownika. Ta metoda ma następujące parametry: Parametr Opis url Ciąg znaków określający adres URL pliku AIR do zainstalowania. Należy użyć adresu URL bezwzględnego, a nie względnego. runtimeVersion Ciąg znaków oznaczający wersję środowiska wykonawczego (np. „1.0”) wymaganego do zainstalowania aplikacji. arguments Tablica argumentów, jakie zostaną przekazane do aplikacji, jeśli zostanie uruchomiona po zainstalowaniu. W argumentach są rozpoznawane tylko znaki alfanumeryczne. Jeśli zachodzi potrzeba przekazania innych wartości, należy rozważyć użycie odpowiedniego systemu kodowania. Aplikacja jest uruchamiana po zainstalowaniu, jeśli element allowBrowserInvocation ma wartość true w pliku deskryptora aplikacji. (Więcej informacji na temat pliku deskryptora aplikacji zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45). Jeśli aplikacja zostanie uruchomiona w wyniku bezproblemowej instalacji z przeglądarki (użytkownik wybrał opcję uruchomienia po instalacji), wówczas obiekt NativeApplication aplikacji wywołuje zdarzenie BrowserInvokeEvent tylko po przekazaniu argumentów. Szczegółowe informacje zawiera sekcja „Uruchamianie zainstalowanej aplikacji AIR z przeglądarki” na stronie 322. Metoda installApplication() może działać wyłącznie wówczas, gdy zostanie wywołana w module obsługi zdarzeń, np. w przypadku zdarzenia myszy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 322 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Metoda installApplication() generuje błąd, jeśli w przeglądarce nie jest zainstalowana wymagana wersja programu Flash Player (wersja 9 z aktualizacją 3 lub nowszą w systemach Windows i Mac OS albo wersja 10 w systemie Linux). W celu zainstalowania zaktualizowanej wersji aplikacji w systemie Mac OS użytkownik powinien mieć odpowiednie uprawnienia dostępu do instalowania w katalogu aplikacji (a także uprawnienia administracyjne, jeśli aplikacja aktualizuje środowisko wykonawcze). W systemie Windows użytkownik potrzebuje uprawnień administratora. Możliwe jest również wywołanie metody getApplicationVersion() pliku air.swf w celu sprawdzenia, czy aplikacja jest już zainstalowana. Tę metodę można wywołać przed zainstalowaniem aplikacji lub po uruchomieniu instalowania. Szczegółowe informacje zawiera sekcja „Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana” na stronie 320. Uruchomiona aplikacja może się komunikować z treścią pliku SWF w przeglądarce — w tym celu może korzystać z klasy LocalConnection. Szczegółowe informacje zawiera sekcja „Komunikacja między aplikacjami” na stronie 313. Uruchamianie zainstalowanej aplikacji AIR z przeglądarki W celu korzystania z trybu wywołania z przeglądarki (która umożliwia uruchomienie aplikacji z przeglądarki) plik deskryptora aplikacji docelowej musi zawierać następujące ustawienia: <allowBrowserInvocation>true</allowBrowserInvocation> (Więcej informacji na temat pliku deskryptora aplikacji zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45). Plik SWF w przeglądarce może uruchamiać aplikację AIR poprzez wywołanie metody launchApplication() w pliku air.swf załadowanym ze strony http://airdownload.adobe.com/air/browserapi/air.swf. Szczegółowe informacje zawiera sekcja „Ładowanie pliku air.swf” na stronie 319. Po załadowaniu pliku air.swf plik SWF może wywołać metodę launchApplication() pliku air.swf, jak w poniższym kodzie: var appID:String = "com.example.air.myTestApplication"; var pubID:String = "02D88EEED35F84C264A183921344EEA353A629FD.1"; var arguments:Array = ["launchFromBrowser"]; // Optional airSWF.launchApplication(appID, pubID, arguments); Metoda launchApplication() jest zdefiniowana na najwyższym poziomie pliku air.swf (który jest załadowany do domeny aplikacji pliku SWF interfejsu użytkownika). Wywołanie tej metody sprawia, że środowisko AIR uruchamia określoną aplikację (jeśli jest zainstalowana i możliwe jest wywołanie przeglądarki, co definiuje ustawienie allowBrowserInvocation w pliku deskryptora aplikacji). Ta metoda ma następujące parametry: Parametr Opis appID Identyfikator dla aplikacji przeznaczonej do uruchomienia. Szczegółowe informacje zawiera sekcja „Definiowanie tożsamości aplikacji” na stronie 48. pubID Identyfikator wydawcy dla aplikacji przeznaczonej do uruchomienia. Szczegółowe informacje zawiera sekcja „Informacje o identyfikatorach wydawców AIR” na stronie 325. arguments Tablica argumentów, które mają zostać przekazane do aplikacji. Obiekt NativeApplication aplikacji wywołuje zdarzenie BrowserInvokeEvent, którego właściwość arguments jest ustawiona na tę tablicę. W argumentach są rozpoznawane tylko znaki alfanumeryczne. Jeśli zachodzi potrzeba przekazania innych wartości, należy rozważyć użycie odpowiedniego systemu kodowania. Metoda launchApplication() może działać wyłącznie wówczas, gdy zostanie wywołana w module obsługi zdarzeń, np. w przypadku zdarzenia myszy. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 323 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Metoda launchApplication() generuje błąd, jeśli w przeglądarce nie jest zainstalowana wymagana wersja programu Flash Player (wersja 9 z aktualizacją 3 lub nowszą w systemach Windows i Mac OS albo wersja 10 w systemie Linux). Jeśli dla elementu allowBrowserInvocation ustawiono wartość false w pliku deskryptora aplikacji, wywołanie metody launchApplication() nie przynosi żadnego skutku. Przed wyświetleniem interfejsu użytkownika do uruchomienia aplikacji konieczne może być wywołanie metody getApplicationVersion() w pliku air.swf. Szczegółowe informacje zawiera sekcja „Sprawdzanie ze strony internetowej, czy aplikacja AIR została zainstalowana” na stronie 320. Gdy aplikacja zostaje wywołana za pośrednictwem funkcji wywołania przeglądarki, wówczas obiekt NativeApplication aplikacji wywołuje obiekt BrowserInvokeEvent. Szczegółowe informacje zawiera sekcja „Wywołanie z przeglądarki” na stronie 296. Jeśli używana jest funkcja wywołania przeglądarki, należy uwzględnić zagadnienia związane z bezpieczeństwem, które opisano w sekcji „Wywołanie z przeglądarki” na stronie 296. Uruchomiona aplikacja może się komunikować z treścią pliku SWF w przeglądarce — w tym celu może korzystać z klasy LocalConnection. Szczegółowe informacje zawiera sekcja „Komunikacja między aplikacjami” na stronie 313. Wdrożenie w przedsiębiorstwie Administratorzy IT mogą zainstalować (instalacja cicha) środowisko wykonawcze Adobe AIR oraz aplikacje AIR, korzystając ze standardowych narzędzi do wdrażania. Czynności, jakie mogą wykonać administratorzy IT: • Cicha instalacja środowiska wykonawczego Adobe AIR przy użyciu narzędzi, takich jak Microsoft SMS, IBM Tivoli lub dowolnego narzędzia do wdrażania, które umożliwia wykonywanie instalacji cichej z wykorzystaniem bootstrappingu • Cicha instalacja aplikacji AIR przy użyciu niektórych narzędzi używanych w celu wdrożenia środowiska wykonawczego Więcej informacji zawiera dokumentacja Podręcznik administratora środowiska Adobe AIR (http://www.adobe.com/go/learn_air_admin_guide_pl). Elektroniczne podpisywanie pliku AIR Elektroniczne podpisywanie plików instalacyjnych AIR za pomocą certyfikatu wystawionego przez zatwierdzony ośrodek certyfikacji (CA) stanowi istotne potwierdzenie dla użytkowników aplikacji, że aplikacja, którą instalują nie została przypadkowo lub złośliwie zmodyfikowana. Ponadto certyfikat stanowi potwierdzenie tożsamości autora podpisu. Środowisko wykonawcze AIR wyświetla nazwę wydawcy podczas instalowania pod warunkiem, że aplikacja AIR została podpisana certyfikatem zaufanym lub takim, który kieruje do certyfikatu zaufanego na komputerze instalacji. W przeciwnym wypadku nazwa wydawcy jest wyświetlana jako „Nieznana”. Ważne: Kod złośliwy może sfałszować plik AIR, korzystając z tożsamości programisty, jeśli w jakiś sposób uzyska plik magazynu kluczy do podpisywania lub wykryje klucz prywatny. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 324 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Informacje o certyfikatach podpisujących kod Zabezpieczenia, ograniczenia oraz obowiązki prawne wynikające ze stosowania certyfikatów podpisujących kod zostały przedstawione w oświadczeniu CPS (Certificate Practice Statements) oraz umowach dotyczących subskrypcji wystawianych przez ośrodek certyfikacji. Więcej informacji na temat umów z ośrodkami certyfikacji, które obecnie wydają certyfikaty do podpisywania kodu dla środowiska AIR, można znaleźć na następujących stronach internetowych: 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) GlobalSign CPS (http://www.globalsign.com/repository/index.htm) Thawte CPS (http://www.thawte.com/cps/index.html) Umowa programisty dotycząca podpisywania kodu — Thawte (http://www.thawte.com/ssl-digital-certificates/freeguides-whitepapers/pdf/develcertsign.pdf) VeriSign CPS (http://www.verisign.com/repository/CPS/) Umowa subskrybenta — VeriSign (https://www.verisign.com/repository/subscriber/SUBAGR.html) Informacje o podpisywaniu kodu w AIR Podpisywanie pliku AIR oznacza dołączenie podpisu elektronicznego do pliku instalacyjnego. Podpis zawiera streszczenie pakietu, które służy do weryfikacji, że plik AIR nie został zmodyfikowany od czasu jego podpisania, a ponadto zawiera informacje o certyfikacie, które służą do sprawdzenia tożsamości wydawcy. W środowisku AIR wykorzystywana jest infrastruktura kluczy publicznych za pośrednictwem magazynu certyfikatów systemu operacyjnego — w tej strukturze określane jest, czy certyfikat może być zaufany. Komputer, na którym zainstalowana jest aplikacja AIR musi bezpośrednio ufać certyfikatowi używanemu do podpisania aplikacji AIR lub musi zaufać łańcuchowi certyfikatów łączących certyfikat z zaufanym ośrodkiem certyfikacji w celu weryfikacji informacji o wydawcy. Jeśli plik AIR jest podpisany certyfikatem, który nie łączy się z jednym z zaufanych certyfikatów głównych (zwykle należą do nich certyfikaty samopodpisane), wówczas nie ma możliwości sprawdzenia informacji o wydawcy. Środowisko AIR może ustalić, czy pakiet AIR nie został zmodyfikowany od czasu jego podpisania, ale nie ma możliwości określenia autora pliku ani autora podpisu. Uwaga: Użytkownik może zaufać certyfikatowi samopodpisanemu, a wówczas wszystkie aplikacje AIR podpisane tym certyfikatem będą wyświetlały wartość pola nazwy wspólnej z certyfikatu jako nazwę wydawcy. Środowisko AIR nie udostępnia użytkownikowi funkcji wyznaczenia certyfikatu jako podpisany. Certyfikat (bez klucza prywatnego) musi zostać udostępniony użytkownikowi osobno, a użytkownik musi korzystać z jednego z mechanizmów dostępnych w systemie operacyjnym lub z odpowiedniego narzędzia w celu zaimportowania certyfikatu do odpowiedniej lokalizacji w magazynie certyfikatów systemu. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 325 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Informacje o identyfikatorach wydawców AIR W ramach procesu budowania pliku AIR narzędzie ADT (AIR Developer Tool) generuje identyfikator wydawcy. Jest to identyfikator unikalny dla certyfikatu służącego do zbudowania pliku AIR. Jeśli ten sam certyfikat zostanie wykorzystany dla wielu aplikacji AIR, identyfikator wydawcy dla każdej z tych aplikacji będzie taki sam. Identyfikator wydawcy służy do identyfikowania aplikacji AIR w komunikacji LocalConnection (patrz „Komunikacja między aplikacjami” na stronie 313). W celu określenia identyfikatora wydawcy zainstalowanej aplikacji należy odczytać właściwość NativeApplication.nativeApplication.publisherID. Poniższe pola są wykorzystywane w celu obliczenia identyfikatora wydawcy: 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 oraz NameAtBirth. Jeśli w przypadku odnowienia certyfikatu wydanego przez ośrodek certyfikacji lub w przypadku ponownego wygenerowania certyfikatu samopodpisanego identyfikator wydawcy ma pozostać taki sam, wówczas zawartość tych pól musi pozostać niezmieniona. Ponadto niezmienione muszą pozostać: certyfikat główny certyfikatu wydanego przez ośrodek certyfikacji oraz klucz publiczny certyfikatu samopodpisanego. Informacje o formatach certyfikatów Narzędzia do podpisywania AIR akceptują dowolne magazyny kluczy dostępne za pośrednictwem architektury Java Cryptography Architecture (JCA). Ta architektura zawiera magazyny plików oparte na plikach, takie jak pliki w formacie PKCS12 (zwykle z rozszerzeniem .pfx lub .p12), pliki .keystore Java, magazyny kluczy PKCS11 urządzeń oraz systemowe magazyny kluczy. Formaty magazynów kluczy, do których narzędzie ADT może uzyskać dostęp, są uzależnione od wersji i konfiguracji środowiska wykonawczego Java używanego do uruchamiania narzędzia ADT. Dostęp do pewnych typów magazynów kluczy, np. do tokenów PKCS11 urządzeń, może wymagać zainstalowania i konfiguracji dodatkowych sterowników oprogramowania i wtyczek JCA. Do podpisywania plików AIR można używać większości istniejących certyfikatów do podpisywania kodu. Można też uzyskać nowy certyfikat wydany specjalnie do podpisywania aplikacji AIR. Na przykład możliwe jest stosowanie dowolnego z wymienionych niżej certyfikatów wydawanych przez ośrodki VeriSign, Thawte, GlobalSign lub ChosenSecurity: • ChosenSecurity • TC Publisher ID for Adobe AIR • GlobalSign • ObjectSign Code Signing Certificate • Thawte: • AIR Developer Certificate • Apple Developer Certificate • JavaSoft Developer Certificate • Microsoft Authenticode Certificate • VeriSign: • Adobe AIR Digital ID • Microsoft Authenticode Digital ID • Sun Java Signing Digital ID TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 326 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Uwaga: Certyfikat musi być utworzony jako certyfikat podpisujący kod. Do podpisywania plików AIR nie można używać certyfikatów SSL ani certyfikatów innego typu. Znaczniki czasowe Podczas podpisywania pliku AIR narzędzie do pakowania zadaje do serwera zapytanie dotyczące ośrodka wystawiającego znaczniki czasu w celu niezależnej weryfikacji daty i czasu podpisu. Uzyskany znacznik czasu zostaje osadzony w pliku AIR. Jeśli certyfikat podpisujący obowiązuje podczas podpisywania, plik AIR może zostać zainstalowany nawet po utracie ważności certyfikatu. Z drugiej strony: jeśli nie uzyskano znacznika czasu, wówczas po utracie ważności lub odrzuceniu certyfikatu nie ma możliwości zainstalowania pliku AIR. Domyślnie narzędzia do pakowania AIR uzyskują znacznik czasu. Jednak aby umożliwić pakowanie przy braku dostępności do usługi znacznika czasu, można wyłączyć wstawianie znacznika czasu. Adobe zaleca, aby wszystkie dystrybuowane publicznie pliki AIR zawierały znacznik czasu. Domyślnym ośrodkiem wystawiającym znaczniki czasu, z którego korzystają narzędzia pakowania AIR, jest Geotrust. Uzyskiwanie certyfikatu W celu uzyskania certyfikatu należy odwiedzić witrynę sieci Web ośrodka certyfikacji, a następnie przeprowadzić proces związany z uzyskiwaniem. Narzędzia, jakie są używane do generowania pliku magazynu kluczy wymaganego dla narzędzi AIR, są uzależnione od typu zakupionego certyfikatu, sposobu przechowywania certyfikatu na komputerze odbierającym oraz w niektórych przypadkach — od przeglądarki używanej w celu odebrania certyfikatu. Na przykład, aby uzyskać i wyeksportować certyfikat Adobe Developer wydany przez ośrodek Thawte, należy użyć przeglądarki Mozilla Firefox. Certyfikat można wyeksportować jako plik P12 lub PFX bezpośrednio z interfejsu użytkownika programu Firefox. Certyfikat samopodpisany można wygenerować za pomocą narzędzia ADT (Air Development Tool) używanego do pakowania plików instalacyjnych AIR. Możliwe jest również korzystanie z niektórych narzędzi innych firm. Instrukcje generowania certyfikatu samopodpisanego, a także instrukcje podpisywania plików AIR zawiera sekcja „Pakowanie pliku instalacyjnego aplikacji AIR za pomocą narzędzia AIR Developer Tool (ADT)” na stronie 360. Pliki AIR można eksportować i podpisywać za pomocą programów Flex Builder, Dreamweaver oraz za pomocą aktualizacji AIR dla programu Flash. Poniższy przykład przedstawia sposób uzyskania certyfikatu AIR Developer Certificate z ośrodka certyfikacji Thawte, a także sposób przygotowania tego certyfikatu do użytku z narzędziem ADT. Przykład: uzyskanie certyfikatu AIR Developer Certificate z ośrodka Thawte Uwaga: Niniejszy przykład ilustruje tylko jeden z wielu sposobów uzyskania i przygotowania certyfikatu podpisującego kod do użytku. Każdy ośrodek certyfikacji ma własne zasady i procedury. W celu zakupienia certyfikatu AIR Developer Certificate w witrynie sieci Web Thawte należy korzystać z przeglądarki Mozilla Firefox. Klucz prywatny dla certyfikatu jest zapisany w magazynie kluczy przeglądarki. Należy się upewnić, że magazyn kluczy Firefox jest zabezpieczony hasłem głównym oraz że komputer jest zabezpieczony fizycznie. (Po zakończeniu procesu uzyskiwania możliwe będzie wyeksportowanie i usunięcie klucza prywatnego z magazynu kluczy przeglądarki). W ramach procesu rejestrowania generowana jest para kluczy: prywatny/publiczny. Klucz prywatny jest automatycznie zapisywany w magazynie kluczy Firefox. Do żądania i pobierania certyfikatu z witryny sieci Web Thawte należy używać tego samego komputera. 1 Odwiedź witrynę sieci Web Thawte i przejdź do strony certyfikatów podpisujących kod dla produktów. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 327 Dystrybucja, instalowanie i uruchamianie aplikacji AIR 2 Z listy certyfikatów podpisujących kod wybierz certyfikat Adobe AIR Developer Certificate. 3 Wykonaj trzykrokowy proces rejestracji. Wymagane jest wprowadzenie informacji o organizacji oraz danych adresowych. Następnie Thawte przeprowadzi weryfikację tożsamości i może zażądać dodatkowych informacji. Po zakończeniu weryfikacji Thawte wyśle wiadomość e-mail z instrukcjami dotyczącymi pobrania certyfikatu. Uwaga: Dodatkowe informacje o typie wymaganej dokumentacji zawiera dokument: https://www.thawte.com/ssldigital-certificates/free-guides-whitepapers/pdf/enroll_codesign_eng.pdf. 4 Pobierz wydany certyfikat z serwisu Thawte. Certyfikat zostanie automatycznie zapisany w magazynie kluczy Firefox. 5 Wyeksportuj plik magazynu kluczy zawierający klucz prywatny i certyfikat z magazynu kluczy Firefox, wykonując poniższe czynności: Uwaga: Prywatny klucz/certyfikat z Firefox jest eksportowany w formacie .p12 (pfx), z którego może korzystać program ADT, Flex, Flash i Dreamweaver. a Otwórz okno dialogowe Menedżer certyfikatów przeglądarki Firefox: b W systemie Windows: wybierz kolejno opcje Narzędzia -> Opcje -> Zaawansowane -> Szyfrowanie -> Wyświetl certyfikaty c W systemie Mac OS: otwórz program Firefox -> Preferencje -> Zaawansowane -> Szyfrowanie -> Wyświetl certyfikaty d W systemie Linux: wybierz kolejno opcje Edycja -> Preferencje -> Zaawansowane -> Szyfrowanie -> Wyświetl certyfikaty e Z listy certyfikatów wybierz certyfikat Adobe AIR Code Signing Certificate i kliknij przycisk Kopia zapasowa. f Wprowadź nazwę i lokalizację pliku, do którego zostanie wyeksportowany plik magazynu kluczy, a następnie kliknij przycisk Zapisz. g Jeśli używane jest hasło główne Firefox, wymagane jest wprowadzenie hasła dla urządzenia zabezpieczenia oprogramowania w celu wyeksportowania pliku. (To hasło jest używane tylko przez program Firefox). h W oknie dialogowym Wybierz hasło kopii zapasowej certyfikatu utwórz hasło dla pliku magazynu kluczy. Ważne: To hasło chroni plik magazynu kluczy oraz jest wymagane, gdy plik jest używany do podpisywania aplikacji AIR. Należy wybrać hasło bezpieczne. i Kliknij przycisk OK. Powinien pojawić się komunikat informujący o pomyślnym zakończeniu wykonywania kopii zapasowej. Plik magazynu kluczy zawierający prywatny klucz i certyfikat jest zapisywany z rozszerzeniem .p12 (w formacie PKCS12) 6 Wyeksportowany plik magazynu kluczy można użyć z programem ADT, Flex Builder, Flash lub Dreamweaver. Hasło utworzone dla pliku jest wymagane zawsze przy podpisywaniu aplikacji AIR. Ważne: Klucz prywatny i certyfikat są nadal zapisane w magazynie kluczy Firefox. Dzięki temu możliwe jest wyeksportowanie dodatkowej kopii pliku certyfikatu, a ponadto jest to dodatkowy punkt dostępu, który musi być chroniony, aby możliwe było zachowanie bezpieczeństwa certyfikatu i klucza prywatnego. Zmiana certyfikatów W niektórych sytuacjach konieczna może być zmiana certyfikatu używanego w celu podpisania aplikacji AIR. Do takich sytuacji należą: • Aktualizacja z certyfikatu samopodpisanego do certyfikatu wydanego przez ośrodek certyfikacji • Zmiana certyfikatu samopodpisanego, który wkrótce utraci ważność, na inny certyfikat TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 328 Dystrybucja, instalowanie i uruchamianie aplikacji AIR • Zmiana certyfikatu komercyjnego np. w przypadku zmiany tożsamości korporacyjnej Certyfikat podpisujący to jeden z elementów, które określają tożsamość aplikacji AIR, dlatego nie ma takiej możliwości, aby po prostu podpisać aplikację i wybrać inny certyfikat. Aby środowisko AIR rozpoznało plik AIR jako aktualizację, należy podpisać plik oryginalny i zaktualizowany plik AIR tym samym certyfikatem. W przeciwnym wypadku środowisko AIR zainstaluje nowy plik AIR jako osobną aplikację, a nie jako aktualizację istniejącej instalacji. W środowisku AIR 1.1 możliwa jest zmiana certyfikatu podpisującego aplikacji za pomocą podpisu migracji. Podpis migracji jest drugim podpisem zastosowanym w celu aktualizacji pliku AIR. Podpis migracji korzysta z certyfikatu oryginalnego, który określa, że autor podpisu jest oryginalnym wydawcą aplikacji. Ważne: Certyfikat należy zmienić zanim nastąpi utrata ważności lub odrzucenie oryginalnego certyfikatu. Jeśli przed utratą ważności certyfikatu nie dojdzie do utworzenia ani aktualizacji podpisu migracji, wówczas użytkownicy będą musieli odinstalować istniejącą wersję aplikacji przed zainstalowaniem aktualizacji. Certyfikaty wydawane w celach komercyjnych mogą być zwykle odnawiane w celu uniknięcia utraty ważności. Certyfikaty samopodpisane nie mogą być odnawiane. W celu zmiany certyfikatów: 1 Utwórz aktualizację aplikacji 2 Spakuj i podpisz plik AIR aktualizacji nowym certyfikatem 3 Podpisz ponownie plik AIR oryginalnym certyfikatem (korzystając z polecenia -migrate narzędzia ADT) Procedura zastosowania podpisu migracji została opisana w sekcji „Podpisywanie pliku AIR w celu zmiany certyfikatu aplikacji” na stronie 370. Po zainstalowaniu zaktualizowanego pliku AIR następuje zmiana tożsamości aplikacji. Zmiana tożsamości ma następujące skutki: • Identyfikator wydawcy aplikacji zmienia się w celu dopasowania do nowego certyfikatu. • Wersja nowej aplikacji nie może uzyskać dostępu do danych w istniejącym zaszyfrowanym magazynie lokalnym. • Zmienia się lokalizacja katalogu zapisu aplikacji. Dane ze starej lokalizacji nie są kopiowane do nowego katalogu. (Nowa aplikacja może zlokalizować katalog oryginalny na podstawie starego identyfikatora wydawcy). • Aplikacja nie może otworzyć lokalnych połączeń za pomocą starego identyfikatora wydawcy. • Jeśli użytkownik ponownie zainstaluje plik sprzed migracji, wówczas środowisko AIR zainstaluje go jako osobną aplikację, korzystając z oryginalnego identyfikatora wydawcy. Zadaniem aplikacji jest przeprowadzenie migracji danych między oryginalnymi i nowymi wersjami aplikacji. W celu przeprowadzenia migracji danych w zaszyfrowanym magazynie lokalnym (ELS) należy wyeksportować dane przed zmianą w certyfikacie. Nowa wersja aplikacji nie może odczytać magazynu ELS starej wersji. (Czasami zamiast migracji danych łatwiej jest ponownie utworzyć dane). Podpis migracji należy stosować dla jak największej liczby kolejnych aktualizacji. W przeciwnym wypadku użytkownicy, którzy nie zaktualizowali wersji oryginalnej, będą musieli zainstalować pośrednią wersję migracji lub będą musieli odinstalować bieżącą wersję przed zainstalowaniem ostatniej aktualizacji. W końcu dojdzie jednak do utraty ważności oryginalnego certyfikatu, a wówczas nie będzie możliwe stosowanie podpisu migracji. (Jednak pliki AIR poprzednio podpisane za pomocą podpisu migracji pozostaną aktualne, chyba że wyłączono opcję umieszczania znaczników czasu. Podpis migracji zawiera znacznik czasu, dzięki czemu środowisko AIR może zaakceptować podpis, nawet jeśli upłynie ważność certyfikatu). Pod innymi względami plik AIR z podpisem migracji jest normalnym plikiem AIR. Jeśli aplikacja zostanie zainstalowana w systemie, który nie zawiera wersji oryginalnej, wówczas środowisko AIR zainstaluje nową wersję w standardowy sposób. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 329 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Uwaga: W przypadku odnawiania certyfikatu wydawanego komercyjnie nie ma potrzeby jego migrowania. Certyfikat odnowiony zachowuje tę samą tożsamość wydawcy co oryginał, chyba że doszło do zmiany nazwy wyróżniającej. Pełną listę atrybutów certyfikatu, które służą do określania nazwy wyróżniającej, zawiera sekcja „Informacje o identyfikatorach wydawców AIR” na stronie 325. Terminologia Niniejsza sekcja zawiera słowniczek terminów, które należy znać podczas podejmowania decyzji dotyczących sposobu podpisania aplikacji dla dystrybucji publicznej. Termin Opis Ośrodek certyfikacji Obiekt w sieci infrastruktury kluczy publicznych, który służy jako zaufana strona trzecia i w sposób ostateczny poświadcza tożsamość właściciela klucza publicznego. Ośrodek zwykle wydaje certyfikaty elektroniczne podpisywane własnymi kluczami prywatnymi, co stanowi dowód sprawdzenia tożsamości posiadacza certyfikatu. Oświadczenie CPS (Certificate Practice Statement) Określa praktyki i strategie ośrodka certyfikacji dotyczące wydawania i weryfikacji certyfikatów. Oświadczenie CPS jest częścią umowy między ośrodkiem certyfikacji a subskrybentami oraz stronami zależnymi. Określa również strategie weryfikacji tożsamości i poziom zabezpieczeń oferowanych przez udostępniane certyfikaty. Lista CRL (Certificate Revocation List) Lista wydanych certyfikatów, które zostały odrzucone i nie należy im ufać. AIR sprawdza CRL podczas podpisywania aplikacji AIR, a także w przypadku braku znacznika czasu przy instalowaniu aplikacji. Łańcuch certyfikatów Łańcuch certyfikatu jest sekwencją certyfikatów, w której każdy certyfikat z łańcucha został podpisany przez kolejny certyfikat. Certyfikat elektroniczny Dokument elektroniczny, który zawiera informacje o tożsamości właściciela, kluczu publicznym właściciela oraz o tożsamości samego certyfikatu. Certyfikat wydany przez ośrodek certyfikacji jest podpisany przez certyfikat należący do wydającego ośrodka. Podpis elektroniczny Zaszyfrowany komunikat lub zaszyfrowane streszczenie, które można odszyfrować tylko za pomocą klucza prywatnego lub za pomocą klucza prywatnego, będącego połową pary klucz publiczny - klucz prywatny. W infrastrukturze PKI podpis elektroniczny zawiera jeden lub większą liczbę certyfikatów elektronicznych, które ostatecznie prowadzą do ośrodka tożsamości. Podpis elektroniczny może służyć do sprawdzenia, czy komunikat (lub plik) nie został zmodyfikowany od czasu podpisania (z uwzględnieniem ograniczeń określonych przez algorytm kryptograficzny), oraz w celu sprawdzenia tożsamości autora podpisu — przy założeniu, że wydający ośrodek certyfikacji jest zaufany. Magazyn kluczy Baza danych zawierająca certyfikaty elektroniczne, a w niektórych przypadkach, powiązane klucze prywatne. Architektura JCA (Java Cryptography Architecture) Rozszerzalna architektura przeznaczona do zarządzania i uzyskiwania dostępu do magazynów kluczy. Więcej informacji zawiera dokumentacja Java Cryptography Architecture Reference Guide. PKCS nr 11 Standard Cryptographic Token Interface Standard określony przez RSA Laboratories. Magazyn kluczy oparty na tokenie sprzętowym. PKCS nr 12 Standard Personal Information Exchange Syntax Standard określony przez RSA Laboratories. Magazyn kluczy oparty na plikach, który zwykle zawiera klucz prywatny oraz skojarzony z nim certyfikat elektroniczny. Klucz prywatny Prywatna część dwuczęściowego, asymetrycznego systemu kryptografii obejmującego klucz prywatny i publiczny. Klucz prywatny należy chronić i nigdy nie należy przesyłać go przez sieć. Komunikaty podpisane elektronicznie są szyfrowane kluczem prywatnym przez autora podpisu. Klucz publiczny Publiczna część dwuczęściowego, asymetrycznego systemu kryptografii obejmującego klucz prywatny i publiczny. Klucz publiczny jest dostępny dla wszystkich i służy do deszyfrowania komunikatów zaszyfrowanych kluczem prywatnym. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 330 Dystrybucja, instalowanie i uruchamianie aplikacji AIR Termin Opis Infrastruktura PKI (Public Key Infrastructure) System zaufania, w którym ośrodki certyfikacji poświadczają prawdziwość tożsamości właściciela klucza publicznego. Klienci sieci polegają na certyfikatach elektronicznych wydawanych przez zaufany ośrodek certyfikacji w celu weryfikacji tożsamości autora komunikatu elektronicznego (lub pliku). Znacznik czasu Elektronicznie podpisany element danych, który zawiera datę i godzinę wystąpienia zdarzenia. Narzędzie ADT może dołączać znaczniki czasu z serwera czasu zgodnego ze standardem RFC 3161 w pakiecie AIR. Jeśli znacznik czasu jest dostępny, środowisko AIR korzysta z niego w celu ustalenia poprawności certyfikatu w czasie podpisywania. Dzięki temu aplikacja AIR może zostać zainstalowana po upływie ważności jej certyfikatu podpisującego. Ośrodek wystawiający znacznik czasu Ośrodek, który wystawia znaczniki czasu. Znacznik, który ma zostać rozpoznany przez środowisko AIR, musi być zgodny ze standardem RFC 3161, a podpis znacznika czasu musi prowadzić do zaufanego certyfikatu głównego na komputerze instalacji. 331 Rozdział 33: Aktualizowanie aplikacji AIR Użytkownicy mogą instalować lub aktualizować aplikację AIR, klikając dwukrotnie plik AIR na ich komputerze lub za pośrednictwem przeglądarki (korzystając z funkcji instalacji bezproblemowej). Instalator środowiska Adobe® AIR™ zarządza procesem instalacji i ostrzega użytkownika, jeśli ma nastąpić aktualizacja już zainstalowanej aplikacji. (Patrz „Dystrybucja, instalowanie i uruchamianie aplikacji AIR” na stronie 314). Można jednak również spowodować, że zainstalowana aplikacja będzie samoczynnie aktualizować się do nowej wersji. W mechanizmie tym korzysta się z klasy Updater. (Zainstalowana aplikacja może wykryć dostępność nowej wersji do pobrania i zainstalowania). Klasa Updater zawiera metodę update(), która umożliwia wskazanie pliku AIR na komputerze użytkownika i zaktualizowanie aplikacji do wersji tego pliku. Zarówno identyfikator aplikacji, jak i identyfikator wydawcy pliku z aktualizacją muszą być identyczne z odpowiednimi identyfikatorami aktualizowanej aplikacji. Identyfikator wydawcy jest wyznaczany na podstawie certyfikatu podpisującego, co oznacza, że zarówno aktualizacja, jak i aktualizowana aplikacja muszą być podpisane tym samym certyfikatem. W wersji AIR 1.1 i nowszych istnieje możliwość przeprowadzenia migracji aplikacji w taki sposób, aby używany był dla niej nowy certyfikat do podpisywania kodu. Migracja aplikacji do nowego certyfikatu wymaga podpisania pliku AIR aktualizacji zarówno nowym, jak i oryginalnym certyfikatem. Migracja do nowego certyfikatu jest procesem jednokierunkowym. Po migracji wyłącznie pliki AIR podpisane nowym certyfikatem będą rozpoznawane jako aktualizacje istniejącej instalacji. Zarządzanie aktualizowaniem aplikacji może być skomplikowanym zagadnieniem. W skład środowiska AIR 1.5 wchodzi nowa architektura aktualizacji aplikacji Adobe® AIR™. Architektura ta obejmuje elementy interfejsu API pomagające programistom w tworzeniu sprawnych mechanizmów aktualizacji aplikacji AIR. Migracja certyfikatu umożliwia zmianę certyfikatu samopodpisanego na komercyjny certyfikat podpisujący kod, a także zmianę jednego certyfikatu samopodpisanego lub certyfikatu komercyjnego na inny. Jeśli migracja do nowego certyfikatu nie zostanie przeprowadzona, użytkownicy muszą usunąć swoje bieżące wersje aplikacji przed zainstalowaniem nowej wersji. Więcej informacji zawiera sekcja „Zmiana certyfikatów” na stronie 327. Informacje o aktualizowaniu aplikacji Klasa Updater (w pakiecie flash.desktop) zawiera jedną metodę, update(), której można użyć do zaktualizowania uruchomionej obecnie aplikacji do innej wersji. Na przykład, jeśli użytkownik ma wersję pliku AIR ("Sample_App_v2.air") umieszczoną na pulpicie, poniższy kod zaktualizuje aplikację: var updater:Updater = new Updater(); var airFile:File = File.desktopDirectory.resolvePath("Sample_App_v2.air"); var version:String = "2.01"; updater.update(airFile, version); Przed użyciem klasy Updater użytkownik lub aplikacja musi pobrać zaktualizowaną wersję pliku AIR do komputera. Więcej informacji zawiera sekcja „Pobieranie pliku AIR na komputer użytkownika” na stronie 333. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 332 Aktualizowanie aplikacji AIR Wyniki wywołania metody Updater.update() Gdy aplikacja w środowisku wykonawczym wywoła metodę update(), środowisko wykonawcze zamyka aplikację, a następnie próbuje zainstalować nową wersję z pliku AIR. Środowisko wykonawcze sprawdza, czy identyfikatory aplikacji i wydawcy określone w pliku AIR zgadzają się z identyfikatorami aplikacji i wydawcy aplikacji wywołującej metodę update(). (Informacje na temat identyfikatora aplikacji i wydawcy zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45). Środowisko sprawdza także, czy ciąg znaków wersji jest identyczny z ciągiem znaków version przekazanym do metody update(). Jeśli instalacja zakończy się pomyślnie, środowisko wykonawcze otwiera nową wersję aplikacji. W przeciwnym wypadku (jeśli nie było możliwe zakończenie instalacji), ponownie otwierana jest dotychczasowa (sprzed instalacji) wersja aplikacji. W celu zainstalowania zaktualizowanej wersji aplikacji w systemie Mac OS użytkownik musi mieć odpowiednie uprawnienia dostępu do zainstalowania w katalogu aplikacji. W systemach Windows i Linux użytkownik musi mieć uprawnienia administracyjne. Jeśli zaktualizowana wersja aplikacji wymaga zaktualizowanej wersji środowiska wykonawczego, instalowana jest nowa wersja tego środowiska. Aby zaktualizować środowisko wykonawcze, użytkownik musi mieć uprawnienia administracyjne w systemie. Podczas testowania aplikacji przy użyciu środowiska ADL wywołanie metody update() powoduje wygenerowanie wyjątku w czasie wykonywania. Informacje o ciągu znaków wersji Ciąg znaków określony jako parametr version metody update() musi być identyczny z ciągiem znaków w atrybucie version głównego elementu application w pliku deskryptora aplikacji dla pliku AIR przeznaczonego do zainstalowania. Określenie parametru version jest wymagane ze względów bezpieczeństwa. Wymaganie weryfikacji numeru wersji w pliku AIR przez aplikację wyklucza niezamierzone zainstalowanie starszej wersji, która mogłaby zawierać luki w zabezpieczeniach wyeliminowane w aplikacji obecnie zainstalowanej. Aplikacja powinna także porównać ciąg znaków wersji w pliku AIR z ciągiem znaków wersji w instalowanej aplikacji, aby uniemożliwić ataki polegające na podstawieniu starszej wersji. Ciąg znaków wersji może mieć dowolny format. Na przykład może być równy „2.01” lub „version 2”. O formacie tego ciągu decyduje twórca aplikacji. Środowisko wykonawcze nie sprawdza poprawności ciągu znaków wersji; kod aplikacji powinien ją sprawdzić przed zaktualizowaniem aplikacji. Jeśli aplikacja Adobe AIR pobierze plik AIR z sieci Web, wskazane jest zapewnienie mechanizmu powiadamiania przez usługę Web Service aplikacji Adobe AIR o pobieranej wersji. Aplikacja może następnie wykorzystać odpowiedni ciąg znaków jako parametr version metody update(). Jeśli plik AIR został uzyskany w inny sposób, a jego wersja jest nieznana, aplikacja AIR może przeanalizować plik AIR w celu określenia informacji o wersji. (Plik AIR ma postać archiwum w skompresowanego w formacie ZIP, a plik deskryptora jest drugim rekordem w archiwum). Szczegółowe informacje o pliku deskryptora aplikacji zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 333 Aktualizowanie aplikacji AIR Prezentacja niestandardowego interfejsu użytkownika służącego do aktualizacji aplikacji Środowisko AIR zawiera domyślny interfejs aktualizacji: Ten interfejs jest używany zawsze, gdy użytkownik po raz pierwszy instaluje aplikację na komputerze. Można jednak zdefiniować własny interfejs, który będzie używany przy instalowaniu następnych wersji aplikacji. Jeśli aplikacja definiuje niestandardowy interfejs aktualizacji, należy dla obecnie zainstalowanej aplikacji określić element customUpdateUI w pliku deskryptora aplikacji: <customUpdateUI>true</customUpdateUI> Gdy aplikacja jest już zainstalowana, a użytkownik otworzy plik AIR z identyfikatorem aplikacji i wydawcy identycznymi z odpowiednimi identyfikatorami zainstalowanej aplikacji, środowisko wykonawcze AIR otwiera aplikację, a nie domyślny instalator aplikacji AIR. Więcej informacji zawiera sekcja „Udostępnienie niestandardowego interfejsu aplikacji dla aktualizacji aplikacji” na stronie 53. Aplikacja w chwili uruchomienia (tj. gdy obiekt NativeApplication.nativeApplication wywoła zdarzenie load) może zdecydować, czy ma dokonać aktualizacji (przy użyciu klasy Updater). Jeśli aktualizacja ma być dokonana, aplikacja może zaprezentować użytkownikowi własny interfejs instalacji (który będzie się różnił od standardowego interfejsu do obsługi aplikacji). Pobieranie pliku AIR na komputer użytkownika Aby użyć klasy Updater, użytkownik lub aplikacja musi uprzednio zapisać plik AIR lokalnie na dysku swojego komputera. Uwaga: W skład środowiska AIR 1.5 wchodzi architektura aktualizacji, która pomaga programistom w realizacji sprawnych mechanizmów aktualizacji aplikacji AIR. Korzystanie z tej architektury może okazać się znacznie łatwiejsze niż bezpośrednie używanie metody update() klasy Update. Szczegółowe informacje zawiera sekcja „Korzystanie z architektury aktualizacji” na stronie 335. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 334 Aktualizowanie aplikacji AIR Poniższy kod odczytuje plik AIR z adresu URL (http://example.com/air/updates/Sample_App_v2.air) i zapisuje ten plik w katalogu magazynu aplikacji: 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."); } Więcej informacji zawiera sekcja „Przepływ pracy odczytu i zapisu plików.” na stronie 122. Sprawdzanie, czy aplikacja została uruchomiona po raz pierwszy Często po zaktualizowaniu aplikacja wyświetla komunikat powitalny lub instrukcję „pierwsze kroki”. Po uruchomieniu aplikacja sprawdza, czy została uruchomiona po raz pierwszy, i na tej podstawie może wyświetlić taki komunikat lub nie. Uwaga: W skład środowiska AIR 1.5 wchodzi architektura aktualizacji, która pomaga programistom w realizacji sprawnych mechanizmów aktualizacji aplikacji AIR. Architektura ta udostępnia łatwe metody sprawdzania, czy dana aplikacja jest uruchomiona po raz pierwszy. Szczegółowe informacje zawiera sekcja „Korzystanie z architektury aktualizacji” na stronie 335. Jedna z metod sprawdzenia tego warunku polega na zapisaniu pliku w katalogu magazynu aplikacji po jej zainicjowaniu. Po każdym uruchomieniu aplikacja powinna sprawdzać, czy plik istnieje. Brak pliku oznacza, że aplikacja została uruchomiona po raz pierwszy dla bieżącego użytkownika. Obecność pliku oznacza, że aplikacja była już co najmniej jeden raz uruchamiana. Jeśli plik istnieje i zawiera numer wersji starszej niż bieżąca, można przyjąć że użytkownik uruchamia nową wersję po raz pierwszy. Jeśli aplikacja zapisuje dane lokalnie (np. w katalogu magazynu aplikacji), niekiedy celowe jest sprawdzenie przy pierwszym uruchomieniu, czy istnieją dane zapisane wcześniej przez poprzednie wersje. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 335 Aktualizowanie aplikacji AIR Korzystanie z architektury aktualizacji Zarządzanie aktualizowaniem aplikacji może być skomplikowanym zagadnieniem. Architektura aktualizacji dla aplikacji AdobeAIRudostępnia elementy interfejsu API, które ułatwiają programistom tworzenie sprawnych mechanizmów aktualizacji aplikacji AIR. Funkcje architektury aktualizacji środowiska AIR wspomagają realizację następujących zadań: • Regularne sprawdzanie, czy są dostępne aktualizacje — w stałych odstępach czasu lub na żądanie użytkownika. • Pobieranie plików AIR (aktualizacji) ze źródła w sieci WWW. • Powiadamianie użytkownika o nowo zainstalowanej wersji przy pierwszym uruchomieniu. • Potwierdzanie, czy użytkownik chce sprawdzić dostępność aktualizacji. • Wyświetlanie informacji o nowej wersji aktualizacji. • Wyświetlanie postępu pobierania i informacji o błędach. Architektura aktualizacji aplikacji AIR zawiera przykładowy interfejs użytkownika, który można wykorzystać w aplikacji. Interfejs ten udostępnia użytkownikowi podstawowe informacje i opcje związane z aktualizacją aplikacji. Aplikacja może także zdefiniować własny niestandardowy interfejs użytkownika współpracujący z architekturą aktualizacji. Architektura aktualizacji aplikacji AIR umożliwia przechowywanie informacji o wersji aktualizacji aplikacji AIR w prostych plikach konfiguracyjnych XML. W przypadku większości aplikacji przygotowanie tych plików konfiguracyjnych i dodanie prostego kodu wystarczy do zapewnienia użytkownikom końcowym odpowiedniej funkcjonalności aktualizacji. Nawet jeśli programista nie zdecyduje się na użycie architektury aktualizacji, aplikacje mogą korzystać z klasy Updater dostępnej w środowisku Adobe AIR, która wspomaga uaktualnianie do nowych wersji. Klasa to umożliwia aplikacji uaktualnienie do wersji zawartej w pliku AIR na komputerze użytkownika. Jednak zarządzanie aktualizacjami zwykle nie sprowadza się do prostej aktualizacji aplikacji na podstawie lokalnego pliku AIR. Pliki w architekturze aktualizacji aplikacji AIR. Architektura aktualizacji aplikacji AIR zawiera następujące katalogi: • doc — dokumentacja (niniejszy dokument) architektury aktualizacji aplikacji AIR. • frameworks — ten katalog zawiera pliki SWC, służące do tworzenia aplikacji w środowisku Flex, oraz pliki SWF, służące do tworzenia aplikacji w środowisku HTML. Więcej informacji zawierają następujące sekcje (bezpośrednio po niniejszej sekcji): • „Konfigurowanie środowiska programistycznego Flex” na stronie 336 • „Uwzględnianie plików architektury w aplikacji AIR opartej na kodzie HTML” na stronie 336 • samples — ten katalog zawiera przykłady przeznaczone dla środowisk Flex i HTML. Przykłady te ilustrują wykorzystanie architektury aktualizacji aplikacji. Pliki przykładowe może kompilować i testować tak samo, jak każdą aplikację AIR. • templates — ten katalog zawiera przykładowe pliki deskryptorów aktualizacji (proste i zlokalizowane) oraz pliki konfiguracyjne. (Więcej informacji o tych plikach zawierają sekcje Konfigurowanie środowiska programistycznego Flex oraz „Prosty przykład: korzystanie z wersji ApplicationUpdaterUI” na stronie 336). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 336 Aktualizowanie aplikacji AIR Konfigurowanie środowiska programistycznego Flex Katalog frameworks/flex architektury aktualizacji zawiera następujące pliki: • ApplicationUpdater.swc — definiuje podstawową funkcjonalność biblioteki aktualizacji, bez interfejsu użytkownika. • ApplicationUpdater_UI.swc — definiuje podstawową funkcjonalność biblioteki aktualizacji wraz z interfejsem użytkownika, którego aplikacja może używać do wyświetlania opcji aktualizacji. Pliki SWC zawierają definicje klas, których można używać przy programowaniu w środowisku Flex. Aby skorzystać z architektury aktualizacji przy kompilowaniu aplikacji za pomocą pakietu Flex SDK, należy uwzględnić plik ApplicationUpdater.swc albo ApplicationUpdater_UI.swc w wywołaniu kompilatora amxmlc. W poniższym przykładzie kompilator ładuje plik ApplicationUpdater.swc z podkatalogu lib w katalogu pakietu Flex SDK: amxmlc -library-path+=lib/ApplicationUpdater.swc -- myApp.mxml W poniższym przykładzie kompilator ładuje plik ApplicationUpdater_UI.swc file z podkatalogu lib pakietu Flex SDK: amxmlc -library-path+=lib/ApplicationUpdater_UI.swc -- myApp.mxml W przypadku tworzenia aplikacji za pomocą kompilatora Flex Builder należy dodać plik SWC na karcie ścieżki biblioteki w ustawieniach ścieżki kompilacji Flex w oknie dialogowym właściwości. Pliki SWC należy koniecznie skopiować do katalogu, do którego będziemy odwoływać się w kompilatorze amxmlc (w przypadku użycia pakietu Flex SDK) lub w programie Flex Builder. Uwzględnianie plików architektury w aplikacji AIR opartej na kodzie HTML Katalog frameworks/html architektury aktualizacji zawiera następujące pliki: • ApplicationUpdater_UI.swf — definiuje podstawową funkcjonalność biblioteki aktualizacji, bez interfejsu użytkownika. • ApplicationUpdater_UI.swf — definiuje podstawową funkcjonalność biblioteki aktualizacji wraz z interfejsem użytkownika, którego aplikacja może używać do wyświetlania opcji aktualizacji. Kod JavaScript w aplikacjach AIR może korzystać z klas zdefiniowanych w plikach SWF. Aby skorzystać z architektury aktualizacji, należy umieścić plik ApplicationUpdater.swf albo ApplicationUpdater_UI.swf w katalogu (lub podkatalogu) aplikacji. Następnie w pliku HTML, w którym architektura będzie wykorzystywana (w kodzie JavaScript) należy umieścić znacznik script ładujący plik: <script src="applicationUpdater.swf" type="application/x-shockwave-flash"/> Lub użyć znacznika script do załadowania pliku ApplicationUpdater_UI.swf: <script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/> Interfejs API zdefiniowany w tych dwóch plikach został opisany w dalszej części niniejszego dokumentu. Prosty przykład: korzystanie z wersji ApplicationUpdaterUI Wersja architektury aktualizacji zapisana w pliku ApplicationUpdaterUI udostępnia prosty interfejs, który łatwo można włączyć do własnych aplikacji. Poniżej przedstawiono prosty przykład. Najpierw tworzymy aplikację AIR, która wywołuje architekturę aktualizacji: 1 Jeśli aplikacja AIR jest oparta na kodzie HTML, ładujemy plik ApplicationUpdaterUI.js: <script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 337 Aktualizowanie aplikacji AIR 2 W logice programowej aplikacji AIR tworzymy instancję obiektu ApplicationUpdaterUI. W języku ActionScript należałoby użyć następującego kodu: var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI(); W języku JavaScript należałoby użyć następującego kodu: var appUpdater = new runtime.air.update.ApplicationUpdaterUI(); Celowe może być dodanie tego kodu do funkcji inicjującej, wykonywanej po załadowaniu aplikacji. 3 Tworzymy plik tekstowy o nazwie updateConfig.xml i dodajemy do niego następujący kod: <?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> Modyfikujemy element URL pliku updateConfig.xml w taki sposób, aby wskazywał docelową lokalizację pliku deskryptora aktualizacji na serwerze WWW (patrz następna procedura). Wartość delay to liczba dni, co jaką aplikacja sprawdza dostępność aktualizacji. 4 Dodajemy plik updateConfig.xml file do katalogu projektu aplikacji AIR. 5 Powodujemy, że obiekt Updater odwołuje się do pliku updateConfig.xml, i wywołujemy metodę initialize() obiektu. W języku ActionScript należałoby użyć następującego kodu: appUpdater.configurationFile = new File("app:/updateConfig.xml"); appUpdater.initialize(); W języku JavaScript należałoby użyć następującego kodu: appUpdater.configurationFile = new air.File("app:/updateConfig.xml"); appUpdater.initialize(); 6 Tworzymy drugą wersję aplikacji AIR, o innym numerze niż pierwsza aplikacja. (Wersja jest podana w pliku deskryptora, w elemencie version). Następnie dodajemy zaktualizowaną wersję aplikacji AIR na serwer WWW: 1 Umieszczamy pliku AIR wersji zaktualizowanej na serwerze WWW. 2 Tworzymy plik tekstowy o nazwie updateDescriptor.xml i dodajemy do niego następującą treść: <?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> Edytujemy elementy version, URL i description pliku updateDescriptor.xml w taki sposób, aby wskazywały na plik AIR aktualizacji. 3 Dodajemy plik updateDescriptor.xml do tego samego katalogu serwera WWW, który zawiera plik AIR aktualizacji. Choć jest to prosty przykład, zapewnia on funkcjonalność aktualizacji wystarczającą w wielu zastosowaniach. W pozostałej części tego dokumentu opisano sposoby wykorzystania architektury aktualizacji odpowiednio do indywidualnych potrzeb. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 338 Aktualizowanie aplikacji AIR Innym przykładem zastosowania architektury aktualizacji jest następująca aplikacja przykładowa w serwisie Adobe AIR Developer Center: Architektura aktualizacji w aplikacji Flash(http://www.adobe.com/go/learn_air_qs_update_framework_flash_pl). Definiowanie pliku deskryptora aktualizacji i dodawanie pliku AIR na serwer WWW Podczas pracy z architekturą aktualizacji AIR konieczne jest zdefiniowanie podstawowych informacji o dostępnej aktualizacji w pliku deskryptora aktualizacji zapisanym na serwerze WWW. Plik deskryptora aktualizacji jest prostym plikiem XML. Architektura aktualizacji włączona do aplikacji sprawdza zawartość tego pliku, aby stwierdzić, czy na serwerze została umieszczona nowa wersja. Plik deskryptora aktualizacji zawiera następujące dane: • version — nowa wersja aplikacji AIR. Musi to być ten sam ciąg znaków, który identyfikuje wersję w pliku deskryptora nowej aplikacji. Jeśli wersja w pliku deskryptora aktualizacji nie jest zgodna z wersją pliku AIR aktualizacji, architektura aktualizacji wygeneruje wyjątek. • url — lokalizacja pliku AIR aktualizacji. Jest to plik zawierający zaktualizowaną wersję aplikacji AIR. • description — opis nowej wersji. Te informacje mogą być wyświetlane dla użytkownika podczas aktualizacji. Elementy version i url są wymagane. Element description jest opcjonalny. Oto przykładowy plik deskryptora aktualizacji: <?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> Aby zdefiniować znacznik description w wielu językach, należy zastosować wiele elementów text definiujących atrybut 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> Umieszczamy plik deskryptora aktualizacji wraz z plikiem AIR aktualizacji na serwerze WWW. Katalog templates dołączony do deskryptora aktualizacji zawiera przykładowe pliki deskryptorów aktualizacji. Zawierają one wersje w jednym języku oraz wersje wielojęzyczne. Tworzenie instancji klasy Updater Po załadowaniu architektury aktualizacji AIR w kodzie (patrz „Konfigurowanie środowiska programistycznego Flex” na stronie 336 i „Uwzględnianie plików architektury w aplikacji AIR opartej na kodzie HTML” na stronie 336) konieczne jest utworzenie instancji klasy Updater, co ilustruje poniższy przykład: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 339 Aktualizowanie aplikacji AIR var appUpdater:ApplicationUpdater = new ApplicationUpdater(); W powyższym kodzie zastosowano klasę ApplicationUpdater (która nie udostępnia interfejsu użytkownika). Oto kod, w którym zastosowano klasę ApplicationUpdaterUI (z interfejsem użytkownika): var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI(); W przykładach kodu zamieszczonych w dalszej części tego dokumentu przyjęto założenie, że został utworzony obiekt Updater o nazwie appUpdater. Konfigurowanie ustawień aktualizacji Zarówno klasę ApplicationUpdater, jak i klasę ApplicationUpdaterUI można skonfigurować za pośrednictwem pliku konfiguracji dostarczonego z aplikacją lub za pomocą kodu ActionScript bądź JavaScript w aplikacji. Definiowanie ustawień aktualizacji w pliku konfiguracyjnym XML Plik konfiguracyjny aktualizacji jest plikiem XML. Może zawierać następujące elementy: • updateURL — ciąg znaków (String). Reprezentuje lokalizację deskryptora aktualizacji na serwerze zdalnym. Dozwolone są wszelkie poprawne lokalizacje URLRequest. Właściwość updateURL musi być zdefiniowana — albo w pliku konfiguracyjnym, albo za pomocą skryptu (patrz „Definiowanie pliku deskryptora aktualizacji i dodawanie pliku AIR na serwer WWW” na stronie 338). Właściwość tę należy zdefiniować przed użyciem obiektu Updater (przed wywołaniem metody initialize() obiektu Updater, co opisano w sekcji „Inicjowanie architektury aktualizacji” na stronie 341). • delay — liczba (Number). Reprezentuje interwał (w dniach, dozwolone są wartości ułamkowe, takie jak 0.25) sprawdzania dostępności aktualizacji. Wartość 0 (domyślna) określa, że obiekt Updater nie będzie okresowo automatycznie sprawdzał dostępności aktualizacji. Plik konfiguracyjny dla klasy ApplicationUpdaterUI może, oprócz elementów updateURL i delay, zawierać następujący element: • defaultUI: lista elementów dialog. Każdy element dialog ma atrybut name odpowiadający oknu dialogowemu w interfejsie użytkownika. Każdy element dialog ma atrybut visible określający, czy okno dialogowe jest widoczne. Wartością domyślną jest true. Oto możliwe wartości atrybutu name: • "checkForUpdate" — odpowiada oknom dialogowym Sprawdź dostępność aktualizacji, Brak aktualizacji i Błąd aktualizacji. • • "downloadUpdate" — odpowiada oknu dialogowemu Pobierz aktualizację. • "downloadProgress" — odpowiada oknom dialogowym Postęp pobierania i Błąd pobierania. • "installUpdate" — odpowiada oknu dialogowemu Zainstaluj aktualizację. • "fileUpdate" — odpowiada oknom dialogowym Aktualizacja pliku, Plik nie jest aktualizacją i Błąd pliku. "unexpectedError" — odpowiada oknu dialogowemu Nieoczekiwany błąd. Ustawienie wartości false powoduje, że odpowiednie okna dialogowe nie będą pojawiać się w trakcie procedury aktualizacji. Oto przykładowy plik konfiguracyjny dla architektury 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> TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 340 Aktualizowanie aplikacji AIR Oto przykładowy plik konfiguracyjny dla architektury ApplicationUpdaterUI zawierający definicję elementów defaultUI: <?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> Właściwość configurationFile powinna wskazywać na lokalizację tego pliku, tak jak w poniższym kodzie: • ActionScript: appUpdater.configurationFile = new File("app:/cfg/updateConfig.xml"); • JavaScript: appUpdater.configurationFile = new air.File("app:/cfg/updateConfig.xml"); Katalog templates architektury aktualizacji zawiera przykładowy plik konfiguracyjny o nazwie config-template.xml. Definiowanie ustawień aktualizacji za pomocą kodu ActionScript lub JavaScript Te same parametry konfiguracyjne można ustawić za pośrednictwem kodu aplikacji, tak jak w poniższym przykładzie: appUpdater.updateURL = " http://example.com/updates/update.xml"; appUpdater.delay = 1; Obiekt Updater ma właściwości updateURL i delay. Właściwości te opisują te same ustawienia, co elementy updateURL i delay w pliku konfiguracyjnym: adres URL pliku deskryptora aktualizacji i interwał sprawdzania dostępności aktualizacji. W wypadku określenia ustawień w pliku konfiguracyjnym i w kodzie wszelkie właściwości ustawione w kodzie przesłaniają odpowiednie ustawienia w pliku. Właściwość updateURL musi być zdefiniowana — albo w pliku konfiguracyjnym, albo za pomocą skryptu (patrz „Definiowanie pliku deskryptora aktualizacji i dodawanie pliku AIR na serwer WWW” na stronie 338) — przed użyciem obiektu Updater (przed wywołaniem metody initialize() obiektu Updater, co opisano w sekcji „Inicjowanie architektury aktualizacji” na stronie 341). W architekturze ApplicationUpdaterUI zdefiniowane są następujące dodatkowe właściwości obiektu Updater: • isCheckForUpdateVisible — odpowiada oknom dialogowym Sprawdź dostępność aktualizacji, Brak aktualizacji i Błąd aktualizacji. • isDownloadUpdateVisible — odpowiada oknu dialogowemu Pobierz aktualizację. • isDownloadProgressVisible — odpowiada oknom dialogowym Postęp pobierania i Błąd pobierania. • isInstallUpdateVisible — odpowiada oknu dialogowemu Zainstaluj aktualizację. • isFileUpdateVisible — odpowiada oknom dialogowym Aktualizacja pliku, Plik nie jest aktualizacją i Błąd pliku. • isUnexpectedErrorVisible — odpowiada oknu dialogowemu Nieoczekiwany błąd. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 341 Aktualizowanie aplikacji AIR Każda z właściwości odpowiada jednemu lub większej liczbie okien dialogowych w interfejsie użytkownika architektury ApplicationUpdaterUI. Wszystkie właściwości są typu Boolean i mają wartość domyślną true. Ustawienie wartości false powoduje, że odpowiednie okna dialogowe nie będą pojawiać się w trakcie procedury aktualizacji. Właściwości okien dialogowych przesłaniają ustawienia w pliku konfiguracyjnym aktualizacji. Proces aktualizacji Architektura aktualizacji AIR realizuje proces aktualizacji w następujących krokach: 1 Procedura inicjowania obiektu Updater sprawdza, czy w zdefiniowanym okresie dokonano już sprawdzenia dostępności aktualizacji (patrz „Konfigurowanie ustawień aktualizacji” na stronie 339). Jeśli przypada termin aktualizacji, proces aktualizacji jest kontynuowany. 2 Obiekt Updater pobiera i interpretuje plik deskryptora aktualizacji. 3 Obiekt Updater pobiera plik AIR aktualizacji. 4 Obiekt Updater instaluje zaktualizowaną wersję aplikacji. Obiekt Updater wywołuje zdarzenia po zakończeniu każdego z tych kroków. W architekturze ApplicationUpdater możliwe jest anulowanie zdarzeń wskazujących na pomyślne zakończenie kroków procesu. W wypadku anulowania jednego z takich zdarzeń anulowany zostanie następny krok procesu. W architekturze ApplicationUpdaterUI obiekt Updater wyświetla okno dialogowe umożliwiające użytkownikowi anulowanie lub wykonanie każdego z kroków procesu. W wypadku anulowania zdarzenia możliwe jest wznowienie procesu poprzez wywołanie metod obiektu Updater. W miarę, jak obiekt Updater w wersji ApplicationUpdater realizuje kolejne etapy aktualizacji, jego bieżący stan jest zapisywany we właściwości currentState. Tej właściwości przypisywany jest ciąg znaków o jednej z następujących możliwych wartości: • "UNINITIALIZED" — obiekt Updater nie został zainicjowany. • "INITIALIZING" — trwa inicjowanie obiektu Updater. • "READY" — obiekt Updater został zainicjowany. • "BEFORE_CHECKING" — obiekt Updater nie sprawdził jeszcze, czy istnieje plik deskryptora aktualizacji. • "CHECKING" — obiekt Updater sprawdza, czy istnieje plik deskryptora aktualizacji. • "AVAILABLE" — plik deskryptora jest dostępny dla obiektu Updater. • "DOWNLOADING" — obiekt Updater pobiera plik AIR. • "DOWNLOADED" — obiekt Updater pobrał plik AIR. • "INSTALLING" — obiekt Updater instaluje plik AIR. • "PENDING_INSTALLING" — obiekt Updater jest zainicjowany i istnieją oczekujące aktualizacje. Niektóre metody obiektu Updater są wykonywane tylko wtedy, gdy obiekt ten jest w określonym stanie. Inicjowanie architektury aktualizacji Po ustawieniu właściwości konfiguracyjnych (patrz „Prosty przykład: korzystanie z wersji ApplicationUpdaterUI” na stronie 336) należy wywołać metodę initialize() w celu zainicjowania aktualizacji: appUpdater.initialize(); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 342 Aktualizowanie aplikacji AIR Metoda ta wykonuje następujące operacje: • Inicjuje architekturę aktualizacji, przeprowadzając cichą instalację wszelkich oczekujących aktualizacji. Wymagane jest wywołanie tej metody podczas uruchamiania aplikacji, ponieważ może ona wymusić ponowne uruchomienie aplikacji. • Sprawdza, czy istnieje oczekująca (odłożona w czasie) aktualizacja, a jeśli tak, instaluje ją. • Jeśli w procesie aktualizacji wystąpi błąd, metoda usuwa informacje o pliku aktualizacji i o wersji z obszaru pamięci aplikacji. • Jeśli minął okres opóźnienia, rozpoczyna proces aktualizacji. W przeciwnym razie ponownie uruchamia licznik czasu. Wywołanie tej metody może spowodować, że obiekt Updater wywoła następujące zdarzenia: • UpdateEvent.INITIALIZED — wywoływane po zakończeniu inicjowania. • ErrorEvent.ERROR — wywoływane, jeśli w trakcie inicjowania wystąpi błąd. Po wywołaniu zdarzenia UpdateEvent.INITIALIZED proces aktualizacji jest ukończony. Wywołanie metody initialize() powoduje, że obiekt Updater rozpoczyna proces aktualizacji i wykonuje wszystkie kroki z uwzględnieniem ustawionego opóźnienia. Możliwe jest jednak także rozpoczęcie procesu aktualizacji w dowolnej chwili, poprzez wywołanie metody checkNow() obiektu Updater: appUpdater.checkNow(); Jeśli proces aktualizacji już trwa, ta metoda nie wykonuje żadnych czynności. W przeciwnym razie rozpoczyna proces aktualizacji. Obiekt Updater może wywoływać następujące zdarzenie w wyniku wywołania metody checkNow(): • zdarzenie UpdateEvent.CHECK_FOR_UPDATE tuż przed próbą pobrania pliku deskryptora aktualizacji. Jeśli zdarzenie checkForUpdate zostanie anulowane, można wywołać metodę checkForUpdate() obiektu Updater. (Patrz następna sekcja). Jeśli zdarzenie nie zostanie anulowane, proces aktualizacji przechodzi do etapu sprawdzania, czy istnieje plik deskryptora aktualizacji. Zarządzanie procesem aktualizacji w wersji ApplicationUpdaterUI W wersji ApplicationUpdaterUI użytkownik może anulować proces za pomocą przycisków Anuluj w oknach dialogowych interfejsu użytkownika. Możliwe jest także programowe anulowanie procesu aktualizacji poprzez wywołanie metody cancelUpdate() obiektu ApplicationUpdaterUI. W celu określenia, które okna dialogowe potwierdzeń mają być wyświetlane przez obiekt Updater, można ustawić właściwości obiektu ApplicationUpdaterUI lub zdefiniować elementy pliku konfiguracyjnego aplikacji. Szczegółowe informacje zawiera sekcja „Konfigurowanie ustawień aktualizacji” na stronie 339. Zarządzanie procesem aktualizacji w wersji ApplicationUpdater Możliwe jest wywoływanie metody preventDefault() obiektów zdarzeń wywoływanych przez obiekt ApplicationUpdater w celu anulowania odpowiednich kroków procesu aktualizacji (patrz „Proces aktualizacji” na stronie 341). Anulowanie domyślnego zachowania stwarza aplikacji możliwość wyświetlenia komunikatu z pytaniem, czy użytkownik chce kontynuować. W dalszych sekcjach opisano sposób kontynuacji procesu aktualizacji w wypadku anulowania jednego z kroków procesu. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 343 Aktualizowanie aplikacji AIR Pobieranie i interpretowanie pliku deskryptora aktualizacji Obiekt ApplicationUpdater wywołuje zdarzenie checkForUpdate przed rozpoczęciem procesu aktualizacji, tuż przed próbą pobrania pliku deskryptora aktualizacji. Jeśli domyślne zachowanie zdarzenia checkForUpdate zostanie anulowane, obiekt Updater nie pobierze pliku deskryptora aktualizacji. Można wywołać metodę checkForUpdate() i tym samym wznowić proces aktualizacji: appUpdater.checkForUpdate(); Wywołanie metody checkForUpdate() powoduje, że obiekt Updater asynchronicznie pobierze i zinterpretuje plik deskryptora. W wyniku wywołania metody checkForUpdate() obiekt Updater może wywołać następujące zdarzenia: • StatusUpdateEvent.UPDATE_STATUS — obiekt Updater pomyślnie pobrał i zinterpretował plik deskryptora aktualizacji. To zdarzenie ma następujące właściwości: • available — wartość typu Boolean. Ustawiana na true, jeśli dostępna jest wersja aplikacji inna niż bieżąca; false w przeciwnym wypadku (wersje są takie same). • version — ciąg znaków (String). Wersja odczytana z pliku deskryptora aplikacji pliku aktualizacji. • details — tablica (Array). Jeśli nie istnieją zlokalizowane wersje opisu, jako pierwszy element tej tablicy jest zwracany pusty ciąg znaków (""), a jako drugi element zwracany jest opis. Jeśli istnieje wiele wersji opisu (w pliku deskryptora aplikacji), tablica zawiera wiele podtablic. Każda tablica ma dwa elementy: pierwszy jest kodem języka (na przykład "en"), a drugi jest odpowiednim opisem (typu String) w tym języku. Patrz „Definiowanie pliku deskryptora aktualizacji i dodawanie pliku AIR na serwer WWW” na stronie 338. • StatusUpdateErrorEvent.UPDATE_ERROR — wystąpił błąd i obiekt Updater nie mógł pobrać lub zinterpretować pliku deskryptora aktualizacji. Pobieranie pliku AIR aktualizacji Obiekt ApplicationUpdater wywołuje zdarzenie updateStatus po tym, jak pomyślnie pobierze i zinterpretuje plik deskryptora aktualizacji. Zachowanie domyślne polega na rozpoczęciu pobierania pliku aktualizacji, o ile jest on dostępny. Jeśli zachowanie domyślne zostanie anulowane, można wywołać metodę downloadUpdate() w celu wznowienia procesu aktualizacji. appUpdater.downloadUpdate(); Wywołanie tej metody powoduje, że obiekt Updater rozpocznie asynchroniczne pobieranie pliku AIR aktualizacji. Metoda downloadUpdate() może wywoływać następujące zdarzenia: • UpdateEvent.DOWNLOAD_START — zostało nawiązane połączenie z serwerem. W przypadku użycia biblioteki ApplicationUpdaterUI to zdarzenie powoduje wyświetlenie okna dialogowego z paskiem postępu pobierania. • ProgressEvent.PROGRESS — wywoływane okresowo w trakcie pobierania pliku. • DownloadErrorEvent.DOWNLOAD_ERROR — wywoływane, jeśli podczas nawiązywania połączenia lub pobierania pliku aktualizacji wystąpi błąd. To zdarzenie jest także wywoływane w wypadku odebrania niepoprawnego statusu HTTP (np. „404 - nie znaleziono pliku”). To zdarzenie ma właściwość errorID — liczbę całkowitą, która stanowi dodatkową informację o błędzie. Dodatkowa właściwość subErrorID może zawierać dalsze informacje o błędzie. • UpdateEvent.DOWNLOAD_COMPLETE — obiekt Updater pomyślnie pobrał i zinterpretował plik deskryptora aktualizacji. Jeśli to zdarzenie nie zostanie anulowane, w wersji ApplicationUpdater nastąpi przejście do instalacji aktualizacji. W wersji ApplicationUpdaterUI zostanie wyświetlone okno dialogowe z opcją kontynuacji. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 344 Aktualizowanie aplikacji AIR Aktualizowanie aplikacji Obiekt ApplicationUpdater wywołuje zdarzenie downloadComplete po zakończeniu pobierania pliku aktualizacji. Jeśli zachowanie domyślne zostanie anulowane, można wywołać metodę installUpdate() w celu wznowienia procesu aktualizacji. appUpdater.installUpdate(file); Wywołanie tej metody powoduje, że obiekt Updater zainstaluje plik AIR aktualizacji. Metoda ma jeden parametr, file, który jest obiektem File wskazującym plik AIR aktualizacji. Obiekt ApplicationUpdater może wywołać zdarzenie beforeInstall w wyniku wywołania metody installUpdate(): • UpdateEvent.BEFORE_INSTALL — wywoływane tuż przed zainstalowaniem aktualizacji. Niekiedy celowe jest zablokowanie instalacji aktualizacji, aby użytkownik mógł dokończyć bieżące zadania przed jej rozpoczęciem. Metoda preventDefault() obiektu Event odracza instalację do następnego uruchomienia i uniemożliwia rozpoczęcie następnego procesu aktualizacji. (Dotyczy to także aktualizacji, które byłyby wynikiem wywołania metody checkNow() lub okresowego sprawdzania dostępności). Instalowanie z arbitralnie wybranego pliku AIR Istnieje możliwość wywołania metody installFromAIRFile() w celu zainstalowania zaktualizowanej wersji aplikacji z pliku AIR na komputerze użytkownika: appUpdater.installFromAIRFile(); Metoda ta powoduje, że obiekt Updater instaluje aktualizację aplikacji z pliku AIR. Metoda installFromAIRFile() może wywoływać następujące zdarzenia: • StatusFileUpdateEvent.FILE_UPDATE_STATUS — wywoływane po tym, jak obiekt ApplicationUpdater pomyślnie sprawdzi poprawność pliku przy użyciu metody installFromAIRFile(). To zdarzenie ma następujące właściwości: • available — ustawiana na true, jeśli dostępna jest wersja aplikacji inna niż bieżąca; false w przeciwnym wypadku (wersje są takie same). • version —ciąg znaków reprezentujący nową dostępną wersję. • path — rodzima ścieżka pliku aktualizacji. Można anulować to zdarzenie, jeśli właściwość available obiektu StatusFileUpdateEvent jest ustawiona na true. Anulowanie zdarzenia powoduje anulowanie aktualizacji. Aby kontynuować anulowaną aktualizację, należy wywołać metodę installUpdate(). • StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR — wystąpił błąd, a obiekt Updater nie mógł zainstalować aplikacji AIR. Anulowanie procesu aktualizacji Metoda cancelUpdate() umożliwia anulowanie procesu aktualizacji: appUpdater.cancelUpdate(); Metoda ta anuluje wszystkie oczekujące operacje pobierania, usuwa wszystkie nie w pełni pobrane pliki i ponownie uruchamia zegar odliczający interwał między sprawdzeniami dostępności aktualizacji. Metoda nie wykonuje żadnych czynności, jeśli trwa inicjowanie obiektu Updater. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 345 Aktualizowanie aplikacji AIR Lokalizowanie interfejsu ApplicationUpdaterUI Klasa ApplicationUpdaterUI udostępnia domyślny interfejs użytkownika procesu aktualizacji. W jego skład wchodzą okna dialogowe umożliwiające rozpoczęcie procesu, anulowanie procesu i wykonywanie innych pokrewnych czynności. Element description pliku deskryptora aktualizacji umożliwia zdefiniowanie opisu aplikacji w wielu językach. Należy w tym celu użyć wielu elementów text definiujących atrybuty lang, co zilustrowano poniżej: <?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> Architektura aktualizacji wybiera opis najlepiej dopasowany do łańcucha lokalizacji użytkownika końcowego. Więcej informacji zawiera sekcja Definiowanie pliku deskryptora aktualizacji i dodawanie pliku AIR na serwer WWW. Programiści korzystający ze środowiska Flex mogą bezpośrednio dodawać nowe języki do pakunku "ApplicationUpdaterDialogs". W języku JavaScript można wywoływać metodę addResources() obiektu Updater. Ta metoda dynamicznie dodaje nowy pakunek zasobów dla języka. Pakunek zasobów definiuje zlokalizowane ciągi znaków w danym języku. Ciągi te są używane w polach tekstowych okien dialogowych. W języku JavaScript można skorzystać z właściwości localeChain klasy ApplicationUpdaterUI w celu zdefiniowania łańcucha ustawień narodowych używanego w interfejsie użytkownika. Zazwyczaj z właściwości tej korzystają tylko programiści posługujący się językiem JavaScript (HTML). W środowisku Flex do zarządzania łańcuchem ustawień narodowych można używać menedżera zasobów. Poniższy przykładowy kod w języku JavaScript definiuje pakunki zasobów dla języka rumuńskiego i węgierskiego: 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; Szczegółowe informacje zawiera opis metody addResources() klasy ApplicationUpdaterUI w skorowidzu języka. 346 Rozdział 34: Lokalizowanie aplikacji AIR Środowisko Adobe® AIR™ 1.1 udostępnia funkcje obsługi dla wielu języków. Wprowadzenie do lokalizowania Lokalizowanie to proces dołączania zasobów w celu obsługi wielu ustawień narodowych. Ustawienia narodowe to kombinacja języka i kodu kraju. Na przykład: en_US dotyczy języka angielskiego używanego w USA, a fr_FR dotyczy języka francuskiego używanego we Francji. W celu zlokalizowania aplikacji dla tych ustawień narodowych należy udostępnić dwa zestawy zasobów: jeden dla ustawień narodowych en_US i jeden dla ustawień narodowych fr_FR. Dla różnych ustawień narodowych mogą występować wspólne języki. Przykład: en_US i en_GB (Wielka Brytania) to różne ustawienia narodowe. W tym przypadku w obydwu ustawieniach narodowych używany jest język angielski, jednak kody krajów wskazują, że są to różne ustawienia narodowe, a więc mogą zawierać różne zasoby. Na przykład: nazwa aplikacji zgodnie z ustawieniami narodowymi en_US może zawierać słowo „color”, a w ustawieniach narodowych en_GB może być to słowo „colour”. Ponadto jednostki walut są reprezentowane w dolarach lub funtach w zależności od ustawień narodowych — inny może być również format daty i godziny. Możliwe jest również udostępnienie zestawu zasobów bez konieczności określania kodu kraju. Na przykład: można udostępnić zasoby en dla języka angielskiego, a także udostępnić zasoby dodatkowe dla ustawień narodowych en_US właściwych dla języka angielskiego używanego w USA. Pakiet SDK AIR udostępnia strukturę lokalizowania HTML (zawarta w pliku AIRLocalizer.js). Struktura udostępnia interfejsy API, które ułatwiają pracę z wieloma ustawieniami narodowymi. Szczegółowe informacje zawiera sekcja „Lokalizowanie treści HTML” na stronie 347. Lokalizowanie to znacznie więcej niż tłumaczenie ciągów znaków używanych w aplikacji. Ten proces obejmuje wszystkie typy zasobów, takie jak pliki audio, obrazy i pliki wideo. Lokalizowanie nazwy i opisu aplikacji w instalatorze aplikacji Elementy name i description w pliku deskryptora aplikacji można określić w wielu językach. Przykład: poniżej przedstawiono nazwę aplikacji w trzech językach (angielskim, francuskim i niemieckim): <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> Atrybut xml:lang dla każdego elementu tekstowego określa kod języka zdefiniowany w dokumencie RFC4646 (http://www.ietf.org/rfc/rfc4646.txt). Element name definiuje nazwę aplikacji, którą wyświetla instalator aplikacji AIR. Instalator aplikacji AIR korzysta ze zlokalizowanej wartości, która najlepiej pasuje do języków interfejsu użytkownika zdefiniowanych przez ustawienia systemu operacyjnego. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 347 Lokalizowanie aplikacji AIR W pliku deskryptora aplikacji można również określić wiele wersji językowych elementu description. Ten element zawiera tekst opisu, który wyświetla instalator aplikacji AIR. Te ustawienia mają zastosowanie tylko do języków dostępnych w instalatorze aplikacji AIR. Nie definiują ustawień narodowych dostępnych dla działających, zainstalowanych aplikacji. Aplikacje AIR mogą udostępniać interfejsy obsługujące wiele języków, łącznie z dostępnymi w instalatorze aplikacji AIR. Więcej informacji zawiera sekcja „Definiowanie właściwości w pliku deskryptora aplikacji” na stronie 46. Wybieranie ustawień narodowych W celu określenia ustawień narodowych, z których korzysta aplikacja, można użyć jednej z poniższych metod: • Monit — aplikację można uruchomić z domyślnymi ustawieniami narodowymi, a następnie można poprosić użytkownika, aby wybrał preferowane ustawienia narodowe. • Capabilities.languages — właściwość Capabilities.languages zawiera tablicę języków dostępnych jako preferowane języki użytkownika, ustawione za pomocą systemu operacyjnego. Ciągi znaków zawierają znaczniki języka (a w razie potrzeby także informacje o skrypcie i informacje regionalne) zdefiniowane w dokumencie RFC4646 (http://www.ietf.org/rfc/rfc4646.txt). W ciągach znaków w roli ograniczników używane są myślniki (na przykład: "en-US" lub "ja-JP"). Pierwsza pozycja w zwróconej tablicy ma taki sam identyfikator języka podstawowego, jak właściwość language. Na przykład: jeśli languages[0] ma wartość "en-US", wówczas właściwość language ma wartość "en". Jeśli jednak właściwość language ma wartość "xu" (język nieznany), wówczas pierwszy element w tablicy languages będzie inny. • Capabilities.language — właściwość Capabilities.language udostępnia kod języka interfejsu użytkownika systemu operacyjnego. Jednak ta właściwość jest ograniczona do 20 znanych języków. Ponadto w systemach w języku angielskim ta właściwość zwraca tylko kod języka, a nie kod kraju. Z tego względu lepiej jest używać pierwszego elementu z tablicy Capabilities.languages. Lokalizowanie treści Flash Składniki ActionScript 3.0 programu Flash CS 3 i Flash CS4 zawierają klasę Locale. Klasa Locale umożliwia kontrolowanie wyświetlania tekstu wielojęzycznego w pliku SWF. W panelu Ciągi Flash można używać identyfikatorów ciągów znaków zamiast literałów ciągów w polach tekstu dynamicznego. Dzięki temu możliwe jest utworzenie pliku SWF, który będzie wyświetlał tekst załadowany z pliku XML właściwego dla języka. Informacje na temat korzystania z klasy Locale Flash zawiera Skorowidz języka i składników ActionScript 3.0. Lokalizowanie treści HTML Pakiet SDK AIR 1.1 zawiera strukturę lokalizowania HTML. Strukturę definiuje plik JavaScript AIRLocalizer.js. Katalog frameworks directory pakietu SDK AIR zawiera plik AIRLocalizer.js. Ten plik zawiera klasę air.Localizer, która udostępnia funkcje ułatwiające tworzenie aplikacji, które obsługują wiele zlokalizowanych wersji. Ładowanie kodu struktury lokalizowania HTML W celu użycia struktury lokalizowania należy skopiować do projektu plik AIRLocalizer.js. Następnie należy dołączyć go do głównego pliku HTML aplikacji, stosując znacznik script: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 348 Lokalizowanie aplikacji AIR <script src="AIRLocalizer.js" type="text/javascript" charset="utf-8"></script> Następnie kod JavaScript może wywołać obiekt air.Localizer.localizer: <script> var localizer = air.Localizer.localizer; </script> Obiekt air.Localizer.localizer jest obiektem singletonowym, który definiuje metody i właściwości przeznaczone do korzystania ze zlokalizowanych zasobów i zarządzania nimi. Klasa Localizer zawiera następujące metody: Metoda Opis getFile() Pobiera tekst określonego pakunku zasobów dla wybranych ustawień narodowych. Patrz „Pobieranie zasobów dla określonych ustawień narodowych.” na stronie 354. getLocaleChain() Zwraca języki do łańcucha ustawień narodowych. Patrz „Definiowanie łańcucha ustawień narodowych” na stronie 353. getResourceBundle() Zwraca klucze pakunku oraz odpowiednie wartości jako obiekt. Patrz „Pobieranie zasobów dla określonych ustawień narodowych.” na stronie 354. getString() Pobiera ciąg znaków zdefiniowany dla zasobu. Patrz „Pobieranie zasobów dla określonych ustawień narodowych.” na stronie 354. setBundlesDirectory( ) Ustawia lokalizację katalogu bundles. Patrz „Dostosowywanie ustawień obiektu Localizer HTML AIR” na stronie 352. setLocalAttributePre fix() Ustawia przedrostek używany przez atrybuty obiektu Localizer używane w elementach HTML DOM. Patrz „Dostosowywanie ustawień obiektu Localizer HTML AIR” na stronie 352. setLocaleChain() Ustawia kolejność języków w łańcuchu ustawień narodowych. Patrz „Definiowanie łańcucha ustawień narodowych” na stronie 353. sortLanguagesByPrefe rence() Sortuje ustawienia narodowe w łańcuchu tych ustawień na podstawie ich kolejności zdefiniowanej w systemie operacyjnym. Patrz „Definiowanie łańcucha ustawień narodowych” na stronie 353. update() Aktualizuje HTML DOM (lub element DOM) z uwzględnieniem zlokalizowanych ciągów znaków dla bieżącego łańcucha ustawień narodowych. Opis łańcuchów ustawień narodowych zawiera sekcja „Zarządzanie łańcuchami ustawień narodowych” na stronie 349. Więcej informacji o metodzie update() zawiera sekcja „Aktualizowanie elementów DOM w celu użycia bieżących ustawień narodowych” na stronie 351. Klasa Localizer zawiera następujące właściwości statyczne: Właściwość Opis localizer Zwraca odwołanie do obiektu singletonowego Localizer dla aplikacji. ultimateFallbackLocale Ustawienia narodowe używane wówczas, gdy aplikacja nie obsługuje preferencji użytkownika. Patrz „Definiowanie łańcucha ustawień narodowych” na stronie 353. Definiowanie pakunków zasobów Struktura lokalizowania HTML odczytuje zlokalizowane wersje ciągów znaków z plików lokalizacji. Plik lokalizacji jest kolekcją wartości opartych na kluczu, serializowanych w pliku tekstowym. Plik lokalizacji jest czasami określany jako pakunek. Należy utworzyć podkatalog katalogu projektu aplikacji, o nazwie locale. (Można użyć innej nazwy, patrz „Dostosowywanie ustawień obiektu Localizer HTML AIR” na stronie 352). Ten katalog będzie zawierał pliki lokalizacji. Ten katalog jest określany jako katalog bundles. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 349 Lokalizowanie aplikacji AIR Dla każdego ustawienia narodowego obsługiwanego przez aplikację należy utworzyć podkatalog katalogu bundles. Każdy podkatalog należy nazwać zgodnie z kodem ustawień narodowych. Na przykład: katalog języka francuskiego powinien mieć nazwę „fr”, a katalog języka angielskiego nazwę „en”. W celu zdefiniowania ustawień narodowych z kodem języka i kraju można użyć znaku podkreślenia (_). Np. katalog języka angielskiego dla USA powinien mieć nazwę „en_us”. (Zamiast znaku podkreślenia można użyć kreski, np. „en-us”. Struktura lokalizowania HTML obsługuje obydwa te znaki). Do podkatalogu ustawień narodowych można dodać dowolną liczbę plików zasobów. Zwykle plik lokalizacji jest tworzony dla każdego języka (plik należy umieścić w katalogu dla tego języka). Struktura lokalizowania HTML zawiera metodę getFile(), która umożliwia odczyt treści pliku (patrz „Pobieranie zasobów dla określonych ustawień narodowych.” na stronie 354. Pliki z rozszerzeniem .properties są plikami właściwości lokalizacji. W tych plikach można zdefiniować wartości kluczwartość dla ustawień narodowych. Plik właściwości definiuje jedną wartość ciągu znaków w każdej linii. Przykład: poniższy kod definiuje ciąg znaków "Hello in English." dla klucza o nazwie greeting: greeting=Hello in English. Plik właściwości definiujący poniższy tekst definiuje sześć par klucz-wartość: title=Sample Application greeting=Hello in English. exitMessage=Thank you for using the application. color1=Red color2=Green color3=Blue Ten przykład prezentuje angielską wersję pliku właściwości, który może być zapisany w katalogu en. Francuska wersja pliku właściwości zostanie umieszczona w katalogu fr: title=Application Example greeting=Bonjour en français. exitMessage=Merci d'avoir utilisé cette application. color1=Rouge color2=Vert color3=Bleu Dla różnych typów informacji można zdefiniować wiele plików zasobów. Na przykład: plik legal.properties może zawierać szablon tekstu prawnego (np. informacje o prawach autorskich). Ten zasób może zostać wykorzystany wielokrotnie w wielu aplikacjach. I podobnie — możliwe jest zdefiniowanie osobnych plików, które będą lokalizowały treść dla różnych części interfejsu użytkownika. W celu zapewnienia obsługi wielu języków należy dla tych plików stosować kodowanie UTF-8. Zarządzanie łańcuchami ustawień narodowych Gdy aplikacja ładuje plik AIRLocalizer.js, sprawdza ustawienia narodowe zdefiniowane w aplikacji. Te ustawienia narodowe odpowiadają podkatalogom katalogu bundles (patrz „Definiowanie pakunków zasobów” na stronie 348). Ta lista dostępnych ustawień narodowych jest znana jako łańcuch ustawień narodowych. Plik AIRLocalizer.js automatycznie sortuje łańcuch ustawień narodowych na podstawie preferowanej kolejności zdefiniowanej w systemie operacyjnym. (Właściwość Capabilities.languages zawiera listę języków interfejsu użytkownika systemu operacyjnego, w preferowanej kolejności). TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 350 Lokalizowanie aplikacji AIR Dlatego jeśli aplikacja zdefiniuje zasoby dla ustawień narodowych „en”, „en_US” i „en_UK”, wówczas struktura obiektu Localizer AIR HTML sortuje odpowiednio łańcuch ustawień narodowych. Gdy aplikacja uruchomi system, który zgłasza „en” jako podstawowe ustawienie narodowe, wówczas łańcuch ustawień narodowych jest sterowany w taki sposób: ["en", "en_US", "en_UK"]. W takim przypadku aplikacja najpierw wyszukuje zasoby w pakunku „en”, a następnie w pakunku „en_US”. Jeśli jednak system zgłasza „en-US” jako podstawowe ustawienie narodowe, wówczas sortowanie jest następujące: ["en_US", "en", en_UK"]. W takim przypadku aplikacja najpierw wyszukuje zasoby w pakunku „en_US”, a następnie w pakunku „en”. Domyślnie aplikacja definiuje pierwsze ustawienie narodowe w łańcuchu lokalizacji jako domyślne ustawienie narodowe do użytku. Użytkownik może wybrać ustawienia narodowe po pierwszym uruchomieniu aplikacji. Następnie możliwe jest zapisanie wybranych ustawień w pliku preferencji i wykorzystanie tych ustawień narodowych przy kolejnym uruchamianiu aplikacji. Aplikacja może korzystać z ciągów zasobów w dowolnych ustawieniach narodowych z łańcucha ustawień narodowych. Jeśli określone ustawienia narodowe nie zdefiniują ciągu znaków zasobu, aplikacja korzysta z kolejnego zgodnego ciągu zasobu dla innych ustawień narodowych zdefiniowanych w łańcuchu tych ustawień. Łańcuch ustawień narodowych można dostosować poprzez wywołanie metody setLocaleChain() obiektu Localizer. Patrz „Definiowanie łańcucha ustawień narodowych” na stronie 353. Aktualizowanie elementów DOM za pomocą treści zlokalizowanej Element aplikacji może odwoływać się do wartości klucza w pliku właściwości lokalizacji. Na przykład: element title w poniższym przykładzie określa atrybut local_innerHTML. Struktura lokalizacji korzysta z tego atrybutu w celu wyszukania zlokalizowanej wartości. Domyślnie struktura wyszukuje nazwy atrybutów, które rozpoczynają się od znaków "local_". Struktura aktualizuje atrybuty z nazwami zgodnymi z tekstem za znakami "local_". W takim przypadku struktura ustawia atrybut innerHTML elementu title. Atrybut innerHTML korzysta z wartości zdefiniowanej dla klucza mainWindowTitle w domyślnym pliku właściwości (default.properties): <title local_innerHTML="default.mainWindowTitle"/> Jeśli bieżące ustawienia narodowe definiują wartość niezgodną, wówczas struktura obiektu Localizer wyszukuje pozostałą część łańcucha ustawień narodowych. Korzysta z następnych ustawień narodowych z łańcucha ustawień, dla którego zdefiniowano wartość. W poniższym przykładzie tekst (atrybut innerHTML) elementu p korzysta z wartości klucza greeting zdefiniowanego w domyślnym pliku właściwości: <p local_innerHTML="default.greeting" /> W poniższym przykładzie atrybut value (i wyświetlony tekst) elementu input korzysta z wartości klucza btnBlue z domyślnego pliku właściwości: <input type="button" local_value="default.btnBlue" /> W celu zaktualizowania modelu DOM HTML w taki sposób, aby korzystał z ciągów znaków zdefiniowanych w bieżącym łańcuchu ustawień narodowych, należy wywołać metodę update() obiektu Localizer. Wywołanie metody update() powoduje, że obiekt Localizer analizuje model DOM i stosuje manipulowanie w miejscach, w których znajdzie atrybuty lokalizacji ("local_..."): air.Localizer.localizer.update(); TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 351 Lokalizowanie aplikacji AIR Możliwe jest zdefiniowanie wartości dla atrybutu (takiego jak „innerHTML”) oraz odpowiadającego mu atrybutu lokalizacji (np. „local_innerHTML”). W takim przypadku struktura lokalizowania zastępuje tylko wartość atrybutu, jeśli znajdzie zgodną wartość w łańcuchu lokalizacji. Przykład: poniższy element definiuje atrybuty value i local_value: <input type="text" value="Blue" local_value="default.btnBlue"/> Możliwe jest również zaktualizowanie wybranego elementu modelu DOM. Informacje zawiera następna sekcja „Aktualizowanie elementów DOM w celu użycia bieżących ustawień narodowych” na stronie 351. Domyślnie obiekt Localizer HTML AIR korzysta z"local_" jako z przedrostka dla atrybutów definiujących ustawienia lokalizacji dla elementu. Na przykład: domyślnie atrybut local_innerHTML definiuje nazwę pakunku i zasobu używaną dla wartości innerHTML elementu. Ponadto domyślnie atrybut local_value definiuje pakunek i nazwę zasobu dla atrybutu value elementu. Możliwe jest takie skonfigurowanie obiektu Localizer, aby korzystał on z przedrostka atrybutu innego niż "local_". Patrz „Dostosowywanie ustawień obiektu Localizer HTML AIR” na stronie 352. Aktualizowanie elementów DOM w celu użycia bieżących ustawień narodowych Gdy obiekt Localizer zaktualizuje model DOM HTML, powoduje, że oznaczone elementy korzystają z wartości atrybutów na podstawie ciągów znaków zdefiniowanych w bieżącym łańcuchu ustawień narodowych. Aby obiekt localizer HTML zaktualizował model DOM HTML, należy wywołać metodę update() obiektu Localizer: air.Localizer.localizer.update(); W celu zaktualizowania tylko określonego elementu DOM należy przekazać ten element jako parametr metody update(). Metoda update() zawiera tylko jeden parametr, parentNode, który jest opcjonalny. Po określeniu parametru parentNode definiuje on element DOM przeznaczony do zlokalizowania. Wywołanie metody update() i określenie parametru parentNode ustawia zlokalizowane wartości jako elementy podrzędne, które określają atrybuty lokalizacji. Przykładem może być poniższy element 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> W celu zaktualizowania elementu do użycia zlokalizowanych ciągów znaków zdefiniowanych w bieżącym łańcuchu ustawień narodowych należy użyć poniższego kodu JavaScript: var divElement = window.document.getElementById("colorsDiv"); air.Localizer.localizer.update(divElement); Jeśli wartość klucza nie zostanie znaleziona w łańcuchu ustawień narodowych, wówczas struktura lokalizacji ustawia wartość atrybutu na wartość atrybutu "local_". Przykład: załóżmy, że w poprzednim przykładzie struktura lokalizowania nie może znaleźć wartości dla klucza lblColors (w żadnym z plików default.properties w łańcuchu ustawień narodowych). W takim przypadku użyje "default.lblColors" jako wartości innerHTML. Użycie tej wartości oznacza (dla programisty) brak zasobów. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 352 Lokalizowanie aplikacji AIR Metoda update() wywołuje zdarzenie resourceNotFound, nawet jeśli nie może znaleźć zasobu w łańcuchu ustawień narodowych. Stała air.Localizer.RESOURCE_NOT_FOUND definiuje ciąg znaków "resourceNotFound". Zdarzenie ma trzy właściwości: bundleName, resourceName i locale. Właściwość bundleName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość resourceName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. Metoda update() wywołuje zdarzenie bundleNotFound, gdy nie może znaleźć określonego pakunku. Stała air.Localizer.BUNDLE_NOT_FOUND definiuje ciąg znaków "bundleNotFound". Zdarzenie ma dwie właściwości: bundleName i locale. Właściwość bundleName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. Metoda update() działa w sposób asynchroniczny (i wywołuje asynchronicznie zdarzenia resourceNotFound i bundleNotFound). Poniższy kod ustawia detektory zdarzeń dla zdarzeń resourceNotFound i 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); } Dostosowywanie ustawień obiektu Localizer HTML AIR Metoda setBundlesDirectory() obiektu Localizer umożliwia dostosowanie ścieżki katalogu bundles. Metoda setLocalAttributePrefix() obiektu Localizer umożliwia dostosowanie ścieżki katalogu bundles oraz dostosowanie wartości atrybutu używanego przez obiekt Localizer. Domyślnie katalog bundles jest zdefiniowany jako podkatalog locale katalogu aplikacji. Za pomocą metody setBundlesDirectory() obiektu Localizer można określić inny katalog. Ta metoda przyjmuje jeden parametr, path, który jest ścieżką żądanego katalogu bundles, w postaci ciągu znaków. Parametr path może mieć jedną z następujących wartości: • Ciąg znaków definiujący ścieżkę względną do katalogu aplikacji, np. "locales" • Ciąg znaków definiujący poprawny adres URL, który korzysta ze schematów app, app-storage lub file URL, takich jak "app://languages" (nie należy używać schematu http URL) • Obiekt File Informacje na temat adresów URL i ścieżek katalogów zawiera sekcja „Ścieżki obiektów File” na stronie 108. Przykład: poniższy kod ustawia katalog bundles jako podkatalog languages katalogu zapisu aplikacji (nie jako katalog aplikacji): air.Localizer.localizer.setBundlesDirectory("languages"); Należy przekazać poprawną ścieżkę jako parametr path. W przeciwnym wypadku metoda zwróci wyjątek BundlePathNotFoundError. Właściwość name tego błędu to"BundlePathNotFoundError", a właściwość message określa niepoprawną ścieżkę. Domyślnie obiekt Localizer HTML AIR korzysta z"local_" jako z przedrostka dla atrybutów definiujących ustawienia lokalizacji dla elementu. Na przykład: atrybut local_innerHTML definiuje nazwę pakunku i nazwę zasobu używaną dla wartości innerHTML poniższego elementu input: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 353 Lokalizowanie aplikacji AIR <p local_innerHTML="default.greeting" /> Metoda setLocalAttributePrefix() obiektu Localizer umożliwia korzystanie z przedrostka atrybutu innego niż "local_". Ta statyczna metoda przyjmuje jeden parametr, który jest ciągiem znaków używanym jako przedrostek atrybutu. Przykład: poniższy kod ustawia strukturę lokalizowania w taki sposób, aby użyć „loc_” jako przedrostka aplikacji: air.Localizer.localizer.setLocalAttributePrefix("loc_"); Istnieje możliwość dostosowania przedrostka atrybutu, z którego korzysta struktura lokalizowania. Możliwe jest dostosowanie przedrostka, jeśli wartość domyślna ("local_") powoduje konflikt z nazwą innego atrybutu używanego w kodzie. Podczas wywoływania tej metody należy stosować poprawne znaki dla atrybutów HTML. (Na przykład: wartość nie może zawierać znaku spacji). Więcej informacji na temat korzystania z atrybutów lokalizacji w elementach HTML zawiera sekcja „Aktualizowanie elementów DOM za pomocą treści zlokalizowanej” na stronie 350. Ustawienia katalogu bundles i przedrostka aplikacji nie są zachowywane między poszczególnymi sesjami aplikacji. Jeśli używany jest niestandardowy katalog bundles lub niestandardowe ustawienie przedrostka atrybutu, należy określić to ustawienie każdorazowo przy inicjowaniu aplikacji. Definiowanie łańcucha ustawień narodowych Domyślnie załadowanie kodu AIRLocalizer.js powoduje ustawienie domyślnego łańcucha ustawień narodowych. Ustawienia narodowe dostępne w katalogu bundles oraz ustawienia języka systemu operacyjnego definiują ten łańcuch ustawień narodowych. (Szczegółowe informacje zawiera sekcja „Zarządzanie łańcuchami ustawień narodowych” na stronie 349). Łańcuch ustawień narodowych można zmodyfikować poprzez wywołanie statycznej metody setLocaleChain() obiektu Localizer. Na przykład: tę metodę można wywołać, jeśli użytkownik preferuje konkretny język. Metoda setLocaleChain() przyjmuje jeden parametr chain, który jest tablicą ustawień narodowych, np. ["fr_FR","fr","fr_CA"]. Kolejność ustawień narodowych w tablicy określa kolejność, w jakiej struktura wyszukuje zasoby (w kolejnych operacjach). Jeśli zasób nie zostanie znaleziony dla pierwszego ustawienia narodowego w łańcuchu, wówczas będzie przeszukiwać zasoby innego ustawienia narodowego. Jeśli argument chain nie jest dostępny, nie jest tablicą lub jest pustą tablicą, wówczas działanie funkcji kończy się niepowodzeniem i następuje wywołanie wyjątku IllegalArgumentsError. Statyczna metoda getLocaleChain() obiektu Localizer zwraca tablicę zawierającą ustawienia narodowe z bieżącego łańcucha ustawień narodowych. Poniższy kod odczytuje bieżący łańcuch ustawień narodowych i dodaje dwa francuskie ustawienia do początku łańcucha: var currentChain = air.Localizer.localizer.getLocaleChain(); newLocales = ["fr_FR", "fr"]; air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain)); Metoda setLocaleChain() wywołuje zdarzenie "change", gdy zakończy aktualizowanie łańcucha ustawień narodowych. Stała air.Localizer.LOCALE_CHANGE definiuje ciąg znaków "change". Zdarzenie ma jedną właściwość localeChain — jest to tablica kodów ustawień narodowych w nowym łańcuchu tych ustawień. Poniższy kod ustawia detektor dla tego zdarzenia: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 354 Lokalizowanie aplikacji 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); } Statyczna właściwość air.Localizer.ultimateFallbackLocale reprezentuje ustawienia narodowe używane wówczas, gdy aplikacja nie obsługuje żadnych preferencji użytkownika. Wartością domyślną jest "en". Można również ustawić inne ustawienia narodowe, co prezentuje poniższy kod: air.Localizer.ultimateFallbackLocale = "fr"; Pobieranie zasobów dla określonych ustawień narodowych. Metoda getString() obiektu Localizer zwraca ciąg znaków zdefiniowany dla zasobów w określonych ustawieniach narodowych. Przy wywołaniu tej metody nie ma potrzeby określania wartości locale. W tym przypadku metoda sprawdza cały łańcuch ustawień narodowych i zwraca ciąg znaków pierwszego ustawienia narodowego, które udostępnia określoną nazwę zasobu. Ta metoda ma następujące parametry: Parametr Opis bundleName Pakunek, który zawiera zasób. Jest to nazwa pliku właściwości bez rozszerzenia .properties. (Na przykład: jeśli ten parametr ma wartość"alerts", kod obiektu Localizer wyszukuje pliki lokalizacji o nazwie alerts.properties. resourceName Nazwa zasobu. templateArgs Opcjonalnie. Tablica ciągów znaków, która zastępuje numerowane znaczniki w ciągu znaków. Przykład: rozważmy wywołanie funkcji, w której parametr templateArgs ma wartość ["Raúl", "4"], a zgodny ciąg znaków zasobu to "Hello, {0}. You have {1} new messages.". W tym przypadku funkcja zwraca "Hello, Raúl. You have 4 new messages.". W celu zignorowania tego ustawienia należy przekazać wartość null. locale Opcjonalnie. Kod ustawień narodowych (np. "en", "en_us" lub "fr") do użycia. Jeśli ustawienia narodowe są określone, ale nie znaleziono zgodnej wartości, metoda nie kontynuuje wyszukiwania wartości w innych ustawieniach narodowych w łańcuchu. Jeśli nie określono kodu ustawień narodowych, funkcja zwraca ciąg znaków z pierwszego ustawienia narodowego z łańcucha, w którym dostępna jest określona nazwa zasobu. Struktura lokalizowania może zaktualizować oznaczone atrybuty modelu DOM HTML. Jednak zlokalizowane ciągi znaków mogą być również używane na inne sposoby. Na przykład: ciąg znaków może być używany w niektórych dynamicznie wygenerowanych kodach HTML lub jako wartość parametru w wywołaniu funkcji. Przykład: poniższy kod wywołuje funkcję alert() z ciągiem znaków zdefiniowanym w zasobie error114 w domyślnym pliku właściwości ustawień narodowych fr_FR: alert(air.Localizer.localizer.getString("default", "error114", null, "fr_FR")); Metoda getString() wywołuje zdarzenie resourceNotFound, jeśli nie może znaleźć zasobu w określonym pakunku. Stała air.Localizer.RESOURCE_NOT_FOUND definiuje ciąg znaków "resourceNotFound". Zdarzenie ma trzy właściwości: bundleName, resourceName i locale. Właściwość bundleName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość resourceName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 355 Lokalizowanie aplikacji AIR Metoda getString() wywołuje zdarzenie bundleNotFound, gdy nie może znaleźć określonego pakunku. Stała air.Localizer.BUNDLE_NOT_FOUND definiuje ciąg znaków "bundleNotFound". Zdarzenie ma dwie właściwości: bundleName i locale. Właściwość bundleName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. Metoda getString() działa asynchronicznie (i wywołuje zdarzenia resourceNotFound i resourceNotFound w sposób asynchroniczny). Poniższy kod ustawia detektory zdarzeń dla zdarzeń resourceNotFound i 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); } Metoda getResourceBundle() obiektu Localizer zwraca określony pakunek dla danego ustawienia narodowego. Wartość zwracana przez metodę jest obiektem z właściwościami zgodnymi z kluczami w pakunku. (Jeśli aplikacja nie może odnaleźć określonego pakunku, metoda zwraca wartość null). Metoda przyjmuje dwa parametry — locale i bundleName. Parametr Opis locale Ustawienie narodowe (np. "fr"). bundleName Nazwa pakunku. Na przykład poniższy kod wywołuje metodę document.write(), aby załadować domyślny pakunek dla ustawienia narodowego „fr”. Następnie wywoływana jest metoda document.write() w celu zapisania wartości kluczy str1 i str2 w tym pakunku: 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/>"); Metoda getResourceBundle() wywołuje zdarzenie bundleNotFound, gdy nie może znaleźć określonego pakunku. Stała air.Localizer.BUNDLE_NOT_FOUND definiuje ciąg znaków "bundleNotFound". Zdarzenie ma dwie właściwości: bundleName i locale. Właściwość bundleName jest nazwą pakunku, w którym nie można znaleźć zasobu. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. Metoda getFile() obiektu Localizer zwraca zawartość pakunku w postaci ciągu znaków dla określonych ustawień narodowych. Plik pakunku jest odczytywany jako plik UTF-8. Metoda zawiera następujące parametry: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 356 Lokalizowanie aplikacji AIR Parametr Opis resourceFileName Nazwa pliku zasobu (np. "about.html"). templateArgs Opcjonalnie. Tablica ciągów znaków, która zastępuje numerowane znaczniki w ciągu znaków. Przykład: rozważmy wywołanie funkcji, w której parametr templateArgs ma wartość ["Raúl", "4"], a zgodny plik zasobu zawiera dwie linie: <html> <body>Hello, {0}. You have {1} new messages.</body> </html> W tym przypadku funkcja zwraca ciąg znaków z dwoma liniami: <html> <body>Hello, Raúl. You have 4 new messages. </body> </html> locale Kod ustawień narodowych (np. "en_GB") do użycia. Jeśli ustawienia narodowe są określone, ale nie znaleziono zgodnego pliku, metoda nie kontynuuje wyszukiwania wartości w innych ustawieniach narodowych w łańcuchu. Jeśli nie określono kodu ustawień narodowych, funkcja zwraca tekst z pierwszego ustawienia narodowego w łańcuchu, który zawiera plik zgodny z wartością resourceFileName. Na przykład: poniższy kod wywołuje metodę document.write() za pomocą treści pliku about.html ustawień narodowych fr: var aboutWin = window.open(); var aboutHtml = localizer.getFile("about.html", null, "fr"); aboutWin.document.close(); aboutWin.document.write(aboutHtml); Metoda getFile() wywołuje zdarzenie fileNotFound, nawet jeśli nie może znaleźć zasobu w łańcuchu ustawień narodowych. Stała air.Localizer.FILE_NOT_FOUND definiuje ciąg znaków "resourceNotFound". Metoda getFile() działa asynchronicznie (i wywołuje zdarzenie fileNotFound w sposób asynchroniczny). Zdarzenie ma dwie właściwości: fileName i locale. Właściwość fileName jest nazwą nieznalezionego pliku. Właściwość locale jest nazwą ustawień narodowych, w których nie można znaleźć zasobu. Poniższy kod ustawia detektor dla tego zdarzenia: 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); } Lokalizowanie walut oraz zapisu daty i godziny Sposób, w jaki aplikacje prezentują daty, godziny i waluty, różni się w zależności od ustawień narodowych. Na przykład: standard USA dla dat określa kolejność miesiąc/dzień/rok, a standard europejski dla dat określa kolejność dzień/miesiąc/rok. Możliwe jest napisanie odpowiedniego kodu w celu formatowania zapisu dat, godzin i walut. Przykład: poniższy kod konwertuje obiekt Date na format miesiąc/dzień/rok lub format dzień/miesiąc/rok. Jeśli zmienna locale (reprezentująca ustawienia narodowe) ma wartość "en_US", funkcja zwraca format miesiąc/dzień/rok. W przykładzie obiekt Date został przekonwertowany na format dzień/miesiąc/rok dla wszystkich innych ustawień narodowych: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 357 Lokalizowanie aplikacji 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(); } } 358 Rozdział 35: Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Narzędzia wiersza poleceń środowiska Adobe® AIR™ umożliwiają testowanie i pakowanie aplikacji Adobe AIR. Te narzędzia mogą być również używane w procesach tworzenia automatycznego. Narzędzia wiersza poleceń są dostępne w pakiecie SDK AIR (http://www.adobe.com/go/learn_air_download_AIRSDK_pl). Korzystanie z programu uruchamiającego ADL (AIR Debug Launcher) Program uruchamiający ADL (AIR Debug Launcher) służy do uruchamiania aplikacji w formacie SWF oraz w formacie HTML podczas programowania. Za pomocą programu ADL można uruchamiać aplikacje bez wcześniejszego pakowania i instalowania. Domyślnie program uruchamiający ADL korzysta ze środowiska wykonawczego dostępnego z SDK, co oznacza, że nie ma konieczności osobnego instalowania środowiska wykonawczego w celu korzystania z ADL. Program ADL wyświetla instrukcje trace oraz błędy środowiska wykonawczego na standardowym wyjściu, ale nie obsługuje punktów zatrzymań ani innych funkcji debugowania. W przypadku złożonego debugowania podczas tworzenia aplikacji w formacie SWF należy korzystać z debugera Flash Debugger (lub Flash CS). Z debugerem Flash Debugger można połączyć się, uruchamiając program debugera przed uruchomieniem aplikacji użytkownika z programem ADL. Uruchamianie aplikacji za pomocą programu uruchamiającego ADL Należy użyć poniższej składni: adl [-runtime runtime-directory] [-pubid publisher-id] [-nodebug] application.xml [rootdirectory] [-- arguments] -runtime runtime-directory Określa katalog zawierający środowisko wykonawcze, jakie będzie używane. Jeśli nie zostanie określony, wówczas katalog środowiska wykonawczego będzie należał do tego samego folderu SDK, z którego używany jest program ADL. Jeśli program uruchamiający ADL zostanie przeniesiony ze swojego folderu SDK, wówczas należy określić katalog środowiska wykonawczego. W systemach Windows i Linux należy określić katalog zawierający katalog Adobe AIR. W systemie Mac OS X należy określić katalog zawierający Adobe AIR.framework. -pubid publisher-id Przypisuje określoną wartość jako identyfikator wydawcy uruchamianej aplikacji AIR. Określenie tymczasowego identyfikatora wydawcy umożliwia testowanie funkcji w aplikacji AIR, np. komunikowanie przez połączenie lokalne, które korzysta z id. wydawcy w celu jednoznacznego zidentyfikowania aplikacji. Ostateczny identyfikator wydawcy jest określany przez certyfikat elektroniczny używany do podpisania pliku instalacyjnego AIR. -nodebug Wyłącza obsługę debugowania. Jeśli ten parametr jest używany, wówczas proces aplikacji nie może się połączyć z debugerem Flash, co powoduje zatrzymanie wyświetlania okien dialogowych z informacjami o nieobsłużonych wyjątkach. (Jednak instrukcje trace nadal są wyświetlane w oknie konsoli). Wyłączenie debugowania umożliwia szybsze działanie aplikacji, a ponadto powoduje wierniejsze emulowanie trybu wykonywania zainstalowanej aplikacji. application.xml Plik deskryptora aplikacji. Patrz „Definiowanie ustawień aplikacji AIR” na stronie 45. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 359 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń root-directory Określa katalog główny aplikacji, która ma być uruchamiana. Jeśli katalog nie jest uruchomiony, zostanie wykorzystany katalog zawierający plik deskryptora aplikacji. -- arguments Wszystkie znaki, jakie pojawią się za znakami „--”, zostaną przekazane do aplikacji jako argumenty wiersza poleceń. Uwaga: Po uruchomieniu aplikacji AIR, która już działa, nie dochodzi do uruchomienia nowej instancji tej aplikacji. Zamiast tego zdarzenie invoke jest wywoływane do działającej aplikacji. Wyświetlanie instrukcji trace W celu wyświetlenia instrukcji trace w konsoli służącej do uruchamiania ADL należy dodać instrukcje trace do kodu za pomocą funkcji trace(): trace("debug message"); air.trace("debug message"); Przykłady ADL Uruchomienie aplikacji w katalogu bieżącym: adl myApp-app.xml Uruchomienie aplikacji w podkatalogu katalogu bieżącego: adl source/myApp-app.xml release Uruchomienie aplikacji i przekazanie dwóch argumentów wiersza poleceń: „tick” i „tock”. adl myApp-app.xml -- tick tock Uruchomienie aplikacji przy użyciu określonego środowiska wykonawczego: adl -runtime /AIRSDK/runtime myApp-app.xml Uruchomienie aplikacji bez obsługi debugowania: adl myApp-app.xml -nodebug Połączenie z debugerem Flash Debugger (FDB) Aby debugować aplikację AIR w formacie SWF za pomocą debugera Flash Debugger, należy uruchomić sesję FDB, a następnie uruchomić wersję debugującą aplikacji. Aplikacja AIR zawierająca wersję debugującą pliku SWF automatycznie połączy się z wykrywającą sesją FDB. Uwaga: Wersja debugująca aplikacji AIR jest wersją, w której główny plik SWF jest kompilowany z flagą -debug. 1 Uruchom program FDB. Program FDB znajduje się w katalogu bin pakietu Flex SDK. Konsola wyświetli monit programu FDB: <fdb> 2 Wykonaj polecenie run: <fdb>run [Enter] 3 W innej konsoli poleceń lub powłoce uruchom wersję aplikacji po debugowaniu: adl myApp.xml 4 Za pomocą poleceń FDB ustaw punkty zatrzymania zgodnie z potrzebami. 5 Wpisz: continue [Enter] Jeśli aplikacja ma format SWF, debuger steruje jedynie wykonaniem kodu ActionScript. Jeśli aplikacja ma format HTML, wówczas debuger steruje jedynie wykonaniem kodu JavaScript. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 360 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Aby uruchomić program ADL bez połączenia z debugerem, należy dołączyć opcję -nodebug: adl myApp.xml -nodebug Aby uzyskać podstawowe informacje na temat poleceń programu FDB, należy wywołać polecenie help: <fdb>help [Enter] Szczegółowe informacje na temat poleceń programu FDB zawiera sekcja Korzystanie z poleceń debugera wiersza poleceń w dokumentacji środowiska Flex. Kody wyjścia i kody błędów w programie ADL Poniższa tabela przedstawia kody wyjścia wyświetlane przez program ADL: Kod wyjścia Opis 0 Pomyślne uruchomienie. Program ADL wyłącza się po wyłączeniu aplikacji AIR. 1 Pomyślne wywołanie działającej aplikacji AIR. Program ADL wyłącza się natychmiast. 2 Błąd składni. Argumenty wprowadzone do ADL są niepoprawne. 3 Nie można znaleźć środowiska wykonawczego. 4 Nie można uruchomić środowiska wykonawczego. Często przyczyną takiej sytuacji jest to, że poziom wersji lub łatki określony w aplikacji nie jest zgodny z poziomem wersji lub łatki środowiska wykonawczego. 5 Błąd z nieznanych przyczyn. 6 Nie można znaleźć pliku deskryptora aplikacji. 7 Zawartość deskryptora aplikacji jest niepoprawna. Ten błąd zwykle wskazuje, że plik XML nie jest poprawnie sformatowany. 8 Nie można znaleźć głównego pliku zawartości aplikacji (określony w elemencie <content> pliku deskryptora aplikacji). 9 Główny plik zawartości aplikacji nie jest poprawnym plikiem SWF lub HTML. Pakowanie pliku instalacyjnego aplikacji AIR za pomocą narzędzia AIR Developer Tool (ADT) Pliki instalacyjne aplikacji AIR w formacie SWF oraz w formacie HTML tworzy się za pomocą narzędzia AIR Developer Tool (ADT). (Jeśli do tworzenia aplikacji służy program Adobe Flash CS3, do stworzenia aplikacji AIR można również użyć polecenia Utwórz plik AIR w menu Polecenia. Więcej informacji zawiera dokument „Aktualizacja środowiska Adobe AIR dla programu Flash CS3 Professional” na stronie 14. Informacje na temat korzystania z programu Flash CS4 do tworzenia aplikacji AIR zawiera sekcja Publikowanie w środowisku Adobe AIR podręcznika Korzystanie z programu Flash) ADT to program Java, który może być uruchamiany z wiersza poleceń lub narzędzia do tworzenia, takiego jak Ant. Pakiety SDK AIR i Flex zawierają skrypty wiersza poleceń wykonujące program w języku Java. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 361 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Pakowanie pliku instalacyjnego aplikacji AIR Każda aplikacja AIR musi zawierać przynamniej plik deskryptora aplikacji oraz główny plik SWF lub HTML. Wszystkie inne instalowane zasoby aplikacji również muszą być spakowane w pliku AIR. Wszystkie pliki instalatora AIR muszą być podpisane certyfikatem elektronicznym. Instalator AIR korzysta z podpisu w celu sprawdzenia, czy po podpisaniu plik aplikacji nie został zmodyfikowany. Użytkownik może użyć certyfikatu podpisującego kod wydanego przez ośrodek certyfikacji lub certyfikatu samopodpisanego. Certyfikat wydany przez zaufany ośrodek certyfikacji stanowi dla użytkowników aplikacji poświadczenie tożsamości wydawcy. Certyfikat samopodpisany może służyć do weryfikowania tożsamości autora podpisu. Ta wada zmniejsza również pewność, że pakiet nie został zmodyfikowany, ponieważ właściwy plik instalacyjny mógł zostać zastąpiony przez falsyfikat, zanim plik dotarł do użytkownika). Plik AIR można spakować i podpisać w jednym kroku, korzystając z polecenia -package narzędzia ADT. Można również utworzyć pośredni, niepodpisany pakiet za pomocą polecenia -prepare, a następnie podpisać go za pomocą polecenia -sign w osobnym kroku. Podczas podpisywania pakietu instalacyjnego narzędzie ADT automatycznie łączy się z serwerem znaczników czasu w celu weryfikacji czasu. Informacje znacznika czasu są dołączone do pliku AIR. Plik AIR, który zawiera zweryfikowany znacznik czasu, może zostać zainstalowany w dowolnym momencie w przyszłości. Jeśli narzędzie ADT nie może nawiązać połączenia z serwerem znaczników czasu, wówczas pakowanie zostaje anulowane. Opcję ustawiania znaczników czasu można anulować, ale bez znacznika czasu zainstalowanie aplikacji AIR będzie niemożliwe po utracie ważności certyfikatu służącego do podpisania pliku instalacyjnego. W przypadku tworzenia pakietu przeznaczonego do aktualizacji istniejącej aplikacji AIR pakiet należy podpisać tym samym certyfikatem, co aplikację oryginalną lub certyfikatem, który ma taką samą tożsamość. Taką samą tożsamość mają dwa certyfikaty, które mają tę samą nazwę wyróżniającą (zawartość wszystkich pól informacji jest zgodna) oraz ten sam łańcuch certyfikatów do certyfikatu głównego. Dlatego możliwe jest używanie odnowionego certyfikatu od ośrodka certyfikacji, pod warunkiem że nie zmieniono żadnych informacji identyfikacyjnych. Od wersji AIR 1.1 możliwa jest migracja aplikacji w celu używania nowego certyfikatu — w tym celu należy użyć polecenia -migrate. Migracja certyfikatu wymaga podpisania pliku AIR nowym i starym certyfikatem. Migracja certyfikatu umożliwia zmianę certyfikatu samopodpisanego na komercyjny certyfikat podpisujący kod, a także zmianę jednego certyfikatu samopodpisanego lub certyfikatu komercyjnego na inny. W przypadku migracji certyfikatu istniejący użytkownicy nie muszą odinstalowywać istniejącej aplikacji przed zainstalowaniem nowej wersji. Podpisy migracji są domyślnie oznaczone znacznikami czasu. Uwaga: Ustawienia pliku deskryptora aplikacji określają tożsamość aplikacji AIR oraz jej domyślną ścieżkę instalacyjną. Patrz „Struktura pliku deskryptora aplikacji” na stronie 45. Pakowanie i podpisywanie pliku AIR w jednym kroku ❖ Należy użyć polecenia -package z następującą składnią (w pojedynczym wierszu polecenia): adt -package SIGNING_OPTIONS air_file app_xml [file_or_dir | -C dir file_or_dir | -e file dir ...] ... SIGNING_OPTIONS Opcje podpisywania identyfikują magazyn kluczy zawierający klucz prywatny oraz certyfikat używany do podpisania pliku AIR. W celu podpisania aplikacji AIR za pomocą certyfikatu samopodpisanego wygenerowanego przez narzędzie ADT należy użyć następujących opcji: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 362 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń -storetype pkcs12 -keystore certificate.p12 W tym przykładzie certificate.p12 jest nazwą pliku magazynu kluczy. (Narzędzie ADT wyświetla monit dotyczący hasła, ponieważ hasło nie zostało określone w wierszu polecenia). Opcje podpisywania zostały w pełni opisane w sekcji „Opcje podpisywania w wierszu poleceń narzędzia ADT” na stronie 366. air_file Nazwa pliku AIR, który jest tworzony. app_xml Ścieżka do pliku deskryptora aplikacji. Ścieżka może zostać określona względem katalogu bieżącego lub jako ścieżka bezwzględna. (Nazwa pliku deskryptora aplikacji zostaje zmieniona na „application.xml” w pliku AIR). file_or_dir Pliki i katalogi, które będą pakowane w pliku AIR. Możliwe jest określenie dowolnej liczby plików i katalogów — poszczególne nazwy należy rozdzielać znakiem spacji. Po umieszczeniu na liście katalogu do pakietu zostaną dodane wszystkie jego pliki i podkatalogi, oprócz plików ukrytych. (Jeśli ponadto określono plik deskryptora aplikacji bezpośrednio, za pomocą znaku wieloznacznego lub rozszerzenia katalogu, ten plik zostanie zignorowany i nie zostanie dodany do pakietu po raz drugi). Wybrane pliki i katalogi muszą znajdować się w bieżącym katalogu lub w jednym z jego podkatalogów. W celu zmiany bieżącego katalogu należy użyć opcji -C. Ważne: Znaki wieloznaczne nie mogą być używane w argumentach file_or_dir za opcją –C. (Powłoki poleceń rozszerzają znaki wieloznaczne przed wprowadzeniem argumentów do narzędzia ADT, co sprawia, że narzędzie ADT poszukuje plików w błędnej lokalizacji). Zamiast nazwy katalogu bieżącego można użyć znaku „.”. Na przykład: polecenie „-C assets .” kopiuje całą zawartość katalogu assets, łącznie z jego podkatalogami, do głównego poziomu pakietu aplikacji. -C dir Zmienia katalog roboczy na katalog dir przed rozpoczęciem przetwarzania kolejnych plików i katalogów dodanych do pakietu aplikacji. Pliki i katalogi są dodawane do katalogu głównego pakietu aplikacji. Opcja –C może być używana dowolną ilość razy w celu uwzględnienia plików z wielu punktów w systemie plików. Jeśli dir określa ścieżkę względną, ścieżka jest odczytywana zawsze względem oryginalnego katalogu roboczego. W miarę przetwarzania przez narzędzie ADT plików i katalogów zawartych w pakiecie następuje zapisywanie względnych ścieżek między katalogiem bieżącym a plikami docelowymi. Podczas instalowania aplikacji te ścieżki są rozwijane do struktury katalogu aplikacji. Dlatego polecenie -C release/bin lib/feature.swf powoduje umieszczenie pliku release/bin/lib/feature.swf w podkatalogu lib głównego folderu aplikacji. -e file dir Umieszcza określony plik w wybranym katalogu pakietu. Uwaga: Element <content> pliku deskryptora aplikacji musi określać końcową lokalizację głównego pliku aplikacji w drzewie katalogów pakietu aplikacji. Przykłady ADT Pakowanie określonych plików aplikacji w katalogu bieżącym: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf components.swc Pakowanie wszystkich plików i podkatalogów w bieżącym katalogu roboczym: adt –package -storetype pkcs12 -keystore ../cert.p12 myApp.air myApp.xml . Uwaga: Plik magazynu kluczy zawiera klucz prywatny używany do podpisania aplikacji. Nigdy nie należy umieszczać certyfikatu podpisującego w pakiecie AIR! Jeśli w komendzie ADT używane są znaki wieloznaczne, plik magazynu kluczy należy umieścić w innej lokalizacji, tak aby nie został dołączony do pakietu. W tym przykładzie plik magazynu kluczy cert.p12 znajduje się w katalogu nadrzędnym. Pakowanie tylko plików głównych i podkatalogu images: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf images Pakowanie pliku application.xml oraz głównego pliku SWF znajdującego się w katalogu roboczym(release/bin): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 363 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń adt –package -storetype pkcs12 -keystore cert.p12 myApp.air release/bin/myApp.xml –C release/bin myApp.swf Pakowanie zasobów z więcej niż jednego miejsca w systemie plików kompilacji. W tym przykładzie przed pakowaniem zasoby aplikacji znajdują się następujących folderach: /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 Uruchomienie poniższego polecenia ADT z katalogu /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 Powoduje utworzenie następującej struktury pakietu: /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 Uruchamianie ADT jako programu Java (bez ustawiania ścieżki klasy): java –jar {AIRSDK}/lib/ADT.jar –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf Uruchamianie ADT jako programu Java (ze ścieżką klasy Java ustawioną w taki sposób, aby zawierała pakiet ADT.jar): TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 364 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń java com.adobe.air.ADT –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf Komunikaty o błędzie programu ADT Poniższa tabela zawiera listę możliwych błędów, które mogą być zgłaszane przez program ADT oraz prawdopodobne przyczyny. Błędy sprawdzania poprawności deskryptora aplikacji Kod błędu Opis Uwagi 100 Nie można dokonać analizy deskryptora aplikacji Sprawdź błędy składni XML w pliku deskryptora aplikacji, np. niezamknięte znaczniki. 101 Brak przestrzeni nazw Dodaj brakującą przestrzeń nazw. 102 Niepoprawna przestrzeń nazw Sprawdź pisownię dla przestrzeni nazw. 103 Nieoczekiwany element lub atrybut Usuń nieprawidłowe elementy atrybuty. Niestandardowe wartości nie są dozwolone w pliku deskryptora. Sprawdź pisownię dla nazw elementów i atrybutów. Upewnij się, że elementy są umieszczone w poprawnym elemencie nadrzędnym oraz atrybuty są używane z poprawnymi elementami. 104 Brak elementu lub atrybutu Dodaj wymagany element lub atrybut. 105 Element lub atrybut zawiera niepoprawną wartość Popraw nieprawidłową wartość. 106 Nieprawidłowa kombinacja atrybutów okna Nie można używać razem niektórych ustawień okna, np. transparency = true i systemChrome = standard. Zmień jedno z niezgodnych ustawień. 107 Minimalny rozmiar okna jest większy niż maksymalny rozmiar okna Zmień ustawienie rozmiaru minimalnego lub maksymalnego. Informacje na temat przestrzeni nazw, elementów, atrybutów i ich poprawnych wartości zawiera sekcja „Definiowanie ustawień aplikacji AIR” na stronie 45. Błędy ikon aplikacji TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 365 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Kod błędu Opis Uwagi 200 Nie można otworzyć pliku ikony Sprawdź, czy w określonej ścieżce istnieje plik. Użyj innej aplikacji, aby upewnić się, że plik można otworzyć. 201 Ikona ma nieprawidłowy rozmiar Rozmiar ikony (w pikselach) musi być zgodny ze znacznikiem XML. Na przykład gdy mamy następujący element deskryptora aplikacji: <image32x32>icon.png</image32x3 2> Obraz w pliku icon.png musi mieć dokładnie 32x32 piksele. 202 Plik ikony zawiera nieobsługiwany format obrazu Jedynym obsługiwanym formatem jest PNG. Skonwertuj obrazy w innych formatach przed spakowaniem aplikacji. Błędy pliku aplikacji Kod błędu Opis Uwagi 300 Brak pliku lub nie można go otworzyć Nie można odnaleźć pliku określonego w wierszu poleceń lub nie można go otworzyć. 301 Brak pliku deskryptora aplikacji lub nie można go otworzyć Nie można znaleźć pliku deskryptora aplikacji w określonej ścieżce lub nie można go otworzyć. 302 Brak w pakiecie głównego pliku treści Plik SWF lub HTML, do którego istnieje odwołanie w elemencie <content> deskryptora aplikacji, należy dodać do pakietu, umieszczając go w plikach wymienionych w wierszu poleceń programu ADT. 303 W pakiecie brakuje pliku ikony Pliki ikon określone w deskryptorze aplikacji należy dodać do pakietu, umieszczając je wśród plików wymienionych w wierszu poleceń programu ADT. Pliki ikon nie są dodawane automatycznie. 304 Początkowa treść okna jest niepoprawna Plik, do którego istnieje odwołanie w elemencie <content> deskryptora aplikacji, nie został rozpoznany jako poprawny plik HTML lub SWF. 305 Początkowa treść okna w wersji SWF nie jest obsługiwana w tej przestrzeni nazw Wersja SWF pliku, do którego istnieje odwołanie w elemencie <content> deskryptora aplikacji, nie jest obsługiwana przez wersję środowiska AIR określonego w przestrzeni nazw deskryptora. Na przykład próba spakowania pliku SWF10 (Flash Player 10) jako początkowej treści aplikacji AIR 1.1 spowoduje powstanie tego błędu. Kody wyjścia dla innych błędów TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 366 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Kod wyjścia Opis Uwagi 2 Błąd składni Sprawdź błędy argumentów wiersza poleceń 5 Nieznany błąd Ten błąd wskazuje na sytuację, w której nie można wyjaśnić warunków błędu. Możliwe główne przyczyny obejmują niezgodność między programem ADT oraz środowiskiem Java Runtime Environment, błąd instalacji ADT lub JRE oraz błędy programistyczne w programie ADT. 6 Nie można zapisać do katalogu wyjściowego Upewnij się, że określony (lub niejawny) katalog wyjściowy jest dostępny i dysk zawierający katalog ma dostateczną ilość wolnego miejsca. 7 Nie można uzyskać dostępu do certyfikatu Upewnij się, że ścieżka do magazynu kluczy została określona poprawnie. Sprawdź, czy do certyfikatu w magazynie kluczy można uzyskać dostęp. Do pomocy w rozwiązywaniu problemów z dostępem do certyfikatów służy narzędzie Java 1.6 Keytool. 8 Niepoprawny certyfikat Plik certyfikatu jest nieprawidłowy, zmodyfikowany lub nieważny. 9 Nie można podpisać pliku AIR Sprawdź opcje podpisywania przekazane do programu ADT. 10 Nie można utworzyć znacznika czasu Program ADT nie może nawiązać połączenia z serwerem znacznika czasu. W przypadku połączenia z Internetem za pośrednictwem serwera proxy może zaistnieć potrzeba konfiguracji ustawień proxy środowiska JRE. 11 Błąd tworzenia certyfikatu Sprawdź argumenty wiersza poleceń użyte do tworzenia sygnatur. 12 Niepoprawne wejście Sprawdź ścieżki plików oraz inne argumenty przekazane do programu ADT w wierszu poleceń. Opcje podpisywania w wierszu poleceń narzędzia ADT Narzędzie ADT korzysta z architektury JCA (Java Cryptography Architecture) w celu uzyskiwania dostępu do kluczy prywatnych i certyfikatów przeznaczonych do podpisywania aplikacji AIR. Opcje podpisywania określają magazyn kluczy, klucz prywatny i certyfikat w tym magazynie kluczy. Magazyn kluczy musi zawierać klucz prywatny oraz skojarzony z nim łańcuch certyfikatów. Klucz certyfikatów służy do określania identyfikatora wydawcy dla aplikacji. Jeśli certyfikat podpisujący prowadzi do zaufanego certyfikatu na komputerze, wówczas wspólna nazwa certyfikatu jest wyświetlana jako nazwa wydawcy w oknie dialogowym instalowania AIR. Narzędzie ADT wymaga, aby certyfikat był zgodny ze standardem x509v3 (RFC3280) oraz aby zawierał rozszerzenie Extended Key Usage z odpowiednimi wartościami dla podpisywania kodu. Ograniczenia certyfikatu są uwzględniane i powinny wykluczać użycie niektórych certyfikatów dla podpisywania aplikacji AIR. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 367 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Uwaga: Narzędzie ADT korzysta w razie potrzeby z ustawień proxy środowiska Java Runtime Environment (JRE), aby nawiązywać połączenia z zasobami Internetu w celu sprawdzania list cofnięcia certyfikatów oraz w celu pobierania znaczników czasu. W razie problemów z połączeniem z zasobami internetowymi podczas korzystania z narzędzia ADT oraz gdy sieć wymaga specjalnych ustawień proxy, konieczne może być skonfigurowanie ustawień proxy JRE. Określanie opcji podpisywania AIR ❖ W celu określenia opcji podpisywania ADT dla poleceń -package i -prepare należy użyć poniższej składni: [-alias aliasName] [-storetype type] [-keystore path] [-storepass password1] [-keypass password2] [-providerName className] [-tsa url] -alias aliasName — Alias klucza w magazynie kluczy. Określenie aliasa nie jest konieczne, jeśli magazyn kluczy zawiera wyłącznie pojedynczy certyfikat. Jeśli alias nie zostanie określony, wówczas narzędzie ADT użyje pierwszego klucza z magazynu kluczy. Nie wszystkie aplikacje do zarządzania magazynami kluczy zezwalają na przypisywanie aliasów do certyfikatów. Jeśli używany jest magazyn kluczy systemu Windows, w postaci aliasu należy użyć nazwy wyróżniającej certyfikatu. Za pomocą programu narzędziowego Java Keytool można wyświetlić listę dostępnych certyfikatów, dzięki czemu możliwe będzie określenie aliasu. Przykład: uruchomienie polecenia: keytool -list -storetype Windows-MY powoduje wyświetlenie następujących danych dla certyfikatu: 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 W celu utworzenia odwołania do tego certyfikatu w wierszu poleceń ADT należy ustawić następujący alias: CN=TestingCert,OU=QE,O=Adobe,C=US W systemie Mac OS X alias certyfikatu w łańcuchu kluczy jest nazwą wyświetlaną w aplikacji Keychain Access. -storetype type — Typ magazynu kluczy określony przez implementację magazynu kluczy. Domyślna implementacja magazynu kluczy dołączona do większości instalacji Java obsługuje typy JKS i PKCS12. Java 5.0 obsługuje typ PKCS11, który umożliwia dostęp do magazynów kluczy w tokenach sprzętowych, a także typ Keychain przeznaczony do dostępu do łańcucha kluczy Mac OS X. Java 6.0 obsługuje typ MSCAPI (w systemie Windows). W przypadku zainstalowania i skonfigurowania innych dostawców JCA mogą być dostępne inne typy magazynów kluczy. Jeśli nie określono typu magazynu kluczy, wówczas używany jest domyślny typ dla domyślnego dostawcy JCA. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 368 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Typ magazynu Format magazynu kluczy Minimalna wersja Java JKS Plik magazynu kluczy Java (.keystore) 1.2 PKCS12 Plik PKCS12 (.p12 lub .pfx) 1.4 PKCS11 Token sprzętowy 1.5 KeychainStore Mac OS X Keychain 1.5 Windows-MY lub WindowsROOT MSCAPI 1.6 -keystore path — Ścieżka do pliku magazynu kluczy dla magazynów opartych na plikach. -storepass password1 — hasło wymagane do uzyskania dostępu do magazynu kluczy. Jeśli nie określono, ADT wyświetla monit dotyczący hasła. -keypass password2 — Hasło wymagane do uzyskania dostępu do klucza prywatnego, który służy do podpisania aplikacji AIR. Jeśli nie określono, ADT wyświetla monit dotyczący hasła. -providerName className — Dostawca JCA dla magazynu kluczy określonego typu. Jeśli nie określono, wówczas ADT korzysta z domyślnego dostawcy dla magazynu kluczy tego typu. -tsa url — Określa adres URL serwera znaczników czasu zgodnego z RFC3161 w celu oznaczenia podpisu cyfrowego znacznikiem czasu. Jeśli nie określono adresu URL, używany jest domyślny serwer znaczników czasu udostępniany przez Geotrust. Jeśli podpis aplikacji AIR jest oznaczony znacznikiem czasu, aplikacja może zostać zainstalowana po utracie ważności certyfikatu, ponieważ znacznik czasu potwierdza, że certyfikat był poprawny w czasie podpisywania. Jeśli narzędzie ADT nie może połączyć się z serwerem znaczników czasu, wówczas podpisywanie zostaje anulowane i pakiet nie zostanie wygenerowany. W celu wyłączenia wstawiania znaczników czasu należy wprowadzić opcję -tsa none. Jednak po utracie ważności certyfikatu podpisującego nie będzie możliwości zainstalowania aplikacji AIR zapakowanej bez znacznika czasu. Uwaga: Opcje podpisywania są równoważne opcjom programu narzędziowego Java Keytool. Za pomocą programu narzędziowego Keytool można sprawdzać magazyny kluczy Windows i zarządzać nimi. Do tego celu można w systemie Mac OS X wykorzystać program narzędziowy zabezpieczeń Apple®. Przykłady opcji podpisywania Podpisywanie za pomocą pliku .p12: -storetype pkcs12 -keystore cert.p12 Podpisywanie za pomocą domyślnego magazynu kluczy Java: -alias AIRcert -storetype jks Podpisywanie za pomocą określonego magazynu kluczy Java: -alias AIRcert -storetype jks -keystore certStore.keystore Podpisywanie za pomocą łańcucha kluczy Mac OS X: -alias AIRcert -storetype KeychainStore -providerName Apple Podpisywanie za pomocą magazynu kluczy Windows: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 369 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń -alias cn=AIRCert -storeype Windows-MY Podpisywanie za pomocą tokenu sprzętowego (zapoznać się z instrukcjami producenta tokenu dotyczącymi konfigurowania Java do użycia tokenu oraz w celu określenia poprawnej wartości providerName): -alias AIRCert -storetype pkcs11 -providerName tokenProviderName Podpisywanie bez osadzania znacznika czasu: -storetype pkcs12 -keystore cert.p12 -tsa none Tworzenie niepodpisanego pośredniego pliku AIR za pomocą narzędzia ADT W celu utworzenia niepodpisanego pośredniego pliku AIR należy użyć polecenia -prepare. W celu wygenerowania poprawnego pliku instalacyjnego AIR należy podpisać plik pośredni AIR za pomocą polecenia ADT -sign. Polecenie -prepare ma takie same flagi i parametry, jak polecenie -package (z wyjątkiem opcji podpisywania). Jedyną różnicą jest to, że plik wyjściowy nie jest podpisany. Plik pośredni jest wygenerowany z rozszerzeniem: airi. W celu podpisania pliku pośredniego AIR należy użyć polecenia ADT -sign. (Patrz Podpisywanie pliku pośredniego AIR za pomocą narzędzia ADT). Przykład ADT adt –prepare unsignedMyApp.airi myApp.xml myApp.swf components.swc Podpisywanie pliku pośredniego AIR za pomocą narzędzia ADT W celu podpisania pliku pośredniego AIR za pomocą narzędzia ADT należy użyć polecenia -sign. Polecenie sign działa tylko z plikami pośrednimi AIR (rozszerzenie airi). Plik AIR nie może zostać podpisany po raz drugi. W celu utworzenia pliku pośredniego AIR należy użyć polecenia adt -prepare. (Patrz „Tworzenie niepodpisanego pośredniego pliku AIR za pomocą narzędzia ADT” na stronie 369). Podpisywanie pliku AIRI ❖ Należy użyć polecenia ADT -sign z następującą składnią: adt -sign SIGNING_OPTIONSairi_fileair_file SIGNING_OPTIONS Opcje podpisywania identyfikują klucz prywatny oraz certyfikat służący do podpisywania pliku AIR. Te opcje podpisywania zostały opisane w sekcji „Opcje podpisywania w wierszu poleceń narzędzia ADT” na stronie 366. airi_file Ścieżka do niepodpisanego pośredniego pliku AIR przeznaczonego do podpisania. air_file Nazwa pliku AIR, który jest tworzony. Przykład ADT adt –sign -storetype pkcs12 -keystore cert.p12 unsignedMyApp.airi myApp.air Więcej informacji zawiera sekcja „Elektroniczne podpisywanie pliku AIR” na stronie 323. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 370 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Podpisywanie pliku AIR w celu zmiany certyfikatu aplikacji W celu aktualizacji istniejącej aplikacji AIR w taki sposób, aby korzystała z nowego certyfikatu podpisującego, należy użyć polecenia ADT -migrate. Migracja certyfikatu może być użyteczna w następujących sytuacjach: • Aktualizacja z certyfikatu samopodpisanego do certyfikatu wydanego przez ośrodek certyfikacji • Zmiana certyfikatu samopodpisanego, który wkrótce utraci ważność, na nowy certyfikat samopodpisany • Zmiana certyfikatu komercyjnego np. w przypadku zmiany tożsamości korporacyjnej Aby możliwe było zastosowanie podpisu migracji, oryginalny certyfikat nadal musi obowiązywać. Po utracie ważności certyfikatu nie ma możliwości zastosowania podpisu migracji. Użytkownicy aplikacji będą musieli odinstalować istniejącą wersję przed zainstalowaniem wersji zaktualizowanej. Podpis migracji jest oznaczony znacznikiem czasu, dlatego aktualizacje AIR podpisane podpisem migracji pozostaną aktualne nawet po utracie ważności certyfikatu. Uwaga: W przypadku odnawiania certyfikatu wydawanego komercyjnie nie ma potrzeby jego migrowania. Certyfikat odnowiony zachowuje tę samą tożsamość wydawcy co oryginał, chyba że doszło do zmiany nazwy wyróżniającej. Pełną listę atrybutów certyfikatu, które służą do określania nazwy wyróżniającej, zawiera sekcja „Informacje o identyfikatorach wydawców AIR” na stronie 325. W celu migracji aplikacji, aby korzystała z nowego certyfikatu: 1 Utwórz aktualizację aplikacji 2 Spakuj i podpisz plik AIR aktualizacji nowym certyfikatem 3 Podpisz ponownie plik AIR certyfikatem original, korzystając z polecenia -migrate Plik AIR podpisany poleceniem -migrate może służyć do zainstalowania nowej wersji aplikacji oraz do zaktualizowania dowolnych poprzednich wersji, łącznie z podpisanym starym certyfikatem. Migracja aplikacji AIR w celu użycia nowego certyfikatu ❖ Należy użyć polecenia ADT -migrate z poniższą składnią: adt -migrate SIGNING_OPTIONS air_file_in air_file_out SIGNING_OPTIONS Opcje podpisywania identyfikują klucz prywatny oraz certyfikat służący do podpisywania pliku AIR. Te opcje muszą identyfikować oryginalny certyfikat podpisujący i zostały opisane w sekcji „Opcje podpisywania w wierszu poleceń narzędzia ADT” na stronie 366. air_file_in Plik AIR dla aktualizacji podpisany certyfikatem new. air_file_out Plik AIR do utworzenia. Przykład ADT adt –migrate -storetype pkcs12 -keystore cert.p12 myApp.air myApp.air Więcej informacji zawiera sekcja „Elektroniczne podpisywanie pliku AIR” na stronie 323. Uwaga: Polecenie -migrate zostało dodane do narzędzia ADT w wersji AIR 1.1. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 371 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Tworzenie certyfikatu samopodpisanego za pomocą narzędzia ADT Certyfikat samopodpisany umożliwia wygenerowanie poprawnego pliku instalacyjnego AIR, ale taki certyfikat stanowi dla użytkowników słabszy dowód prawdziwości pliku, ponieważ nie ma możliwości zweryfikowania certyfikatu samopodpisanego. Podczas instalowania samopodpisanego pliku AIR informacje o wydawcy są wyświetlane jako nieznane. Certyfikat wygenerowany przez ADT jest ważny przez pięć lat. W przypadku utworzenia aktualizacji dla aplikacji AIR, która została podpisana certyfikatem samopodpisanym, należy użyć tego samego certyfikatu w celu podpisania oryginalnych i zaktualizowanych plików AIR. Certyfikaty wygenerowane przez ADT są zawsze unikalne, nawet jeśli używane są te same parametry. Dlatego jeśli wymagane jest samopodpisanie aktualizacji za pomocą certyfikatu wygenerowanego przez ADT należy zachować oryginalny certyfikat w bezpiecznej lokalizacji. Ponadto wygenerowanie zaktualizowanego pliku AIR po utracie ważności oryginalnego certyfikatu wygenerowanego przez ADT nie będzie możliwe. (Możliwe jest publikowanie nowych aplikacji z innym certyfikatem, ale nie nowych wersji tej samej aplikacji). Ważne: Z powodu ograniczeń certyfikatów samopodpisanych, firma Adobe zaleca korzystanie z komercyjnych certyfikatów wydawanych przez zaufane ośrodki certyfikacji do podpisywania publicznie wydawanych aplikacji AIR. Certyfikat i skojarzony klucz prywatny wygenerowany przez ADT są zapisane w pliku magazynu kluczy typu PKCS12. Określone hasło jest ustawione w kluczu, a nie w magazynie kluczy. Generowanie certyfikatu identyfikatora elektronicznego dla samopodpisanych plików AIR ❖ Należy użyć polecenia ADT -certificate (w pojedynczym wierszu polecenia): adt -certificate -cn name [-ou org_unit][-o org_name][-c country] key_type pfx_file password -cn name Ciąg znaków przypisany jako wspólna nazwa nowego certyfikatu. -ou org_unit Ciąg znaków przypisany jako jednostka organizacyjna wydająca certyfikat. (Opcjonalnie). -o org_name Ciąg znaków przypisany jako organizacja wydająca certyfikat. (Opcjonalnie). -c country Dwucyfrowy kod kraju ISO-3166. Certyfikat nie zostanie wygenerowany, jeśli zostanie wprowadzony niepoprawny kod. (Opcjonalnie). key_type Typ klucza używany dla certyfikatu, „1024-RSA” lub „2048-RSA”. pfx_file Ścieżka pliku certyfikatu do wygenerowania. password Hasło dla nowego certyfikatu. Hasło jest wymagane podczas podpisywania plików AIR tym certyfikatem. Przykłady generowania certyfikatu 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 W celu użycia tych certyfikatów do podpisywania plików AIR należy użyć następujących opcji podpisywania z poleceniami ADT -package i -prepare: -storetype pkcs12 -keystore newcert.p12 -keypass 39#wnetx3tl -storetype pkcs12 -keystore SigningCert.p12 -keypass 39#wnetx3tl TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 372 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń Korzystanie z narzędzia Apache Ant z narzędziami SDK W niniejszej sekcji przedstawiono przykłady użycia narzędzia Apache Ant do testowania i pakowania aplikacji AIR. Uwaga: Sekcja nie zawiera pełnego opisu narzędzia Apache Ant. Dokumentacja narzędzia Ant jest dostępna na stronie http://Ant.Apache.org. Korzystanie z narzędzia Ant w prostych projektach Ten przykład ilustruje tworzenie aplikacji AIR za pomocą narzędzia Ant oraz narzędzi wiersza poleceń AIR. Wszystkie pliki zapisane w jednym katalogu mają prostą strukturę. Aby ułatwić ponowne korzystanie ze skryptu tworzenia, w przykładach przedstawiono zastosowanie kilku zdefiniowanych właściwości. Jeden zestaw właściwości identyfikuje zainstalowane lokalizacje narzędzi wiersza poleceń: <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"/> Drugi zestaw właściwości jest właściwy dla projektu. Te właściwości przyjmują konwencję nazewnictwa, w której deskryptor aplikacji i pliki AIR są nazywane na podstawie nazwy głównego pliku źródłowego. Inne konwencje również mogą być obsługiwane. <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"/> Wywoływanie ADL w celu przetestowania aplikacji W celu uruchomienia aplikacji za pomocą ADL należy użyć zadania exec: <target name="test" depends="compile"> <target name="test"> <exec executable="${ADL}"> <arg value="${APP_DESCRIPTOR}"/> </exec> </target> Wywoływanie narzędzia ADT w celu spakowania aplikacji W celu spakowania aplikacji należy użyć zadania Java, aby uruchomić narzędzie adt.jar: TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 373 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń <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> Jeśli aplikacja zawiera więcej plików do spakowania, można dodać dodatkowe elementy <arg>. Korzystanie z narzędzia Ant w bardziej złożonych projektach Struktura katalogu typowej aplikacji jest bardziej złożona i może zawierać więcej katalogów niż jeden. Poniższy przykład ilustruje plik build służący do kompilowania, testowania i pakowania aplikacji AIR, która ma bardziej praktyczną strukturę katalogu projektu. Ten przykładowy projekt zawiera pliki źródłowe aplikacji oraz inne zasoby, takie jak pliki ikon w katalogu src. Skrypt build tworzy następujące katalogi robocze: build Zawiera publikowane (bez debugowania) wersje skompilowanych plików SWF. debug Zawiera niespakowaną wersję zdebugowaną aplikacji, łącznie ze skompilowanymi plikami SWF oraz plikami zasobów. Program narzędziowy ADL uruchamia aplikację z tego katalogu. release Zawiera końcowy pakiet AIR Narzędzia AIR korzystają z niektórych dodatkowych opcji w celu otwierania plików na zewnątrz bieżącego katalogu roboczego: Testowanie Drugi argument przekazany do ADL określa katalog główny aplikacji AIR. W celu określenia katalogu głównego należy dodać poniższą linię do zadania testowania: <arg value="${debug}"/> Pakowanie Pakowanie plików z podkatalogów, które nie powinny stanowić części ostatecznej struktury pakietu, wymaga użycia dyrektywy -C w celu zmiany katalogu roboczego ADT. Gdy używana jest dyrektywa -C, pliki i podkatalogi z nowego katalogu roboczego są kopiowane do poziomu głównego pliku pakietu AIR. Polecenie -C build file.png kopiujefile.png do głównego poziomu katalogu aplikacji. I podobnie — -C assets icons kopiuje folder icons do głównego poziomu, a także kopiuje wszystkie pliki i katalogi folderu icons. Przykład: poniższa sekwencja linii w zadaniu pakowania dodaje katalog icons bezpośrednio do poziomu głównego pliku pakietu aplikacji: <arg value="-C"/> <arg value="${assets}"/> <arg value="icons"/> Uwaga: Jeśli wymagane jest przeniesienie wielu zasobów do różnych lokalizacji względnych, zwykle łatwiej jest zestawić je do katalogu tymczasowego za pomocą zadań Ant niż budować złożoną listę argumentów dla ADT. Po zorganizowaniu zasobów w celu ich spakowania można użyć prostej listy argumentów ADT. TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 374 Tworzenie aplikacji AIR za pomocą narzędzia wiersza poleceń <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> 375 Indeks Symbole : (dwukropek) — znak, w nazwach parametrów instrukcji SQL 177 AIR Debug Launcher (ADL) kody wyjścia i kody błędów 360 AIR Developer Tool (ADT) Ajax obsługa w obszarze izolowanym aplikacji 34 ? (znak zapytania) — znak, w nienazwanych parametrach SQL 178 AIRI, pliki 369 @ (at) — znak, w nazwach parametrów instrukcji SQL 177 opcje podpisywania 366 aktualizowanie aplikacji AIR 53, 331 pakowanie pliku AIR 361 aktywne okno 73, 74 tworzenie certyfikatów samopodpisanych 371 aktywność (użytkownika), wykrywanie 302 Liczby 1024-RSA 371 2048-RSA 371 A AC_FL_RunContent(), funkcja (w pliku default_badge.html) 316 AIR, aplikacja deinstalacja 27 AIR, aplikacje aktualizowanie 24, 53, 331 dystrybucja 314 ikony 52 zabezpieczenia 34 aktywowanie okien 68, 74 allowBrowserInvocation, element (plik deskryptora aplikacji) 53, 293, 296 allowCrossDomainXHR, atrybut (elementy ramek i ramek pływających) 224, 229 allowLoadBytesCodeExecution, właściwość (klasa LoaderContext) 42 AC_RuntimeActiveContent.js 316 informacje o prawach autorskich 50 alwaysInFront, właściwość (klasa NativeWindow) 74 acceptDragDrop(), metoda (klasa NativeDragManager) 135, 140 instalowanie 24, 314 aplikacje acompc, kompilator 247 skojarzenia typów plików 53, 301 app, schemat adresów URL 275 Acrobat 221, 274 uruchamianie 293, 314, 322 Action Message Format (AMF) 136 ustawienia 45, 48, 300 app, schemat URL 40, 43, 69, 113, 222, 242, 250 ActionScript wersje 48, 302, 332 odwołania do skryptów między plikami w języku JavaScript 243 ścieżka instalacji 48 wychodzenie 293 wykrywanie instalacji 320 ActionScript, dokumentacja 10 wywołanie 293 activate(), metoda (klasa NativeWindow) 68, 74 wywołanie z przeglądarki 53 active, zdarzenie 80 activeWindow, właściwość (klasa NativeApplication) 73 zamykanie 293 AIR, aplikacji powiązania typu pliku 295 Patrz Aplikacje AIR AppInstallDisabled (ustawienia rejestru Windows) 27 Apple, certyfikaty programistów 325 applicationDescriptor, właściwość (klasa NativeApplication) 300 ApplicationDomain, klasa 244 applicationStorageDirectory, właściwość (klasa File) 109 ApplicationUpdater_UI.swf, plik 336 addChild(), metoda (klasa Stage) 71 AIR, certyfikaty programistów 325 ApplicationUpdater.swc, plik 336 addChildAt(), metoda (klasa Stage) 71 AIR, pliki ApplicationUpdater.swf, plik 336 Adobe Acrobat Developer Center 275 pakowanie 361 ApplicatoinUpdater_UI.swc, plik 336 Adobe AIR podpisywanie 323 app-storage, schemat adresów URL 275 aktualizowanie 24 AIR, środowisko wykonawcze app-storage, schemat URL 26, 40, 43, 113 instalowanie 24 aktualizowanie 24 app-support, schemat URL 250 nowe funkcje 55 odinstalowywanie 2 architektura aktualizacji 335 odinstalowywanie 2 poziomy poprawek 46, 302 arguments, właściwość wprowadzenie 7 wykrywanie 302, 319 Adobe Media Player 279 air, właściwość (plik AIRAliases.js) 220, 241 Adobe Press, książki 10 AIRAliases.js, plik 220 Adobe Reader 221, 274 AIRI, pliki Adobe, dokumentacja 10 adresy URL 242 kopiowanie i wklejanie -pomoc 150 obsługa przeciągania i upuszczania 134, 143 AES-CBC, szyfrowanie 128-bitowe 217 tworzenie za pomocą narzędzia AIR Developer Tool (ADT) 369 AIRLocalizer.js, plik 347 klasa BrowserInvokeEvent 297 klasa InvokeEvent 294 argumenty wiersza poleceń przechwytywanie 294 asfunction, protokół 30 asynchroniczne programowanie XMLHttpRequests 240 asynchroniczne, programowanie bazy danych 170, 174, 192 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 376 Indeks at (@) — znak, w nazwach parametrów instrukcji SQL 177 browseForDirectory(), metoda (klasa File) 111 clientX, właściwość (zdarzenia przeciągania HTML) 143 ataki na skutek zamiany wersji na starszą i bezpieczeństwo 44 browseForOpen(), metoda (klasa File) 112 browseForSave(), metoda (klasa File) 112 clientY, właściwość (zdarzenia przeciągania HTML) 143 attach(), metoda (klasa SQLConnection) 188 browserInvoke, zdarzenie 297, 323 Clipboard, klasa autoExit, właściwość (klasa NativeApplication) 298 AUTOINCREMENT, kolumny (SQL) 187 automatyczne uruchamianie (uruchamianie aplikacji AIR podczas logowania) 296 BrowserInvokeEvent, klasa 296 bufor międzydomenowy, zabezpieczenia 30 ByteArray, klasa konstruktor 156 getData(), metoda 136, 140 clipboard, właściwość (klasa NativeDragEvent) 140 clipboard, zdarzenie 226 metoda compress() 159 clipboardData, właściwość (zdarzenia clipboard) 226 metoda readBytes() 156 close, zdarzenie 80 metoda readFloat() 156 close(), metoda (klasa NativeWindow) 75 metoda readInt() 156 close(), metoda (obiekt okna) 61 bezpieczeństwo 178 metoda readObject() 156 closing, zdarzenie 75, 80, 257 błędy 188 metoda readUTFBytes() 156 complete, zdarzenie 244, 248, 254 identyfikatory wierszy 187 metoda uncompress() 159 compress(), metoda (klasa ByteArray) 159 informacje 167 metoda writeBytes() 156 CompressionAlgorithm, klasa 159 klasy używane z bazami 169 metoda writeFloat() 156 klucze podstawowe 186, 187 metoda writeInt() 156 content, element (plik deskryptora aplikacji) 51 kolumny 168 metoda writeObject() 156 contenteditable, atrybut (HTML) 146 określanie typów danych 178, 191 metoda writeUTFBytes() 156 ContextMenuEvent, klasa pliki 167 właściwość bytesAvailable 157 pobieranie danych 179 właściwość length 157 pola 168 właściwość position 157 B bazy danych połączenie 174 contextMenuOwner, właściwość 93 mouseTarget, właściwość 93 copy(), metoda (klasa NativeApplication) 153 copyTo(), metoda (klasa File) 120 tabele 168, 172 C Canvas, obiekt 224, 231 tryb asynchroniczny 170 Capabilities CPS, oświadczenie (certificate practice statement) 329 struktura 168 tryb synchroniczny 170 language, właściwość 347 tworzenie 171 languages, właściwość 347 usuwanie danych 188 wiele, praca z wieloma 188 wiersze 168 Capabilities, klasa playerType, właściwość 302 certyfikaty wydajność 178 formaty 325 zastosowania 167 łańcuchy 329 zmiana danych 188 migracja 327, 370 copyToAsync(), metoda (klasa File) 120 CREATE TABLE, instrukcja (SQL) 172 createDirectory(), metoda (klasa File) 117 createElement(), metoda (obiekt Document) 240 createRootWindow(), metoda (klasa HTMLLoader) 68, 70, 235 createTempDirectory(), metoda (klasa File) 117, 122 createTempFile(), metoda (klasa File) 122 bezczynność (użytkownika) 302 opcje w wierszu poleceń narzędzia ADT 366 bezpieczeństwo podpisywanie kodu 44 creator, właściwość (klasa File) 119 baza danych 178 podpisywanie plików AIR 323 CRL, lista (Certificate Revocation List) 329 obszary izolowane 221, 222, 249, 302 utrata ważności 326 CSS szyfrowanie danych 217 zmiana 327, 370 bazy danych w pamięci 171 big-endian, kolejność bajtów 158 certyfikaty samopodpisane 44, 323, 371 bitmapowe obrazy, ustawianie dla ikon 102 childSandboxBridge, właściwość bitmaps, właściwość (klasa Icon) 102 bitmapy LoaderInfo, klasa 37 Window, obiekt 32 kopiowanie i wklejanie -pomoc 150 ChosenSecurity, certyfikaty 324, 325 obsługa przeciągania i upuszczania 134, 143 clearData(), metoda bounce(), metoda (klasa Icon) 103 creationDate, właściwość (klasa File) 119 AIR, rozszerzenia 233 dostęp do styli HTML z kodu ActionScript 248 currentDirectory, właściwość (klasa InvokeEvent) 294 currentDomain, właściwość (klasa ApplicationDomain) 244 ClipboardData, obiekt 225 customUpdateUI, element (plik deskryptora aplikacji) 53, 293, 333 DataTransfer, obiekt 143, 226 czyszczenie katalogów 119 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 377 Indeks D dane binarne Patrz tablice bajtów dane, szyfrowanie 217 data, właściwość NativeMenuItem, klasa 91 DataTransfer, obiekt types, właściwość 146 DataTransfer, obiekt (przeciąganie i upuszczanie w treści HTML) 143, 144, 145, 146, 226 Date, obiekty, konwertowanie między ActionScript i JavaScript 248 deactivate, zdarzenie 80 debugowanie za pomocą ADL 359 default_badge.html 316 deflate, kompresja 159 deinstalacja AIR, aplikacje 27 DELETE, instrukcja (SQL) 188 deleteDirectory(), metoda (klasa File) 119 deleteDirectoryAsync(), metoda (klasa File) 119 deleteFile(), metoda (klasa File) 121 deleteFileAsync(), metoda (klasa File) 121 description, element (plik deskryptora aplikacji) 50 designMode, właściwość (Document, obiekt) 146 stylesheets, właściwość 248 Endian.BIG_ENDIAN 158 wirtelin(), metoda 227 Endian.LITTLE_ENDIAN 158 write(), metoda 34, 227, 240 enterFrame, zdarzenie 71 writeln(), metoda 34, 240 error, zdarzenie 176 documentRoot, atrybut (elementy ramek i ramek pływających) 221, 229, 250 documentRoot, atrybut (ramki i ramki pływające) 31 documentRoot, atrybuty (ramki i ramki pływające) 31 documentsDirectory, właściwość (klasa File) 109 eval(), funkcja 29, 33, 223, 236, 238 execute(), metoda (klasa SQLStatement) 177, 179, 186 exists, właściwość (klasa File) 119 exit(), metoda klasa NativeApplication 298 doDrag(), metoda (klasa NativeDragManager) 135, 137, 140 F FDB (debuger) 359 dokumentacja, pokrewna 10 File, klasa 107, 108 dominitialize, zdarzenie 230 DPAPI (skojarzenie zaszyfrowanych danych z użytkownikami) 217 applicationStorageDirectory, właściwość 108 browseForDirectory(), metoda 111 drag, zdarzenie 142, 226 browseForOpen(), metoda 112 dragend, zdarzenie 142, 226 browseForSave(), metoda 112 dragenter, zdarzenie 142, 226 copyTo(), metoda 120 dragleave, zdarzenie 142, 226 copyToAsync(), metoda 120 dragover, zdarzenie 142, 226 createDirectory(), metoda 117 dragstart, zdarzenie 142, 226 createTempDirectory(), metoda 117, 122 DRM 279 createTempFile(), metoda 122 poświadczenia 288 creationDate, właściwość 119 DRMAuthenticateEvent, klasa 280, 287 creator, właściwość 119 DRMErrorEvent, klasa 280 deleteDirectory(), metoda 119 kody błędów 288 deleteDirectoryAsync(), metoda 119 subErrorID, właściwość 288 deleteFile(), metoda 121 designMode, właściwość (obiekt Document) 227 DRMStatusEvent, klasa 280 deleteFileAsync(), metoda 121 drop, zdarzenie 142, 226 desktopDirectory, właściwość 108 deskryptor aktualizacji, plik (architektura aktualizacji) 338 dropAction, właściwość (klasa NativeDragEvent) 139, 140 documentsDirectory, właściwość 108 desktopDirectory, właściwość (klasa File) 109 dropEffect, właściwość (DataTransfer, obiekt) 143, 144, 226 exists, właściwość 119 Dictionary, klasa 241 drukowanie 222 Digital Rights Management 279 dwukropek ( dispatchEvent(), metoda (klasa NativeWindow) 62 ) — znak, w nazwach parametrów instrukcji SQL 177 display(), metoda (klasa NativeMenu) 97 dynamiczne generowanie kodu 33 displaying, zdarzenie 89, 99 dystrybucja aplikacji AIR 314 displayStateChanging, zdarzenie 62, 81 Dock, ikony 103 podskakiwanie 103 dock, ikony obsługa 102 Document, obiekt getDirectoryListingAsync(), metoda 118 getRootDirectories() 108 getRootDirectories(), metoda 108 isDirectory, właściwość 119 lineEnding, właściwość 116 load() metoda 130 modificationDate, właściwość 119 displayState, właściwość(klasa Stage) 81 displayStateChange, zdarzenie 62, 81 encoding, właściwość 116 E effectAllowed, właściwość (DataTransfer, obiekt) 143, 144, 145, 226 ekrany 83 moveTo(), metoda 120 moveToAsync(), metoda 120 moveToTrash(), metoda 121 moveToTrashAsync(), metoda 121 główny 84 name, właściwość 119 przenoszenie okien między 84 nativePath, właściwość 108, 119 wyliczanie 84 parent, właściwość 119 createElement(), metoda 240 encoding, właściwość (klasa File) 116 relativize(), metoda 114 designMode, właściwość 146, 227 EncryptedLocalStore, klasa 217 resolvePath(), metoda 108 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 378 Indeks save(), metoda 130 separator, właściwość 116 size, właściwość 119 spaceAvailable, właściwość 116 tworzenie odwołania w lokalnej bazie danych 171 type, właściwość 119 getDirectoryListing(), metoda (klasa File) 118 getDirectoryListingAsync(), metoda (klasa File) 118 getResult(), metoda (klasa SQLStatement) 186 getScreensForRectangle(), metoda (klasa Screen) 84 pdfCapability, właściwość 274 placeLoadStringContentInApplicationSa ndbox, właściwosć 36 runtimeApplicationDomain, właściwość 244 width, właściwość 235 zdarzenia 254 htmlLoader, właściwość (obiekt okna) 69 url, właściwość 108, 119 getStatus(), metoda (plik air.swf) 319 userDirectory, właściwość 108 GlobalSign, certyfikaty 324, 325 file, schemat URL 40, 113, 242 htmlLoader, właściwość (obiekt Window) 220, 228, 235 główny ekran 84 FileMode, klasa 107 HTMLPDFCapability, klasa 274 GZIP, format 159 HTMLUncaughtScriptException, klasa 255 H hasEventListener(), metoda 259 I icon, element (plik deskryptora aplikacji) 52 hasła Icon, klasa filename, element (plik deskryptora aplikacji) 48 FileReference, klasa load(), metoda 130 save(), metoda 130 FileStream, klasa 107 konfigurowanie dla zaszyfrowanych treści multimedialnych 279 bitmaps, właściwość 102 bounce(), metoda 103 fileTypes, element (plik deskryptora aplikacji) 53, 301 height, element (plik deskryptora aplikacji) 52 Flash Media Rights Management Server 279 Flash Player 55, 219, 222, 241 height, właściwość (klasa HTMLLoader) 235 Flash, dokumentacja 10 hostContainer, właściwość (PDF) 276 id, element (plik deskryptora aplikacji) 48 FlashVars, ustawienia (dla korzystania z pliku badge.swf) 316 HTML identyfikatory aplikacji 48 Flex obsługa przeciągania i upuszczania 136 icon, właściwość (klasa NativeApplication) 102 id, element (klasa NativeApplication) 300 AIR, rozszerzenia 229 identyfikatory wydawców 300, 325 drukowanie 222 idleThreshold, właściwość (klasa NativeApplication) 302 kopiowanie i wklejanie 151 ikony FLV, szyfrowanie wideo 279 ładowanie treści 235 FMRMS (Flash Media Rights Management Server) 279 model DOM, dostęp z kodu ActionScript 244 Format AMF (Action Message Format) 156, 159 nakładanie treści SWF 70 Dock 102, 103 obiekty osadzone 221 obrazy 102 obsługa przeciągania i upuszczania 134, 143 pasek zadań 74, 102 funkcja wywołania z przeglądarki 53 funkcje (JavaScript) definicje 34 obszary izolowane 222 konstruktor 239 okna 68 literały 34 przewijanie 254 wtyczki 221 G getApplicationVersion(), metoda (plik air.swf) 320 getData(), metoda Clipboard, klasa 140 ClipboardData, obiekt 225 DataTransfer, obiekt 146, 226 zdarzenie kopiowania i wklejania HTML 151 getData(), metoda (dla właściwości dataTransfer zdarzenia przeciągania HTML) 143 animowanie 102 aplikacja 52 usuwanie 102 zasobnik systemowy 102 ikony Docku menu 92 minimalizowanie okna 74 zabezpieczenia 31, 221, 250 ikony paska tytułowego (Windows) 66 zdarzenia 254 ikony paska zadań 74, 88, 92 htmlBoundsChanged, zdarzenie 254 htmlDOMInitialize, zdarzenie 254 HTMLLoader placeLoadStringContentInApplicationSa ndbox, właściwość 235 HTMLLoader, klasa 235 createRootWindow(), metoda 68, 70, 235 height, właściwość 235 JavaScript, dostęp 220 getData(), metoda (klasa Clipboard) 136 loadString(), metoda 36, 235 getDefaultApplication(), metoda (klasa NativeApplication) 301 paintsDefaultBackground, właściwość 64, 71 ikony proxy Mac OS 66 img, znaczniki (w treści obiektów TextField) 29 Info.plist, pliki (Mac OS) 50 informacje o prawach autorskich dla aplikacji AIR 50 initialWindow, element (plik deskryptora aplikacji) 51, 61 innerHTML, właściwość 34, 227, 240 INSERT, instrukcja (SQL) 191 installApplication(), metoda (plik air.swf) 321 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 379 Indeks installFolder, element (plik deskryptora aplikacji) 50 katalogi 109, 117 kopiowanie 118 instalowanie aplikacji AIR 314 odwołania 109 instrukcje, SQL 175 przenoszenie 118 INTEGER PRIMARY KEY, kolumny (SQL) 187 tworzenie 117 interfejs API systemu plików 107 InvokeEvent, klasa 54, 294 właściwość arguments 294 właściwość currentDirectory 294 isDirectory, właściwość (klasa File) 119 isHTTPS, właściwość (klasa BrowserInvokeEvent) 297 L label, właściwość (klasa NativeMenuItem) 153 lastInsertRowID, właściwość (klasa SQLResult) 186 usuwanie 119, 121 lastUserInput, właściwość (klasa NativeApplication) 302 wyliczanie 118 lightweight, okna 63 wywołanie aplikacji 294 lineEnding, właściwość (klasa File) 116 katalogi tymczasowe 117 klasa ContextMenu 90, 93 listRootDirectories(), metoda (klasa File) 109 klasa ContextMenuItem 90 listy plików klasa Keyboard 90 obsługa przeciągania i upuszczania 143 Klasa NativeMenu 89, 97 literały obiektów (w JavaScript) 33 Klasa NativeMenuItem 89 little-endian, kolejność bajtów 158 klawisz Command 90 load, zdarzenia 240 J Java Cryptography Architecture (JCA) 366 klawisz Control 90 load, zdarzenie 221, 223, 244 klawisz Shift 90 load(), metoda (FileReference, klasa) 130 JavaScript klawisze modyfikatorów, pozycje menu 90 loadBytes(), metoda (klasa Loader) 42 klawisze podstawowe Loader, klasa 69 isSetAsDefaultApplication(), metoda (klasa NativeApplication) 301 AIR, obsługa 222 błędy 237, 244, 255, 258 dostęp do, interfejsy API środowiska AIR 241 odwołania do skryptów między plikami w języku ActionScript 243 PDF 275 plik AIRAliases.js 220, 241 programowanie 235 środowisko wykonawcze AIR 219 unikanie błędów dotyczących bezpieczeństwa 237 pozycje menu 90 klawisze skrótów dla poleceń menu 90 klucze podstawowe bazy danych 186 klucze prywatne 366 kody błędów DRM 288 kolejność bajtów 158 kolejność okien 74 kolejność wyświetlania, okna 74 Loader.loadBytes(), metoda 42 LoaderContext, klasa allowLoadBytesCodeExecution, właściwość 42 applicationDomain, właściwość 36 securityDomain, właściwość 36 LoaderInfo, klasa childSandboxBridge, właściwość 37 parentSandboxBridge, właściwość 37 loadString() metoda (HTMLLoader, klasa) 36 zabezpieczenia 250 kolumny (baza danych) 168 zdarzenia błędów 254 kompresowanie danych 159 loadString(), metoda (kasa HTMLLoader) 235 zdarzenia, obsługa 257 konstruktory funkcji (w JavaScript) 223 LocalConnection, klasa 316, 323 kopiowanie i wklejanie locationChange, zdarzenie 254 javascript, schemat URL 34, 229, 239 JavaScript, zabezpieczenia 33 domyślne polecenia menu (Mac OS) 153 JavaSoft, certyfikaty programistów 326 HTML 151, 225 języki, obsługiwane w instalatorze aplikacji AIR 50 odpowiedniki klawiszy 154 polecenia menu 152 logowanie, uruchamianie aplikacji AIR podczas 296 JSON 223 skróty klawiszy 152 lokalizowanie 346 kopiowanie katalogów 118 logowanie do systemu, uruchamianie aplikacji AIR podczas 296 lokalne bazy danych Patrz bazy danych K karnacja niestandardowa 63 kopiowanie plików 120 kopiowanie, zdarzenie 151 lokalne obszary izolowane z obsługą sieci 28 karnacja systemowa 63 kosz (usuwanie pliku) 121 lokalne obszary izolowane z systemem plików 28, 222 okna HTML 68 katalog aplikacji 109 katalog dokumentów 109 katalog osobisty 109 katalog pulpitu 109 katalog zapisu aplikacji 26, 109, 113, 242 kupony, używanie z treścią zaszyfrowaną DRM 279 kursor, efekty przeciągania i upuszczania 140, 144 lokalne zaufane obszary izolowane 28, 222 M Mac OS ikony proxy 66 pasek narzędziowy 66 magazyny kluczy 366, 371 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 380 Indeks mainScreen, właściwość (klasa Screen) 84 maksymalizacja okien 52, 62, 76 minimizable, element (plik deskryptora aplikacji) 52 maximizable, element (plik deskryptora aplikacji) 52 minimize(), metoda (klasa NativeWindow) 76 maximize(), metoda (klasa NativeWindow) 76 minimumPatchLevel, atrybut (plik deskryptora aplikacji) 46 maxSize, element (plik deskryptora aplikacji) 52 minSize, element (plik deskryptora aplikacji) 52 menu 87 mnemonicIndex, właściwość aplikacja 92, 99 NativeMenuItem, klasa 91 Dock 88 model DOM HTML i rodzime okna 61 domyślne 88 modificationDate, właściwość (klasa File) 119 ikona paska zadań 92 ikony paska zadań 88 klasy do pracy z 88 menu kontekstowe 93 niestandardowe 88 Moje dokumenty, katalog (Windows) 109 monitory Patrz ekrany mosty obszaru izolowanego 32, 36, 221, 222, 237, 250 supportsDockIcon, właściwość 102 supportsMenu, właściwość 99 supportsSystemTrayIcon, właściwość 102 NativeApplication,klasa właściwość autoExit 298 właściwość startAtLogin 296 NativeApplication.setAsDefaultApplication (), metoda 301 NativeBoundsEvent, klasa 80 nativeDragComplete, zdarzenie 135, 139, 141 nativeDragDrop, zdarzenie 135 nativeDragEnter, zdarzenie 135, 139, 140, 141 NativeDragEvent, klasa clipboard, właściwość 140 dropAction, właściwość 139, 140 odpowiedniki klawiszy 90 mouseDown, zdarzenie 78, 135 nativeDragExit, zdarzenie 135, 141 okno 92, 99 mouseMove, zdarzenie 135 NativeDragManager, klasa podmenu 89, 92 move, zdarzenie 62, 80 podręczne 92, 97 moveTo(), metoda polecenia kopiowania i wklejania 152 pozycja Docku 92 File, klasa 120 Window, obiekt 61 pozycje 89 moveToAsync(), metoda (klasa File) 120 struktura 88, 89 moveToTrash(), metoda (klasa File) 121 strumień zdarzenia 89, 97 tworzenie 92 moveToTrashAsync(), metoda (klasa File) 121 typy 88 moving, zdarzenie 80 zdarzenia 99 menu aplikacji 87, 99 tworzenie 92 menu Docku 88 doDrag(), metoda 135, 137, 140 nativeDragOver, zdarzenie 135, 139, 140, 141 nativeDragStart, zdarzenie 135, 141 nativeDragUpdate, zdarzenie 135, 141 NativeMenuItem, klasa data, właściwość 91 keyEquivalent, właściwość 90 keyEquivalentModifiers, właściwość 90 wiersze separatora 93 XML, definiowanie za pomocą 95 acceptDragDrop(), metoda 135, 140 N name, element (plik deskryptora aplikacji) 49 mnemonicIndex, właściwość 91 submenu, właściwość 89 właściwość label 153 name, właściwość (klasa File) 119 nativePath, właściwość (klasa File) 109, 119 NativeApplication, klasa 229 NativeWindow, klasa 61 activeWindow, właściwość 73 activate, metoda 74 applicationDescriptor, właściwość 300 activate(), metoda 68, 74 copy(), metoda() 153 addEventListener(), metoda 80 getDefaultApplication(), metoda 301 alwaysInFront, właściwość 74 icon, właściwość 102 close(), metoda 75 id, właściwość 300 dispatchEvent(), metoda 62 messageHandler, właściwość (PDF) 276 idleThreshold, właściwość 302 JavaScript, dostęp 220 Microsoft Authenticode, certyfikaty 326 isSetAsDefaultApplication(), metoda 301 konstruktor 68 Microsoft Authenticode, id. elektroniczne 325 lastUserInput, właściwość 302 maximize(), metoda 76 metoda addEventListener() 293 minimize(), metoda 76 Microsoft Windows metoda exit() 298 orderBehind(), metoda 74 publisherID, właściwość 300, 325 orderInBackOf(), metoda 74 removeAsDefaultApplication(), metoda 301 orderInFrontOf(), metoda 74 HTML, kopiowanie i wklejanie 225 runtimePatchLevel, właściwość 302 orderToFront(), metoda 74 HTML, przeciąganie i upuszczanie 143 runtimeVersion, właściwość 302 restore(), metoda 76 setAsDefaultApplication(), metoda 53 stage, właściwość 71 menu kontekstowe 87, 93 HTML 94 menu okien 87, 99 tworzenie 92 menu podręczne 87, 97 tworzenie 92 ikony paska tytułowego 66 migracja podpisu 327, 370 MIME, typy minimalizowanie okien 52, 62, 74, 76 orderToBack(), metoda 74 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 381 Indeks startMove(), metoda 79 odczytywanie plików 122 zachowanie 63 startResize(), metoda 78 odinstalowywanie zamykanie 62, 75, 298 systemChrome, właściwość 63 systemMaxSize, właściwość 68 systemMinSize, właściwość 68 transparent, właściwość 63, 64 tworzenie instancji 72 środowisko wykonawcze AIR 2 odniesienia do obiektów kopiowanie i wklejanie -pomoc 150 odpowiedniki klawiszy kopiowanie i wklejanie 154 zarządzanie 73 zdarzenia 80 zmiany rozmiarów 52, 62, 78 okna dialogowe wyboru katalogów 111 okna dialogowe wyboru plików 112 type, właściwość 63 odpowiedniki klawiszy dla poleceń menu 90 okna o wyglądzie „kanapkowym” 74 visible, właściwość 68, 74 odwołania do skryptów między plikami 36, 243, 249 okna pulpitu odwołania obiektów okna w trybie pełnoekranowym 81 zdarzenia 80 nativeWindow, obiekt Window, obiekt 220, 228 nativeWindow, właściwość Stage, klasa 67, 73 nativeWindow, właściwość (obiekt okna) 61, 69 obsługa przeciągania i upuszczania 134 Patrz okna onclick, moduł obsługi 240 ogranicznik ścieżki (system plików) 111 ondominitialize, atrybut 230 OID, nazwa kolumny (SQL) 187 onload, moduł obsługi 33 okna 60 onmouseover, moduł obsługi 240 aktywne 73, 74 open(), metoda NativeWindowDisplayStateEvent, klasa 81 aktywowanie 68 NativeWindowInitOptions, klasa 67, 68 inicjalizowanie 66 nazwa wydawcy 323 karnacja 63 open(), metoda (klasa SQLConnection) 171 nazwane parametry (w instrukcjach SQL) 177 karnacja niestandardowa 63 karnacja systemowa 63 openAsync(), metoda (klasa SQLConnection) 171, 174 nazwy użytkowników klasy do pracy z 61 opener, właściwość (obiekt okna) 69 kolejność 74 orderBehind(), metoda (klasa NativeWindow) 74 konfigurowanie dla zaszyfrowanych treści multimedialnych 279 NetStream, klasa preloadEmbeddedMetadata(), metoda 282 kolejność wyświetlania 74 lightweight 63 maksymalizacja 52, 62, 76 resetDRMVouchers(), metoda 284 minimalizowanie 52, 62, 74, 76 setDRMAuthenticationCredentials(), metoda 280, 284 nieprostokątne 64 Netstream, klasa okna normal 63 okna utility 63 SQLConnection, klasa 171 Window, obiekt 35, 68, 229 orderInBackOf(), metoda (klasa NativeWindow) 74 orderInFrontOf(), metoda (klasa NativeWindow) 74 orderToBack(), metoda (klasa NativeWindow) 74 początkowe 61 orderToFront(), metoda (klasa NativeWindow) 74 nieaplikacyjne obszary izolowane 30, 148, 221, 222, 236, 237, 250 położenie 52 ośrodki certyfikacji 44 przenoszenie okien 84 outerHTML, właściwość 227 nienazwane parametry (w instrukcjach SQL) 178 przesuwanie 62, 78, 79 niestandardowy interfejs użytkownika aktualizacji aplikacji 333 przywracanie 62, 76 odtwarzanie zaszyfrowanej treści 280 przezroczystość 52, 64 nieznana nazwa wydawcy (w instalatorze aplikacji AIR) 323 rozmiar 52, 68 normal, okna 63 rozmiar minimalny 68 NSHumanReadableCopyright, pole (Mac OS) 50 strumień zdarzenia 62 rozmiar maksymalny 68 P P12, pliki 325 paintsDefaultBackground, właściwość (klasa HTMLLoader) 64, 71 pakowanie plików AIR AIR Developer Tool (ADT) 361 styl 63 parameters, właściwość (klasa SQLStatement) 176, 177 tło 64 O obiektu osadzone (w HTML) 221 parametry, w instrukcjach SQL 177 tryby skalowania stołu montażowego 68 parent, właściwość (klasa File) 119 tworzenie 66, 72, 235 obiekty serializowane parent, właściwość (obiekt okna) 69 typy 63 parentSandboxBridge, właściwość kopiowanie i wklejanie -pomoc 150 ukrywanie 74 obsługa przeciągania i upuszczania 134 widoczność 52 obszar izolowany aplikacji 28, 221, 222, 235, 236, 237, 240, 250, 302 właściwości 51 obszary izolowane 28, 222, 249, 302 LoaderInfo, klasa 37 Window, obiekt 32, 228 wygląd 63 parentSandboxBridge, właściwość (obiekt Window) 251 wyświetlanie 74 pasek narzędziowy (Mac OS) 66 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 382 Indeks pasek zadań, ikony 102 pomoc techniczna 10 paski menu 89 postMessage(), metoda (obiekt PDF) 276 instalowanie aplikacji AIR z 321 PDF poświadczenia uruchamianie aplikacji AIR z 296, 322 obsługa 221, 274 PDF, treść dodawanie do aplikacji AIR 274 komunikacja ze skryptami JavaScript 275 ładowanie 275 znane ograniczenia 277 pdfCapability, właściwość (klasa HTMLLoader) 274 Pęk kluczy (skojarzenie zaszyfrowanych danych z użytkownikami) 217 dla treści zaszyfrowanej mechanizmem DRM 288 poświadczenia użytkowników i bezpieczeństwo 43 przeglądarki sieci Web wykrywanie środowiska wykonawczego AIR 319 wykrywanie, czy aplikacja AIR jest zainstalowana 320 powiązania typu pliku 295 przenoszenie katalogów 118 poziomy poprawek przenoszenie plików 120 AIR, środowisko wykonawcze 302 przesuwanie okien 62, 78, 79 poziomy poprawek, środowisko wykonawcze AIR 46 przykładowe aplikacje 2 pozycje menu 89 publisherid, plik 300 przywracanie okien 62, 76 PFX, pliki 325 checked 91 placeLoadStringContentInApplicationSand box, właściwość (HTMLLoader, klasa) 36, 235 data, przypisywanie do 91 playerType, właściwość odpowiedniki klawiszy 90 R ramka pływająca, elementy 31, 221, 224, 229 Capabilities, klasa 302 publisherID, właściwość (klasa NativeApplication) 300, 325 enabled 91 klawisze skrótu 90 stany 91 ramki 31 plik AIRAliases.js 241 tworzenie 93 ramki, elementy 221, 224, 229 plik deskryptora aplikacji 45 wybieranie 98 readBytes(), metoda (klasa ByteArray) 156 znaki mnemoniki 91 readFloat(), metoda (klasa ByteArray) 156 odczytywanie 300 plik konfiguracyjny aktualizacji (architektura aktualizacji) 339 pozycje menu, checked 91 readInt(), metoda (klasa ByteArray) 156 pozycje menu, enabled 91 readObject(), metoda (klasa ByteArray) 156 baza danych 167 preloadEmbeddedMetadata(), metoda (klasa NetStream) 282 readUTFBytes(), metoda (klasa ByteArray) 156 kopiowanie 120 print(), metoda (obiekt Window) 222 kopiowanie i wklejanie -pomoc 150 Program Files, katalog (Windows) 314 RegExp, obiekty, konwertowanie między ActionScript i JavaScript 248 obsługa przeciągania i upuszczania 134 odczytywanie 122 programMenuFolder, element (plik deskryptora aplikacji) 51 odwołania 111 programowanie asynchroniczne pliki przenoszenie 120 usuwanie 121 zapisywanie 122 system plików 107 programowanie synchroniczne system plików 107 rejestrowanie typów plików 301 relacyjne bazy danych Patrz bazy danych relativize(), metoda (klasa File) 114 removeAsDefaultApplication(), metoda (klasa NativeApplication) 301 pliki cookie 225 przeciąganie do wewnątrz, gest 134, 139 removeEventListener(), metoda 258 pliki tymczasowe 122 przeciąganie i upuszczanie resetDRMVouchers(), metoda (klasa NetStream) 284 pliki, interfejs API 107 podmenu 89, 92 do nieaplikacyjnego obszaru izolowanego (w HTML) 148 podpisy domyślne zachowanie w HTML 142 migracja 327, 370 Flex, obsługa 136 podpisy elektroniczne 323, 361, 366 formaty przesyłania 134 podpisywanie kodu 44, 323 gesty 134 podpisywanie plików AIR 361 HTML 141, 226 pola (baza danych) 168 klawisze modyfikatorów 140 polecenia menu kursor, efekty 140, 144 kopiowanie i wklejanie 153 polecenia, menu Patrz pozycje menu połączenie z bazą danych 174 powiązane klasy 134 zdarzenia w HTML 142 przeciąganie na zewnątrz, gest 134, 136 przeglądanie położenie myszy podczas przeciągania 141 w celu wyboru katalogu 111 położenie okien 52 w celu wyboru pliku 112 resizable, element (plik deskryptora aplikacji) 52 resize, zdarzenie 62, 80 resizing, zdarzenie 80 resolvePath(), metoda (klasa File) 109 Responder, klasa 176, 186 restore(), metoda (klasa NativeWindow) 76 result, zdarzenie 176 rodzime menu Patrz menu rodzime okna Patrz okna ROWID, nazwa kolumny (SQL) 187 _ROWID_, nazwa kolumny (SQL) 187 rozbudowane aplikacje internetowe (RIA) 7 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 383 Indeks rozmiar, okna 68 separator, właściwość (klasa File) 116 SQLEvent, klasa 169 rozszerzenia (plik), kojarzenie z aplikacją AIR 53 serializowanie obiektów 136 SQLIndexSchema, klasa 169 setAsDefaultApplication(), metoda (klasa NativeApplication) 53, 301 SQLLite, obsługa bazy danych 166 setData(), metoda SQLMode, klasa 169, 175 rozszerzenia (plik), powiązanie z aplikacją AIR 295 rozszerzenia (plików), kojarzenie z aplikacją AIR 301 runtime, właściwość (obiekt Window) 69, 220, 228, 241 runtimeApplicationDomain, właściwość (klasa HTMLLoader) 244 runtimePatchLevel, właściwość (klasa NativeApplication) 302 runtimeVersion, właściwość (klasa NativeApplication) 302 S sandboxRoot, atrybut (elementy ramek i ramek pływających) 221, 224, 229, 250 sandboxRoot, właściwość ramka 31 ramka pływająca 31 sandboxType, właściwość Patrz także bazy danych ClipboadData, obiekt 225 SQLResult, klasa 169, 186 DataTransfer, obiekt 143, 145, 226 SQLSchemaResult, klasa 169 setDragImage(), metoda (dla właściwości dataTransfer zdarzenia przeciągania HTML) 143 SQLStatement, klasa 169, 175 execute, metoda 177 setDRMAuthenticationCredentials(), metoda (klasa NetStream) 280, 284 execute(), metoda 179, 186 setInterval(), funkcja 34, 228, 239 parameters, obiekt 176 setTimeout(), funkcja 34, 228, 239 parameters, właściwość 177 silne powiązanie zaszyfrowanych danych 217 sqlConnection, właściwość 176 getResult(), metoda 186 text, właściwość 176, 177, 179, 188 size, właściwość (klasa File) 119 SQLTableSchema, klasa 169 skojarzenia typów plików 53, 301 SQLTransactionLockType, klasa 169 skróty klawiszy SQLTriggerSchema, klasa 169 kopiowanie i wklejanie 152 SQLUpdateEvent, klasa 169 spaceAvailable, właściwość (klasa File) 116 SQLViewSchema, klasa 169 SQL środowisko wykonawcze AIR klasa BrowserInvokeEvent 297 AUTOINCREMENT, kolumny 187 Security, klasa 302 CREATE TABLE, instrukcja 172 save(), metoda (FileReference, klasa) 130 DELETE, instrukcja 188 scaleMode, właściwość informacje 169 nowe funkcje 55 Stage class nativeWindow property 73 Stage, klasa INSERT, instrukcja 191 addChild(), klasa 71 schematy URL 113 instrukcje 175 addChildAt(), metoda 71 Schowek 225 INTEGER PRIMARY KEY, kolumny 187 displayState, właściwość 81 klasy używane z językiem 169 nativeWindow, właściwość 67 Stage, klasa 78 kopiowanie i wklejanie 150 ścieżki (plików i katalogów) 113 nazwane parametry (w instrukcjach) 177 ścieżki względne (między plikami) 114 nienazwane parametry (w instrukcjach) 178 ścieżki, względne 114 Screen, klasa 83 getScreenForRectangle(), metoda 84 mainScreen, właściwość 84 screens, właściwość 84 screens, właściwość (klasa Screen) 84 screenX, właściwość (zdarzenia przeciągania HTML) 143 OID, nazwa kolumny 187 określanie typów danych 178, 191 parametry w instrukcjach 177 ROWID, nazwa kolumny 187 _ROWID_, nazwa kolumny 187 SELECT, instrukcja 179, 191 UPDATE, instrukcja 188 scaleMode, właściwość 68, 78 stage, właściwość NativeWindow, klasa 71 StageDisplayState, klasa 81 StageScaleMode, klasa 68, 78 Start, menu (Windows) 51 startAtLogin, właściwość (klasa NativeApplication) 296 startMove(), metoda (klasa NativeWindow) 79 screenY, właściwość (zdarzenia przeciągania HTML) 143 SQLCollationType, klasa 169 SQLColumnNameStyle, klasa 169 startResize(), metoda (klasa NativeWindow) 78 scroll, zdarzenie 254 SQLConnection, klasa 169 StatusEvent, klasa 280 Security, klas allowDomain(), metoda 36, 41 Security, klasa sandboxType, właściwość 302 attach(), metoda 188 open, metoda 171 open(), metoda 171 openAsync(), metoda 171, 174 stylesheets, HTML manipulowanie w kodzie ActionScript 248 styleSheets, właściwość (obiekt Document) 248 securityDomain, właściwość (klasa BrowserInvokeEvent) 297 sqlConnection, właściwość (klas SQLStatement) 176 subErrorID, właściwość (klasa DRMErrorEvent) 288 SELECT, instrukcja (SQL) 179, 191 SQLError, klasa 169, 176 submenu, właściwość select, zdarzenie 89, 98, 99 SQLErrorEvent, klasa 169, 176 NativeMenuItem, klasa 89 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 384 Indeks Sun Java, podpisywanie, id. elektroniczne 325 transparent, właściwość (klasa NativeWindow) 63, 64 V Verisign, certyfikaty 324, 325 supportsDockIcon, właściwość (klasa NativeApplication) 102 tworzenie katalogów 117 version, element (plik deskryptora aplikacji) 48 supportsSystemTrayIcon, właściwość (klasa NativeApplication) 102 type, właściwość (klasa NativeWindow) 63 SVG (skalowalna grafika wektorowa) 222 SWF, pliki ładowanie za pomocą znacznika script 246 SWF, treść type, właściwość (klasa File) 119 types, właściwość DataTransfer, obiekt 226 zdarzenie kopiowania i wklejania HTML 151 zdarzenie przeciągania HTML 143 nakładanie na HTML 70 types, właściwość (DataTransfer, obiekt) 146 w HTML 221 typy danych, baza danych 191 synchroniczne programowanie XMLHttpRequests 240 synchroniczne, programowanie bazy danych 170, 174, 192 system plików zabezpieczenia 40 systemChrome, właściwość (klasa NativeWindow) 63 systemMaxSize, właściwość (klasa NativeWindow) 68 systemMinSize, właściwość (klasa NativeWindow) 68 U ukrywanie okien 74 uncaughtScriptExcpetion, zdarzenie 254 uncompress(), metoda (klasa ByteArray) 159 unload, zdarzenia 227 UntrustedAppInstallDisabled (ustawienia rejestru Windows) 27 UPDATE, instrukcja (SQL) 188 update(), metoda (klasa Updater) 331 visible, element (plik deskryptora aplikacji) 52 visible, właściwość NativeWindow, klasa 68, 74 W WebKit 219, 222, 233 -webkit-border-horizontal-spacing, właściwość CSS 233 -webkit-border-vertical-spacing, właściwość CSS 233 -webkit-line-break, właściwość CSS 233 -webkit-margin-bottom-collapse, właściwość CSS 233 -webkit-margin-collapse, właściwość CSS 233 -webkit-margin-start, właściwość CSS 233 -webkit-margin-top-collapse, właściwość CSS 233 -webkit-nbsp-mode, właściwość CSS 233 -webkit-padding-start, właściwość CSS 233 szyfrowanie 279 UpdateDisabled (ustawienia rejestru Windows) 27 szyfrowanie treści wideo 279 Updater, klasa 331 -webkit-text-fill-color, właściwość CSS 233 Uprawnienia wymagane do aktualizacji środowiska wykonawczego AIR lub aplikacji AIR 315, 322 -webkit-text-security, właściwość CSS 233 T tabele (baza danych) 168 uprawnienia wymagane do aktualizacji środowiska wykonawczego AIR lub aplikacji AIR 25 -webkit-user-modify, właściwość CSS 234 url, właściwość wersje, aplikacja AIR 302 tworzenie 172 tablice bajtów kolejność bajtów 158 pozycja w 157 wielkość 157 tekst kopiowanie i wklejanie -pomoc 150 obsługa przeciągania i upuszczania 134, 143 text, właściwość (klasa SQLStatement) 176, 177, 179, 188 TextField, klasa HTML załadowany do 235 File, klasa 109, 119 url, właściwość (klasa File) 109 URLs ładowanie treści HTML z 235 -webkit-rtl-ordering, właściwość CSS 233 -webkit-user-drag, właściwość CSS 142, 234, 145 -webkit-user-select, właściwość CSS 142, 145, 234 widoczność okien 52 width, element (plik deskryptora aplikacji) 52 width, właściwość (klasa HTMLLoader) 235 URLStream, klasa 224 wielkość okien 52 uruchamianie aplikacji AIR 293, 314, 322 wiersze (baza danych) 168, 186 uruchomienie (systemu), uruchamianie aplikacji AIR podczas 296 wiersze separatora, menu 93 userDirectory, właściwość (klasa File) 109 Window, obiekt Window, klasa 61 userIdle, zdarzenie 302 childSandboxBridge, właściwość 32 userPresent, zdarzenie 302 close(), metoda 61 ustalanie kolejności okien 74 htmlLoader, obiekt 220 tło okien 64 ustawienia narodowe, wybieranie dla aplikacji 347 htmlLoader, właściwość 69, 228, 235 tłumaczenie aplikacji 346 ustawienia rejestru Windows 27 transparent, element (plik deskryptora aplikacji) 52 usuwanie katalogów 119, 121 img, znaczniki 29 Thawte, certyfikaty 324, 325 title, element (plik deskryptora aplikacji) 52 transparent, okna 52, 64 usuwanie plików 121 utility, okna 63 użytkownik, wykrywanie aktywności 302 moveTo(), metoda 61 nativeWindow, obiekt 220 nativeWindow, właściwość 61, 69, 228 open, metoda 229 open(), metoda 35, 68 TWORZENIE APLIKACJI ADOBE AIR 1.5 W PROGRAMIE ADOBE FLASH CS4 PROFESSIONAL 385 Indeks opener, właściwość 69 parent, właściwość 69 parentSandboxBridge, właściwość 32, 228, 251 print(), metoda 222 runtime, właściwość 29, 35, 69, 220, 228, 241 X x, element (plik deskryptora aplikacji) 52 zamykanie okien 62, 75, 298 XML zasobnik systemowy, ikony definiowanie menu za pomocą 95 klasa 241 XML, przestrzeń nazw (plik deskryptora aplikacji) 46 zapisywanie plików 122 obsługa 102 zaszyfrowane dane, przechowywanie i pobieranie 217 zatwierdzanie danych WindowedApplication, klasa 61 XMLHttpRequest, obiekt 35, 223, 229, 240 Witryna pomocy technicznej firmy Adobe 10 XMLList, klasa 241 zdalne obszary izolowane 28, 222 właściwość bytesAvailable (klasa ByteArray) 157 xmlns (plik deskryptora aplikacji) 46 zdarzenia y, element (plik deskryptora aplikacji) 52 właściwość clipboardData (zdarzenia kopiowania i wklejania HTML) 151 właściwość contextMenuOwner (klasa ContextMenuEvent) 93 wywołanie aplikacji 297 detektory 257 HTML 254 Z zabezpieczenia asfunction, protokół 30 menu 89, 97 moduły obsługi 257 NativeWindow, klasa 80 właściwość keyEquivalent (klasa NativeMenuItem) 90 ataki na skutek zamiany wersji na starszą 44 właściwość keyEquivalentModifiers (klasa NativeMenuItem) 90 zdarzenia menuItemSelect 90 błędy JavaScript 237 zdarzenia menuSelect 90 bufor międzydomenowy 30 zdarzenie contextmenu 94 CSS 30 zdarzenie load 237 dynamiczne generowanie kodu 33 zdarzenie zamknięcia 298 eval(), funkcja 33 zdarzenie zamykania 298 funkcja wywoływania z przeglądarki 297 ZIP, format pliku 161 HTML 31, 33, 219, 221, 236 ZLIB, kompresja 159 woluminy główne 109 img, znaczniki 29 zmiany rozmiarów okien 52, 62, 78 write(), metoda (obiekt Document) 227, 240 instalowanie (aplikacja i środowisko wykonawcze) 24 znaczniki czasowe 326 właściwość length (klasa ByteArray) 157 właściwość mouseTarget (klasa ContextMenuEvent) 93 właściwość position (klasa ByteArray) 157 właściwość supportsMenu (klasa NativeApplication) 99 writeBytes(), metoda (klasa ByteArray) 156 writeFloat(), metoda (klasa ByteArray) 156 writeInt(), metoda (klasa ByteArray) 156 writeln(), metoda (obiekt Document) 227, 240 JavaScript 250 katalog zapisu aplikacji 26 ładowanie treści 69 znaki mnemoniki writeUTFBytes(), metoda (klasa ByteArray) 156 nieaplikacyjne obszary izolowane 30 wtyczki (w HTML) 221 obszary izolowane 28 wycinanie, zdarzenie 151 wygląd okien 63 odwołania do skryptów między plikami 36 wyliczanie ekranów 84 pola tekstowe 29 wyliczanie katalogów 118 poświadczenia użytkownika 43 wymagania ramka 30, 31 obszar izolowany aplikacji 28 ramka pływająca 30, 31 wymiary, okna 52 sprawdzone procedury 42 wystawcy certyfikatów (CA) 323 struktura Ajax 34 wyświetlacze system plików 40 wyświetlanie okien 74 wywołanie aplikacji AIR 293 wywoływanie z przeglądarki, funkcja 296 wywoływanie zdarzenia 293 src, właściwość 34 Loader.loadBytes(), metoda 42 mosty obszaru izolowanego 32, 36, 250 Patrz ekrany znaczniki script 223, 227, 240, 242, 246 znak zapytania (?) znak, w nienazwanych parametrach SQL 178 writeObject(), metoda (klasa ByteArray) 156 renderowanie PDF 274 rodzime okna 62 uprawnienia użytkownika podczas instalacji 25 window.open() 35 XMLHTTPRequest 230 XMLHttpRequest, obiekty 35 zamykanie aplikacji 298 zamykanie aplikacji AIR 293 pozycje menu 91