IntroductionWelcome| 00:04 | Hi! I am James Talbot, and welcome to AIR 2
with Flash and Flex Essential Training.
| | 00:10 | In this course, I'll be showing you
how to develop cross-platform desktop
| | 00:14 | applications for Adobe AIR 2.0.
| | 00:17 | I'll walk you through prototyping an
AIR application with Flash Catalyst.
| | 00:21 | We'll talk about how to package and to
play applications, including digitally
| | 00:25 | signing and installing them
right on the end user's machine.
| | 00:28 | We'll also talk about using system
windows, and we'll examine how to create
| | 00:33 | application windows on multiple platforms.
| | 00:36 | And we'll even display HTML
content right in Adobe AIR 2.0.
| | 00:40 | We'll implement AIR security, and
we'll talk about how to encrypt and lock
| | 00:46 | down that database.
| | 00:48 | I love working with AIR, and I am
thrilled to be able to share my knowledge,
| | 00:51 | tip, and tricks with you.
| | 00:53 | So let's roll up our sleeves and
explore AIR 2 with Flash and Flex.
| | Collapse this transcript |
| Understanding the prerequisites| 00:00 | In order to get the most from this
course, we are going to assume that
| | 00:03 | you know ActionScript 3.
| | 00:05 | Whether you've learned ActionScript 3
from working with Flash CS5 or from Flash
| | 00:10 | Builder, that knowledge will
serve you well in this course.
| | 00:14 | We will primarily be using Flash
Builder as our main integrated development
| | 00:18 | environment, but we'll be focusing on
the AIR-specific APIs that are utilized
| | 00:24 | inside of ActionScript 3.
| | Collapse this transcript |
| Using the exercise files| 00:00 | If you have access to the exercise
files for this course, you can put them on
| | 00:03 | your desktop, as I have, or anywhere
else on your system that you like.
| | 00:07 | The top folder contains subfolders
for each chapter, which contain the
| | 00:12 | exercise files themselves.
| | 00:14 | As you can see, if I open up one of
the subfolders, for example Creating
| | 00:18 | Application Windows, there is both
a Begin folder and an End folder.
| | 00:23 | The Begin folder contains the
starting files for each exercise, and all the
| | 00:27 | exercises for this lesson
are included in this fxp file.
| | 00:32 | The End file are all of the completed exercises.
| | 00:36 | So in case you have any problems or
anything, you can import the End project and
| | 00:42 | be able to see the finished,
completed version, which should be working.
| | 00:46 | If you do not have access to these
files, you can follow along with your own
| | 00:49 | files as we proceed throughout the course.
| | Collapse this transcript |
|
|
1. Getting Started Understanding the runtime application| 00:00 | Adobe AIR allows applications to be
used outside of the browser, integrating
| | 00:04 | directly with the desktop.
| | 00:06 | The beauty of this is the application
can be built once in the tool or the
| | 00:10 | language of the developer's choice,
and then it can be deployed to multiple
| | 00:14 | platforms, including Mac, Windows,
Linux, as well as multiple different smart
| | 00:19 | phones and tablets, and that sort of thing.
| | 00:22 | The application can be written in Ajax,
| | 00:25 | it can be written utilizing Flash
Catalyst, if you don't know any code at all,
| | 00:29 | or it can be written in Flex using Flash
Builder, or it can even be written in Flash CS5.
| | 00:36 | These applications provide a lot more
than is able to be provided in the browser.
| | 00:41 | So, for example, we can provide notifications.
| | 00:43 | This provides the ability for these
applications to run in the background and
| | 00:47 | provide information on an as needed basis.
| | 00:50 | An example might be a social application,
having your Facebook update statuses
| | 00:55 | pop up or have Twitter status as pop up.
| | 00:57 | That would be a great example of being
able to utilize notifications and have
| | 01:01 | that pop up while you are
in a Microsoft Word document,
| | 01:03 | completely outside of the browser.
| | 01:06 | AIR also enables customers to
develop a better branded experience.
| | 01:10 | We can do something totally outside of
a browser, have a widget on your desktop
| | 01:14 | that is nothing to do with the
browser at all, and you can get rid of that
| | 01:19 | browser chrome, and you're
really not limited at all.
| | 01:23 | We also have the ability to
access native functionality.
| | 01:26 | So we can have users be able to drag and
drop things directly into our AIR application,
| | 01:31 | be able to create custom Windows in
exactly the way that Linux or Mac or Windows
| | 01:36 | does that and AIR handles
all that complexity for us.
| | 01:40 | So, for example, if we have an
application storage directory, that application
| | 01:43 | storage directory is totally
different on Mac and Windows.
| | 01:48 | But as an AIR developer, I only
have to specify the application storage
| | 01:51 | directory, and AIR handles the
complexity of where that is on the platform,
| | 01:56 | so it makes it really easy
to develop these applications.
| | 02:00 | Same thing is with data management.
| | 02:01 | AIR allows for local data storage, a
local database, and local files, and we can
| | 02:07 | manage our data in a much
more sophisticated manner.
| | 02:09 | We can minimize unnecessary network
traffic and create a great offline use
| | 02:15 | experience for the end user.
| | 02:16 | So, for example, if I need to
access my application when I may not
| | 02:19 | have Internet access,
| | 02:20 | I will be able to use it on a plane or
on a train, and for the developer, I can
| | 02:25 | utilize much more efficient development,
because these applications are built
| | 02:29 | with modern web programming techniques that
are rapidly designed prototyped and delivered.
| | 02:35 | In addition, we have all the
advantages of a web application, because we can
| | 02:38 | provide updates to the end user that we
will learn about in the course as we go on.
| | 02:43 | Let's just take a look at some of
the advantages of an AIR application.
| | 02:46 | What I am going to do is just go over
to my desktop here, and you'll see, right
| | 02:52 | here, I have this workflow lab,
which is an AIR installer package.
| | 02:57 | With an AIR application, you can
actually install this directly to your desktop
| | 03:01 | and be able to utilize this
like a desktop application.
| | 03:04 | So, for example, something like
Photoshop or Flash Catalyst or Flex Builder,
| | 03:09 | you can utilize an AIR
application in the same way.
| | 03:11 | So I'll go for the installation
process, just as you'd install Photoshop.
| | 03:15 | It says, "Are you sure you want to
install this application to your computer?"
| | 03:19 | You can see the publisher it says Adobe
Systems, and you can also see it's been
| | 03:23 | verified, because we have a
Class 3 digital certificate.
| | 03:26 | So, go ahead and just click Install.
| | 03:29 | This will install it here, in
Program Files. I will choose Continue.
| | 03:33 | Windows is warning me,
it's installing this application.
| | 03:36 | It's going to create a desktop shortcut.
| | 03:38 | I can provide a custom icon.
| | 03:40 | You'll see it automatically opened up.
| | 03:42 | But there's also a desktop icon here.
| | 03:44 | You'll see it creates that.
| | 03:45 | You'll see it appears here in my
taskbar, along with that icon, just like
| | 03:49 | PowerPoint appears over here.
| | 03:51 | So it's a desktop application.
| | 03:53 | I can minimize it, I can maximize it,
and I can integrate with the file system.
| | 03:59 | You can see here, for example,
again, this looks just like Photoshop,
| | 04:02 | this Adobe Workflow. And if I just choose
Basic Workflow, I can create a new project.
| | 04:08 | This is just a workflow management tool,
| | 04:10 | sort of similar to something like a
Microsoft project that enables you to
| | 04:13 | track different projects.
| | 04:15 | So, I call this My Project.
| | 04:17 | I can specify a font size, select
whether it's Freeform or whether it is
| | 04:21 | Duration based, and you could see here,
for example, if I look under here, I can
| | 04:27 | add different resources and links, and
that sort of thing, to build my timeline,
| | 04:32 | as well as additional rows.
| | 04:34 | But the main point of this is just
to understand that this is a desktop
| | 04:37 | application, and you can see that
this is sort of the forefront of web
| | 04:42 | application development, and we are
starting to see the emergence of this
| | 04:45 | type of application.
| | 04:47 | These applications work on
multiple different platforms.
| | 04:50 | So, I could install this, whether I
am on Windows, whether I am on a Mac,
| | 04:53 | whether I am on a Linux, or even on
different devices, and this would work
| | 04:57 | exactly the same way, and the
developer only has to develop that code once
| | 05:01 | instead of having the whole Mac team, a
whole Windows team, a whole Android team,
| | 05:06 | I can just develop it once and have
it work exactly the same way in all of
| | 05:10 | these different places.
| | 05:12 | And Adobe AIR 2.0 is about enabling this and
providing a better experience for the end user.
| | 05:20 | So, again it provides a seamless
transition from the browser to the desktop content,
| | 05:26 | so users can take these web
applications even further, and again, we can provide
| | 05:31 | access to all of the capabilities that
that platform, or that device offers.
| | Collapse this transcript |
| Understanding AIR 2| 00:00 | Adobe AIR 2.0 enables you to work in
familiar environments, whether that
| | 00:04 | environment is Flash Builder, Flash
CS5, Flash Catalyst, or even HTML and
| | 00:10 | JavaScript with CSS and
XML, otherwise known as Ajax.
| | 00:14 | We can also leverage the PDF file format
in any application utilizing Adobe AIR.
| | 00:20 | So Adobe AIR itself actually has no interface.
| | 00:23 | It's just simply a wrapper that
allows us to access the operating system.
| | 00:29 | Adobe has gone out and built an Adobe
AIR for Windows, for Mac, for Linux, and
| | 00:34 | for multiple, different device OSs, if
we are targeting Smart Phones or tablets,
| | 00:39 | and that sort of thing.
| | 00:40 | We just develop specifically for Adobe
AIR and not for any specific browser or
| | 00:46 | any specific operating system,
and we don't have to do any testing.
| | 00:50 | So there's two different components of AIR.
| | 00:52 | We have the HTML component that
contains HTML, JavaScript, XML, and of course we
| | 00:57 | can display Flash or PDF.
| | 00:59 | Then we have the Flash component, and
we have Flex, ActionScript, XML, audio,
| | 01:04 | and video, and we can, of course,
display HTML and PDF in there.
| | 01:08 | So that's how Adobe AIR is actually put
together, and we utilized the Adobe AIR
| | 01:14 | SDK, which contains a schema
and a template for an application
| | 01:19 | descriptor file that contains
information about the files, such as the ID, the
| | 01:23 | name, the version of it.
| | 01:25 | It also specifies if we use any default
icons. And then we have a framework for
| | 01:31 | the Adobe AIR APIs in the SDK, and we
have to actually install the SDK, and
| | 01:36 | that's done in another lesson.
| | 01:38 | We also have an AIR installation badge
and a command line tool for building and
| | 01:43 | deploying AIR Applications.
| | 01:45 | So AIR itself is a free technology.
| | 01:48 | You can purchase tools from Adobe, for
example Flash builder or Flash Catalyst -
| | 01:54 | Adobe charges money for those tools,
but AIR itself is a free technology, and if
| | 01:58 | you want to just use Microsoft
Notepad and compile the application via the
| | 02:02 | command line, you're able to do that
simply by downloading the free SDK and
| | 02:07 | installing the free software development kit.
| | 02:10 | So you can publish these AIR projects
from Flash Builder, Flash CS5, and this
| | 02:14 | creates an installer
package and the export wizard.
| | 02:18 | There is also a developer tool that
will enable you to build a native operating
| | 02:22 | system installer package.
| | 02:24 | So, for example, a .exe file for
Windows or a .dmg file for Macintosh.
| | 02:31 | That's called ADT, known as the
Adobe AIR Developer tool, and that is
| | 02:35 | available for free in the SDK.
| | 02:38 | There is also an Air Debug
Launcher that will enable you to test AIR
| | 02:42 | Applications, and the AIR file format
itself is just simply a compressed file
| | 02:47 | format for installation.
| | 02:50 | This includes the application
descriptor and a SWF HTML file.
| | 02:54 | So Adobe AIR itself supports
ActionScript and JavaScript development in the
| | 02:59 | interface that's most comfortable to you.
| | 03:00 | The AIR Developer tool is included
in Flash Builder, Flash CS5, and Flash
| | 03:05 | Catalyst, and is used for packaging
the application into an AIR file.
| | 03:09 | You can also access this from the
command line, if you want a package and install
| | 03:13 | the applications yourself,
because Adobe AIR is a free technology.
| | Collapse this transcript |
| Installing and using the AIR SDK| 00:00 | In this course, we're going to focus
on developing Adobe AIR applications
| | 00:04 | with Flash Builder.
| | 00:06 | In order to do that, we need to
install the Adobe AIR SDK into Flash builder.
| | 00:12 | So the first step that you need to do
is just navigate your web browser to
| | 00:15 | adobe.com/products/air/tools.
| | 00:21 | Scroll down here, and you'll
see the Adobe AIR SDK right here.
| | 00:25 | Go ahead and click on that, and
depending on whether you're on Windows
| | 00:29 | or whether you're on Macintosh or
whether you're on the Linux, download
| | 00:33 | the appropriate SDK.
| | 00:34 | So I'd download the Windows English SDK,
and you could see here I've downloaded
| | 00:40 | this directly to my desktop, the Adobe AIR SDK.
| | 00:44 | Go ahead and open this up with
something like WinZip or whatever's appropriate.
| | 00:49 | In fact, in this case, I just
opened it up with the default, Windows.
| | 00:52 | What I'm going to do is just take
this, take everything in the SDK here,
| | 00:57 | I'm just going to copy it to my
clipboard, and then what I want you to do is
| | 01:02 | navigate to where your
Flash Builder is installed.
| | 01:05 | So on the Macintosh,
that'll be under Applications.
| | 01:09 | In this case, it's under the C drive.
| | 01:12 | You'll see it under Program Files
(x86)/Adobe/Adobe Flash Builder 4.
| | 01:18 | You'll see a directory in here called
sdks, and you should see another directory
| | 01:23 | in here called 4.0.0.
| | 01:26 | What I want you to do is just paste
everything that you copied into this
| | 01:30 | directory, and I want you to just choose
Copy and Replace, and just choose Yes to
| | 01:38 | all, and copy everything in
that SDK to overlay here.
| | 01:43 | Again, I'll do this for the next 151 conflicts.
| | 01:47 | That will, again, allow me to overlay the
current Flex SDK with all of the Adobe AIR SDK.
| | 01:57 | So you'll need this to be able to
follow along in the course, and the Adobe AIR
| | 02:01 | SDK, of course, is free, and it's
available for download, and the Adobe SDK is
| | 02:06 | already there with Flash CS5.
| | 02:09 | So if you're utilizing Flash CS5 as
your primary development tool, you don't
| | 02:12 | need to worry about it.
| | 02:13 | Same thing - it's already there with Flash
Catalyst, so you don't need to worry about it.
| | 02:18 | And of course, for those of you
utilizing Notepad, or another tool, you can unzip
| | 02:24 | that SDK to wherever you'd like.
| | Collapse this transcript |
|
|
2. Getting Started with Flash Builder and Adobe AIRCreating an AIR project in Flash Builder| 00:00 | In order to organize all of our files
and code in an AIR application, Flash
| | 00:05 | Builder uses a metaphor called a project.
| | 00:08 | In this video, we'll create an AIR
project in FlashBuilder 4, and we'll build a
| | 00:12 | very simple application, and test it
in the AIR Debug library Runtime, which
| | 00:17 | comes with the AIR SDK.
| | 00:19 | We'll also examine the AIR-specific settings
that are used when we create a new project.
| | 00:26 | So I'd like you first to open up Flash
Builder, and let's build a new AIR project.
| | 00:32 | So go ahead and click on File > New,
and choose Flex Project, and let's call
| | 00:38 | our project LyndaAIR.
| | 00:42 | You might need to uncheck this Use
default location if it's checked and just hit
| | 00:47 | the Browse button and point this to
the Begin folder in your exercise files.
| | 00:52 | My exercise files are on my desktop, so
I am going to scroll down here, and I am
| | 00:57 | going to point this to the
Begin folder that you see here.
| | 01:01 | The Application type, we're going to
be running our application in Adobe AIR.
| | 01:06 | So you'll see it says
Desktop, and the SDK version,
| | 01:10 | we want to point this to Flex 4.0,
and in the last lesson we learned how
| | 01:14 | to overlay the AIR 2.0 SDK over the Flex SDK
so that we have all of that AIR functionality.
| | 01:22 | If this is not your default SDK, you'll
want to point it to the 4.0 SDK because
| | 01:26 | that is the one that we overlaid.
| | 01:29 | Note here Flex 4.0 requires Adobe AIR 1.5.
| | 01:33 | Again, in our case, we've
overlaid that SDK with Adobe AIR 2.0,
| | 01:38 | so Adobe AIR 2.0 will be
required for this project.
| | 01:41 | We are also not going to use a server
technology for now, so we are not going to
| | 01:45 | use a remote object or anything like that,
| | 01:46 | so you can leave that blank and
just have that set to None/Other.
| | 01:52 | Our Output folder is where
our files will be published to.
| | 01:55 | That's the bin-debug folder.
| | 01:57 | You can leave that default there.
| | 01:59 | Note, Flash Builder will include all of the
different libraries that we need for AIR;
| | 02:04 | notice here is our airglobal.swc,
the framework.swc, spark.swc.
| | 02:09 | All of these SWCs are automatically
included in our application that AIR needs
| | 02:14 | because we specified this as an AIR
project, so it makes it very easy to use.
| | 02:19 | The component set is going to be MX+Spark.
| | 02:22 | Spark are the new components that
are supported in Flex 4, and MX are, of
| | 02:27 | course, the old components.
| | 02:28 | We want to give ourselves
the flexibility to use both.
| | 02:31 | So go ahead and just make sure
that radio button there is checked.
| | 02:35 | Make sure your Main source folder is
set to src, and your Main application file
| | 02:40 | should be LyndaAIR.mxml.
| | 02:44 | The Application ID, these should
always be globally unique to prevent name
| | 02:50 | confusion in the installed end user environment.
| | 02:53 | What many developers do is they
use a reverse domain name notation.
| | 02:58 | So let's follow that convention,
and we'll say com.lynda.LyndaAIR.
| | 03:06 | We are sort of using that reverse name
notation just to provide a unique ID to
| | 03:11 | avoid any confusion when
applications are installed;
| | 03:14 | that's very important.
| | 03:15 | And again, that's unique to an AIR application.
| | 03:18 | So now go ahead and click Finish, and
Flash Builder will automatically create us
| | 03:22 | a main.mxml file, and note, for those of
you who are used to developing in Flex,
| | 03:29 | note that our main tag here is a
WindowedApplication, not an Application because
| | 03:35 | this is a desktop application.
| | 03:37 | Let's go ahead and just build a really
simple little project here, and the first
| | 03:42 | thing I'd like you to do is just
simply add in a Layout tag to tell us that
| | 03:46 | we're going to be organizing all
of our assets in a vertical fashion.
| | 03:50 | So I am going to just say s:layout,
like you see there, and we will specify
| | 03:56 | s:VerticalLayout, and then I'll
specify I'd like to have a paddingLeft=10
| | 04:06 | pixels and a paddingTop= 10 pixels,
just to provide some margins here.
| | 04:14 | Make sure you close off your
VerticalLayout tag, like so.
| | 04:17 | Of course, you should have your
ending layout tag there.
| | 04:20 | Let's just add a few other spark components.
| | 04:23 | So the first thing I'll do is
just simply add a label control.
| | 04:27 | So I'll say <s:label, as you see
there, and let's assign this an
| | 04:34 | id="myLabel," and let's set some text
here, and I'm just going to simply say
| | 04:43 | text="Web applications"/>.
| | 04:50 | So I will click there.
| | 04:51 | There is my little label control.
| | 04:54 | Then immediately after that,
I will add a Button control.
| | 04:57 | So I will say <s:button, as you see there,
and I'll add a click event to the button.
| | 05:06 | So I'll say click=, and let's just
change the text control in the myLabel.
| | 05:12 | So I'll say myLabel -
| | 05:14 | notice the introspection appears right here -
| | 05:17 | I'll say myLabel.text=, and we
will put in the word, "Become
| | 05:25 | desktop applications."
| | 05:28 | So when the user clicks the button, it
will change the text of that label control;
| | 05:33 | very simple little application.
| | 05:35 | So I'll close that, and I
will also close my Button tag.
| | 05:39 | Now, you can see I've built a very
simple AIR application, and I can run this
| | 05:44 | AIR application just as I
would a Flex application.
| | 05:48 | But instead of showing it in the Flash
player, it's going to show it in the AIR
| | 05:52 | Debug Library that comes with the AIR SDK.
| | 05:56 | So let's take a look at that, and
this is just useful for testing our AIR
| | 06:01 | application, because as you've seen
already in this series, usually when you
| | 06:04 | distribute an AIR application,
the user has to install that.
| | 06:07 | Well, for testing, that can be very
difficult to have to go through that
| | 06:10 | install process every time.
| | 06:12 | So we provide this little AIR Debug library
that allows you to debug your applications.
| | 06:18 | So go ahead and click File > Save.
| | 06:20 | You should see that this compiles okay,
and you'll see that I forgot my last
| | 06:26 | double quote there at the end of my button.
| | 06:28 | So I'll resave that again, and you
should see that the application compiles fine.
| | 06:34 | Now, I will run this.
| | 06:36 | When I run the application here, notice
you'll see that I have my simple button,
| | 06:41 | I have the word "Web applications," and
notice this is in the AIR Debug library.
| | 06:47 | This I can minimize.
| | 06:48 | I can maximize it, just like I could any
application once it's actually installed
| | 06:53 | on the end user's machine.
| | 06:55 | Now notice, when I click the button,
it says Web applications Become
| | 07:00 | desktop applications.
| | 07:02 | So we've now created our first
AIR Project in Flash Builder.
| | 07:06 | We've built a very simple application
that can be viewed in the AIR runtime.
| | 07:10 | Of course, this could be viewed on not
only multiple devices, but it could be
| | 07:14 | viewed on Mac, Windows, or Linux, and
this is the first step in building a
| | 07:19 | more complicated desktop application
that can actually be installed on an
| | 07:24 | end user's machine.
| | Collapse this transcript |
| Compiling a project in Flash Builder| 00:00 | In this video, we will take an AIR
application that has been tested in the AIR
| | 00:03 | Debug runtime, and we will create an
installation package so the user can
| | 00:07 | install this directly to their machine.
| | 00:10 | We will digitally sign the
application to ensure authenticity, and we'll
| | 00:13 | incorporate all of the assets
that the application will use.
| | 00:17 | We will also experience how an end user
would actually install this application,
| | 00:22 | and then we will test this
application as a desktop application.
| | 00:27 | So you'll see here that I've imported
this FXP file that's in your Begin folder,
| | 00:32 | and that FXP file is called FB_Project.
| | 00:37 | If you've followed along from the first video,
feel free to just use the same exact video.
| | 00:42 | You'll see that everything is the same here.
| | 00:44 | For example, the lyndaAIR.mxml file should
be the same main.mxml file that you created.
| | 00:50 | So if you've just starting to watch this
video, be sure that you've imported the
| | 00:53 | FB_Project from your Begin folder.
| | 00:57 | So now, let's export this as an AIR
Package so the user can install this.
| | 01:03 | So all you have to do is just click on
Project and choose Export Release Build.
| | 01:10 | You'll see here I am going to choose my
FlashBuilder Project, and this is the LyndaAIR.mxml.
| | 01:16 | You'll see I have the option of
whether or not to enable view source, which
| | 01:19 | means that the user can
actually see the source code.
| | 01:21 | In this case, I don't want my end users
to see the source code, so I am going to
| | 01:25 | leave that unchecked.
| | 01:26 | And I can choose the name of
the file that I want to export.
| | 01:30 | In this case, it's called LyndaAIR,
and this is going to be the AIR file that
| | 01:35 | the end user actually clicks
on to install the application.
| | 01:40 | You'll see it also says Export and sign
an AIR file with a digital certificate.
| | 01:45 | So I have a couple of choices here.
| | 01:48 | And the first thing is I could browse
out to a p12 file, and this might be a
| | 01:53 | Class 3 public certificate that you
could get from a company such as VeriSign,
| | 01:58 | and again, if you want to become a
serious AIR developer, it's a very good thing
| | 02:02 | to get so that your users will know
that you are trustworthy, and that your
| | 02:06 | application doesn't contain any malicious code.
| | 02:10 | In our case, right now we don't have that.
| | 02:12 | So let's create a self-signed certificate.
| | 02:14 | So I am going to choose Create, and I
am going to put in the Publisher name
| | 02:18 | here is James Talbot. That's me.
| | 02:20 | You'll see that I have a country, I can
choose the encryption that I like, and I
| | 02:25 | can also put in a password.
| | 02:28 | In this case, I'll use the word
"password," so I won't forget what that is.
| | 02:31 | Then I can browse to where I would like
to actually put this, and in this case
| | 02:36 | I'll just call this certificate lynda.p12.
| | 02:40 | This is a self-signed certificate.
| | 02:43 | So when the user actually installs this,
it'll say that the publisher identity
| | 02:47 | is actually unknown.
| | 02:49 | Because even though I've put James
Talbot here, I could put anything.
| | 02:52 | This has no way of verifying
that I am actually James Talbot.
| | 02:56 | That's what companies like VeriSign do
is they actually verify that James Talbot
| | 03:01 | is in fact James Talbot.
| | 03:03 | That will enable it to say
that this is a trusted identity.
| | 03:07 | In this case, AIR has no way of knowing
whether or not I am in fact who I say I am.
| | 03:12 | We have that.
That'll put in the digital certificate.
| | 03:15 | Go ahead and click Next, and this is
where we can indicate the files that we
| | 03:20 | want to include with our AIR application.
| | 03:23 | So if we had any videos, if we had
any icons, anything else that the AIR
| | 03:28 | application would need, we
could include those files with the
| | 03:31 | installation package as well.
| | 03:33 | You'll see that by default every AIR
application has to include a SWF and a
| | 03:39 | descriptor file, which is an XML file,
this descriptor file that contains
| | 03:45 | certain information.
| | 03:46 | And in the next walkthrough, we'll
look at the descriptor file even more.
| | 03:49 | So go ahead and click Finish, and what
you should see is you should see that
| | 03:54 | you have your lyndaAIR.air file right here, and
now you can install this just like an end user.
| | 04:01 | So what I'm going to do is just click
on this, and you'll see, again, it says
| | 04:05 | the publisher is unknown, and it's
also telling me that this file has
| | 04:08 | unrestricted system access.
| | 04:11 | So, hopefully most end users will be
getting pretty nervous right about now.
| | 04:15 | But in this case we know that my
application has no malicious code.
| | 04:18 | So I am just going to click on Install.
| | 04:21 | I'll click on Continue.
| | 04:22 | Notice it will automatically add a
shortcut to my desktop, and I am not going to
| | 04:27 | start the application after the installation.
| | 04:29 | Again, Windows is warning me that AIR is
going to make some changes, and I do this install.
| | 04:33 | So I am installing the application.
| | 04:36 | It says my installation is completed.
| | 04:38 | Now if I just minimize FlashBuilder,
you'll see that I have this lyndaAIR
| | 04:43 | application right here my on desktop.
| | 04:45 | And notice I have minimize buttons,
I have maximize buttons, I have a close
| | 04:49 | button, and it works just like it did in the
AIR runtime library when we did the testing.
| | 04:57 | So you can see that.
| | 04:58 | Of course, if I want to uninstall this
application, I uninstall this just like a
| | 05:03 | normal Windows program.
| | 05:05 | So I would click Start, I would choose
Control panel, and I would click on Uninstall a Program.
| | 05:11 | I could locate my lyndaAIR application
here, and I could click it and uninstall
| | 05:18 | the lyndaAIR application, just like I
would any other Windows application.
| | 05:24 | So it's asking me to
close that. That makes sense.
| | 05:27 | So we've created an AIR application
package that can be installed on multiple
| | 05:32 | platforms, including Windows, Mac, and Linux.
| | 05:35 | Again, there is no difference.
| | 05:37 | The user can take that AIR application,
as long as AIR itself is installed on
| | 05:41 | any one of those platforms,
the process is exactly the same.
| | 05:44 | So we've experienced how it's
installed, we've also digitally signed the
| | 05:48 | application to ensure its authenticity,
and we're now ready to learn a little
| | 05:53 | bit more about the importance
of the application descriptor.
| | Collapse this transcript |
| Using the application descriptor file| 00:00 | In this video, we will examine the
application descriptor file, and understand
| | 00:04 | the customizations that can be performed
to an Adobe AIR application using this file.
| | 00:09 | The application descriptor file is
essential for developers wishing to take
| | 00:13 | advantage of Adobe AIR, and allows us
to update a desktop application in much
| | 00:17 | the same way a web application is updated.
| | 00:20 | An application descriptor file is
required for every AIR application.
| | 00:27 | Let's go ahead and just examine
this application descriptor file.
| | 00:31 | You'll see here I've
imported this Flash Builder project.
| | 00:35 | For those of you who've been working
along since the beginning, you can continue
| | 00:38 | to use the same project.
| | 00:40 | You should see that there
is a lyndaAIR-app.xml file.
| | 00:44 | This is the application descriptor.
| | 00:47 | This just specifies different parameters
for installing and launching AIR applications.
| | 00:53 | So you'll see Flash Builder actually
builds much of this for us, but we could, of
| | 00:58 | course, build our own application
descriptor if we were not using Flash Builder.
| | 01:02 | You'll also notice that Flash CS5 also
builds an application descriptor, once we
| | 01:06 | get to that unit as well.
| | 01:08 | But for those of you who might choose
to use AIR just using the command line,
| | 01:12 | you could build your own
application descriptor file.
| | 01:15 | So here you'll see I've specified an ID, and
this is, of course, specified in Flash Builder.
| | 01:20 | We use the reverse domain name notation.
| | 01:23 | You'll also see that there is a file name.
| | 01:25 | There is a version.
| | 01:26 | We can specify the description information.
| | 01:29 | We can specify copyright information.
| | 01:31 | You can customize windows, in terms of
the default chrome that's going to be
| | 01:35 | used, whether windows are initially visible.
| | 01:39 | To utilize these aspects, all you have
to do is uncomment these tags in here,
| | 01:44 | and the AIR application will read
this XML file, and do things like set the
| | 01:49 | initial Y position, set the
minimum size, the maximum size.
| | 01:53 | You can choose different supported
profiles that you're going to use,
| | 01:57 | again, how the application handles updates.
| | 02:00 | There are all kinds of customizations
that you can make to your AIR application
| | 02:05 | directly through this file.
| | 02:07 | Let's just make a very simple customization.
| | 02:10 | You'll see that the current
version of this application is v1.
| | 02:14 | Let's change the current
version of our application to v2.
| | 02:19 | So now I'm just going to click File >
Save, and what I'm going to do is go back
| | 02:23 | to my lynda.AIR.mxml, and I'm going to
choose Project, and I'm going to click on
| | 02:30 | Export Release Build.
| | 02:32 | In this case, I'm going to say lyndaAIR.air.
| | 02:34 | It's going to overwrite
the one that's already there.
| | 02:36 | That's fine, for now.
| | 02:38 | I'm going to click on Password.
| | 02:40 | I'll use the same certificate I used earlier.
| | 02:42 | You can use whichever certificate you
like, or you can create a self-signed one.
| | 02:46 | I'll click Next, and I'll choose
which files I'd like to include.
| | 02:50 | Of course, I have to include
my XML file. I'll click Finish.
| | 02:54 | It says it already exists.
| | 02:55 | Do I wish to overwrite it? I'll put Yes.
| | 02:58 | Then I'll reinstall the application,
and AIR should tell me that the installed
| | 03:03 | version on my machine is currently v1,
but the version to be installed is v2,
| | 03:08 | and it's giving me the option to replace this.
| | 03:11 | So I'll click Replace, and it will
now update my application with the new
| | 03:16 | application that I've put in.
| | 03:19 | So that's just one of the
customizations that you can make utilizing the
| | 03:22 | application descriptor file.
| | 03:24 | In a later chapter, we'll learn
actually how to utilize the application
| | 03:28 | descriptor file to prevent downgrade attacks.
| | 03:32 | So, for example, if you already have
version 2, and a hacker wants you to go
| | 03:36 | back down to version 1 because it's
less secure, we as a developer can prevent
| | 03:40 | that, and we'll learn how to
do that later on in the course.
| | 03:43 | So we've seen the application
descriptor file, and we've seen how it's
| | 03:47 | essential for updating new versions
of an application, as well as making all
| | 03:51 | kinds of customizations.
| | 03:53 | So we're now ready to begin
exploring the unique AIR desktop APIs and
| | 03:57 | customizations available.
| | Collapse this transcript |
| Creating a desktop application icon| 00:00 | The desktop icon provides a public
face for your application that appears on
| | 00:04 | Windows, Mac, and Linux systems.
| | 00:06 | In this video, we will examine how to
provide a customized icon for your application.
| | 00:12 | We do this through the XML descriptor file.
| | 00:15 | The first thing you can see here is
that the Flash Builder project has already
| | 00:18 | been imported from your Begin folder.
| | 00:21 | If you scroll down, you
should see that you have your
| | 00:24 | lyndaAIR-app.xml descriptor.
| | 00:28 | So let's go ahead and open up the descriptor.
| | 00:31 | If you scroll down, you'll see, on
approximately line 102 here, that you have an icon setting.
| | 00:40 | This enables us to provide a
customized desktop and system icon for our
| | 00:44 | application, so that we don't
have to have the default AIR icon.
| | 00:49 | You'll also see that, in the assets
folder in your project, we've provided
| | 00:54 | different icons at different resolutions that
we can specify to represent our application.
| | 01:00 | So the first thing you
need to do is uncomment this.
| | 01:03 | So I'm going to uncomment this, and you'll see
that now the descriptor file will have an icon.
| | 01:11 | What you want to do is just point
this to the image that you want for each
| | 01:15 | particular resolution.
| | 01:17 | So here I'm going to say assets.
| | 01:20 | I'm just going to simply say icon16.png.
| | 01:25 | Then here I'm going to point this to
assets/icon32.png, and then I'm going to
| | 01:34 | say assets/icon48.png.
| | 01:41 | Then here I will point this to the 128, and I
will say icon128.png, just as you see there.
| | 01:52 | Just a quick note about these tags:
sometimes it will fail to produce the AIR
| | 01:57 | file if these are not populated
correctly in your descriptor file.
| | 02:01 | It will just sort of silently fail.
| | 02:03 | So that is definitely
something to watch out for.
| | 02:06 | For many of you, you may see that it
silently fails if you're missing a node, or
| | 02:10 | you left something commented that
shouldn't be commented, or you have to
| | 02:13 | straight comment in there.
| | 02:14 | So that is something to watch out for.
| | 02:16 | It just won't build the actual AIR
application if something is wrong in
| | 02:20 | the descriptor file.
| | 02:21 | So again, something to watch
out for. Go ahead and save this
| | 02:25 | lyndaAIR-app.xml file.
| | 02:29 | What you can do is just open your
default package, open lyndaAIR.mxml,
| | 02:35 | go ahead and click on Project,
and choose Export Release Build.
| | 02:39 | You'll see that we've specified my
Flash Builder project lyndaAIR.mxml.
| | 02:44 | We're exporting to the lyndaAIR.air file.
| | 02:48 | Then we'll use the same
certificate as we used before.
| | 02:51 | My password here was password.
| | 02:54 | Go ahead and just click Next.
| | 02:56 | Be sure that it's including
the images with the application.
| | 02:59 | Be sure that all of these are checked,
so that it's going to build those
| | 03:03 | actually into the AIR file, so the
application will have use of that.
| | 03:07 | Go ahead and click Finish, and you
should see it exports that release build, and
| | 03:12 | you'll see this lyndaAIR.air.
| | 03:15 | Now again, if it silently failed,
go back and check that application
| | 03:18 | descriptor file, and make sure that
everything is populated the way it should
| | 03:22 | be, and there are no stray
characters, or anything like that.
| | 03:25 | So now I'm going to install this.
| | 03:27 | Again, in my case, I don't have
this lyndaAIR already installed.
| | 03:31 | For some of you out there, it
may say Replace. That's fine.
| | 03:34 | Go ahead and replace it, or click
Install, depending on what appears.
| | 03:38 | Now I'm just going to click Continue.
| | 03:40 | It's going to install this to my system.
| | 03:45 | You should see that now it has a
customized icon, and you could see that icon
| | 03:50 | right here at the upper left-hand corner.
| | 03:53 | Even if I go here, you'll see that,
inside of my tasks, it also has a customized
| | 03:59 | icon, as well as actually in my taskbar,
| | 04:02 | you can see that customized icon.
| | 04:04 | For those of you who published it as
a desktop application, and say create a
| | 04:07 | shortcut on the desktop, it would
also build that customized desktop icon.
| | 04:13 | So we've now learned how to
change this icon for your application.
| | 04:17 | We can use a customized image and
provide a much better, more professional user
| | 04:22 | experience for our end users.
| | Collapse this transcript |
| Creating a system tray icon| 00:00 | Adobe AIR allows a large number of
customizations and branding to each
| | 00:04 | application that you create.
| | 00:06 | In addition to changing the icon for
your application that appears on the
| | 00:10 | desktop, you can also change the icon
that appears in the System Tray on Windows
| | 00:14 | or in the Dock for Macintosh machines.
| | 00:17 | Now we can of course change this in the
application descriptor like we learned
| | 00:21 | in the last video, but we also have the
capability of changing this at runtime,
| | 00:25 | which allows us to create an even more
customized user experience, because we
| | 00:29 | can have the System Tray icon change
when the application progresses, or when
| | 00:34 | the user presses a
button, or something like that.
| | 00:36 | So let's explore how to change the
System Tray icon at runtime, and this also
| | 00:41 | applies to changing other
icons at runtime as well.
| | 00:45 | So the first thing I've done is I've
imported the Flash Builder project.
| | 00:48 | You can see it says FB_Project.
| | 00:50 | You'll see you have your lyndaAIR.mxml.
| | 00:53 | Go ahead and open up this lyndaAIR.mxml.
| | 00:58 | The first thing I'd like you to
do is just add in a script block.
| | 01:02 | So I'm just going to simply say fx:Script.
| | 01:07 | The first thing that I'm going to do
is I'm simply going to add in a meta
| | 01:11 | tag here that is going to point to the
image file that I want to use in my application.
| | 01:17 | I'm going to be using this at runtime.
| | 01:19 | So here I'm just going to say Embed,
add the meta tag here, and then I'm
| | 01:24 | going to specify source="assets,
just like that, and then I'll say icon16.png.
| | 01:35 | You should see that, of course, this
is right here in our assets folder here.
| | 01:40 | So there is my assets.png. That's perfect.
| | 01:45 | Then the next thing I want you to do
is just declare a private variable.
| | 01:48 | So I'll say private var, and let's call
this icon16, and let's type this as a class.
| | 01:56 | So I'll simply say Class there.
| | 01:58 | Now the next thing I want to
do is add in an init method.
| | 02:02 | So I'll say private
function init (), just like so.
| | 02:08 | Then this is not going to be returning
anything, so I'll specify the word "void,"
| | 02:12 | just as you see there.
| | 02:14 | Inside of this, now I want
to add some conditional logic.
| | 02:17 | So I want to test if I'm on a Windows,
or if I'm on a Macintosh machine.
| | 02:21 | So to do that, the NativeApplication
actually has a property that we can use
| | 02:25 | called supportsSystemTrayIcon.
| | 02:28 | So let's just add in some conditional logic.
| | 02:31 | I will say if, and I will reference my
NativeApplication.supportsSystemTrayIcon.
| | 02:41 | Then I want it to execute the code below.
| | 02:43 | Now let's add in an else if for our Macintosh.
| | 02:47 | I'll say, else if
NativeApplication.supportsDockIcon for the Macintosh.
| | 02:56 | So I'll add in this
conditional logic directly below that.
| | 03:00 | So that makes sense.
| | 03:02 | Then inside of the
supportsSystemTrayIcon, what I'm simply going to do is I'm
| | 03:07 | going to reference the NativeApplication.
| | 03:12 | I'm going to say nativeApplication,
right here, dot, and I'll specify the icon,
| | 03:19 | and I'll specify .bitmaps.
| | 03:21 | Notice bitmaps needs to be an array.
| | 03:24 | So I'll say =, and I'll use the
shorthand notation for an array by using
| | 03:29 | this bracket here, and I will simply
instantiate a new object from the class
| | 03:35 | that I created earlier.
| | 03:36 | So I'll say new icon16(), just like so,
and then I'll reference the bitmap data
| | 03:43 | stored inside of this class.
| | 03:45 | So I'll say .bitmapData. Okay, close that.
| | 03:50 | That will then change out the System
Tray icon to be what I specified right here,
| | 03:56 | in terms of my icon16.
| | 03:58 | Now I'm going to just use exactly this
same code for the Dock Tray icon as well.
| | 04:03 | So you can just take that code there, and
just copy it, and then paste it down here.
| | 04:09 | For those of you on a Mac, you should
see that this works just as well as it
| | 04:12 | does on a Windows machine.
| | 04:13 | But of course, this gives you
flexibility to have a different icon with a
| | 04:17 | different resolution for Mac,
because obviously the Dock icon looks very
| | 04:21 | different than the System Tray icon.
| | 04:23 | So it gives you a lot of
flexibility as a developer.
| | 04:26 | So that's a very nice functionality.
| | 04:28 | The final step here is just go back up
to your WindowedApplication tag, and add
| | 04:33 | a creationComplete here.
| | 04:35 | I'm just going to say creationComplete=init.
| | 04:39 | So this is just saying, when all the
components are ready for use, go ahead and
| | 04:43 | call this init function.
| | 04:46 | Now this code should work exactly the same way.
| | 04:48 | This system's tray icon, and the
NativeApplication, this will work exactly the
| | 04:52 | same way on Flash CS5;
| | 04:55 | the only difference is of course you
wouldn't have a Script block and the
| | 04:58 | creationComplete, because all of
that's dependent on the Flex framework.
| | 05:02 | You would add your code in a movie clip,
or on the timeline, or wherever you
| | 05:05 | like to add your code in Flash CS5.
| | 05:08 | But again, the AIR APIs are
fully supported in Flash CS5 as well.
| | 05:13 | We're just choosing to use Flash Builder here.
| | 05:17 | So the next step is just to
save and compile your file.
| | 05:21 | You should see that it compiles with no problem.
| | 05:24 | Then let's go ahead and just click
on Project > Export Release Build.
| | 05:30 | You'll see that it says your FB_Project,
choose LyndaAIR.mxml, export to your LyndaAIR.air.
| | 05:37 | I'll use the same certificate I used in
the earlier video, which as you remember
| | 05:41 | if you watched that video,
| | 05:43 | the password was simply password.
| | 05:45 | So I'm typing in password there.
| | 05:46 | For those of you who are starting this
video, you can create a new self-signed
| | 05:50 | certificate, or you can point it to a
Class 3 public certificate, if you happen
| | 05:54 | to have one on hand.
| | 05:55 | You're welcome to do that.
| | 05:57 | Then go ahead and click Next.
| | 05:59 | Make sure that your assets are being
included, so the icons are being included here.
| | 06:05 | Just go ahead and click Finish.
| | 06:08 | Now you should be able to
install your Lynda.AIR.air file.
| | 06:12 | You'll see it says Replace.
| | 06:16 | That will replace the application.
| | 06:18 | Again, I had installed that from an earlier video.
| | 06:19 | So you can go ahead and click Replace.
| | 06:23 | You should see that System Tray icon right here.
| | 06:25 | For those of you on the Mac on your
Dock, you should see that you have this.
| | 06:29 | Now this can be very useful, and very
useful for customizing applications.
| | 06:33 | Many times, applications might put
their preferences here, allow users to set
| | 06:38 | certain things about the application,
and they're able to do that directly from
| | 06:42 | the System Tray here.
| | 06:44 | So using Adobe AIR 2.0, we
can change the System Tray icon,
| | 06:48 | we can change the Desktop icon, and we
can do this at runtime, providing a much
| | 06:53 | more seamless, connected
experience for the end user.
| | Collapse this transcript |
|
|
3. Creating an Adobe AIR Application with Flash Professional CS5 Creating an AIR application in Flash CS5| 00:00 | We can create Adobe AIR
applications directly from Flash CS5.
| | 00:04 | AIR files can be treated like any
other application created using Flash.
| | 00:08 | So, we can use animations,
video, ActionScript, and so on.
| | 00:12 | The AIR Application Programming
Interface, otherwise known as the API, is fully
| | 00:17 | supported in Flash CS5.
| | 00:19 | We will learn how to use these AIR-
specific APIs, which also allow us to do
| | 00:24 | things like access the file system or create
a database throughout the rest of this course.
| | 00:29 | When you open up Flash CS5, you'll see
you have the option of directly creating
| | 00:34 | a brand-new Adobe AIR application
that supports ActionScript 2, and that
| | 00:38 | utilizes the APIs, and includes
everything that the Adobe AIR application needs.
| | 00:43 | You can also take an existing Flash
application and convert that into an AIR application.
| | 00:49 | So, here I'll just click on Open, and
I'd like you to go to your Getting Started
| | 00:54 | with Flash student files
and go to the Begin folder.
| | 00:58 | You'll see a FLA file in
here called Publishing_Final.
| | 01:02 | Go ahead and open up your FLA file,
and you'll see that this is a very
| | 01:05 | simple little application.
| | 01:06 | It's called TWO TREES OLIVE FARM
INTERACTIVE TOUR, and you'll see that this is
| | 01:11 | much more visual than a
Flash Builder application.
| | 01:15 | We can much more easily incorporate
artwork and other visual elements.
| | 01:20 | You'll see that the development
environment is much more visual as well.
| | 01:24 | So, let's just take a
quick look at the application.
| | 01:26 | So, just click Control,
choose Test Movie and Test.
| | 01:31 | That should give us a SWF file right now.
| | 01:34 | We can actually just take a look.
| | 01:35 | You can see here, here're some
photographs of the olive farm.
| | 01:39 | If I click here, again, just some
icons there, and then you also see that
| | 01:44 | again some information about extracting,
and some information about bottling
| | 01:49 | the actual Olive Oil.
| | 01:50 | So, you'll see a very nice
little interactive application.
| | 01:54 | If I want to publish this and install
this somewhere on a user's machine, or
| | 01:57 | on a kiosk, or something, this could be very
useful, and I might use Adobe AIR for that.
| | 02:03 | So, you'll also see that
you've taken all the code here.
| | 02:06 | If you look at the Timeline, you'll
see, in this case, the code for this
| | 02:10 | application is actually on
the animation's movie clip.
| | 02:13 | So if I just double-click here to go
into the movie clip here, you'll see that
| | 02:17 | I've added my code directly on the
Timeline, which is very different than we've
| | 02:21 | done in Flash Builder.
| | 02:23 | But you can see the code is very similar.
| | 02:25 | We have our addEventListeners, in this
case we're listening for a MouseEvent
| | 02:29 | click, and this is, of course, where
you would put your AIR code to create your
| | 02:33 | databases, and do everything that we're
going to work with and learn about in the
| | 02:37 | course as we go further along.
| | 02:39 | Now, no, we don't support FXP files
directly in Flash CS5 because you would use
| | 02:46 | Flash Catalyst in
conjunction with Flash Builder.
| | 02:50 | We're now ready to start learning
about how to publish AIR applications.
| | 02:54 | This course is actually about the Adobe
AIR Application Programming Interface,
| | 02:58 | and everything we learn
also applies to Flash CS5.
| | 03:01 | The development environment of Flash is
very different than Flash Builder, and
| | 03:05 | it takes a much more visual approach.
| | Collapse this transcript |
| Packaging an AIR application in Flash CS5| 00:00 | Flash CS5 gives us the ability to fully
package and deliver an Adobe AIR 2.0 application.
| | 00:06 | From Flash CS5, we can
publish an AIR application.
| | 00:09 | We can digitally sign the application.
| | 00:11 | We can either use a self-certificate or
a Class 3 public certificate, just like
| | 00:15 | in Flash Builder, but we can also access assets,
| | 00:19 | we can update applications, and
| | 00:21 | we'll learn how to do all
of this later in the course.
| | 00:24 | We can even add custom
icons directly from Flash CS5.
| | 00:28 | Let's explore how to publish an
AIR application from Flash CS5.
| | 00:33 | First thing I'd like you to do is
just click here under Open a Recent Item,
| | 00:37 | choose Open, and point this to your
Getting Started with Flash, and point this
| | 00:41 | to your Publishing_Final application right here.
| | 00:44 | I'm going to open up that Publishing
_Final, and you'll see we have our
| | 00:48 | interactive olive farm tour.
| | 00:50 | We want to actually take this and
publish this as an AIR application.
| | 00:55 | So, you can un-select the animations
movie clip if you have it selected.
| | 00:58 | Just click anywhere, and you'll see
you have the properties for the entire
| | 01:02 | document when you do so.
| | 01:04 | So, here you could see that we're
already set to publish to Adobe AIR 2.
| | 01:08 | We're using, of course, ActionScript 3.0,
and you could specify the default profile.
| | 01:14 | Here you'll see we can actually specify the
Adobe AIR 2 settings when we publish this.
| | 01:20 | So, just click Edit here, and you can choose
the name of the file that you want to output.
| | 01:26 | In this case, we're going to call it
Olive_Oil.air, and we can even create a
| | 01:30 | Windows installer, directly
from Flash, which is very cool.
| | 01:35 | You'll see here the file name we're
using is called Publishing_Final, the App
| | 01:39 | name is called Publishing_Final.
| | 01:41 | We can specify that.
| | 01:43 | So, just like we did before, I'm going
to say com.lynda.olive, just so it has a
| | 01:51 | unique application name. Same thing here.
| | 01:55 | I'll call this my Olive Oil,
and I can specify the version.
| | 01:59 | I could specify the chrome, directly from
here as well as the description, the copyright.
| | 02:05 | You can also see I can use
these different profiles.
| | 02:07 | We'll learn about what Desktop and
Extended Desktop mean, and then later on,
| | 02:12 | there would be another series on
actually developing for mobile devices
| | 02:16 | utilizing Adobe AIR.
| | 02:18 | At the time of this video, to develop
mobile applications, you will currently use
| | 02:24 | Flash CS5, and Flash Builder is not supported.
| | 02:28 | So here, under Signature, we can, of
course, code sign, and we can create a
| | 02:33 | self-signed digital
certificate directly from here.
| | 02:36 | So let's create one.
| | 02:38 | Just like we learned before,
I'll put in James Talbot.
| | 02:40 | I'll put in my organization, if I like.
| | 02:43 | I could put in a password.
| | 02:45 | Of course, when I install this
application, just like we saw from Flash Builder,
| | 02:50 | I will have the same issue that it will
say that this is unknown, because this
| | 02:55 | is a self-signed certificate.
| | 02:56 | The system has no way of
verifying that I'm actually James Talbot.
| | 03:00 | If I want to do that, I should contact a
company like VeriSign who can verify my
| | 03:04 | identity and issue me a
Class 3 public certificate.
| | 03:09 | So, I'll save this as cert.p12.
| | 03:14 | I'll fill out all of this information,
and I'll say lynda.com, and I'll click OK.
| | 03:21 | It will create me a self-signed
certificate, as you see there.
| | 03:26 | I can even specify my icons directly from Flash.
| | 03:31 | So for the 16x16, I can point
these to the icons that I want to use,
| | 03:36 | if I want to give custom
application icons. And I can also specify some
| | 03:41 | advanced settings here.
| | 03:42 | I can specify the initial window
settings, the X and the Y, the maximum
| | 03:46 | width, the maximum height,
| | 03:48 | whether it's maximizable, the Install folder,
and I can even provide a custom UI for updates.
| | 03:54 | So, all of this is just a simple way
of modifying the application descriptor
| | 03:59 | file, which we discussed in the Flash
Builder unit. The application descriptor
| | 04:04 | file contains all of this, but Flash
CS5 provides us a nice way of customizing
| | 04:09 | this, without having to go in and modifying
that XML, and uncommenting, and doing all of that.
| | 04:15 | Flash CS5 does that all for us.
| | 04:18 | So, go ahead and click Publish.
| | 04:20 | Make sure you've filled out a
password for your certificate.
| | 04:23 | Go ahead and click Publish.
| | 04:25 | You'll see it'll export the movie.
| | 04:28 | It will publish this as an AIR file,
and it'll publish it in the same directory
| | 04:34 | as your Flash file, and in this case,
I have also created a Windows installer
| | 04:38 | file directly from Flash CS5.
| | 04:41 | So, I'll go to my exercise files.
| | 04:44 | I'll go to my Getting Started with Flash CS5.
| | 04:48 | I'll go to my Begin.
| | 04:49 | In this case, I have my FLA.
| | 04:51 | I also have a SWF file.
| | 04:54 | But you should also see you have a
Windows application file, as well as an AIR file.
| | 05:00 | So here we can actually install this
via Windows, because we created an EXE.
| | 05:04 | I can choose Continue and install
this actually as a Windows installer.
| | 05:10 | Here is my application as an AIR application.
| | 05:15 | This was all created in Flash CS5.
| | 05:18 | So, that's very, very neat.
| | 05:20 | We've seen how AIR applications can
be published directly from Flash CS5.
| | 05:24 | The first step is to use the
Properties panel to adjust the AIR settings, and
| | 05:28 | then we actually publish the application.
| | 05:30 | We can do everything that we can do
from Flash Builder, including specifying
| | 05:34 | custom icons, digitally signing the application.
| | 05:37 | It can be difficult to import a
Flash application - a FLA file on a visual
| | 05:42 | application - into Flash Builder.
| | 05:45 | So it's important for us to make a
decision about which tool you want to use to
| | 05:48 | build AIR applications.
| | 05:50 | In this course, we've decided to use
Flash Builder to showcase the APIs, but
| | 05:55 | everything we learn also applies to
ActionScripting here in Flash CS5.
| | Collapse this transcript |
|
|
4. Creating an Adobe AIR Application with Flash Catalyst CS5Creating an AIR application with Flash Catalyst| 00:00 | Flash Catalyst is a design tool for
rapidly creating application interfaces and
| | 00:05 | interactive content without
having to do any coding at all.
| | 00:09 | We use Flash Catalyst to create
applications like product guides, design
| | 00:13 | portfolios, and even complex user interfaces.
| | 00:16 | Designers usually import content into
Flash Catalyst from a tool like Adobe
| | 00:20 | Illustrator or Adobe Photoshop.
| | 00:23 | Flash Catalyst can then output the
application to an Adobe AIR Application that
| | 00:27 | can be used to pitch an idea, or even
create a stand-alone desktop application.
| | 00:32 | The project can also be exported from
Flash Catalyst into Flash Builder where a
| | 00:37 | developer can connect it to
backend systems and data, as well as add
| | 00:41 | additional AIR functionality.
| | 00:43 | Let's explore a little bit about how to
create an AIR Application in Flash Catalyst.
| | 00:49 | Many times, a designer will just
provide me an Adobe Illustrator file, and I
| | 00:54 | need to convert this into an application.
| | 00:56 | So, in this case, my designer has
provided me with an Adobe Illustrator file, so
| | 01:00 | I am just going to choose Create New
Project from Design File, here in Flash Catalyst.
| | 01:05 | So, I'll click here. This is an Illustrator file,
and I'll browse to my Desktop where my
| | 01:09 | exercise files are.
| | 01:11 | You'll see I have my exercise files
here, and then you'll also see that there
| | 01:15 | is a unit 04 -Getting Started with
Catalyst and AIR, and there's a Begin
| | 01:19 | directory here, and you'll see this Illustrator
file, marked by the Ai here, called olive_tour.
| | 01:25 | Let's go ahead and open up this,
and you'll see that it creates this.
| | 01:29 | You can just accept the defaults here.
| | 01:31 | It will go ahead and analyze the file,
and it will actually convert the file so
| | 01:36 | that I can use this with Flash Catalyst.
| | 01:39 | I am going to go through and actually
add some interactivity and add some very
| | 01:42 | simple interactions here in Catalyst,
and then we are going to actually take
| | 01:47 | this application and publish it as an
Adobe AIR Application, which is going to
| | 01:52 | be very exciting, and then the user can
then install this application, and this is
| | 01:57 | a great way of actually protyping
different types of applications.
| | 02:01 | So, here you can see I have this
great design that my designer has created,
| | 02:07 | and you could see they have created
some little buttons and that sort of thing
| | 02:10 | in Adobe Illustrator.
| | 02:12 | What we want to do is actually make
this functional so that we can provide a
| | 02:15 | demo for our customer, and we can
convert this into a very useful format.
| | 02:19 | So, let's go ahead and learn a little
bit about Flash Catalyst and then publish
| | 02:23 | this as an Adobe AIR application.
| | 02:26 | So, you'll see these different buttons
here. The first thing I want you to do
| | 02:29 | is take the artwork, you'll see the layers
have been preserved from Adobe Illustrator.
| | 02:34 | So the first thing I want you to do is
just take this artwork and convert this
| | 02:38 | artwork into custom components.
| | 02:40 | So, you'll see to see I
have these different layers.
| | 02:42 | I have a Growing layer.
| | 02:43 | I have a Picking layer.
| | 02:44 | I have an Extracting layer and a Bottling layer.
| | 02:47 | I'll just right-click or Ctrl+
Click here on this particular layer.
| | 02:51 | I'll say Convert Artwork to Component,
and I'll make this into a Custom/Generic
| | 02:55 | Component, and I'll do this for
each one of the different layers.
| | 03:00 | So, now I am just making this into a
custom component for extracting, make this
| | 03:06 | into a custom component for bottling.
| | 03:08 | For each of the different states of my
application, I'll make this into a custom component.
| | 03:15 | So let's add the Tasting here as well.
| | 03:18 | What I want to happen is I am going to
create a little storyline to actually
| | 03:22 | explain the olive farm interactive tour.
| | 03:25 | What I want to happen is I want these
to actually be buttons and allow the
| | 03:29 | user to navigate through the
storyline, simply by clicking on each one of
| | 03:33 | these buttons, and I am going to
create different states that are going to
| | 03:36 | represent the storyline.
| | 03:37 | So, let's go ahead and do that.
| | 03:38 | I'm going to create five different states.
| | 03:41 | So, if I just scroll up here, you'll
see that this is actually called Growing.
| | 03:46 | That's my first state.
| | 03:48 | Then I'm going to go and
just create duplicate states.
| | 03:51 | I am going to create a total of five
states, by clicking on the Duplicate State here.
| | 03:56 | So, there I have a total of five
states, and let's just name these into
| | 04:01 | something that makes a little
more sense, so we know where we are.
| | 04:03 | So this would be the Picking state.
| | 04:06 | So, you could see what I'm doing is I'm
taking this in Illustrator, and I am actually
| | 04:09 | adding this interactivity to it, and
I don't have to write any code at all.
| | 04:14 | So, then I am going to say Extracting,
I am going to add this to Bottling, and
| | 04:20 | then I am going to add
here to Tasting here as well.
| | 04:25 | So, you'll see Growing, Picking,
Extracting, Bottling, and Tasting.
| | 04:29 | You'll see all of these different states.
| | 04:31 | Again, to make this really easy what I
want - on the Growing state, I only want
| | 04:35 | the Growing button to appear, and I
want the user to be able to click to
| | 04:39 | navigate between different states.
| | 04:40 | So, we are just creating a very
simple navigational system here, but on the
| | 04:44 | Growing state, I don't want any
of the other states available.
| | 04:47 | So, this is just simply as easy as
unchecking all of these other states.
| | 04:53 | So, just unchecking the visibility here,
the little eye to mark the visibility,
| | 04:58 | and you'll see that none of the other
states will actually be visible in this
| | 05:02 | state, and note none of the
buttons there are available.
| | 05:06 | So, now what I want to do is just take
this, and I want to be able to actually
| | 05:09 | add an interaction to this state.
| | 05:12 | So, the first thing is I want this to happen
when the user actually clicks on this button.
| | 05:17 | So, what I am going to do is just right-
click here and just say Convert Artwork
| | 05:21 | to Component and make
this into a button control.
| | 05:25 | So, you'll see Flash Catalyst converted this
button into a button control, as you see there.
| | 05:33 | Then I am going to go ahead and
actually add an interaction, and I am going to
| | 05:37 | say On Click, Play Transition to State,
and let's have this transition to the
| | 05:41 | Picking state here, and then I'll click OK.
| | 05:44 | All right, now let's go to the Picking
state, and in the Picking state, what I
| | 05:49 | want to appear is I don't want the
first Button to appear, and I don't want any
| | 05:53 | of the other buttons to appear,
except, of course, for the Picking button.
| | 05:58 | So I'll do the same thing
here on the Picking state.
| | 06:01 | I'll right-click here, choose Convert
Artwork to Component, choose Button.
| | 06:06 | Now this is in fact a button.
| | 06:09 | Then I will add an interaction.
| | 06:11 | I'll say On Click, Play Transition
to State, and the state I'd like it to
| | 06:16 | transition to is the Extracting state.
| | 06:19 | I can say, When in Any State, and click OK.
| | 06:22 | We'll do one more here.
| | 06:24 | So I'll go back to my Extracting state.
| | 06:26 | I'll hide everything except for
the Extracting state, just like so.
| | 06:32 | Okay, so now I've hidden
everything except there.
| | 06:35 | I'll convert this into a
button, Convert into Button.
| | 06:41 | Then I will choose Add Interaction, I'll
say On Click, Play Transition to State,
| | 06:47 | and I'll say Choose State.
| | 06:48 | Let's play to the Bottling
state, and then I will click OK.
| | 06:53 | So, you should see, in your Growing
state you have the Growing button, in your
| | 06:57 | Picking state you have this, and of
course you could add in different content for
| | 07:01 | each one of these, but in our case we
are just using this to demonstrate how to
| | 07:05 | build an actual AIR Application.
| | 07:08 | One of the huge advantages of Catalyst is I
can publish this directly as an AIR application.
| | 07:14 | So, now you could see I've
built this little application.
| | 07:16 | Let's go ahead and publish this.
| | 07:18 | So, I am just going to simply click
File > Publish to SWF/AIR, and I could
| | 07:24 | choose where I'd like to output this to.
| | 07:26 | Let's just output it to our desktop for now.
| | 07:29 | So, I'll just output it to the desktop,
and I can actually make sure that it's
| | 07:32 | built for accessibility.
| | 07:34 | Well, what we are going to do
is build an AIR application.
| | 07:37 | So all we have to do is just simply
check this box, and all the interaction that
| | 07:41 | I've added here in Flash Catalyst, I
can build it as an AIR Application.
| | 07:45 | So, here I click Publish, and Flash
Catalyst will publish this as a SWF and also
| | 07:51 | publish an AIR application that I
can install and use as a pretty awesome
| | 07:57 | prototype to show people what the
capabilities of the Flash platform are.
| | 08:02 | This is very exciting.
| | 08:03 | You could see here it's developing an AIR
application and just like we've done,
| | 08:07 | let's walk through the installation of
this, and let's examine how this looks in
| | 08:12 | terms of an AIR application, and we
can see all of that functionality.
| | 08:15 | So, I am just going to minimize Catalyst
here, and you should see that there's a
| | 08:19 | folder now on your desktop called olive_
tour, and in there is a folder called AIR,
| | 08:24 | as well as one you could deploy to the
web if you wanted to take this as just a
| | 08:28 | regular Flash file, but let's choose AIR.
| | 08:30 | You'll see this as my AIR installer.
| | 08:32 | Let's go ahead and double-click on this,
and this will walk us through the process.
| | 08:37 | Again, this is just a prototype, so you can
see that the publisher identity is unknown.
| | 08:41 | We don't have the chance to put
in our certificate or anything.
| | 08:44 | But I'm going to go ahead and install this.
| | 08:45 | It's going to create a
little shortcut on my desktop.
| | 08:48 | It's installing it.
| | 08:49 | Again, Windows just warned me that this
is actually installing a new application
| | 08:54 | and here is my AIR application.
| | 08:56 | So, you should see, when I click here,
it moves from state to state, just as we
| | 09:02 | examined, and just as we expected it to,
based on what we developed in our Flash
| | 09:07 | Catalyst application.
| | 09:08 | So, Flash Catalyst allows us to
create complex AIR applications without
| | 09:12 | knowing any code at all.
| | 09:14 | We can create awesome prototypes in
Illustrator or Photoshop, and export it to an
| | 09:18 | application that can be
installed on an end user's machine.
| | 09:21 | In order for us to add more complex
functionality, we can actually export the
| | 09:26 | application to Flash Builder and
really start using this as a base for all
| | 09:30 | of our code.
| | Collapse this transcript |
| Exporting a Flash Catalyst project into Flash Builder| 00:00 | At the end of this video, we will have
seen how to export a project from Flash
| | 00:04 | Catalyst into Flash Builder.
| | 00:06 | Eventually Flash Catalyst will have reached
its limits, and it will be time to
| | 00:10 | import our project into Flash
Builder to add more complex functionality.
| | 00:13 | This will ultimately allow us to do
things like connecting to remote data, or
| | 00:18 | connecting to a database.
| | 00:20 | We'll be able to create
loosely coupled components.
| | 00:22 | We'll be able to use all of the
complex AIR APIs that we have to use through
| | 00:27 | code that we'll learn
about later in this course.
| | 00:30 | So exchanging data between Flash
Catalyst and Flash Builder is really very easy
| | 00:35 | because they use exactly the same file format.
| | 00:37 | So go ahead and open up Flash Catalyst
CS5, and you'll see, in your Begin folder,
| | 00:43 | if I choose Open Project, you'll see
in your exercise folders, and your Begin
| | 00:47 | folder there is a FXP file called olive_tour.
| | 00:51 | Go ahead and open up that, and this is
just your typical Flash Catalyst project.
| | 00:55 | It's very straightforward.
| | 00:56 | We have some different states, and we
have some cool artwork that ultimately
| | 01:00 | started off in Adobe Illustrator.
| | 01:02 | And you could see it looks good,
it's been created by a designer, but the
| | 01:06 | developer has gone into Catalyst and
added some functionality for the UI, and
| | 01:11 | you'll see it's an FXP file.
| | 01:13 | So to exchange data, really
it just couldn't be any easier.
| | 01:16 | All your have to do is save it in Flash Catalyst,
| | 01:18 | open up that same FXP file, so just
say Import Flex Project, click Browse and
| | 01:27 | choose Exercise Files.
| | 01:29 | And then we're going to go to Getting
Started with Flash Catalyst and AIR > Begin.
| | 01:34 | You'll see your olive_tour.fxp file.
| | 01:37 | Click Open and then click Finish.
| | 01:40 | And this will actually import this project
directly into Flash Builder. So here we go.
| | 01:48 | Here is our project here, and
you'll see we have the source files.
| | 01:53 | You'll see, in this case, it's called Main.mxml.
| | 01:57 | This code came directly from Flash
Catalyst that we were able to create.
| | 02:02 | Now, if I run this, you should see this
functions just like your applications in Flash Catalyst.
| | 02:10 | The only problem here is,
is this is a web application;
| | 02:14 | This is not an AIR application. And you can
tell because up at the top it says Application.
| | 02:20 | So in order to convert this into an AIR
application, we actually - if we want to
| | 02:25 | do things like access the file system,
or create native application windows, or
| | 02:29 | use a database - we're going to need
to actually convert this into an AIR
| | 02:33 | project, and that's what we're going to do next.
| | Collapse this transcript |
| Converting a Flex project into an AIR project| 00:00 | When we import a project from
Flash Catalyst into Flash Builder, it is
| | 00:04 | automatically imported as a Flex project.
| | 00:07 | In order to take advantage of the AIR
application programming interface, or to
| | 00:11 | digitally sign the application, or to
export a release build, we must convert it
| | 00:16 | into an AIR project.
| | 00:17 | In this video, we're going to learn how
to take a Flex application and convert it
| | 00:21 | into an AIR project.
| | 00:23 | So I'm going to click on File, I'm going
to import a flex project, and I'm going
| | 00:28 | to Import this olive_tour, and
notice this is a Flex project.
| | 00:32 | As I import it, you'll see that this has
an Application tag in the main application.
| | 00:37 | So here I want to go to my source, my
package, and notice that this actually
| | 00:43 | has an Application tag.
| | 00:44 | I want to go ahead and convert this
into an AIR application, which means it
| | 00:49 | would have to have a Window application.
| | 00:52 | What I'm going to do it's just simply
right-click on the project, and what you
| | 00:57 | should see is there is a setting in
here called Add/Change Project Type.
| | 01:03 | So what I can do is I can convert
this into an Adobe AIR project, and Flash
| | 01:09 | Builder will do that for me automatically.
| | 01:11 | It will convert all the application
tags to WindowedApplication, it'll add an
| | 01:16 | application descriptor file, and it
will go ahead and make this into a
| | 01:20 | desktop application.
| | 01:22 | Then of course I, as a developer, would have
to go in and use the appropriate API's,
| | 01:26 | create the database,
create the separate windows.
| | 01:28 | I would still have work to do as a
developer, but this just makes it a lot easier
| | 01:33 | to actually convert this into an AIR project.
| | 01:37 | So now you'll see my application
tags are changed to WindowedApplication.
| | 01:42 | If you run the application well - you
have to save it of course - but if you run
| | 01:47 | the application, you'll see that this
will now run in Adobe AIR, and you could
| | 01:52 | export a release build.
| | 01:53 | So you can see that it's
has converted this into AIR.
| | 01:56 | You'll see it's running in Adobe AIR.
| | 01:58 | I can minimize it, I can maximize it,
and you should be able to see that, and
| | 02:02 | you'll also see, down here, that it
created your application descriptor file.
| | 02:08 | That assigns it an ID.
| | 02:10 | It assigns it a file name.
| | 02:12 | It assigned it a version number.
| | 02:14 | So this settings for the HTML wrapper
are removed that would normally be in a
| | 02:18 | Flex application. The custom
Flash Player settings are removed.
| | 02:22 | It modified the library path to
include air_global.swf, instead
| | 02:27 | of player_global.swf.
| | 02:29 | This process cannot be undone, so bear
that in mind, and we can also, of course,
| | 02:34 | export this as a release build, and
digitally sign the application have an AIR
| | 02:38 | file, that the user can actually install.
| | 02:41 | So in order to use any of these
application programming interfaces, if we want
| | 02:46 | to access the file system, or create native
windows, our project has to be an AIR project.
| | 02:51 | This showed us how to actually
convert a Flex project into an AIR project.
| | Collapse this transcript |
|
|
5. Creating Application Windows Creating windows| 00:00 | Applications often need multiple
windows, and AIR allows us to create as many
| | 00:05 | windows as we need for an
application without any dependence on the
| | 00:08 | underlying operating system.
| | 00:10 | So we create windows in exactly the
same way, whether we're utilizing Windows,
| | 00:14 | Macintosh, or Linux.
| | 00:16 | As long as we're using Adobe AIR,
there is no difference between creating
| | 00:20 | windows in all of those
different operating systems.
| | 00:24 | We can create windows that look and
behave differently based upon our needs, and
| | 00:28 | we can even create custom
windows and program them ourselves.
| | 00:32 | So let's get started.
| | 00:34 | You'll see here that I've
imported the ApplicationWindow FXP file.
| | 00:39 | You'll see that there is
a source directory here.
| | 00:41 | So go ahead and open up the source
directory and then open the default package,
| | 00:45 | and you'll see there is ApplicationWindow1.mxml.
| | 00:49 | Go ahead and just open up this
ApplicationWindow1.mxml, as you see here, and
| | 00:55 | you'll see that my root tag here is the
WindowedApplication, and you'll see of
| | 00:59 | course there's a blank script block,
and then there's also a button here.
| | 01:04 | Let me go ahead and just run this application.
| | 01:08 | You'll see that this opens up in AIR, and
you'll see that there is an Open New Window button.
| | 01:14 | If I currently click on this, it does nothing.
| | 01:17 | What we want to do is when the user
clicks on this Open New Window button, we
| | 01:21 | want it to create a brand-
new operating system window.
| | 01:25 | So let's go ahead and do that.
| | 01:28 | First thing I want to do is just
create the window that it's going to open.
| | 01:31 | So go ahead and use your Components
directory here, and right-click on the
| | 01:35 | Components directory, click
New, and choose MXML Component.
| | 01:41 | You'll see that it creates a
package here called components.
| | 01:44 | Then for the Name here, let's create a
new window, and let's call this window
| | 01:51 | MyWindow1, as you see there.
| | 01:55 | Let's make sure that this window
is based off of the window class.
| | 02:01 | So here, I'm just going to simply say
Window, and let's make sure that we use the
| | 02:06 | Window - spark.components here.
| | 02:09 | So I'm going to click here.
| | 02:11 | This is utilizing the latest version of the
window class, as opposed to the MX version.
| | 02:16 | Then you're going to say the width of
this is 400, and the height of this is 300.
| | 02:20 | That's fine.
| | 02:22 | So go ahead and click Finish.
| | 02:24 | You'll see it creates us a new
MyWindow1.mxml in the Components directory.
| | 02:30 | Now again, we're just utilizing this
as an example, and in this case we're
| | 02:34 | utilizing Flash Builder.
| | 02:36 | For you Flash developers out there,
this works exactly the same way
| | 02:40 | utilizing the AIR APIs.
| | 02:42 | We open up windows in exactly the same
way so you may create a button, your
| | 02:47 | own custom button in a SWF file, and
you can open up windows in that way.
| | 02:51 | In this case we're utilizing MXML
because we're utilizing Flash Builder, but the
| | 02:56 | same basic principles apply
to Flash development as well.
| | 03:01 | So here is my MyWindow1.mxml.
| | 03:04 | Let's go ahead and switch to Design
mode, and just add some content here.
| | 03:08 | So the first thing I'd like you to
do is scroll down to the Controls, and
| | 03:12 | let's just add a DataGrid to our component
so we'll see something when we open this up.
| | 03:17 | We should see that DataGrid, and just as a
good practice, let's add in a button here.
| | 03:22 | We, of course, want to be able to give
the user a way to close this window.
| | 03:26 | So give this button an ID of
closeButton, and for the Label that the user will
| | 03:33 | see, let's call that Close.
| | 03:35 | In a movie later, we'll actually close this
window, so just type in "this.close" for now.
| | 03:41 | We'll write a method called Close that
will actually do the closing of this window.
| | 03:46 | So now we've created a simple component.
| | 03:48 | Let's go ahead and just save this component.
| | 03:53 | Then what I'd like you to do is go
back to the ApplicationWindow1.mxml, and
| | 03:58 | of course, when we want this window
to open, we want it to open up when the
| | 04:03 | user clicks the button.
| | 04:05 | So let's add a click handler to our button here.
| | 04:09 | So I'm just going to simply say
click =, and then I'm going to press the
| | 04:13 | Spacebar, and you'll see it
says click - InteractiveObject.
| | 04:16 | So I'm going to click there, and then
I'm going to say Generate Click Handler.
| | 04:22 | This is just a timesaving feature of
Flash Builder, and what it allows us to do
| | 04:27 | is automatically it builds the method
that the Click Handler is going to call.
| | 04:31 | So you'll see I have my openButton_
clickHandler, you'll see the names match
| | 04:36 | up here, and it's going to simply call this
method when the user clicks on that button.
| | 04:42 | It just saves us a lot of typing.
| | 04:45 | So the first thing I want you to do is
just go to the top of your clickHandler,
| | 04:51 | and just declare a private variable.
| | 04:54 | So I'm going to say private var, and
I'm going to call this window, and I'm
| | 04:58 | going to type this as
"Window," as you see there.
| | 05:02 | So that's going to create my private
var window:Window, and you'll see for some
| | 05:07 | reason in this case, it
didn't add an import statement.
| | 05:12 | So what I can do is I can click on
Window here, and I can type in Ctrl+Space,
| | 05:18 | and you'll see I can click
Window, and it says mx.core.
| | 05:23 | Well, that's not the one we use.
| | 05:24 | We use the Spark components.
| | 05:26 | So let's choose Spark, and you
should see it automatically adds an
| | 05:30 | import statement there.
| | 05:32 | Now, in most cases, Flash
Builder automatically will add that there.
| | 05:35 | For some reason, it didn't, and just
make sure that it says Window here, and it
| | 05:39 | imports this Spark.components.Window,
just for those of you checking.
| | 05:43 | I'm sure many of you probably did add
that import statement, as you see there.
| | 05:48 | So now that we've done that, let's
just go back down to our clickHandler.
| | 05:53 | This is just simply ActionScript 3, so
it's exactly the same in Flash or Flex.
| | 05:58 | What I'm going to say is I'm going to
say window, I'm going to use the New
| | 06:02 | command, and I'm going to
say is equal to MyWindow1.
| | 06:09 | Then, of course, I have to add my paren,
paren there, and you'll see I have MyWindow1window1
| | 06:14 | Now, you'll see in this case Flash
Builder did automatically add the import
| | 06:18 | statement, and this is, of course, a
custom component that I wrote, and it's
| | 06:22 | coming from my components directory.
| | 06:24 | This is what we just built.
| | 06:25 | It says import components.MyWindow1,
and you'll see it goes directly to this
| | 06:31 | Components directory that you see there.
| | 06:34 | So here I have window = MyWindow1.
| | 06:38 | Then finally, all I have to do is just
use the Open command to open this up.
| | 06:43 | So I'm going to type in the word
"window," I'm going to add in a dot, and
| | 06:47 | I'm going to use the open method, just
like that, and then type in my paren,
| | 06:51 | parenwindow.open().
| | 06:52 | So now what should happen is when the
user clicks on that button, it's going to
| | 06:57 | call this clickHandler, it's going to
create a new object called window, based on
| | 07:01 | this component, it's going
to then open up that window.
| | 07:04 | So let's go ahead and just save this.
| | 07:07 | You'll see that it
compiles with no problem here.
| | 07:11 | Then I'm going to go ahead
and run this application.
| | 07:14 | You'll see it opens up inside of AIR, and
then I'm going to click on Open New Window.
| | 07:21 | You'll see it will open up my new window,
and I can drag this window around, like
| | 07:26 | any other operating system
window. I can minimize it.
| | 07:30 | You should be able to see that it
appears in my taskbar here. You can see that.
| | 07:35 | Both of those appear in my taskbar,
because they are Adobe AIR applications.
| | 07:42 | So we have shown how to create a new
window inside of an AIR application,
| | 07:46 | and you can see this is done exactly the
same way on Windows, Mac, and Linux systems.
| | 07:50 | That's one of the magic things about Adobe AIR.
| | 07:53 | We're now ready to manipulate these
windows, and we can also learn how to change
| | 07:57 | the look and the feel of
them in upcoming movies.
| | Collapse this transcript |
| Changing the look and feel of application windows| 00:00 | We can change the look and feel of an
AIR window by modifying the system chrome,
| | 00:05 | which refers to the controls that
allow a user to open, minimize, maximize,
| | 00:10 | close, and drag a window.
| | 00:12 | We can choose between lightweight
where the window does not appear in the
| | 00:15 | taskbar, or normal where it does
appear in the taskbar, or even utility, which
| | 00:20 | is an even more slimmed down version
of lightweight, and this does not also
| | 00:24 | appear in the taskbar.
| | 00:26 | We can also choose whether or not the
window takes up the entire user's screen.
| | 00:31 | Let's go ahead and get started and
learn how to customize these windows
| | 00:35 | that we're creating.
| | 00:37 | So the first thing I'd like you to do is,
of course, import the application window
| | 00:40 | project, go down here to default
package, open up ApplicationWindow2.mxml.
| | 00:48 | Notice here that we have our
openButton_clickHandler, and this just creates a
| | 00:53 | new instance of this
component here, called MyWindow2.mxml.
| | 00:59 | Let's go ahead and run the
application and just examine what we have when
| | 01:03 | we're beginning here.
| | 01:04 | So I'm going to run my AIR application.
| | 01:06 | I'm going to click New Window, and
you'll see it opens up a brand-new window,
| | 01:10 | complete with the system
chrome. I can minimize it.
| | 01:14 | You'll see that both windows appear in my
taskbar here, and I can see all of that.
| | 01:20 | Let's close off both of these windows.
| | 01:22 | So I'm going to just close off both
these windows, and let's make some
| | 01:27 | customizations here.
| | 01:29 | So in the components folder, open
MyWindow2.mxml, and on top of the Window tag
| | 01:37 | here, what I'd like you to do is just
simply add in a new type, and let's make
| | 01:43 | this now a lightweight window.
| | 01:46 | So I'm going to say type =
"lightweight," and then let's specify a systemChrome
| | 01:51 | here, and note systemChrome is camel-case.
| | 01:54 | So I'm going to say systemChrome = "none".
| | 02:01 | So now I have added a type of lightweight,
and I've specified a systemChrome of none.
| | 02:07 | So now what I'm going to
do is save this and run.
| | 02:12 | Note you'll have to run it
from ApplicationWindow2.mxml.
| | 02:16 | So here I'm going to run the
application, and now if I click on Open New
| | 02:22 | Window, notice there is no systemChrome,
and you should also see that it's no
| | 02:27 | longer in the taskbar.
| | 02:29 | The only AIR application that I
currently have open in my taskbar is just
| | 02:34 | simply the ApplicationWindow2, not the
component, or the other window, like we saw before.
| | 02:40 | You'll see that both of those are there,
and let's close off both of these AIR
| | 02:46 | windows that you see there.
| | 02:48 | Let's go ahead and change, go back to
MyWindow2.mxml, and let's go ahead and
| | 02:54 | just change the type back to normal
from lightweight, and you should now see
| | 03:00 | that there is a taskbar item, though
the systemChrome will still be gone.
| | 03:05 | So just go ahead and click File > Save,
| | 03:07 | go back to your ApplicationWindow, click
Run, and you'll see that I didn't close
| | 03:14 | off my other window there,
which could be very important.
| | 03:18 | Let's see if I can close that
off by looking at my taskbar.
| | 03:22 | You'll notice we've added in a close
button into this, so it's easier to close,
| | 03:27 | and that may happen to some of you.
| | 03:29 | So here I'm just going to click close.
| | 03:31 | I'll go back to my Flash
Builder, and let's run this again.
| | 03:36 | When I click open, you'll see that
it's available from the taskbar.
| | 03:40 | You'll see that
ApplicationWindow2 is here on the taskbar.
| | 03:44 | Of course, I can simply close it by
clicking on the X. Well, in this case I
| | 03:49 | can't click on the X, of course, but
because I have the systemChrome defined, but
| | 03:55 | here I'll click close, and you'll
see I be able to close it that way.
| | 03:59 | So now let's go ahead and go back to
MyWindow2, and let's examine how we can
| | 04:04 | customize this with the fullscreen.
| | 04:06 | So you'll see there is a Button already here.
| | 04:09 | So here, on approximately line 35, I'm
just going to add an another Button
| | 04:13 | control, and I'm going to say s:Button,
as you see there, and I'll give this an
| | 04:20 | id of - let's call this
fullScreenButton, as you see there, and let's assign
| | 04:27 | this a label so the user sees this, and we'll
just call this Full Screen, as you see there.
| | 04:34 | Then add an a click event, and then type
in equal and press the Spacebar, and you'll
| | 04:40 | see it says click - InteractiveObject,
and then it says Generate clickHandler.
| | 04:46 | You'll see it automatically created us
this fullscreen clickHandler, and you'll
| | 04:50 | see it built this up here in the Script block.
| | 04:55 | Go ahead and make sure to
close off your Button tag.
| | 04:58 | Let's go up to our
fullscreen clickHandler here.
| | 05:03 | What I'd like you to do is just
reference the stage and specify .displayState, as
| | 05:11 | you see there, and then specify
is equal to StageDisplayState.
| | 05:15 | Be sure you use the camel case
there, and then specify a .FULL_SCREEN.
| | 05:25 | When the user clicks on that Full
Screen button, this will cause the window to
| | 05:28 | take up the entire screen.
| | 05:31 | Now, you want to use this very,
very cautiously, because the only way a
| | 05:34 | user will be able to escape from
this window is by pressing the Escape
| | 05:37 | button on their keyboard.
| | 05:39 | So you might want to add a visual queue,
something like that, so the user knows
| | 05:43 | to click the Escape button.
But let's examine what that does.
| | 05:48 | Let's go ahead and click File > Save.
| | 05:50 | You'll see that compiles okay.
| | 05:52 | Go back to your ApplicationWindow2.mxml,
run the application, and you'll see I'm
| | 05:59 | going to open up my New Window.
| | 06:01 | We should now see there is a
Full Screen button for my window.
| | 06:04 | Notice there still is no systemChrome, so I
don't have the minimize, maximize buttons.
| | 06:08 | And I'm going to click Full Screen, and
you'll see that now this window takes up
| | 06:13 | my full screen, but as an end user,
you'll see I can't see my taskbar.
| | 06:17 | The only way to escape from this window is
by pressing the Escape key, as you see there.
| | 06:24 | So we've taken a look at how to
modify the basic chrome for windows created
| | 06:28 | inside of Adobe AIR.
| | 06:30 | In order to customize these windows,
we can use the systemChrome and the type
| | 06:34 | properties to modify their behavior.
| | 06:36 | Now that we've explored a basic
level of window customization, we're ready
| | 06:41 | to begin manipulating windows and
understanding some of the events that windows emit.
| | 06:46 | So I'm going to close off
that window, and that's it.
| | Collapse this transcript |
| Using window events| 00:00 | AIR application windows, by default,
have the ability to maximize, minimize,
| | 00:05 | restore and activate, which means
receive the user focus, and also can be moved
| | 00:11 | around by the end user.
| | 00:13 | Using the Adobe AIR APIs, we can control
this behavior and even add custom icons
| | 00:19 | above and beyond the
existing AIR window default chrome.
| | 00:23 | We can even suppress default event behavior.
| | 00:26 | For example, we can
customize the closing of a window.
| | 00:29 | This allows us to add a whole other
level of customization to controlling
| | 00:34 | windows in Adobe AIR.
| | 00:37 | So you'll see here that I've imported
the Application Window project, and what
| | 00:41 | I'd like you to do is just open up this
ApplicationWindow3.mxml, and you'll see
| | 00:48 | I have this application window.
| | 00:50 | You'll see I'm opening up a new
window, and in this case it's the
| | 00:52 | component MyWindow_3.
| | 00:56 | And go ahead and open up MyWindow3 here .MXML,
and you'll see when I open up MyWindow3.mxml,
| | 01:04 | if I scroll down here, you will see
that there is my fullscreen click handler,
| | 01:08 | which puts it into a Full Screen mode.
| | 01:10 | But then you will also see that I've
created a minimize button click handler, a
| | 01:14 | maximize button click handler,
and a restore button click handler.
| | 01:18 | And you'll see down here, I have
these buttons a minimize button, a
| | 01:21 | maximize button, and a restore
button, that's calling each of those
| | 01:25 | respective click handlers.
| | 01:27 | So here you will see that I have the
restore method, the maximize method, and
| | 01:30 | the minimize method.
| | 01:32 | And what I have basically done is written
customized buttons to control these actions.
| | 01:38 | So let's go back to
ApplicationWindow3 and run this.
| | 01:42 | And you'll see, when I run this window,
and I click Open New Window, you'll see
| | 01:46 | that I can minimize the window,
| | 01:48 | I can maximize the window, simply
by clicking on one of these buttons.
| | 01:52 | So, for example, if I minimize it,
you'll see that I'll minimize the window.
| | 01:56 | I can also, of course,
maximize it by clicking here.
| | 01:59 | I can unmaximize it by clicking there.
| | 02:01 | But you can see that I can control
these functions through custom icons.
| | 02:05 | So I could put whatever I want.
| | 02:07 | I could create a cool animation and
have that be my Maximize button, simply by
| | 02:11 | being able to reference that
code, which is pretty cool.
| | 02:14 | Notice there is also a
suppress closing check box here.
| | 02:17 | So let's get an idea of how to
actually customize this window behavior.
| | 02:21 | So one of the things you'll see, the
only way I can actually move around this
| | 02:25 | window is by clicking up
here on the default chrome.
| | 02:28 | Let's say I want the user to have the
ability to click anywhere in the window
| | 02:32 | and be able to drag it around;
you'll see that I can't do that.
| | 02:35 | So let's add that functionality to
our window application, so we can get an
| | 02:39 | idea of how this works.
| | 02:40 | So I am going to close off this and
then close off my main AIR application, and
| | 02:46 | the first thing I want you to do is go
back to your MyWindow3.mxml component,
| | 02:52 | and let's build in a new method here.
| | 02:55 | So I am just going to simply say
"protected function," just like so, and let's
| | 03:01 | call this function moveWindow, and this
is going to happen on a mouse event, so
| | 03:07 | I am going to say event:, and I am
going to type this as a mouse event.
| | 03:12 | Okay, this function won't be
returning anything, so I will specify void.
| | 03:16 | So there is my move window that you see there.
| | 03:19 | And then inside of this I'm just going
to just simply reference nativeWindow,
| | 03:25 | and I am going to use startMove method to
start the ability to move around this window.
| | 03:30 | So here I am going to put in my
semicolon, and then, up here in the init
| | 03:34 | function, let's set up an event
listener to listen for a mouse down anywhere
| | 03:39 | inside of this window.
| | 03:40 | So I am going to just simply say
addEventListener, like you see there, and then
| | 03:45 | I am going to say
MouseEvent, like so, .MOUSE_DOWN;
| | 03:53 | and then I am going to call this method
that I just wrote, which is called moveWindow.
| | 03:58 | So what I'm saying there is anytime the
user clicks anywhere on that window, go
| | 04:03 | ahead and give them the
ability to start moving that window.
| | 04:07 | So here I'm just going to hit File > Save.
| | 04:08 | I am going to save MyWindow3, I am
going to go back to my application window,
| | 04:13 | and I am going to run this.
| | 04:15 | So I'll click here. You will see that
will open up my AIR application.
| | 04:19 | I am going to click on Open
New Window. Now watch this:
| | 04:22 | I can click anywhere and
start moving this window around
| | 04:26 | because of that functionality that I just added.
| | 04:29 | So that is pretty cool.
| | 04:31 | So I am going to close off both these
windows, and we can also not only do that,
| | 04:37 | but we can prevent certain
default behavior from occurring.
| | 04:41 | So say, for example, let's say I want
to totally control whether or not the user
| | 04:45 | can even close a window.
| | 04:47 | I might want that window to always be
open and not give the user the ability
| | 04:51 | to close that window.
| | 04:52 | Let's get an idea of how to do that.
So now go back to your MyWindow3.mxml
| | 04:58 | component, and just below your init
function, let's add in another method
| | 05:03 | called Control Closing.
| | 05:05 | So here I am going to say "protected
function," and I'll call this "controlClosing,"
| | 05:11 | and then I will say "event:Event."
| | 05:18 | And in this case this method
won't be returning things, so I will
| | 05:20 | specify another void there.
| | 05:22 | And then I'm just going to
add in some additional logic.
| | 05:25 | And I will add an if statement, and I
will say "if event.cancelable," which means
| | 05:31 | I can control that event,
| | 05:34 | "&&," you'll see that there
is a check box down here.
| | 05:37 | You will see the check box
has an ID of suppressClosing.
| | 05:42 | So I will say, if this is going to
happen, if the user clicks on the check box,
| | 05:46 | I'll say the name, which is the ID of
the suppressClosing check box, so if
| | 05:52 | event.cancelable && suppressClosing.
selected, which means the user has selected
| | 05:59 | that check box, and then I will add in
my condition here, and I will just say
| | 06:05 | event.preventDefault.
| | 06:09 | And that will prevent that default
closing event from occurring if, of course,
| | 06:14 | that check box is selected.
| | 06:18 | So add in a semicolon here, make sure that
all my brackets are good. That looks good.
| | 06:24 | And then, finally, I will
listen for this event to occur.
| | 06:28 | So again, I'll add in another
addEventListener in my init function, so I will
| | 06:33 | say addEventListener.
| | 06:36 | Here I will say event.CLOSING, and
again, when this closing event occurs, I want
| | 06:45 | it to call this function, controlClosing,
which of course, as you see down here,
| | 06:50 | is exactly the name of the method that I just
wrote, called Control Closing, as you see there.
| | 06:56 | So I will say controlClosing, add in my
semicolon, and then I will save this component.
| | 07:03 | You will see that compiles okay.
| | 07:05 | I'll go back to my
ApplicationWindow. I'll run this.
| | 07:09 | Now you will see, if I click on Open New
Window, just like so, notice my Suppress
| | 07:16 | Closing is now checked, and watch this.
| | 07:19 | When I click on the Close button, you
should see it doesn't work, because I can
| | 07:24 | control whether or not the user
can actually close this window.
| | 07:30 | So we've taken a look at how AIR
window behavior can be customized.
| | 07:34 | Using the techniques we demonstrated
here, we could create custom icons that
| | 07:38 | would close or maximize windows;
really, the sky is the limit.
| | 07:41 | We could create animations.
| | 07:43 | We could even force windows to stay
open based on particular things happening
| | 07:48 | inside of our application, so you can
see how customizable the window class is.
| | Collapse this transcript |
|
|
6. Accessing Files on the Operating System Moving and copying files| 00:00 | One of the huge advantages of Adobe
AIR 2.0 is the fact that a developer can
| | 00:05 | manipulate files on the native operating system.
| | 00:08 | We can move, delete, and copy
files directly from Adobe AIR.
| | 00:13 | Now, of course, this can be very dangerous,
| | 00:15 | so you want to make sure that you
don't manipulate any files, for example, in
| | 00:18 | the Windows directory, because
you could do damage to your system.
| | 00:22 | But that aside, the first step in
manipulating files is to use the file
| | 00:27 | object in the Adobe AIR API, and this, of
course, can be accessed from both Flash or Flex.
| | 00:33 | We'll be utilizing Flash Builder here,
and this object creates a reference to a
| | 00:37 | file on whatever operating system AIR
happens to be running on, whether it's
| | 00:41 | Mac, Windows, or Linux.
| | 00:44 | Then we can manipulate that file from Adobe AIR.
| | 00:47 | So let's get started.
| | 00:49 | You'll see here that I've
imported the FileSystem project.
| | 00:53 | Let's go ahead and open up FileSystem1.mxml.
| | 00:58 | You'll see here we have some starting code here.
| | 01:00 | You'll see that most of this is
fairly straightforward, but you'll see, of
| | 01:03 | course, that there is a Script block.
| | 01:05 | In here, I've declared a
bunch of different variables.
| | 01:08 | I've declared a variable called new
directory, source file, and destination file.
| | 01:12 | Ultimately, we're going to be able to
set up a system that'll be able to copy
| | 01:15 | files directly from our AIR application.
| | 01:18 | I've built the skeleton of a few
methods here called init and copyFile.
| | 01:23 | Then there is a button
here called Copy File as well.
| | 01:26 | You can just see on creationComplete
that the init is actually being called.
| | 01:31 | So if I run this, you'll simply see
at this point, there is just a button
| | 01:34 | that says Copy File.
| | 01:37 | You'll see at this point,
this button does nothing.
| | 01:39 | But let's go ahead and actually
build some functionality in here.
| | 01:43 | So the first thing I'd like you to do
is let's just create our file objects
| | 01:47 | that will reference these files on whatever
operating system AIR happens to be running on.
| | 01:51 | Let's do that here in the init method.
| | 01:54 | So the first thing I want you to do
is just create a new variable here
| | 01:58 | called new directory. I'll say newDir.
| | 02:02 | I'll just say this will be equal
to File.applicationStorageDirectory.
| | 02:09 | Of course, the
applicationStorageDirectory can vary by operating system.
| | 02:13 | In many cases, it can be under a user's
data, but again, because we're doing this
| | 02:17 | from AIR, AIR will handle
that complexity and find the
| | 02:21 | applicationStorageDirectory for us.
| | 02:23 | Then I'm going to use
that resolvePath method here.
| | 02:27 | I'm just going to simply say resolvePath.
| | 02:28 | I'm going to pass it the string literal
here, the paths, and I'm going to pass
| | 02:34 | it the word "files" for now.
| | 02:36 | So, it's going to resolve that path.
| | 02:38 | I'll close off my parentheses here.
| | 02:41 | Then I'm going to say newDir.
| | 02:44 | So I'll reference the
variable that I just created.
| | 02:46 | I'm going to create a new directory.
| | 02:48 | So I'll use this
createDirectory method that you see here.
| | 02:53 | Let's simply just do a trace,
so I can see what happens.
| | 02:57 | So I'm going to say trace (newDir.nativePath).
| | 03:04 | We should see the native path to this directory.
| | 03:07 | Now, of course, as I said before, this
is going to vary by operating system.
| | 03:11 | In this case, I happen to be using Windows,
so it'll display the path inside of Windows.
| | 03:16 | For those of you who are on a Mac, or
those of you testing this even on a Linux
| | 03:19 | system, you'll see that
you'll get a different result here.
| | 03:21 | So I'm just going to hit Save.
| | 03:24 | Then I'm going to click Debug application.
| | 03:27 | You should see the path, and it should
write this directly to your console here.
| | 03:32 | So you'll see in my case, and on Windows 7 -
could vary with different versions of Windows even -
| | 03:37 | but you'll see here it says, Users\James
| | 03:39 | Talbot\AppData\Roaming\FileSystem1\Local Store.
| | 03:44 | It created this here right under files.
| | 03:48 | So this will show you the newly created
directory, so we can get an idea of how that works.
| | 03:54 | So now I'd like you to
scroll down in your code here.
| | 03:57 | Let's go to this pre-written
skeleton of a function here called copyFile.
| | 04:03 | Let's first of all add
some conditional logic here.
| | 04:05 | I'm just going to say if (newDir.exists).
| | 04:12 | So that's just saying if this new
directory is already here, let's create a
| | 04:17 | variable here called source file.
| | 04:19 | So I'm going to say source file
srcFile = File.applicationDirectory.
| | 04:31 | Then I'm going to say .resolvePath.
| | 04:36 | Then I'm going to say, I'll put in
the String literal here for the path, and
| | 04:40 | I'll specify assets/lynda.txt.
| | 04:47 | You'll see that that lynda.txt file
is located right here in your assets
| | 04:55 | directory for your project.
| | 04:57 | It's going to say
applicationDirectory.resolvePath("assets/lynda.txt").
| | 05:03 | That text file is located in that directory.
| | 05:05 | So now I'm going to add a trace function.
| | 05:08 | I'm going to simply just say trace.
| | 05:11 | Let's put in - so we know what we're tracing -
| | 05:13 | I'll put in srcFile.path:
| | 05:17 | put in a space, and end my string literal.
| | 05:20 | I'll add a concatenation here, and I'll
specify srcFile.nativePath, as you see there.
| | 05:28 | Then I'll close that.
| | 05:29 | I'll say nativePath.
| | 05:31 | So we'll see that trace,
so we can see where that is.
| | 05:35 | Then I'm going to create another
variable here called destination file.
| | 05:38 | So I'll say destFile.
| | 05:40 | I'll say again, = newDir.
| | 05:44 | This is my file object, as you saw before.
| | 05:47 | I'm going to say newDir.resolvePath.
| | 05:54 | I'm going to say lynda.txt, as you see there.
| | 06:01 | Then that's going to resolve the path there.
| | 06:04 | Then I can use the copyTo.
| | 06:05 | So I'll say srcFile.copyTo.
| | 06:11 | Then I'll specify my destFile, as we saw there.
| | 06:15 | I'll simply just specify that I'd like
it to overwrite it, if it's already there.
| | 06:19 | So here, I'm going to say true.
| | 06:21 | So that's just saying if it's
already there, go ahead and overwrite it.
| | 06:25 | Then let's just simply do a trace
here, so we can see the path again.
| | 06:29 | So I'm going to say destFile path: space.
| | 06:35 | Again, add a concatenation, and I'll
say destFile.nativePath, just like so,
| | 06:43 | and close that off.
| | 06:45 | So let's go ahead and save this.
| | 06:48 | You'll see that that compiles fine.
| | 06:51 | Now I'm going to debug this.
| | 06:53 | So I'm going to click on Debug.
| | 06:57 | You'll see the two traces that
I've done here in the console.
| | 07:01 | You'll see first of all, of course, the first
trace that I've done to the files directory.
| | 07:05 | But now, you'll see I click on Copy
File, and you'll see the srcFile path
| | 07:09 | Users\James Talbot\Adobe Flash
Builder 4\FileSystem\assets\lynda.txt.
| | 07:14 | You'll see where it copied it to.
| | 07:16 | In this case, it copied it to James
Talbot\AppData\Roaming\FileSystem\Local
| | 07:22 | Store\files\lynda.txt.
| | 07:24 | So it actually took this source file,
and copied it here to this destination.
| | 07:30 | Again, of course, this
will vary by operating system.
| | 07:33 | So we've shown how to reference a file,
how to create a directory, and then
| | 07:37 | manipulate that file using the Adobe AIR
API, which, of course, is valid in both
| | 07:43 | Flash Builder, utilizing the Flex
Framework, and just in the Flash itself.
| | 07:48 | We're now ready to learn about how
to actually use the file system visual
| | 07:51 | components that ship with the Flex
framework to make this process easier and more visual.
| | 07:57 | We could, of course, build our own
components, whether in Flash or Flex, but
| | 08:01 | these file system components that
shipped with the Flex framework just make
| | 08:05 | it a lot easier.
| | Collapse this transcript |
| Using the file browsing components| 00:00 | Adobe AIR has specific APIs for
manipulating files on the file system under the
| | 00:05 | hood, but these, of course,
are not displayed to the user.
| | 00:09 | If we wish to involve a user in the
process, we can either build custom file
| | 00:13 | components or use the file system
browsing components that ship with the
| | 00:18 | Flex framework, and are utilized with Adobe AIR.
| | 00:22 | For those of you who are Flash
developers, and aren't familiar with the Flex
| | 00:25 | framework, what you see here I think
will help you a lot in terms of being able
| | 00:29 | to develop your own custom file
components inside of Flash, utilizing these APIs.
| | 00:34 | So let's get a look at how these
actually work, because these components will
| | 00:39 | allow a user to select a specific
directory, and then they'll be able to the
| | 00:43 | select a specific file from the directory,
or we can set it up so they can even
| | 00:47 | select multiple files from a directory.
| | 00:50 | We can display these files in a visual way,
either utilizing a grid, a tree, or a list component.
| | 00:59 | So let's go ahead and actually look at this.
| | 01:02 | You'll see the first thing I've
done here is I've imported the
| | 01:04 | FileSystem project.
| | 01:06 | You'll see I have that there.
| | 01:07 | Then I'd like you to scroll down to
FileSystem2.mxml, and go ahead and open up that.
| | 01:13 | You'll see I just have a
few components already here.
| | 01:16 | So in this case, I have a Label
control that says Start Folder, and another
| | 01:20 | one called Text Input.
| | 01:22 | Then below that, I have another one
that says Selected and selectedPath.
| | 01:27 | So let's just go ahead and run this,
so we know what we're working with.
| | 01:31 | You'll see I have a Start Folder where the
user can point to, and what they've selected.
| | 01:36 | What I want to have is some visual
components that will actually display how
| | 01:39 | these files are set up on
the user's local machine.
| | 01:44 | As we saw before, one of the things we can
do to do this is to create a new file object.
| | 01:51 | So let's go ahead and create a new file object.
| | 01:53 | Let's make sure that this file
object can be used with data binding.
| | 01:58 | So I'm going to say Bindable here.
| | 01:59 | I'm going to add the Bindable meta
tag, and I'm going to say private var.
| | 02:04 | Let's call this dir, and
let's type this as a File object.
| | 02:09 | I'm simply going to say new File().
| | 02:12 | That's going to create a
new file object called dir.
| | 02:18 | If you scroll down, you'll see that
there is a folderPath_clickHandler here.
| | 02:23 | This folderPath_clickHandler is called
if the user clicks inside of the first
| | 02:29 | folderPath that we saw.
| | 02:31 | So let's say, when this is actually
called, let's use my file object, and
| | 02:37 | I'm going to say browseForDirectory right here.
| | 02:41 | So that's going to cause the
browseForDirectory to appear.
| | 02:45 | Then let's just display Select a Directory,
| | 02:50 | so the user will be able to select a directory.
| | 02:53 | Then let's add an EventListener for
what happens when the user actually
| | 02:57 | does select a directory.
| | 02:59 | So I'll say
dir.addEventListener, as you see there.
| | 03:05 | I'll say Event.SELECT, which means
the user has actually selected a file.
| | 03:12 | So when this happens, when the user
actually selects the file from that directory,
| | 03:16 | I wanted to call this method up
here called directorySelected.
| | 03:22 | So here I'll say
directorySelected, as you see there.
| | 03:26 | Then inside of the directorySelected
function, let's go ahead and just add this code.
| | 03:32 | So I'm going to say folderPath.text.
| | 03:37 | That's the text field that we saw,
that we created, that was already
| | 03:41 | pre-created for us.
| | 03:43 | Let's say folderPath.text
is equal to the File object.
| | 03:50 | Then I'm going to say event.target.
| | 03:53 | So event.target is, of course,
coming from this clickHandler.
| | 03:57 | So this is going to be
when the user selects that.
| | 04:01 | So that's going to be the file
object, when I say event.target.
| | 04:05 | We're going to cast that as a file object.
| | 04:08 | Then I'm going to say nativePath.
| | 04:10 | So that's going to point to whatever
operating system the user happens to be on.
| | 04:15 | That's going to display the
nativePath inside of that field.
| | 04:19 | So here, I'm going to say nativePath.
| | 04:22 | So now what I want you to do is you'll
see between the two HGroups, let's add in
| | 04:28 | a new custom component to display this.
| | 04:30 | So here, I'm going to say mx:FileSystemList.
| | 04:37 | I'm going to assign this an id
of fileComp, as you see there.
| | 04:45 | Then I'm going to specify
itemClick when the user clicks on an item.
| | 04:48 | I'm just going to simply create a
ClickHandler for this, just as we've done before.
| | 04:55 | So I'll say itemClick generate a ClickHandler.
| | 04:57 | You'll see it automatically
generates me a ClickHandler up here.
| | 05:01 | So when the user clicks on one of those
files that have actually been displayed,
| | 05:05 | then I'll close off this.
| | 05:08 | Inside of this ClickHandler,
let's just delete this comment.
| | 05:13 | What I'm going to say is I'm
going to say selectedPath.text =
| | 05:20 | event.target.selectedItem.nativePath.
| | 05:28 | So that will display the selectedPath
inside of that textbox that you see there.
| | 05:34 | Then let's scroll back up to our
directorySelected event handler.
| | 05:40 | Let's just add the code here.
| | 05:42 | I'm going to say
fileComp.directory = event.target here.
| | 05:50 | Again, I'm going to cast that as
a File object, as you see there.
| | 05:56 | And fileComp is referencing
the visual display of the files.
| | 06:03 | Here I'm just saying the directory of
where this is going to point to is set to
| | 06:08 | event.target as File, as you see there.
| | 06:13 | So let's go ahead and save this.
| | 06:14 | Then I'm going to run.
| | 06:18 | Once I run this, you'll see
that I have my folders here.
| | 06:22 | So you'll see that it references, for
example, because of the FileSystemList
| | 06:26 | without doing anything, you should see
you have the C and the D folders here.
| | 06:30 | So in the Start Folder, what I'm going to
do is I'm going to click in the Start Folder.
| | 06:35 | It points to the desktop here.
| | 06:37 | So make sure the desktop is chosen,
and click on the Exercise Files.
| | 06:41 | You'll see all of the lynda exercise files here.
| | 06:44 | Go ahead and click OK.
| | 06:46 | Notice it will then display the path
to each one of these files here for
| | 06:50 | the exercise files.
| | 06:52 | You can click on it, and it will then
display it in the Selected field, and it
| | 06:56 | will display the exact path to
each one of these different files.
| | 07:01 | So if I click here, you'll see
Securing AIR Applications, and so on.
| | 07:05 | Of course, I can change this
to a different directory here.
| | 07:08 | So, for example, if I chose it to
Libraries, I could click under Documents, or
| | 07:12 | My Documents in this case, and
I can see what's under there.
| | 07:17 | There are multiple different visual
components that we can use besides just
| | 07:22 | the FileSystemList.
| | 07:24 | They all work exactly the same way.
| | 07:27 | So let's change this to,
instead of a FileSystemList,
| | 07:31 | let's change this to a FileSystemTree. Save.
| | 07:35 | You'll see they have exactly the same APIs,
so I can still use itemClick and everything.
| | 07:39 | Now I'm going to run.
| | 07:42 | You'll see that this now is displayed
inside of a tree format, instead of a list.
| | 07:48 | So here I'll point back to my exercise files.
| | 07:51 | I'll open one of these, and note
that this is displayed in a tree format
| | 07:55 | instead of a list format.
| | 07:57 | We can do the same thing here, and just
change this into a FileSystemDataGrid,
| | 08:04 | and display it in this way.
| | 08:07 | You'll see it'll be displayed in a grid format.
| | 08:09 | So again, same API.
| | 08:10 | It can use exactly the same code.
| | 08:12 | Then I'm going to run.
| | 08:15 | You should see that this is now
displayed in a grid format here instead of in a
| | 08:22 | list, or in a tree format.
| | 08:25 | So, we've seen how to use the
FileSystem components to visually represent the
| | 08:29 | manipulation of files.
| | 08:31 | Of course, we could always build
our own custom components for handling
| | 08:34 | manipulation of the FileSystem, but
these components can save lots of time.
| | 08:40 | These components are built, and are
inside of the Flex framework, but of
| | 08:44 | course, Flash developers could build
their own components utilizing the AIR
| | 08:49 | APIs, just as we've seen here.
| | Collapse this transcript |
| Launching files in their default application| 00:00 | A new feature of Adobe AIR 2.0 is
the ability to open files in their
| | 00:04 | native application.
| | 00:05 | For example, if an end user's
machine was set up to open all doc files in
| | 00:08 | Microsoft Word, we could automatically
spawn Microsoft Word from inside of the
| | 00:13 | Adobe AIR application whenever
a user clicked on a doc file.
| | 00:17 | This is achieved through the File class,
and the File class has a new method
| | 00:20 | called open with default application.
| | 00:23 | Let's explore how to use this new method.
| | 00:25 | So, the first thing I'd like you to do
is just make sure that your FileSystem
| | 00:28 | project is imported, and then go
ahead and click on FileSystem3.mxml.
| | 00:35 | Let's explore the starting code
that we have in this application.
| | 00:39 | So, I'm just going to run the application,
and you'll simply see that there is a button.
| | 00:44 | So, we're going to add the code that
when the user clicks on this button, it
| | 00:46 | opens up a file browsing dialog box.
| | 00:49 | Of course, that's going to vary by
operating system, but for our purposes in
| | 00:53 | AIR, we know how to do that
already, so we'll do that.
| | 00:56 | Then when the user selects a type of
file, we're going to try to open it with
| | 01:01 | the default application
method of the File class.
| | 01:04 | If that fails, we're going to try to
catch any errors through the catch method
| | 01:08 | here, as well as through the onIOError.
| | 01:11 | The first step here is to just simply declare
our file object inside of the init() method.
| | 01:18 | So, here I'm going to fileToOpen = new
File(), and that's going to create an
| | 01:25 | instance of the File class.
| | 01:28 | Then I'm going to add an EventListener,
so I'm going to say fileToOpen, I'm
| | 01:31 | going to say addEventListener, just
like so, and let's listen for the SELECT
| | 01:39 | event, which just means that the file has
actually been selected by the end user.
| | 01:44 | Then when the user actually selects
a file, let's call this prewritten
| | 01:48 | method that you see down here, called
onFileSelect, that's going to actually try to open it up.
| | 01:54 | So, here I'm just going to say
onFileSelect, as you see there.
| | 01:59 | Then let's also add in fileToOpen.
| | 02:02 | Let's also try to catch any errors.
| | 02:04 | So, here I'm going to say
addEventListener again, and I'm going to say
| | 02:08 | IOErrorEvent, and then
I'm going to say onIOError.
| | 02:18 | If you look below, you'll see that
there is a method there called onIOError.
| | 02:22 | So, this is just if any exceptions or
errors are thrown outside of actually
| | 02:26 | trying to do the on default application.
| | 02:29 | So, we'll look at that in a moment.
| | 02:31 | So, now in the onFileSelect here, let's
first of all select where we're writing
| | 02:37 | this to the file system, so here I am
going to say filePath.text, and remember,
| | 02:43 | there is a filePath RichText control.
| | 02:47 | So, I'll say filePath.text, and then let's,
of course, just cast this as a File object.
| | 02:53 | I'm going to say (event.target), and
this is, of course, going to reference my
| | 02:59 | File object, because this onSelect
method is called when the user selects a file
| | 03:04 | from the File object.
| | 03:06 | I'm going to reference the nativePath,
so that will write the native path of
| | 03:11 | where that file is to this RichText field.
| | 03:15 | So, again, I'm going to reference
my File object, so I'm going to say
| | 03:18 | fileToOpen, and then I'm just going to
simply use my openWithDefaultApplication.
| | 03:25 | So, this will open up the file with
whatever has been associated with it on
| | 03:29 | the end user's machine.
| | 03:31 | So, for example, if the user has to
open up Microsoft Word whenever a doc file
| | 03:35 | is opened, it will open up Microsoft Word.
| | 03:39 | In some cases, we may be prohibited from
opening a specific type of application.
| | 03:44 | So, for example, on Windows, we are
prohibited from opening up executable files.
| | 03:50 | So, if there is an error, let's simply
say Alert.show, and then just say "The
| | 03:56 | operating system is prohibited
from opening this type of file".
| | 04:06 | Another type of error that could occur
is that there could be no particular file
| | 04:10 | association with this particular type of file.
| | 04:14 | If that happens, this onIOError event
will be called from the File object.
| | 04:20 | So, here, I'm going to say Alert.show,
and I'll just say, "There is no default
| | 04:29 | file type for this type of file".
| | 04:34 | If I do this, this will work on a
Macintosh or on a Linux machine, but this will
| | 04:40 | silently fail on a Windows machine.
| | 04:43 | Again, that's in the AIR documentation,
so we should see a silent fail if we
| | 04:48 | test this on Windows.
| | 04:50 | So, I'm just going to add in a
comment there, so we understand.
| | 04:53 | We remember that this actually silently
fails on Windows, and it just doesn't open up.
| | 04:58 | We will see that in just a moment.
| | 05:00 | So, now we have this.
| | 05:02 | Let's just go ahead and save this
FileSystem3.mxml, and let's run, and let's
| | 05:08 | perform some tests here.
| | 05:11 | On my particular machine, I currently have any
doc files set up to open up in Microsoft Word.
| | 05:16 | So, I'm going to just choose Click to
browse, as you see there, and you're going
| | 05:21 | to see that nothing happens at this
point, because, of course, what I forgot to
| | 05:25 | do is I forgot to open up a Browse
dialog box, which is, of course, one of the
| | 05:30 | most important things here.
| | 05:32 | So, you'll see here on the Button, it
says click="browseToOpen (event)", and
| | 05:38 | you'll see I have my browseToOpen.
| | 05:41 | Again, just as a review from some of
the other lessons, to open this up, I can
| | 05:45 | say fileToOpen, and I can say
browseForOpen, and then I'm going to say "Browse
| | 05:56 | for a file," as you see there.
| | 05:59 | This will open up a browsing dialog box,
whether we're on Windows, whether we're
| | 06:03 | on Mac, or whether we're on Linux.
| | 06:05 | So, let's test that now.
| | 06:07 | I'm going to hit File > Save, and
then Run, and we should see, it opens up.
| | 06:12 | When I click on browse, it's
going to open up a File dialog box.
| | 06:17 | What I'm going to do is I'm just going
to explore my user here, so I'm going
| | 06:22 | to say C:>Users, in this case, and I'm
going to say James Talbot/Adobe Flash Builder 4.
| | 06:30 | You'll see I have my FileSystem project,
and inside of this FileSystem project,
| | 06:35 | under source, you'll see my assets directory.
| | 06:39 | You'll see I have a bunch
of files called LocalFile.
| | 06:42 | On my machine, I have all doc
files set to open up in Microsoft Word.
| | 06:47 | So, for example, if I choose
LocalFile.doc, and I click Open, you should see
| | 06:52 | that it starts up
Microsoft Word. That works fine.
| | 06:56 | You could see I can now view
this file inside of Microsoft Word.
| | 07:00 | Let's run some other tests. Click browse.
| | 07:04 | You also see there is an EXE
file in here called localFile.
| | 07:07 | So, if I click on localFile, and I
choose Open, again, Windows is prohibited
| | 07:13 | from opening up EXE files.
| | 07:15 | So, you'll see that my catch worked
here, and it says the operating system is
| | 07:19 | prohibited from opening up this type of file.
| | 07:22 | So, that's exactly the expected behavior.
| | 07:25 | Now, on my machine, PDFs don't
have any type of file association.
| | 07:29 | So, I don't have it
opening up in Acrobat or Reader.
| | 07:33 | This system does not know what a PDF is.
| | 07:35 | So, let's click on Open, and we
should see that this just silently fails in
| | 07:40 | Windows, because there is
no association with PDF.
| | 07:45 | For those of you on a Mac, you should
see that it actually displays that error
| | 07:49 | message that says there is no
default file association for PDFs.
| | Collapse this transcript |
| Working with mass storage devices| 00:00 | Adobe AIR 2.0 can detect when
mass storage devices are attached and
| | 00:04 | detached from its host.
| | 00:06 | Once these applications are connected,
Adobe AIR can write to them just as if
| | 00:10 | they were local to the host.
| | 00:12 | This is a very powerful function, and
managed through the storage volume, storage
| | 00:15 | volume info, and storage volume change classes.
| | 00:19 | Let's begin to work with these classes
and learn how to read and write files and
| | 00:22 | attach mass storage devices, as well as
learning how to manage multiple different
| | 00:28 | devices that have been attached to our host.
| | 00:31 | So, let's just examine what we have
here, in terms of the starting file.
| | 00:35 | So, you'll see I've imported the
FileSystem project, and you'll also see that
| | 00:40 | I've opened up FileSystem4.mxml.
| | 00:44 | So, let's examine the interface that we
have, and you'll see that I have a list
| | 00:48 | control here, and this list control is
going to eventually display all of the
| | 00:52 | mounted devices attached to my system.
| | 00:56 | Then as I select each one of these
devices, I am going to want it to display the
| | 01:00 | Device name, the Device path, the
Device type, Is it Writable, Is it Removable.
| | 01:06 | Normally, of course, in real life you'd
able to use this information to be able
| | 01:10 | to add conditional logic.
| | 01:11 | So, for example, you might say, is device writable,
before you start writing to the device.
| | 01:15 | Of course, you might display the path
in a text field so the user knows where
| | 01:21 | it's writing to, and you
can get that information here.
| | 01:24 | Now, I'm organizing multiple devices, so
the way that I thought I'd organize this
| | 01:29 | is by creating a value object.
| | 01:31 | So, you'll see I have a folder called
vo, and inside of that folder, I have an
| | 01:34 | ActionScript file called Device.as, and
this is just simply to organize multiple
| | 01:41 | different devices that might be attached.
| | 01:43 | So, each time a new device is attached, I am
going to create a new instance of this class.
| | 01:49 | Then you could see I am going to
populate it with the rootDirectory, the
| | 01:53 | name, the nativePath, the fileSystemType,
whether it's Writable, and whether it's Removable.
| | 01:59 | All this information is actually
stored in the Event object when a device is
| | 02:03 | actually attached to the system.
| | 02:05 | I am going to simply just pass the
event object to this device class, and I'm
| | 02:10 | going to create a new object that I can display.
| | 02:14 | The beauty of this is I am going to
store all of those objects inside of this
| | 02:18 | ArrayCollection called devices.
| | 02:21 | So, all of those objects are
going to be stored inside of this
| | 02:24 | ArrayCollection called devices.
| | 02:26 | You could see here I have my devices:
ArrayCollection, and I am going to simply
| | 02:31 | just add the information to this
ArrayCollection every time a new device is
| | 02:35 | attached to the system, and that way
we'll be able to organize all of the
| | 02:39 | devices and in this case you'll see
that we'll attach more than one device.
| | 02:43 | So, what I want you do is go to your
init function, and let's add in an event to
| | 02:50 | occur when a user actually
attaches a device to the system.
| | 02:55 | So, I am going to say
StorageVolumeInfo, and then I am going to say
| | 03:01 | .storageVolumeInfo, and then I am going
to say addEventListener, and then here I
| | 03:10 | want to us say STORAGE_VOLUME_MOUNT.
| | 03:14 | So, this is going to occur when a
device is attached to the system.
| | 03:19 | So I want to happen is when a device is
attached to the system, I want it to call
| | 03:23 | this onDeviceMount method
that you see right below here.
| | 03:27 | So, I am just going to say onDeviceMount,
and that will call this onDeviceMount
| | 03:36 | when a device is attached to the system.
| | 03:39 | So, what I want to do here is I want
to create a new instance of this device
| | 03:43 | class, and I want to populate it with
the information about the device, and then
| | 03:50 | I want to take that information
and place it into an ArrayCollection.
| | 03:55 | This is all pretty straightforward.
| | 03:56 | So inside of this onDeviceMount,
I just want to simply say, var.
| | 04:00 | I am going to say device.
| | 04:02 | I am going to data type this as a device here.
| | 04:06 | So, I am going to say var device:Device
= new Device, as you see there, and then
| | 04:16 | I am going to say the event object.
| | 04:18 | This event object is fired every time a USB
is plugged into the computer or into the host.
| | 04:26 | So, here I am going to say new Device
(event), and then I am going to simply
| | 04:30 | just reference the storageVolume.
| | 04:32 | This is where all the information is stored.
| | 04:34 | So, the name of the device, all of that.
| | 04:37 | So, I am going to pass that in, and
I've set up so that the Device value object
| | 04:42 | can simply just populate this, and I'll have
this data stored all inside of that device.
| | 04:48 | Now, of course, what happens if
more than one device is attached?
| | 04:52 | Well, I don't want to lose the
other device it's already been attached,
| | 04:55 | so what I am going to do is just
store this all in an ArrayCollection.
| | 04:57 | So, I will reference the
ArrayCollection which, of course, was created up here
| | 05:02 | called devices, and I'll just
use the addItem method here.
| | 05:06 | So, I'll say addItem, and
I'll add in my value objects.
| | 05:11 | So I'll say addItem (device) there,
and that will add that into the
| | 05:16 | devices ArrayCollection.
| | 05:19 | So, now the only other thing I want to
do is just scroll down here. Mine is on
| | 05:23 | approximately line 52 here.
| | 05:25 | You'll see this List control,
and it's the deviceList.
| | 05:28 | So, this is the list
| | 05:29 | that's going to display all the devices
that have been attached to the host.
| | 05:34 | What I want to do is just set up a data
binding, so I will use the dataProvider,
| | 05:39 | and I want to just bind this to the
ArrayCollection of those devices objects.
| | 05:43 | So, I am going to say dataProvider =
"(devices)" and set that up, like so.
| | 05:51 | So, that this will then display all of the
devices that have been attached to the system.
| | 05:57 | So, go ahead and Save your
FileSystem4.mxml. Go ahead and run this.
| | 06:04 | Currently, I don't have any USB
devices attached to the system, so what I'm
| | 06:10 | going to do is just simply attach a
USB device that has two different names.
| | 06:18 | You'll see here - this is just the Window
thing that the AutoPlay happens, so I'll
| | 06:21 | just close that off -
| | 06:23 | you'll see actually this USB
device has three different names.
| | 06:26 | You'll see I have U3 System, No
Name, and U3 System, in this case.
| | 06:31 | So, you'll see the Device path here is
called F. You can see the Device type.
| | 06:35 | In this case this isn't writable. That's false.
| | 06:38 | It is removable.
| | 06:40 | You can see the Device path,
| | 06:42 | you can see the name, and then
you could see the U3 System here.
| | 06:46 | So, we can access all of this
information about each USB device, and we can now
| | 06:52 | read and write to these devices by
using file objects, just like we learned in
| | 06:56 | earlier portions of this lesson.
| | 07:00 | So, we've seen how to use AIR to
access files on an external mass storage
| | 07:04 | device, and you can see that AIR
dispatches storage volume events that detect
| | 07:09 | when these storage devices
have been attached to the host.
| | 07:12 | These events provide us lots of useful
information that we can use in our code,
| | 07:16 | such as name, pack, type of
file, whether it's writable.
| | 07:21 | We even have references to the root
directory and to the storage volume itself,
| | 07:25 | so we can utilize these just as they
were part of the regular file system.
| | Collapse this transcript |
|
|
7. Accessing External Resources from an Adobe AIR ApplicationDetecting network availability| 00:00 | One of the huge advantages of an Adobe AIR
application is the ability to work offline.
| | 00:06 | Adobe AIR can connect to external
resources if it has network connectivity;
| | 00:10 | otherwise, we can use the built-in
functionality, such as the SQLite database,
| | 00:14 | to create offline
applications with great user experiences.
| | 00:18 | The first step is to detect
whether or not the Adobe AIR client has
| | 00:21 | network connectivity.
| | 00:23 | If it does, we can go ahead and
access those external resources.
| | 00:27 | If not, we can create an alternate user
experience that relies, for example, on
| | 00:31 | the internal SQLite database.
| | 00:33 | Let's go ahead and get started.
| | 00:36 | You'll see here that I've
imported the ExternalResources.fxp file.
| | 00:41 | Then let's go ahead and open
up the ExternalResources1.mxml.
| | 00:46 | You'll see this is a very simple file,
and all we basically have here is
| | 00:52 | the skeleton of an init function, and the
skeleton of another function called showStatus.
| | 00:58 | The first thing I'd like you to do is
just declare a private URL monitor variable.
| | 01:04 | So, I'm just going to say private var,
and let's call it monitor, and I'm going
| | 01:10 | to datatype this as a
URLMonitor that you see here.
| | 01:17 | You should see that it automatically
imports the URLMonitor class there.
| | 01:24 | Let's go down to our init method, and let's
use this monitor variable that we just created.
| | 01:30 | So I'm going to say monitor is equal to,
and let's create a new URLMonitor right
| | 01:37 | here, and then inside of this, let's
try to access an external resource.
| | 01:42 | So, what I'll say is I'll just say,
new URL request, and inside of this
| | 01:47 | URLRequest, let's try to access lynda.com.
| | 01:52 | So I'm going to say lynda.com, and
then let's listen for the status of the
| | 01:59 | network connection that we're able
to do the utilizing the monitor class.
| | 02:03 | So, I'm just going to say monitor, and
we'll use addEventListener, and then I'll
| | 02:09 | listen for the STATUS event to
determine the status of my network connection.
| | 02:15 | Then once that occurs, I'm going to call the
function that you see below, called showStatus.
| | 02:22 | So, let's call the showStatus function
to determine the network connection, and
| | 02:27 | then what I need to do
is just start the monitor.
| | 02:31 | So, I'm just going to simply say
monitor, and we'll use the start method of
| | 02:36 | the monitor object.
| | 02:38 | So that will start the monitoring
to determine whether or not we have a
| | 02:41 | network connection.
| | 02:42 | So now, once I've done that, you'll
see that the showStatus will call.
| | 02:46 | Let's just add a simple trace
statement, and let's say Network connected:
| | 02:54 | space, and then we'll say
Plus, and we'll say URLMonitor.
| | 03:02 | We'll say event.target.
| | 03:05 | This is, of course, the
object that omitted the event.
| | 03:08 | So, I'll say event.target, and then
we'll just determine whether or not
| | 03:12 | my network connection is available by
using the available property of the URLMonitor.
| | 03:19 | So, I'll add that in.
And let's go ahead and test.
| | 03:22 | Now, in fact, I am connected to a network
at this moment, so I should get, when I test this -
| | 03:27 | I'm going to just save this - and
when I actually compile this, I should get -
| | 03:31 | you'll see here I just forgot to end my
parentheses there at the end.
| | 03:37 | So let me just fix that.
| | 03:40 | I'm going to just hit Save.
| | 03:41 | You should see that resolves.
| | 03:43 | I am connected to a network at this point.
| | 03:47 | When I actually debug this
application, it should say that I am, in fact,
| | 03:52 | connected to the network.
| | 03:54 | So let's check our console here, and you'll
see here it says Network connected: true.
| | 04:00 | So now what I'm going to do is I'm going
to unplug the network cable, and I'm no
| | 04:06 | longer connected to the network.
| | 04:07 | So when I do that, it should
now say Network connected: false.
| | 04:12 | So let me debug the application.
| | 04:14 | You'll see that I no longer am
connected to the network when I test this.
| | 04:19 | Now I'm going to close that.
| | 04:22 | In this case, you'll see that it
says Network connected: false.
| | 04:26 | So, as you're developing your
applications, and as you're doing your
| | 04:29 | programming, you can determine if
your AIR client has network connectivity.
| | 04:34 | So, you could now use conditional logic
to have the application go to different
| | 04:39 | states, depending on whether or
not there is network connectivity.
| | 04:42 | One of the states could utilize the
internal database, for example, if there was
| | 04:46 | no network connection.
| | 04:47 | It is essential, before attempting
to access these external resources, to
| | 04:52 | determine if there is network
availability in order to have the best possible
| | 04:56 | user experience in your AIR applications.
| | Collapse this transcript |
| Connecting to web applications using HTTP| 00:00 | If an Adobe AIR application has access
to external resources, we can use the URL
| | 00:06 | request object, with the URL loader
object, to access external web sites from
| | 00:11 | directly inside of an Adobe AIR application.
| | 00:14 | If we need to send data to an external
web site, we can send the data using the
| | 00:18 | URL variables class.
| | 00:20 | In this exercise, we're going to build a
very simple AIR client that is able to
| | 00:26 | go out and update a Twitter site.
| | 00:28 | So we're going to be able to enter the
information into the Adobe AIR client;
| | 00:32 | the Adobe AIR client will use the URL
loader class and the URL request class, as
| | 00:37 | well as the URL variables class, to
send that information to a pre-created
| | 00:42 | Twitter account called
lynda AIR. Let's get started.
| | 00:46 | You can see the first thing
I've done here is I've imported the
| | 00:50 | ExternalResources project here, and
then you'll see there is a file in here
| | 00:54 | called ExternalResources2.
| | 00:57 | Go ahead and open up that file.
| | 00:59 | You'll see mine is already open,
and let's just examine what we have.
| | 01:03 | We've already created a very simple
interface here for you, where we have a form,
| | 01:08 | and inside of that form we're giving
the user the ability to send out a link, a
| | 01:12 | message, and there's also a button
called Send Message, and when the user clicks
| | 01:15 | on this button, we were calling
a method here called sendToURL.
| | 01:21 | You'll see the sendToURL method right
here, and let's go ahead and just run
| | 01:25 | this application before we do anything,
so we can take a look at what we're
| | 01:29 | working with, and you'll see we have
a Link and a Message, and the user can
| | 01:33 | click on the Send Message.
| | 01:35 | What we want it to be able to do is
update the lynda AIR Twitter account
| | 01:39 | with that information.
| | 01:42 | So here's my sendURL.
| | 01:43 | So the first step is to just
simply create a URLRequest object.
| | 01:48 | So let's call that request, and of
course type it as a URLRequest, and just
| | 01:54 | simply say "new URLRequest" and Twitter
has an API where we can actually go out
| | 02:02 | and update statuses here.
| | 02:04 | So let's point this URLRequest to that site.
| | 02:06 | So I'm going to say "http://twitter.com/
statuses/update.xml," and that will enable
| | 02:17 | us to update this information.
| | 02:20 | Then I'm going to create a base64 encoder.
| | 02:24 | So I'm going to say "var base64:
Base64Encoder," and this will enable me to pass
| | 02:34 | the information that Twitter needs.
| | 02:36 | We're going to encode this.
| | 02:37 | So I'm going to say "new
Base64Encoder," just like so.
| | 02:43 | Then I'm going to use the
method called encode of this class.
| | 02:47 | So I'll say "base64.encode," and the
first thing I need is I need the credentials
| | 02:54 | for my Twitter account.
| | 02:55 | So the name of the account is
called lyndaAIR, and the password to the
| | 03:02 | account is called airrocks.
| | 03:05 | So just type in a colon between
the username and the password.
| | 03:09 | So I'm going to just close my encode
method there, also close my quotations.
| | 03:15 | So you have the airrocks there.
| | 03:17 | What we're going to do is we're going
to pass this using the request headers
| | 03:22 | part of the URL request.
| | 03:23 | What I'm going to do is I'm going to
not only pass this username and password,
| | 03:27 | but I'm also going to pass the amount
of authorization that I'm going to give
| | 03:31 | the end user, which in this case is
going to be just a basic authorization.
| | 03:35 | So what I'm going to do is store this
information in a complex data object, in an array.
| | 03:41 | So I'm going to say "var headerArray."
| | 03:43 | I'll type that as an array, and I'm
going to simply just say "new Array" and
| | 03:51 | inside of this, I'm going to
create a new URLRequestHeader object.
| | 03:56 | I'll choose the URLRequestHeader object,
and then for the URLRequest, I'm going
| | 04:01 | to just specify that I
want to set the authorization.
| | 04:06 | Here, for the authorization, I'm just
going to say ", Basic," and then I'm
| | 04:11 | going to pass the
credentials in my base64 object.
| | 04:16 | I'm just going to convert that into a
string using the toString method, just like
| | 04:20 | so, and then I will close off my
parentheses, as you see there, and as you can
| | 04:27 | see, that will create my URL
request header and my header array.
| | 04:32 | So the next step here is to just simply put
that in my request headers for my URLRequest.
| | 04:39 | So I'm going to access my URLRequest
object, and you'll see there's a property
| | 04:43 | in here called requestHeaders, and I'm
going to put the headerArray in there.
| | 04:49 | So it'll be passed along once I use
the URL loader to load in that request.
| | 04:55 | Let's make sure that we're posting this.
| | 04:58 | So the method is going to
be Post, as opposed to get.
| | 05:03 | So we are going to use the Post
method to send this URLRequest.
| | 05:07 | Then finally, of course, we want to
pass the information that the user types
| | 05:11 | in to the AIR client.
| | 05:13 | So I'm going to do that
through the URL variables class.
| | 05:16 | Let's create a new object here called
variables, and I'm going to type this as
| | 05:23 | the URLVariables class, and I'm just
going to simply say "= new URLVariables."
| | 05:33 | Again, this is going to be
exactly the same code for those of you
| | 05:36 | following along in Flash.
| | 05:38 | It's just I happen to be using Flash
Builder here, but again, this code works
| | 05:42 | just as well inside of the Flash CS5 as well.
| | 05:46 | So here I have my variables, and I
have new URLVariables, and now let's just
| | 05:52 | simply store the
information that we want to pass.
| | 05:55 | So here I'm going to say "variables,"
and I'm going to create a property here
| | 06:01 | called status, and this will,
of course, be passed to Twitter.
| | 06:05 | What I want to do is I want to pass the
information that the user has typed in
| | 06:10 | this message TextArea.
| | 06:11 | You'll see it has an ID of Message,
and also I want pass the information in
| | 06:16 | message, and I want to pass the
information in the link text input there.
| | 06:21 | So I'm going to pass it there,
and up here, I'm going to go up here to
| | 06:25 | variables, and I'm just going to
simply pass link.text, and just for clarity's
| | 06:32 | sake, let's add in a line break.
| | 06:34 | So I'll add in this character here to
represent a line break, and then I'll just
| | 06:38 | simply say "message.text" as well.
| | 06:42 | So that will store that information in the
status and pass that information to the URL loader.
| | 06:49 | So let's reference my URLRequest again,
and you'll see there's a property on the
| | 06:53 | URLRequest called data.
| | 06:56 | So I'll reference the data, and I
will simply just say data is equal to my
| | 07:02 | URLVariables object that I created.
| | 07:06 | Finally, let's use the loader to
actually load this, and to actually call this.
| | 07:12 | So here I'm going to say "var loader,"
and I will say "URLLoader = new URLLoader."
| | 07:26 | Then I'm going to simply use the load
method of my loader object, and I'm going
| | 07:32 | to pass it the URLRequest object that
has all the data, that has all the header
| | 07:39 | information, has all the
information that Twitter is going to need.
| | 07:42 | So that will then pass the information
from my AIR application back out to Twitter.
| | 07:49 | Now I'm going to simply say "loader.
addEventListener" because we want to listen
| | 07:54 | for when this is actually complete, and
I will simply just say "Event.COMPLETE."
| | 08:01 | When this is finished sending the
information to Twitter, I want it to call this
| | 08:06 | completeHandler that you see there on line 33.
| | 08:11 | Finally, I'm just going to update my flag.
| | 08:15 | It says isUpdating = true, and then of
course, once it's complete, it's going to set
| | 08:20 | that flag back to false.
| | 08:24 | So now we've seen how to
actually access external resources.
| | 08:27 | Of course, in real life you might want
to give them a great interface and add
| | 08:32 | some conditional logic to see if
you're connected to the network or not.
| | 08:35 | If you're not connected to the network,
maybe you want to store the information
| | 08:39 | using some persistent data store, such
as a database and then have it sync up
| | 08:43 | to the network later on.
| | 08:45 | We'll cover that later on in this
course, but for now let's go ahead and save
| | 08:48 | this to external resources.
| | 08:51 | Here you should see that compiles with
no problem, and then go ahead and run
| | 08:56 | this, and let's specify a link.
| | 09:00 | So I'm going to just say "http:lynda.
com," and I'm going to say "AIR 2.0
| | 09:12 | update from AIR clients."
| | 09:18 | So I'll click on Send Message, and you
should see that sends the information to Twitter.
| | 09:26 | What now I'll do is just
switch directly out here to Twitter.
| | 09:30 | I'll refresh it, and now you'll see,
when you go out to twitter.com/lynda AIR,
| | 09:37 | you should see your status update on
the front of the screen here, that you put
| | 09:42 | in from the Adobe AIR application.
| | 09:43 | So you could see we've created a
very useful application by sending the
| | 09:50 | information via the URL request class
and using the URL loader class to actually
| | 09:56 | make the call to the Twitter web site.
| | 09:58 | Again, this is very useful if the AIR
application is connected to the network,
| | 10:04 | but if it's not, you may want to add
in some conditional logic where the user
| | 10:08 | could do this offline, and it would
then send the information out to Twitter
| | 10:12 | once they were back online.
| | Collapse this transcript |
| Displaying HTML content| 00:00 | The Adobe AIR run-time has the ability
to display HTML content alongside Flash
| | 00:06 | content, to provide a more
compelling user experience.
| | 00:09 | We are going to load an HTML page inside of
the AIR runtime, using the HTML Loader class.
| | 00:15 | We will display the HTML
using the HTML component.
| | 00:20 | The Adobe AIR HTML leverages WebKit
technology, which provides full support for
| | 00:26 | all HTML tags, including Flash,
JavaScript, images, and CSS, which allows us to
| | 00:32 | build complex applications,
utilizing Ajax techniques.
| | 00:37 | Let's get a taste of how to
incorporate HTML into an AIR application.
| | 00:42 | So you'll see the first thing I
have done here is I have imported the
| | 00:45 | ExternalResources.fxp file.
| | 00:48 | And then what I would like you to do
is just open up ExternalResources3.mxml,
| | 00:54 | and you'll see here, I have
a very simple interface here.
| | 00:57 | So, you can see I have a
skeleton of some functionality.
| | 01:01 | I have an init method, I have a
gotoLink method, I have a loadComplete, a
| | 01:05 | locationChange, and then you also see I
have a Label that says Load an HTML page.
| | 01:11 | The user will be able to specify an Address.
| | 01:13 | You'll see that there is also a link,
and then there is an Open URL button.
| | 01:17 | So let's just take a quick
look at the user interface.
| | 01:19 | I am going to just run this, and
you'll see I have Load HTML page.
| | 01:25 | What I want to happen is, for
example, if the user types in
| | 01:28 | http://www.lynda.com, they click Open URL,
| | 01:34 | I want it to actually load
this into my AIR application -
| | 01:38 | not spawn another browser or something
like that, but actually display this HTML
| | 01:43 | in the AIR application.
| | 01:45 | So, let's look at how to do this.
| | 01:47 | The first thing I want you to do is
let's add in a component that can
| | 01:50 | actually display that HTML.
| | 01:54 | So if you scroll down here, you
should see the </s:Group>. Mine is on
| | 01:57 | approximate line 48.
| | 01:59 | And what I want to do is inside of this
group, I am going to add in an HTML component.
| | 02:04 | So this is actually in the mx namespace.
| | 02:07 | So, I'll go ahead and just
say, mx:HTML, as you see there,
| | 02:12 | and then assign this an ID of
page, so, we can reference it,
| | 02:17 | specify the visible property, and let's
tie this to our flag called isLoading.
| | 02:24 | So let's set up a binding here.
| | 02:25 | I am going to say, isLoading, as you see
there, and then close off your binding,
| | 02:31 | and remember, we have this little flag
up here in the location change, called
| | 02:35 | isLoading, and again, we are setting it
to, when it's complete, we are going to
| | 02:39 | set that to true, and we'll
eventually set up an event listener there.
| | 02:43 | But for now just set the visibility
property of the HTML to isLoading, so the
| | 02:47 | users will only see this component
when the HTML is done, loaded in.
| | 02:51 | And let's set the width equal to 100%
of the component that it's sitting in, in
| | 02:58 | this case the group component.
| | 02:59 | So we are going to set 100%,
and the same thing for the height.
| | 03:03 | Let's also set that to 100%, of the
component that it's in, which, of course, in
| | 03:08 | this case is the group component.
| | 03:10 | So now you have added in your HTML
component, and let's set up our event
| | 03:14 | listeners, and we can do that
inside of the init method up here.
| | 03:18 | So I am going to scroll back up to my
init method, and what I am going to say is
| | 03:23 | I am going to reference my HTML
component, which of course I need page, and I
| | 03:29 | am just going to add in an event listener.
| | 03:31 | So, I'll say, addEventListener, as you
see here, and I will simply just say,
| | 03:37 | Event.COMPLETE, which just simply
means that the HTML is loaded in.
| | 03:44 | And I will then use my loadComplete
method that you see right down below here,
| | 03:50 | and that's going to set my flag to
is true, which will in turn set the
| | 03:54 | visibility of the HTML
component to true as well.
| | 03:58 | So, here I have said page.
addEventListener, I have called the loadComplete, and
| | 04:02 | let's set up one more that, what
happens if the location changes.
| | 04:07 | So, here I am again going to say, page.
addEventListener, and then I will say,
| | 04:15 | Event.LOCATION_CHANGE - make sure
that's all caps - and then I'll say,
| | 04:23 | locationChange, and I'll call that method again.
| | 04:27 | And that's below there, and that's
going to set isLoading to false, so that,
| | 04:32 | again, if the user types in a
different location for the HTML, it'll go back
| | 04:36 | and not display the old HTML component when they
type that in, while the other one is loading in.
| | 04:42 | And then finally, in the gotoLink
function, let's just set page, and we can
| | 04:49 | specify the location of the HTML to display.
| | 04:52 | So I am going to say, page.location -
remember that's my component - and then I am
| | 04:57 | just going to simply type in link,
which is the link where the user is going to
| | 05:01 | type in the URL, and I'll
set that to the text property.
| | 05:06 | That's how simple displaying
the HTML is in an AIR application.
| | 05:10 | So now I am just going to hit File > Save.
| | 05:13 | You should see that it compiles with no problem.
| | 05:15 | Go ahead and run the application.
| | 05:18 | And in the Address field, type
in any site that you would like.
| | 05:22 | Be sure to include the http.
| | 05:24 | Of course, you could have added that in
manually, if you didn't want your users.
| | 05:27 | But in our case, we are just specifying
whatever is in the text properties,
| | 05:30 | so the http is needed.
| | 05:33 | And in this case, I will say lynda.com,
I'll click open URL, and you should see,
| | 05:40 | it loads it in, and now, look at that,
our HTML page is displayed directly inside
| | 05:47 | of our AIR application.
| | 05:50 | You'll see, I'll be able to switch it out as well.
| | 05:52 | So let's say I switch it out to
adobe.com, and you should see it displays that,
| | 05:59 | as well as all of the Flash and
everything else that is on this page.
| | 06:06 | So, we've seen how to load HTML into an
AIR application using the HTML Loader
| | 06:10 | class, and how to display the HTML
using the HTML Loader component.
| | 06:15 | Using these components, we can
combine HTML and Flash inside of a
| | 06:19 | desktop application.
| | Collapse this transcript |
| Interacting with native operating processes| 00:00 | Adobe AIR 2.0 supports Command Line
Integration, otherwise known as CLI, to launch
| | 00:07 | and interact with native
processes on the host operating system.
| | 00:11 | Native process interaction is
managed by the native process classes.
| | 00:16 | In order to launch a native process, it
must be available on the host, then we
| | 00:20 | can use the native process and native
process start-up info classes, where we
| | 00:25 | can configure the path and the command line
arguments that we want to pass to the process.
| | 00:30 | Now native processes will only launch
if the AIR application is packaged and
| | 00:36 | installed using a native installer.
| | 00:38 | For example, we can't have a .air file.
| | 00:42 | We would have to have .exe file if we
are deploying this on a Windows machine or
| | 00:47 | .dmg file if we are
deploying this on a Macintosh.
| | 00:50 | So by interacting with native processes,
we lose a lot of the cross platform
| | 00:56 | capabilities of AIR, because we are
going to need to specify some Windows-only
| | 01:01 | arguments or some Macintosh-only arguments.
| | 01:05 | So in that way we lose that, but we
still have the ability to create really
| | 01:09 | sophisticated applications utilizing
AIR, Flash, the Flex framework, whatever
| | 01:15 | we choose to do to build these AIR
applications we can integrate directly with
| | 01:20 | native operating system processes, which
allow our applications to go even further.
| | 01:26 | The AIR Developer tool, otherwise known
as the ADT, which we looked at earlier
| | 01:30 | in the course, can package and AIR
application into a native installer, such as
| | 01:36 | an EXE or in DMG file.
| | 01:38 | So that capability is there.
| | 01:40 | So let's get an example of how to do
this, and we are going to do a very
| | 01:44 | simple example, and I'll try to show
you how to do this on both the Windows
| | 01:48 | and Macintosh platform.
| | 01:50 | So the first thing I'd like you to do
is just import your ExternalResources
| | 01:53 | project, as you see here, and
open up an ExternalResources4.mxml.
| | 02:00 | So, the first step here is to just
create a file object that's going to point to
| | 02:05 | the native process, the executable, on a
Windows machine, or where the application
| | 02:10 | is on a Macintosh machine.
| | 02:11 | So let's look, we are going to create a variable here.
| | 02:15 | We will call it an exe, and we are
going to type this as a File object, because
| | 02:19 | this will ultimately represent a file.
| | 02:22 | And I am going to just simply
say new File, as you see here.
| | 02:27 | For those of you who are on the Macintosh,
this is where the differences apply, of course.
| | 02:32 | We are going to point us to the text
editor that you want to open up on a Macintosh.
| | 02:36 | So in this case, I'm just going to simply say
| | 02:39 | Applications/TextEdit.ap/
Contents/MacOS/TextEdit.
| | 02:55 | Close my arguments there.
| | 02:57 | So now this will work fine
if you are on a Macintosh.
| | 02:59 | As you can guys can see probably, I am
on a PC, so this won't work for me, but
| | 03:05 | for those of you viewers viewing this
on a Macintosh, that should work fine.
| | 03:09 | So now what I am going to do is just
change this, so this points actually
| | 03:12 | to Notepad on the PC.
| | 03:15 | So in this case, we are going to spawn
respond the Notepad process, and all I
| | 03:18 | have to do is just say C:/Windows/notpad.exe.
| | 03:26 | That's the process we are going to start
directly from our process from our AIR applications.
| | 03:32 | So we are going to start Notepad here.
| | 03:34 | So now let's declare a nativeProcess object,
and I will type this as a NativeProcess,
| | 03:44 | like you see there. And I will simply
just say new NativeProcess, just like so.
| | 03:50 | So that will create a new native
process, and then let's also create a native
| | 03:54 | process start up info object.
| | 03:57 | So here I am going to saying
nativeProcess, just as you see here, and I am
| | 04:01 | going to say StartupInfo.
| | 04:05 | So I am going to call my
object nativeProcessStartupInfo.
| | 04:08 | I am going to type this as a
NativeProcessStartupInfo, and I am just going to
| | 04:18 | say new NativeProcessStartupInfo, and
that will create a new object based on the
| | 04:28 | NativeProcessStartupInfo class.
| | 04:32 | Now I am going to reference
that object I just created.
| | 04:34 | So I am going to
NativeProcessStartupInfo, as you see there, and what I am going
| | 04:41 | to do is I am going to say, I am going
to specify the executable, and this is
| | 04:46 | going to be what I stored in the File
object, and you can remember the name of
| | 04:49 | that was called exe.
| | 04:52 | Again, these lines of code are going to
be exactly the same, whether you are on
| | 04:55 | Mac, Windows, or Linux.
| | 04:58 | Now I can specify some certain arguments
that I want to pass to the native process.
| | 05:03 | Well, a very simple argument that I might
want to pass to this native process is
| | 05:07 | what text file do you want it to open up?
| | 05:09 | So obviously, processes have multiple
different arguments that you can pass to
| | 05:13 | it, but in our case, what we will do
is we will specify the path of the text
| | 05:16 | file that we wish to open up,
and we will see how to that.
| | 05:20 | So I am going to just create a variable here.
| | 05:22 | I am going to call it args, and I am
going to type it as a vector, and then I am
| | 05:28 | just going to say dot, and then I am
going to specify the word "String," because
| | 05:32 | that's what I am going to be passing in here.
| | 05:34 | So I am going to say (var args:
| | 05:37 | Vector.<String> = new Vector), and then
I am going to say .<String> again here,
| | 05:46 | just as you see there, then of course,
I am going to add my paren paren, and
| | 05:50 | that's going to create a new arguments.
| | 05:53 | What I am going to do is I am going to
push the arguments that I want to pass to
| | 05:57 | the native process into this vector.
| | 06:00 | So I am just going to simply say, args.
push, and then what I want you to do is
| | 06:05 | push the path to the object
that you want it to open up.
| | 06:10 | In this case, this is going to be
the text file that I want it to open up.
| | 06:13 | So what I want you to do is, if you
haven't done so already, just create a text
| | 06:17 | file on your desktop called lynda,
and this should be called lynda.txt.
| | 06:23 | Then once you have done that, I want
you to pass in the path to this text file.
| | 06:30 | So, for those of you on a Macintosh,
I want you to just say Users and then
| | 06:35 | whoever you are logged in as.
| | 06:36 | If I was on a Mac, I might be logged as,
say jtalbot and then just say Desktop
| | 06:41 | and then specify your text file.
| | 06:44 | So in this case, I could say lynda.txt.
| | 06:47 | If you are on a Macintosh, that
would be the path you would specify.
| | 06:51 | For me, again, I am on a Windows.
| | 06:53 | So here I am going to simply say C:,
and I am going to specify Users, and then
| | 07:00 | I am going to specify James Talbot, as you see
there, and then I am going to specify Desktop.
| | 07:08 | Then I am going to specify lynda.txt and
then close your quotes, close your parentheses.
| | 07:18 | Now what you can do is, for the
NativeProcessStartupInfo, just add the args
| | 07:24 | Vector that you created to
the arguments property of the
| | 07:28 | NativeProcessStartupInfo that you created here.
| | 07:31 | Here I will just say
nativeProcessStartupInfo. Then I will say .arguments is
| | 07:43 | equal to args, which is of
course what I am passing in.
| | 07:47 | So I am going to say
nativeProcessStartupInfo.args. That's equal to the Vector.
| | 07:52 | Then finally, just go ahead and start
that process anytime you like in your code.
| | 07:56 | So in this case, I will say
nativeProcess.start, and I will pass it, the
| | 08:02 | nativeProcessStartupInfo object that I
created, along with the arguments, and you
| | 08:12 | should be good to go.
| | 08:13 | So now go ahead and save the
ExternalResources4.mxml, and you will see
| | 08:18 | that should compile, no problem.
| | 08:20 | Now in order for this to work there is
going to be one more thing I need you to check.
| | 08:24 | It should already be in your
starting files, but open up the
| | 08:27 | ExternalResources4-app.xml
application descriptor, and scroll down a bit, and
| | 08:35 | what you should see is right underneath the
name property, which on mine is on line 26,
| | 08:41 | you should see a tag in
here called supportedProfiles.
| | 08:44 | This has to be in here
in order for this to work.
| | 08:48 | So here I have supportedProfiles, and
you should see you have this setting in
| | 08:52 | here called extrendedDesktop.
| | 08:54 | In order for you to interact with
native processes, you have to have this set
| | 08:59 | up in your AIR file.
| | 09:00 | You can see here it says, extendedDesktop.
| | 09:02 | So we should be good to go there.
| | 09:04 | Let's go back to our ExternalResources4.
mxml, and you should see, when you test
| | 09:11 | this, it will work in the debug
application here, but if I package this up into
| | 09:17 | an AIR file, by clicking Export
Released Build, this will not actually work.
| | 09:22 | So you have to use the AIR Developer
tool to package this up into an EXE file
| | 09:27 | or into a DMG file, depending on
which platform you are targeting.
| | 09:32 | So remember that, but we can test it for now.
| | 09:34 | So go ahead and click on Run ExternalResources4.
| | 09:38 | That should start up your debug library
here, and you will see that there is a
| | 09:42 | button that says Open
lynda.txt with the text editor.
| | 09:46 | If you click here, it should open up
Notepad along with the file that you've
| | 09:52 | specified in your argument, and
you should see that that works.
| | 09:56 | So what we have done is we have
created a very, very simple example of how to
| | 10:00 | launch a native operating
system process from Adobe AIR.
| | 10:04 | In most cases, we would, of course, test
for which operating system we are using,
| | 10:08 | as well as handle the events that
occur when the process is closed before the
| | 10:12 | AIR application, or we might want to
test if this process is already running.
| | 10:17 | We can also test if the process is
supported using the nativeProcess dot
| | 10:21 | is supported property.
| | 10:23 | A possible way of approaching this
might be to use try catch blocks, which is
| | 10:27 | of course covered in other lynda.com
courses, and remember, too, that an AIR
| | 10:31 | application cannot interact with a
native process unless it's packaged into a
| | 10:37 | native installer.
| | Collapse this transcript |
| Interacting with other AIR applications| 00:00 | AIR applications can communicate with
other AIR applications running on the
| | 00:04 | same system, or they can communicate with
other SWF content running inside of a browser.
| | 00:10 | A connection can be made with SWF
content running any version of ActionScript
| | 00:14 | that supports the local connection class.
| | 00:16 | So this includes ActionScript 1,
ActionScript 2, or ActionScript 3.
| | 00:22 | Both the sender and the receiver
application must create a local connection object.
| | 00:27 | So let's invoke a function in one AIR
application from another AIR application,
| | 00:33 | and then set up that application to
actually receive that function invocation.
| | 00:39 | So you'll see here, I've imported my
ExternalResources project, and what I'd
| | 00:43 | like you to do is open up
ExternalResources5.mxml.
| | 00:47 | So go ahead and open up that, and
let's just go ahead and review some of the
| | 00:54 | existing code that we already have here.
| | 00:56 | You will see here that I have a
function here called sendToLocal, and then
| | 01:00 | you'll see also that there is an
onStatus function here, with the Switch case,
| | 01:05 | that I can see that, again, whether or
not the LocalConnection.send succeeded or
| | 01:09 | failed, and then you'll see that there
is a label here that says Send message
| | 01:13 | to another AIR application, and there
is a link, there is a message, and then
| | 01:17 | there is a button called Send Message.
So let's just go ahead and run this, and take a look.
| | 01:21 | And this will enable this AIR
application to send this to another AIR
| | 01:26 | application, or another SWF content
that supports the LocalConnection object.
| | 01:31 | So the first I'm going to do is
just create a LocalConnection object.
| | 01:36 | So what I'd like you do, just say,
private var, and I am going to say,
| | 01:42 | sendingConn, I am going to data type
this as a LocalConnection object, and I am
| | 01:49 | going to simply say, is
equal to new LocalConnection.
| | 01:53 | And that's going to create a
new LocalConnection object.
| | 01:57 | And then what I want you to do is go
to the sendToLocal function here, and
| | 02:03 | let's reference our sendingConn object.
So I will say sendingConn, and let's
| | 02:08 | add an addEventListener, in case
anything goes wrong, and I am going to
| | 02:12 | reference the statusEvent, and I
want it to call on Status, if there is a
| | 02:19 | problem, and then I am just going to
simply say, sendingConn.send, and what we
| | 02:26 | are going to do here is we are going to
say send_lynda, and then I am going to
| | 02:34 | say displayMessage, as you see there.
| | 02:37 | So I am going to say send_lynda displayMesage.
| | 02:41 | You can place whatever you like there,
and then I am going to simply say, comma,
| | 02:46 | also send whatever the user has typed
in the link.text field, and whatever they
| | 02:51 | have typed in the message.text field.
| | 02:55 | So, again, that's going to send the
contents of those two fields directly to
| | 02:59 | where we tell it to send it to.
| | 03:01 | So now I am just going to close that.
| | 03:04 | And then what I want you to do is open up this
| | 03:07 | LocalConnectionReceiver.mxml file.
| | 03:11 | So make sure you save here, and then
open up the LocalConnectionReceiver.mxml
| | 03:17 | file, and what I want you to do is, up at
the top here, let's create a connection.
| | 03:24 | So I am going to private var, and I
am going to say recConn, also data type
| | 03:31 | this as a LocalConnection object,
and then I am going to say new
| | 03:37 | LocalConnection, and then I want you to,
now that you've created this variable,
| | 03:43 | I want you to open up the init
function, and inside of the init function, I
| | 03:47 | want you to add the following code.
| | 03:48 | I am going to reference my
LocalConnection object that I just created, specify
| | 03:53 | the client as this, which is going to
refer to the LocalConnectionReceiver.
| | 03:57 | I am going to allow all domains to
access this. Again, I'll reference my
| | 04:03 | LocalConnection, and I'll say
.allowDomain, now just specify an asterisk to
| | 04:11 | allow all domains, which of course could
be a security risk; you'd probably want
| | 04:15 | to specify just specific domains
that you want to be able to access this.
| | 04:19 | Again, take my LocalConnection object,
I am going to say Connect, and then I am
| | 04:24 | going to specify _lynda here to connect there.
| | 04:31 | So now what I want you to do is
save this, and then go back to your
| | 04:38 | ExternalResources5.mxml, go ahead and
run this, and move that off to the side, go
| | 04:45 | back over to your
LocalConnectionReceiver.mxml, go ahead and run this.
| | 04:53 | Now, go ahead and minimize Flash Builder
here, and you should see that these two
| | 04:58 | SWF files can now communicate with each other.
| | 05:00 | So I am going to specify http, and
we'll specify lynda.com and message
| | 05:08 | from ExternalResource5.
| | 05:14 | I will click on Send Message, and you
should see that it is able to be sent over
| | 05:20 | to this other AIR application
through the LocalConnection object.
| | 05:25 | What we have done is we have shown how
the LocalConnection object can be used to
| | 05:28 | allow an AIR application to
communicate with other SWF-based content.
| | 05:33 | This type of functionality can be very
useful for dashboard or other similar
| | 05:37 | type systems, where multiple
applications could be running on the same desktop.
| | Collapse this transcript |
|
|
8. Using Adobe AIR's Built-In DatabaseCreating a database file| 00:00 | Adobe AIR 2.0 has a robust
SQLite database built right into it.
| | 00:05 | This can be extremely useful for
storing complicated relational data and
| | 00:09 | especially useful for offline applications.
| | 00:12 | We can create a database, and then we
can pass SQL statements to it, and even
| | 00:16 | have this database sync with
the remote server-side database.
| | 00:20 | The database built into Adobe AIR
allows persistent storage to be a reality
| | 00:25 | in AIR applications.
| | 00:28 | So as you can see, the first thing
I've done here is I have imported the
| | 00:30 | UsingDatabase.fxp file.
| | 00:33 | So go ahead and do that, and then
you'll see this file, UsingDatabase1.mxml.
| | 00:39 | Go ahead and open up that, and
let's examine the existing code.
| | 00:43 | So first of all, you'll see that I've
imported the SQLConnection class, as
| | 00:46 | well as the File class.
| | 00:48 | We're going to use both of those.
| | 00:49 | We will talk about what the Static
Constants mean in a minute, but you'll see
| | 00:53 | that we've also created a Customers
Array, and then there are a bunch of different
| | 00:57 | functions, including an init function,
a connect to actually connect to the
| | 01:01 | database, a createTable function, insert,
getCustomers, customersResult, to get
| | 01:08 | all of our information from the database,
and in subsequent walkthroughs, we will
| | 01:11 | be covering how each one of those work.
| | 01:14 | For now, let's just run the application,
and you should just see a DataGrid.
| | 01:18 | And that DataGrid is populated with the ID,
the name and the job title of each customer.
| | 01:24 | We want this information to be stored
in the database, and eventually we're
| | 01:28 | going to build the interface here, so
end users can enter the information here
| | 01:32 | and populate the database.
| | 01:34 | But we're not there yet.
| | 01:36 | What we need to do now is we need to
connect and create a brand-new database
| | 01:42 | inside of Adobe AIR that's related to
this particular application, of course,
| | 01:47 | because customers may have
more than one AIR application.
| | 01:50 | So we want to create a unique
database for this application, and we're also
| | 01:54 | going to need to do some conditional
logic to test to see if there is already
| | 01:57 | an existing database.
| | 01:58 | Because if there's already an
existing database, we want the application to
| | 02:02 | connect to that database
related to this application.
| | 02:06 | So let's learn a little
bit about how to do that.
| | 02:08 | What I'd like you to do is go to the
Script Block here, and inside of the Script
| | 02:12 | Block, just create two new variables.
| | 02:14 | So I am going to say
private var dbConn:SQLConnection,
| | 02:22 | and then also create another variable
here called private var dbFile and then
| | 02:28 | data type this as a File object.
| | 02:32 | So now the first step is we want to tell it
where we want this database to be located.
| | 02:38 | Let's reference our File object,
which we call dbFile, and then let's just
| | 02:42 | simply say is equal to new File, and
then let's specify a path for the database.
| | 02:50 | In this case, I want this to be cross-platform.
| | 02:52 | So I want it to work equally well on
Windows, on Mac, on Linux, and again,
| | 02:58 | I don't want to add conditional logic to
test for each one of those operating systems.
| | 03:02 | So what we are going to do here is
we are simply going to specify the
| | 03:05 | App Storage directory.
| | 03:07 | So I am going to say app-storage, and
AIR is going to handle that complexity,
| | 03:12 | because Windows application is
stored in one particular directory, and
| | 03:15 | Macintosh application is stored in
another, but AIR will handle where that
| | 03:19 | actual file path is.
| | 03:20 | So all we, as an AIR developer,
have to do is specify app-storage.
| | 03:23 | So I am going to say app-storage, I am
going to say colon, and I am going to
| | 03:28 | give my database a name.
| | 03:30 | Well, this is going to be storing our customers,
| | 03:31 | so let's call it customers1.db.
| | 03:36 | Actually, I will call it customers,
because we hopefully will have more than
| | 03:39 | one customer, close that, and that's just
specifying where our database is going to be.
| | 03:47 | The first thing we need to do is test
to see if this database already exists.
| | 03:52 | So what I am going to do is I am going
to simply say, if dbFile.exists, so this
| | 03:59 | is basically saying if it does not
exist, I want it to create a new database.
| | 04:05 | So we are going to create our new
database in a method called CONNECT, and let's
| | 04:09 | just say CONNECT, and that method is
right down here, and you will see Connect
| | 04:15 | is expecting a parameter of type Number,
and we have these two parameters that
| | 04:20 | have been created already.
| | 04:21 | So CONNECT:Number = 0 and CREATE_DB:Number = 1.
| | 04:26 | So let's say Connect, and let's
pass it the CREATE_DB constant.
| | 04:32 | So I am going to simply say, just CREATE_DB.
| | 04:36 | I am going to call that Connect method.
| | 04:38 | This is basically saying, of course, if
the DB file does not exist, call Connect
| | 04:44 | and pass it the Create DB, because in
Connect, we are going to handle connecting
| | 04:48 | to an existing database or
creating a brand-new database.
| | 04:53 | So here, inside of my Connect, what I
am going to do is I am going to simply
| | 04:57 | just test, I am going to add some more
conditional logic, and I am going to say if type.
| | 05:03 | So type is going to be one, so in
this case, that will return True.
| | 05:08 | So I am going to say if type, and let's
go ahead and simply create a new database.
| | 05:15 | So here I said, if type, I am going to
say dbConn.addEventListener, and then I
| | 05:24 | am going to say SQLEvent.OPEN, which
just means I am opening up the database
| | 05:31 | that's stored in that file object.
| | 05:33 | So I am going to say SQLEvent.OPEN,
and let's call the createTable method.
| | 05:39 | This we are going to learn in a
subsequent walkthrough how to actually create
| | 05:42 | tables, but that's going to
create us a brand-new table.
| | 05:46 | So that will actually create a
database, and go back up here to the if
| | 05:50 | dbFiles.exists, and let's just say
trace ("Database created"), and that
| | 05:59 | will create a database.
| | 06:01 | Go ahead and add in an Else
statement here, and now of course, we want to
| | 06:05 | connect to the database,
if it is already existing.
| | 06:08 | So that's why we are
adding in the Else statement.
| | 06:10 | So here, I'm going to say connect,
and I am going to pass it the constant
| | 06:14 | CONNECT, which is going to be
a zero, as you see up there.
| | 06:19 | So I am going to say Connect, and then I
am going to pass it that constant CONNECT.
| | 06:24 | I am going to again add a little trace
in here, and just say DB file available,
| | 06:32 | like you see there, and that's
going to connect there.
| | 06:36 | So now let's add in that to
connect to an existing database.
| | 06:40 | So again, in my Connect function, I
will just simply add in an Else statement,
| | 06:46 | and I'll simply say dbConn to
reference my database connection, which we will
| | 06:52 | build in just a second,
.addEventListener, and then I'm going to say
| | 07:00 | SQLEvent.OPEN, and then we will call my
getCustomers, because I want to retrieve
| | 07:08 | the customers that are already in
that database and pull those back.
| | 07:11 | So here I am going to say getCustomers,
so dbConn.getCustomers, and then of
| | 07:16 | course, we actually need to create the
connection to the database, and remember
| | 07:21 | that we had already imported the flash.
data.SQLConnection, so at the top of your
| | 07:26 | Connect method here, just
say dbConn = new SQLConnection.
| | 07:35 | That will again create a new connection
to the database, and then it will open
| | 07:41 | it up in the conditional
logic that we see down below.
| | 07:45 | So now right after your conditional
logic, just let's add two event listeners.
| | 07:50 | So let's do two things.
| | 07:51 | So first of all, let's add an
event listener to listen to an error.
| | 07:54 | So I am going to say
addEventListener, and I am just going to say
| | 07:58 | SQLErrorEvent.ERROR.
| | 08:03 | Let's call our errorHandler, and then
I just want to say dbConn.openAsync.
| | 08:14 | This is going to open up the database,
and the database, just as we talked about
| | 08:17 | before, is stored in a file object.
| | 08:20 | So here I am just going to say dbFile.
| | 08:23 | If there is no database on the
system, it will create a new database.
| | 08:27 | If there is a database, it will
open up that existing database.
| | 08:33 | So let's go ahead and test this.
| | 08:35 | You should see, if I click File > Save,
you should see that this compiles okay.
| | 08:40 | I am going to just debug the
application by clicking under here, and I am going
| | 08:43 | to say Debug UsingDatabase1, and what
we should see is because there is no
| | 08:49 | existing database on my system here, I
am going to say database created, and you
| | 08:54 | will see that trace execute.
| | 08:57 | If I debug it again, you should see that
it says DB file available, because it's
| | 09:02 | already created the database.
| | 09:04 | So you'll see down here, under the
trace name, that it says DB file available,
| | 09:08 | because that's already been created.
| | 09:11 | So I am going to close off Database1, and
let's just take a look at our file system here.
| | 09:16 | You should see that it wrote it to
the application storage directory.
| | 09:20 | Now I am using Windows 7, and of
course, this will vary by platform.
| | 09:24 | But on Windows 7, it stores it under
C:/Users/James Talbot and AppData, but
| | 09:32 | this is a hidden folder.
| | 09:34 | So you may need - in my case, I've done
it already, it's here, under AppData -
| | 09:38 | but you may need to press the Alt key,
choose Tools > Folder Options, go to
| | 09:44 | View, and then where it says Hidden
files and folders, you may need to click
| | 09:49 | here Show hidden files, folders, and
drives, because AppData can be hidden.
| | 09:54 | So you may need to do that.
| | 09:55 | Then you will be able to see your
AppData folder here on Windows 7, go to
| | 09:59 | Roaming, and here you should see your
UsingDatabase1, Local Store, and here it is:
| | 10:07 | your Customers1.DB.
| | 10:10 | So now we've shown how to create a
SQLite database in the Adobe AIR 2.0
| | 10:15 | client, and now we're actually
ready to start writing SQL statements to
| | 10:20 | populate this database with data.
| | Collapse this transcript |
| Adding table data to a database| 00:00 | In order to communicate with the
built-in database in Adobe AIR, we use
| | 00:04 | Structured Query
Language, otherwise known as SQL.
| | 00:08 | We will show in this video how to
create a database table, how to insert a
| | 00:11 | record into the database, how to
retrieve data from the database, and finally,
| | 00:16 | how to assign these results to a
data provider, so that we can display the
| | 00:20 | results visually, using Flex Components.
| | 00:23 | For those of you following along in
Flash, everything that we're doing here in
| | 00:26 | Flash Builder applies, except for the
use of the components. In Flash you'd have
| | 00:31 | to build your own
components to display that data.
| | 00:34 | So you'll see that I've imported the
UsingDatabase.fxp file, and just scroll
| | 00:40 | down here to the UsingDatabase2.mxml file.
| | 00:43 | Go ahead and open up that
UsingDatabase2.mxml file.
| | 00:48 | What I'd like you to do is, up at the
top of your script block, let's go ahead
| | 00:52 | and import some of the classes
that we're going to be using.
| | 00:56 | So the first thing I'd like you to do is
just say import flash.data.SQLResult, and
| | 01:05 | then let's also import
the flash.data.SQLStatement.
| | 01:12 | Then the first step here is to, of
course, create a table and again, let's just
| | 01:18 | take a quick look at the existing code,
but if you remember we have our Connect
| | 01:22 | method, and this connect connects to
the database, and it first of all checks
| | 01:25 | to see if there's an existing database,
or it creates a new database, and again,
| | 01:29 | you'll see if there is no existing
database, it will call the createTable method.
| | 01:34 | If there is an existing database,
it will just get those customers from
| | 01:37 | the existing database.
| | 01:39 | So in our case, we are not going to
have an existing database, and you will see
| | 01:42 | that we have the createTable.
| | 01:44 | You'll also see - otherwise, it's the
same code as before - but you will also see
| | 01:49 | that we have added a little interface
to the DataGrid that's going to display
| | 01:52 | the list of customers.
| | 01:53 | We've also added a little interface, so
that users can add records, and you'll
| | 01:57 | see I have a Name and a Title field
here to be able to add records directly to
| | 02:02 | the database, as well,
which they will be able to do.
| | 02:06 | So once the database file has been
created, and we can connect to the database,
| | 02:11 | we are going to need to create a table
in this database, and to create a table,
| | 02:15 | we are going to need to write
some SQL to be able to do that.
| | 02:18 | The first step is to
simply just declare our object.
| | 02:23 | In this case, let's call it dbStatement,
and this is going to be a SQLStatement.
| | 02:28 | So I will just type in SQLStatement, and
I will simply just say new SQLStatement.
| | 02:39 | So this will create a new SQLStatement,
and then of course, we need to define
| | 02:43 | the connection that we are going to use.
| | 02:44 | So I will say dbStatement.
sqlConnection, and we are going to use the same
| | 02:50 | connection as we used before, which as
you remember, is dbConn, and you'll see
| | 02:56 | dbConn is our new SQLConnection
connecting back to that database.
| | 03:00 | So go ahead and just call that
dbConn, and then let's write the SQL.
| | 03:06 | So here, I will say dbStatement, and
to write the SQL, you just use the text
| | 03:10 | property, and let's go ahead and
write the SQL that will actually create a
| | 03:14 | table in the database.
| | 03:16 | So here I'll simply say Create Table
If Not Exists, and then I will create a
| | 03:28 | table here called customer, and let's
define what our customer table will look like.
| | 03:32 | Here I will say, id, and I will specify
Integer, and I want this to be our Primary Key.
| | 03:39 | So I will say Integer Primary Key,
and then I will have another column here
| | 03:43 | called name, and this will be of type
Text, and then I'll have another column
| | 03:49 | here called Title, and this
will also be of type Text.
| | 03:55 | So that is our actual SQL
statement that will actually create our table.
| | 04:01 | So now what we want to do is once that
table has been created, I want it to go
| | 04:06 | out and get customers.
| | 04:08 | So in the Create Table, I am
just going to add a Result event.
| | 04:11 | So once it's created, I am just going to
say dbStatement, and I am going to add
| | 04:18 | an event listener, and here on the
addEventListener, I am just going to say
| | 04:24 | SQLEvent.RESULT, and we will call the
getCustomers method that we are going to
| | 04:33 | write later on, and this is going to
retrieve all the customers from the
| | 04:37 | database, if there are any,
which there probably won't be,
| | 04:39 | but we will put that in, and
I am going to say dbStatement.
| | 04:43 | We are also going to add an error handler here.
| | 04:45 | So I will say addEventListener.
| | 04:47 | In this case, we will handle an error,
and we have also written a method here
| | 04:52 | called errorHandler to handle any
errors and display those to the end users, if
| | 04:57 | there is some error actually
connecting to the database.
| | 05:01 | So we have added both those
addEventListener: SQLEvent, and SQLErrorEvent, to
| | 05:06 | call those respective methods.
| | 05:08 | Then I am just going to
simply say dbStatement.execute.
| | 05:13 | That will go ahead and actually execute
this SQL statement and create that table.
| | 05:18 | So that's my Create Table function, and
then in the insertCustomers method, you
| | 05:24 | will just see there is some pre-built
code already, just to save us some typing.
| | 05:28 | You will see we have already created
the dbStatement, we've already specified
| | 05:31 | the dbStatement and the SQL
connection to dbConn, and then we've added an
| | 05:36 | EventListener here to listen for the error.
| | 05:39 | So let's go ahead and write the SQL,
so that this will insert any customers
| | 05:43 | that the user types in into this table.
| | 05:47 | The first step is just say dbStatement.
| | 05:50 | Let's write our SQL.
| | 05:51 | I am going to say .text here = Insert Into.
| | 05:58 | We are going to insert this into our
customer table, and we are going to insert
| | 06:02 | in the name and the title columns,
because our primary key is going to be created
| | 06:07 | for us automatically.
| | 06:09 | So I am going to say Insert Into
customer name, title, and then I am going to
| | 06:13 | insert the values here, and I am going
to specify :name, :title.
| | 06:23 | These I am actually going to specify as
parameters, which we will see in a second here.
| | 06:27 | So here I am going to
specify that, insert name, title.
| | 06:30 | Now, let's specify these as parameters.
| | 06:33 | So I will say dbStatement, and I
will say parameters, and the first
| | 06:40 | parameter that I am going to specify is going
to be :name, just as we see in our SQLStatement.
| | 06:48 | So I will say :name, and then this will
simply just be, if you scroll down here,
| | 06:55 | you will see there is a field where the
user can type in the name, and that text
| | 06:58 | input field is called nameInput.
| | 07:01 | So let's make sure that that matches.
| | 07:03 | I will say nameInput.text, and then
let's do the same thing for the title.
| | 07:11 | So I will say dbStatement.parameters,
and then I will say :title = titleInput,
| | 07:24 | which is the name of the field.
| | 07:25 | So I will say titleInput.text, as you see there.
| | 07:32 | Then the only other thing I want you
to do is, when you insert the customers
| | 07:36 | here, I want you to call, again, the
getCustomers when there is a result, so that
| | 07:41 | the user will actually see some feedback.
| | 07:43 | So when they actually click that
button, Add Customer, they will see the grid
| | 07:47 | update immediately with the new data.
| | 07:49 | So let's add in another event listener.
| | 07:52 | So I will just add it up here to be consistent.
| | 07:54 | I will add it right after the error.
| | 07:55 | I will say addEventListener,
and we will say SQLEvent.Result;
| | 08:01 | on that result, once these have been
added to the database, just call this
| | 08:05 | getCustomers method down there.
| | 08:10 | So that will call that getCustomers
method, and then finally, the last step here
| | 08:15 | is to just simply execute our SQL.
| | 08:20 | So here, I'll type in execute, and
that will execute the SQLStatement.
| | 08:27 | So now, in our getCustomers, let's write
the SQL so it will actually select that
| | 08:31 | information from our database.
| | 08:34 | So I'll say dbStatement.text, and then
let's write our SQL in the text property.
| | 08:41 | So here I will say select ID, name,
title From the customer table.
| | 08:50 | So I'll add that, and then let's add
in another addEventListener so that once
| | 08:56 | this is added in, it will update the
DataGrid with the appropriate information.
| | 09:00 | So let's just say dbStatement.
addEventListener, and then in this case, we will
| | 09:12 | say SQLEvents.Result, and then we will
call the customersResult method directly
| | 09:21 | below, and this will update the data grid with
the new information here from our getCustomers.
| | 09:27 | So we'll call that.
| | 09:28 | We'll call the customers.
| | 09:30 | This should be customersResult so it
matches the method down here; customersResult.
| | 09:36 | So there I have my addEventListener,
and then of course, the final step here is
| | 09:42 | to just simply execute the
dbStatement against the database.
| | 09:46 | So I will say execute.
| | 09:48 | So that will put in the execute
statement, and then finally, go down to your
| | 09:55 | customersResults here, and
let's declare a new variable.
| | 09:59 | So I am going to call this var dbResult.
| | 10:01 | I am going to type this as a SQLResult
object, and here I will simply just say
| | 10:10 | SQLResult is equal to my SQLStatement.
| | 10:15 | I am going to type this as
SQLStatement, and I am going to just say
| | 10:19 | event.target, and of course,
who's emitting this event?
| | 10:25 | That's dbStatement.
| | 10:26 | So I'm just casting this as a
SQLStatement, which makes sense.
| | 10:29 | So I am going to say event.target.
| | 10:31 | From this, there is a method that
makes this really, really easy to do.
| | 10:35 | I just say getResult, and that will get
me the results from the SQLStatement and
| | 10:41 | place it in a nice, clean array, and
note up here, I've already declared an
| | 10:46 | array, called customersArray.
| | 10:48 | So I will scroll down here, and you
should see now that the data grid, the data
| | 10:55 | provider is that customersArray.
| | 10:57 | So inside of our getCustomers here, I
will just simply say customers, which is
| | 11:05 | the array, and then I will
just say = dbResult.data.
| | 11:14 | Let me not put it in the getCustomers method.
| | 11:16 | I'll just cut that out, and make sure
that this is put in my customersResult
| | 11:21 | method, as you see there.
| | 11:22 | So I will say customers = dbResult.
data, and we now have a functioning app.
| | 11:30 | So let's go ahead and save this.
| | 11:32 | You should see that it compiles with no problem.
| | 11:35 | Go ahead and run the app, and you'll
see the data grid, and you will also see
| | 11:38 | the interface to add in some records.
| | 11:40 | So currently there are no
records in the database.
| | 11:43 | So now I will just say
James Talbot, Technical Trainer.
| | 11:52 | Now, if I click Add Record, you should
see it adds that record to the database.
| | 11:58 | So we've shown you how to create tables,
| | 12:00 | we've shown how to write information
to these tables from our AIR application,
| | 12:04 | and display these values utilizing data
binding directly from a SQL statement.
| | 12:09 | These values will remain if the AIR
application is closed or if the computer
| | 12:13 | is even turned off. So watch this.
| | 12:15 | If I just get rid of this, I
closed off my AIR application,
| | 12:19 | I run it again, we should see that it
will now read the database, and it will
| | 12:24 | see this information.
| | 12:25 | Even if I turned off the computer,
came back, we'd still see James
| | 12:29 | Talbot, Technical Trainer.
| | 12:31 | So now, let's learn how to insert
some more complicated data types into the
| | 12:36 | database that even the SQLite database
may not support, and I'll show you some
| | 12:40 | workarounds on how to do that.
| | Collapse this transcript |
| Storing and using unsupported data types| 00:00 | SQLite doesn't support all the different
data types that we might actually need.
| | 00:05 | However, Adobe AIR extends the
data types supported by SQLite
| | 00:09 | through affinities.
| | 00:11 | And these are AIR-specific data types
that are converted to an underlying SQLite
| | 00:16 | data format when they are
actually stored in the database.
| | 00:19 | In this video, we will demonstrate how
to store a date object in the database,
| | 00:23 | even though it is not supported in SQLite.
| | 00:26 | AIR will do the conversion automatically for us.
| | 00:29 | We can use this technique to store very
complicated file types in the database.
| | 00:34 | For example, we could use this
to store images in the database.
| | 00:37 | So you'll see that I've imported that
UsingDatabase.fxp file, and you'll also
| | 00:44 | see that I have the UsingDatabase3.mxml file.
| | 00:47 | Go ahead and open up that
UsingDatabase3.mxml file.
| | 00:52 | Then what I'd like you to do is just
scroll down, and if I scroll down here,
| | 00:57 | you'll see the existing code
here that we've already worked with.
| | 01:00 | You'll see the createTable.
| | 01:02 | You can see that we've inserted Customers.
| | 01:04 | We can getCustomers.
| | 01:05 | You also see a customersResult,
and you also see we've added a
| | 01:08 | formatDates functions.
| | 01:11 | So let's figure out how to store
this information in the database.
| | 01:15 | So I'm going to go back up to my
createTable method, and you'll see here
| | 01:19 | it's creating my table, and in this
case, it's creating an Integer, a Primary
| | 01:22 | Key, a name, and a title.
| | 01:24 | And we saw how to do this in an earlier
video, but what I want you to do is just
| | 01:28 | modify this so it also includes a date of birth.
| | 01:32 | So directly after the title here, I'll
scroll over here, but just type in "dob",
| | 01:38 | and let's specify this as a DATE type.
| | 01:41 | Now, SQLite doesn't have the
capability of actually storing dates, but AIR
| | 01:46 | will handle this for us.
| | 01:47 | So here I'm going to say dob and then
DATE, and then in the getCustomers SQL
| | 01:53 | statement here, I want you to also edit
this so it also gets the date of birth values.
| | 01:59 | So here it says name, title, and I want
you to change this, so it also will get
| | 02:04 | the dob from the customer
information, now that we've modified that.
| | 02:09 | And then in the insertCustomer here,
we'll just make it easy, but you'll see in
| | 02:14 | the insertCustomer, I want to be able to insert
a new value into the new date of birth column.
| | 02:20 | So here, where it says INSERT INTO
customer, you see it says name, title - let's
| | 02:27 | add in a dob value right here.
| | 02:30 | And then for the Values here,
I also want you to specify :dob.
| | 02:37 | And then in the insertCustomer method,
still here, I want you to add in a
| | 02:42 | new parameter here.
| | 02:43 | So here I'm going to say dbStatement.parameters.
| | 02:48 | I'm going to specify :dob for the date of birth.
| | 02:54 | So there, I'm specifying that, and then
I'm going to specify is equal to, and just
| | 02:59 | to make this easy, let's just put in a
Date ourselves, as opposed to letting the
| | 03:04 | user type it in, so we don't
have to modify the user interface.
| | 03:07 | So of course, we could normally go out
to a date field and have it put in the
| | 03:11 | date, but here I'll just used the Date object.
| | 03:13 | I'll say new Date, and I
will specify 1971, 10, 3.
| | 03:25 | And then you'll see I
have my dbStatement.execute.
| | 03:28 | And then let's just finally modify our
DataGrid. So we don't have to modify all
| | 03:32 | the user interface, but I'll
just add in a DataGridColumn here.
| | 03:36 | And I'll will say mx:DataGridColumn.
| | 03:43 | And here I will specify the dataField
I will be using, and this will be dob,
| | 03:49 | because this is coming
directly from the database.
| | 03:52 | The headerText here that I want to
appear on the DataGrid will be Date of Birth.
| | 04:01 | And then the labelFunction, which has
already have been created, which we looked
| | 04:04 | at, and this will be called for each
row just to put the date into a nice
| | 04:08 | format, will be called
formatDates, just like so.
| | 04:15 | Close off my DataGridColumn.
| | 04:17 | And now, if I save and run, you should
see AIR will handle this conversion - even
| | 04:25 | though SQLite doesn't support dates
directly AIR will handle this conversion
| | 04:29 | for us automatically.
| | 04:31 | And if I run, you'll see I have my date of birth.
| | 04:34 | I will add in a record here.
| | 04:37 | I'll say James Talbot, Technical Trainer.
| | 04:42 | Add Record, and you should see it
automatically adds in my date of birth there
| | 04:49 | based on that date object,
because I've specified that.
| | 04:52 | So we have shown how to use AIR to write
specific date formats to the SQLite database.
| | 04:59 | And remember, these aren't
supported directly in SQLite.
| | 05:02 | You could also use this technique to
write other types of data, such as images,
| | 05:06 | to the database.
| | Collapse this transcript |
|
|
9. Securing Adobe AIR ApplicationsUnderstanding AIR security| 00:00 | Adobe AIR applications run with the
installing user's security settings.
| | 00:04 | So generally they are able to read,
write, and delete local files, launch other
| | 00:09 | applications, communicate
over the network, and so on.
| | 00:13 | AIR also manages all of the memory,
minimizing any risks due to buffer overflow,
| | 00:18 | memory corruption, that sort of thing.
| | 00:21 | AIR also manages the
installation of each application.
| | 00:24 | This is actually controlled by Adobe AIR,
and not by the installing application,
| | 00:28 | which minimizes security risks, as well.
| | 00:31 | AIR also provides a Security Sandbox,
which limits access to the operating system,
| | 00:36 | depending on where the code originated.
| | 00:39 | All AIR applications are marked as
Unknown, unless they've been signed with a
| | 00:43 | Class 3 public certificate issued
by a company, such as VeriSign, which
| | 00:48 | specializes in verifying people's identity.
| | 00:51 | Let's go ahead and explore a
little bit about AIR security.
| | 00:55 | You see, the first thing I've done here
is I have imported the SecuringAIR.fxp
| | 00:59 | file, and I'd like you to open up
SecuringAIR1.mxml, and you'll see that I have
| | 01:06 | a very simple little application here.
| | 01:08 | I've imported the ArrayCollection class.
| | 01:09 | I've also imported the Alert class.
| | 01:12 | I have declared a new File here,
and there is a blank init method.
| | 01:16 | There's also a directorySelected
and a selectDirectory method.
| | 01:20 | Let's go ahead and actually explore
the interface that we will be using here,
| | 01:25 | and you will basically just
see I have a folder to search.
| | 01:28 | I can search for something in that
folder, and if I click on Search, it opens up
| | 01:32 | a Browse Directory dialog box.
| | 01:35 | So let's test some of the capabilities,
and just get an idea of how to test this
| | 01:40 | and how to actually get an idea of
some of the Security Settings in AIR.
| | 01:44 | So I'd like you go to the init method here.
| | 01:47 | And I'd like you just say trace, and
first of all, we are going to use the
| | 01:51 | Capabilities object.
| | 01:53 | So this Capabilities object
contains lots of information.
| | 01:57 | So, for example, I can tell, you
know, whether or not my player has MP3
| | 02:01 | capability, it has printing capability.
| | 02:03 | You can see it's accessible.
| | 02:06 | I could see the languages, the
manufacturer. I can see all this information.
| | 02:11 | Let's go ahead and look at the type
of player that this code is running in.
| | 02:16 | So I will say playerType, as you see
here, and this could be, for example, it
| | 02:21 | might come back as the ActiveX
plug-in on Internet explorer.
| | 02:25 | But it might comeback as desktop
player, which, of course, is Adobe AIR.
| | 02:29 | So we can use that. So let's try that.
| | 02:32 | And then I am going to say trace, and I
am going to use the Security class here.
| | 02:37 | So here I will say security, and I
can see the application, exact settings,
| | 02:43 | where it's local trusted, remote,
the type of sandbox that I am using,
| | 02:47 | and let's try that.
| | 02:48 | Let's see what type of sandbox we're
using, so we can get an idea of some of
| | 02:51 | other different sandbox
types available in Adobe AIR.
| | 02:56 | Then I'm also going to add a
trace statement here, where I have
| | 03:00 | capabilities.localFileReadDisable.
| | 03:05 | This'll specify whether the Read
access to the user's hard disk has been
| | 03:09 | administratively prohibited.
| | 03:11 | So, for example, in some companies,
especially locked down organizations like
| | 03:15 | banks or the government, they may have
a setting where users cannot write to
| | 03:19 | their own hard drive, and AIR would
need to know that, so you could add some
| | 03:22 | conditional logic and put in an
alternate system for the user to, for example,
| | 03:27 | store their data; maybe they will be store
it up on the server, or something like that.
| | 03:30 | We will test that, and then I would
like you to go down to the selectDirectory
| | 03:36 | method that you see here, and this is,
of course, where the user is able to select
| | 03:40 | a directory and whether
able to browse for directory.
| | 03:43 | You will see, once they select a
directory, it'll write this information up here
| | 03:48 | to the directorySelected method.
| | 03:50 | Let's go ahead and just wrap this
around some conditional logic, just so we can
| | 03:56 | get an idea of how to do that.
| | 03:57 | So here I am going to say if
capabilities.localFileReadDisable, so I will just
| | 04:06 | wrap this code around that conditional logic,
| | 04:10 | we should see that the directory will not open.
| | 04:12 | So again, if this returns true this will
not open, and we will test that in a moment.
| | 04:17 | So let's go ahead and just run this.
| | 04:19 | I am going to hit Save, and let's debug this.
| | 04:24 | And you should see that now, if you look
at your console here, you will see that
| | 04:28 | we are utilizing the Adobe AIR
application, you'll see the Security Sandbox is
| | 04:33 | Application, and then you also should
see the capabilities.localFileReadDisable
| | 04:38 | is false which means that
it has not been disabled.
| | 04:42 | So again, if I place my code in here,
if this is true, then execute this code.
| | 04:49 | So that's not what we want, so you
should see, when I actually go back to my
| | 04:52 | AIR application here,
| | 04:54 | if I select something, you'll
see that won't actually work.
| | 04:57 | It won't pop open the Directory dialog box.
| | 05:00 | So what we can do here is just negate
this by putting an exclamation point here.
| | 05:06 | And that will say if this is false,
which in fact it is because I do have
| | 05:10 | localReadWrite access to my
hard drive, that should work.
| | 05:14 | So let's just go ahead and run that.
| | 05:17 | And you should now see that
I can select something here.
| | 05:21 | For example, I can select James Talbot,
and it will populate that directory here
| | 05:25 | in my folder to search text field there.
| | 05:29 | So a Sandbox is a logical permissions
group assigned to each file installed, or
| | 05:34 | loaded into an AIR application, based
on where that file originated from.
| | 05:39 | It makes sense to only include trusted
files and assets inside of an AIR application.
| | 05:44 | Files that have been saved to the file.
application storage directory, which
| | 05:49 | we've done in earlier walkthroughs in
this course, have privileges that are
| | 05:52 | limited by their Sandbox,
according to the operating system.
| | Collapse this transcript |
| Using encrypted data storage| 00:00 | A unique, persistent, encrypted local
data store is available for each AIR
| | 00:04 | application installed for each user.
| | 00:07 | This is a great way to store sensitive
data such as a user ID and password, when
| | 00:12 | we may not have access to the web.
| | 00:14 | A desktop application may need to store
this information and may not be able to
| | 00:18 | write it to a server.
| | 00:20 | The encrypted local data store in Adobe
AIR uses AES-CBC 128 bit encryption, and
| | 00:28 | it utilizes the keychain on the Mac or
the DPAPI on Windows to associate the
| | 00:34 | encrypted data with each machine user.
| | 00:37 | The flash.data.EncryptedLocalStore
provides static methods to manage this data.
| | 00:43 | Let's explore them now.
| | 00:44 | So, you'll see I have my SecuringAIR
application imported, and go ahead and open
| | 00:50 | up SecuringAIR2.mxml.
| | 00:54 | The first thing I'd like you to do is
let's just examine the application that we
| | 00:58 | have, and you'll see here I am
going to just run the application.
| | 01:02 | You'll see right now the
application has a bit of functionality.
| | 01:07 | You'll see right here it says no
password set when this first starts.
| | 01:11 | Then you are going to see I can type
in a password here, and I can say Set
| | 01:15 | Password, and it will simply display a
form, and it'll tell me that the password
| | 01:19 | is encrypted and stored.
| | 01:21 | Well, the password actually is not
encrypted and stored. That's going to be the
| | 01:25 | functionality that we are going to add
in to the application here, but you'll
| | 01:29 | see that we've built this already for
you, just to save you a lot of typing.
| | 01:33 | You'll see right now, what we are going
to make happen when we build this is it
| | 01:38 | should say, instead of saying Set
Password here, we want it to say submit
| | 01:42 | password and once the user has set a
password, we want this button to say submit password.
| | 01:47 | They would have to type in the correct
password here to be able to access the form.
| | 01:52 | So, that's the
functionality that we're going to build.
| | 01:54 | You can see much of functionality is
already there. We are just going to utilize
| | 01:57 | the EncryptedLocalDataStore.
| | 01:59 | So, what we are going to do is when
this is Set Password the user is going
| | 02:02 | to type in a password.
| | 02:04 | That's going to write it to
the EncryptedLocalDataStore.
| | 02:07 | Then it's going to, first of all, check
to see if there's already a password.
| | 02:10 | If there is a password, this button
will say submit password, and they'll have
| | 02:14 | to type in the password.
| | 02:16 | Then we will compare with whatever the
user types with what's already in the
| | 02:19 | EncryptedLocalStore.
| | 02:22 | So, our first step is to import the
flash.data.EncryptedLocalStore class.
| | 02:28 | So, I am just going to say
flash.data.EncryptedLocalStore.
| | 02:36 | So that's our first step
is to import this class.
| | 02:40 | Then inside of your init method, what I
want you to do is just get the password,
| | 02:46 | if it's already there.
| | 02:47 | So, let's, first of all, in our init
method, actually this variable has been
| | 02:50 | created here, of a ByteArray.
| | 02:53 | So, again, it's stored encrypted so we
are going to use the ByteArray class, and
| | 02:57 | I am just going to say
storedPasswordBytes=EncryptedLocalStore.
| | 03:08 | Then I am going to use the getItem
method, and I am going to get the password
| | 03:13 | here, and that's how we are going
to store in the EncryptedLocalStore.
| | 03:15 | So, I am just saying take this password
from the EncryptedLocalStore and put it
| | 03:21 | in the storedPasswordBytes.
| | 03:24 | So that's my first step.
| | 03:26 | Then the second thing is, here if the
storedPassword is null, you'll see it
| | 03:30 | says no password set.
| | 03:32 | So, if there's nothing in that
EncryptedLocalStore, you'll see that,
| | 03:36 | but then if there is something in there,
what I want to do is I want to take
| | 03:40 | whatever's in there, and I want to make
it into a string so that I can compare
| | 03:44 | it against what the user typed in,
which is also going to be a string.
| | 03:47 | So, here I am going to say
storedPasswordString, and you could see that variable
| | 03:52 | has already been created up here.
| | 03:54 | I'm just going to simply say
storedPasswordString = StoredPassword.bytes, and
| | 04:03 | you'll see there's a very useful
method in here called readUTFBytes.
| | 04:09 | This readUTFBytes will go through
this and actually read what's in there.
| | 04:15 | So, here I have storedPassword, and
you'll see I just have a quick typo here.
| | 04:20 | That doesn't need to be a dot.
| | 04:21 | That's the name of my variable.
| | 04:23 | So, I have
StoredPasswordBytes, and I have readUTFBytes.
| | 04:29 | Then here you'll see I'll just simply
go, and I'll say StoredPasswordBytes,
| | 04:37 | and then I'll just say .length, which
will simply be the length of how long
| | 04:41 | that is, and it will then read the
UTFBytes for the entire password and place
| | 04:47 | that into the string here.
| | 04:48 | I'll have the storedPasswordString, so
I can do a comparison later on when the
| | 04:53 | user actually clicks that button.
| | 04:55 | So, there are two things I want to do
when the user actually clicks the button,
| | 04:58 | and this is the clickHandler for the button.
| | 05:01 | So, the first thing I want to do is,
of course, I want to set the password,
| | 05:06 | if it's already there.
| | 05:07 | So, if there is no password there, I want
to set the password. So let's do that.
| | 05:12 | So, I am going to create a variable
here called setBytes, and I'll type this as
| | 05:17 | a ByteArray, and I'll simply say = new ByteArray.
| | 05:23 | So that will create a new variable called
setBytes, which is going to be a ByteArray.
| | 05:29 | Then I'll utilize that, and I'll just
use the writeUTFBytes, and I'll just say
| | 05:36 | write the UTFBytes and
write it to password here.
| | 05:40 | So, that will write the UTFBytes to
password, and then finally, I will take my
| | 05:46 | EncryptedLocalDataStore here.
| | 05:48 | So, I'll say EncryptedLocalStore.setItem,
and I will simply say set password and
| | 06:01 | put this setBytes variable right in
there, inside of my EncryptedLocalDataStore.
| | 06:08 | So, I am taking this variable, putting
it inside of the EncryptedLocalStore, and
| | 06:13 | I'm calling it password, which
you can see, up here the getItem,
| | 06:18 | I'm also utilizing the password
there if it happens to already exist.
| | 06:22 | Now, you'll also see, if the
buttonText here is Submit Password,
| | 06:26 | you'll see this code is already here
for us, but we're doing a quick comparison
| | 06:30 | here, and I am saying if the
password != storedPasswordString.
| | 06:36 | Remember, password, if we go up here,
you'll see password is simply that
| | 06:40 | passwordInput.text field and the text property.
| | 06:44 | So, here I'm doing this quick comparison.
| | 06:45 | I am just saying if the
password != storedPasswordString in the
| | 06:50 | EncryptedLocalDataStore, go ahead
and pop open an alert box that says
| | 06:54 | incorrect password.
| | 06:56 | Otherwise, if it is correct, do the showForm.
| | 07:00 | So, our application should now be functional.
| | 07:02 | So what I'd like you to do is just go
ahead and save your application, and
| | 07:06 | you'll see I have a quick error
here where it says StoredPasswordBytes.
| | 07:10 | In this case, you'll see what I've
done is I have a capital when I shouldn't.
| | 07:14 | So, here I am going to hit Save.
| | 07:17 | You should see that it should solve my
problem, and I have storedPasswordBytes,
| | 07:24 | and you'll also see that I
put the capital over here.
| | 07:27 | Lots of typing can do that to you.
| | 07:30 | Now, if I run the application, it
says no passwords set at this point.
| | 07:36 | Now, let's type in a password.
| | 07:38 | I'll just use the word
"password," so I won't forget.
| | 07:41 | I hit Set Password.
| | 07:42 | It says password encrypted and
stored, and it displays the form.
| | 07:46 | Well, let's make sure that that is the case.
| | 07:48 | I'll close off my AIR Application.
| | 07:51 | I'll run it again, and now
it should say Submit Password.
| | 07:55 | So, if I type in the wrong password
here, note it says incorrect password,
| | 07:59 | because of that conditional logic.
It's going back out to the local data
| | 08:03 | storage, it's verifying it, and it's not there.
| | 08:05 | Now, let's type in the right password, and
you should see it then displays the form.
| | 08:11 | So, the EncryptedLocalDataStore is
available per application, and is useful for
| | 08:17 | storing sensitive information, such as
user credentials, inside of a desktop
| | 08:22 | application that may not have access to the
web, but you still may need users to log on.
| | 08:26 | We are now ready to learn how to
actually encrypt the entire database, which is
| | 08:31 | also possible, and this will provide
us an even greater level of security.
| | Collapse this transcript |
| Encrypting the AIR database| 00:00 | Adobe AIR 2.0 supports AES encryption
of local databases, and encryption is
| | 00:06 | enabled when the local database is created.
| | 00:09 | We can specify an encryption key during
database creation, and the databases can
| | 00:13 | be encrypted to that key.
| | 00:16 | We should never use plain text keys,
because source code may be distributed, or
| | 00:19 | binary files could be reverse engineered.
| | 00:22 | To provide a maximum level of security,
we can use in ActionScript class that
| | 00:26 | generates secure keys.
| | 00:28 | So let's go ahead and import our
SecuringAIR project and go ahead and open
| | 00:33 | up SecuringAIR3.mxml.
| | 00:36 | You'll see we have a very simple
application here that actually goes ahead
| | 00:40 | and creates a database.
| | 00:42 | You'll see that we created TABLE.
| | 00:43 | There is a customers:Array.
| | 00:46 | You could see that I have, in the app-
storage directory, I am creating a database
| | 00:49 | here called Security3.db.
| | 00:53 | Again, you could see its inserting
some information into the table, and so
| | 00:57 | on, and down the line.
| | 00:58 | Let's go ahead and just run the application.
| | 01:00 | We'll take a quick look here, and
I'll actually add some data here.
| | 01:04 | So let's say James Talbot.
| | 01:06 | We'll say Presenter.
| | 01:10 | I will add in another record here, Tom Mueller.
| | 01:16 | We'll say Producer.
| | 01:19 | So now I have a very simple database.
| | 01:21 | You can see it's writing this
information to my local database.
| | 01:25 | If I just go over here to My Computer
/James Talbot/AppData/Roaming, you
| | 01:33 | should see now, under SecuringAIR4, under
the Local Store, it has actually created
| | 01:38 | a database here where that
information is being stored.
| | 01:42 | If I open this up, you would see the
name and the title, and it's not secure.
| | 01:47 | So what we want to do is we want to
actually take this database file and encrypt
| | 01:51 | it so that it is secure.
| | 01:53 | That's what we are going
to do in this walkthrough.
| | 01:56 | So, what I want you to do is go out to
approximately line 50 here in your walkthrough.
| | 02:04 | So here's approximately line 50. What we're
going to do, we're going to create an encryption key.
| | 02:09 | So create a new Variable here, and
let's call this encryptionKey, just as you
| | 02:15 | see there, and let's make sure
that this is set as a ByteArray.
| | 02:18 | So I am going to say var
encryptionKey = new ByteArray.
| | 02:27 | Then what I am going to do is I am
going to take this encryption key, and I'm
| | 02:30 | going to write an encryption key.
| | 02:32 | So I'll say encryptionKeys.writeUTFBytes,
and let's write the string here.
| | 02:41 | We're going to write it to
precisely 16 bytes, just like that
| | 02:49 | So I'll write that as my encryption key,
and then what I want to now,
| | 02:54 | I've written this simple key is that I
want to add it to the database when the
| | 02:58 | database is actually created.
| | 03:00 | So, I am going to do this, because remember
that database is created at the init method,
| | 03:05 | so, as you can see, here's my DB
file. That's creating the new database.
| | 03:09 | So what I want you to do is just
instead of saying securities3 database, let's
| | 03:14 | call this security3-encrypted.db.
| | 03:20 | So we're now creating that database.
| | 03:22 | Then you should see there's a
function in here, called dbConn.openAsync.
| | 03:30 | So what I want you to do here is in
the openAsync, you'll see it has currently
| | 03:35 | opened db file, but what I want
you to do is just say SQLmode.CREATE.
| | 03:44 | So that's going to create the database,
and then I'm just going to say null for
| | 03:48 | the responder, because there is none.
| | 03:50 | We'll say autoCompact = false, and
then the pageSize here, I'll put in 1024.
| | 03:59 | Then for the encryptionKey, I want to
use that encryption key that I created
| | 04:03 | earlier, and that's how I can do that.
| | 04:05 | So here I'll just say encryptionKey,
and that means when it opens up the
| | 04:09 | database, it creates that, it
will use that encryption key.
| | 04:14 | So now I am going to just hit Save
and when I run this you'll see that it
| | 04:20 | actually creates a new database.
| | 04:23 | This database will be an encrypted database.
| | 04:26 | Notice it's a new database.
| | 04:27 | So I'll put in James, Presenter, and
then I'll put in Tom, Producer again.
| | 04:37 | So now you'll see I have
two records in my database.
| | 04:41 | So now I have that, but now watch what happens.
| | 04:44 | Again, you should see that if I run
the application again you'll see that, of
| | 04:47 | course, it's persistent, because
this is stored in the database.
| | 04:49 | Watch what happens if I remove the
encryption key when I try to open up
| | 04:56 | the existing database.
| | 04:57 | You should see that it will not be able
to open the database because it needs
| | 05:03 | to have that actual key to open up the database.
| | 05:06 | Again, you'll see that that does not open
it up, and it cannot access the database.
| | 05:12 | So AIR databases can be
secure if they are encrypted.
| | 05:15 | We can use an encryption key, which is
a 16-bit string encoded as a ByteArray.
| | 05:21 | We specify this key when a database
is created, and then we have to specify
| | 05:24 | the key whenever we create
or open up the database again.
| | 05:28 | Opening a database with the wrong
key won't work, and in that way the
| | 05:33 | database is secure.
| | Collapse this transcript |
| Updating AIR versions| 00:00 | Adobe AIR provides a secure
approach to application updating.
| | 00:04 | In order to update any application,
the Application ID and the Publisher
| | 00:08 | ID values of the original application must
match those of the new updated application.
| | 00:14 | The original application must also
know the precise version number of the new,
| | 00:18 | updated application.
| | 00:20 | Finally, the developer may
programmatically compare the original and the
| | 00:24 | new version numbers in order to
prevent downgrade attacks by enforcing
| | 00:28 | version incrementation.
| | 00:30 | Let's explore how to use the
Updater Class in Adobe AIR 2.0.
| | 00:35 | You can see is the first I have
done here is import the SecuringAIR
| | 00:37 | application, and you'll see in the
source directory, in the default package, you
| | 00:41 | will see SecuringAIR4.mxml.
| | 00:44 | Go ahead and open up this, and you
will see I just have a very, very simple
| | 00:48 | little application here.
| | 00:49 | We're going to go ahead and run it.
| | 00:51 | We will take a look at the user
interface, and you'll see here, I have the
| | 00:55 | Security4 Application, and this is
currently Version 2.0, and then as a user, I
| | 01:01 | can type in a new version, and
I can choose Update Application.
| | 01:05 | Now there's no functionality involved
in here yet, but we are going to use
| | 01:08 | this application to just learn a
little bit about how Adobe AIR is able to
| | 01:13 | update applications.
| | 01:15 | So the first thing I'd like you to do
is just import, but I'm just going to
| | 01:19 | import flash.desktop.Updater.
| | 01:26 | Now again, for those of you working
in Flash CS5, this code will be exactly
| | 01:30 | the same for updating;
| | 01:31 | it's just in this case, we happen to be
using something from the Flex framework,
| | 01:35 | but the code itself for
updating will be exactly the same;
| | 01:38 | it's all ActionScript3.
| | 01:39 | I would like you to scroll down to the
Update Application, and let's get an idea
| | 01:43 | of what's happening here.
| | 01:45 | You'll see that I have this Update Application.
| | 01:48 | In this Update Application, you'll
notice here on the button here, this is
| | 01:52 | calling a method called selectApplication.
| | 01:55 | So this is when the user selects a new
application to Update. So you will see
| | 01:59 | here is my selectApplication, and then
on the File, when they actually select
| | 02:04 | the file, you'll see it
then calling updateApplication.
| | 02:07 | And the first thing we want to do in
the updateApplication, when the user
| | 02:11 | selects a new file to upgrade, we want to
check and see if there is, in fact, a newer version.
| | 02:18 | So what we're going to do is we are
going to just add in some additional logic
| | 02:21 | here, and I'm just going to say if, and
I have another method down here where I
| | 02:26 | can actually check for a new version.
| | 02:28 | So assuming this is true, I want to
just say checkForNewerVersion, so that I am
| | 02:37 | just putting check for newer version.
| | 02:38 | I am going to call that method, and
notice this method is returning a Boolean.
| | 02:42 | Now, I haven't added the Version Check
down here, but if it's in fact true, it's
| | 02:46 | going to return true if there is a new version;
| | 02:48 | if there is a not a new version, it's
going to false, and it won't execute this code.
| | 02:53 | So there, I am utilizing version
incrementation, as you see there.
| | 02:57 | So I have this checkForNewerVersion.
So if there is in fact a newer version, I'm
| | 03:04 | then going to call the updater
class and get it to do the updating.
| | 03:07 | So here I am going to say var updater,
create a new variable, and I will data
| | 03:11 | type that as the Updater class, and
I will just simply say new Updater.
| | 03:16 | So that will create a new Updater object, and
then let's also create a new file object.
| | 03:22 | So I am going to call it var newApp,
and this will be whatever app the user has
| | 03:26 | selected - it would have to be an
AIR app, of course - and then I am going to
| | 03:30 | say, is equal to event.target.
| | 03:34 | Remember, this is coming from a file
object, so this is going to be a file.
| | 03:39 | So let's cast this as a file, just to be sure.
| | 03:44 | So that's going to say I am going to
take this newApp, and this is going to
| | 03:47 | be the newApp that the user has selected,
and then I am ready to use the updater class.
| | 03:52 | So I am going to say Updater. Let's
use the update method. And I am going to
| | 03:57 | update it with the new application
that the user has selected, and whatever
| | 04:02 | version number they have actually typed in.
| | 04:05 | So, I am going to say version.text
here, and then let's add just an else
| | 04:10 | statement, and just pop open an Alert
box, so I am going to say Alert.show, and
| | 04:17 | we will say Invalid version number,
which just means that will pop up with the
| | 04:25 | invalid version number, as you see there.
| | 04:29 | And now, let's actually do the version
check and make sure that there is a new version.
| | 04:33 | So where is the version actually indicated?
| | 04:37 | Remember, that's here in our
application descriptor file.
| | 04:40 | So I am going to go ahead and just
open up that application descriptor file,
| | 04:44 | scroll down to about Line 27, and
notice this is currently set to Version 2.0.
| | 04:51 | So, let's get this so we can
actually utilize this for version checking.
| | 04:56 | So, we could actually read XML.
| | 04:58 | So, here I am just going to say var appXml.
| | 05:01 | I am going to data type this as
XML, and then I am going to say,
| | 05:06 | NativeApplication.
nativeApplication, and we will then reference the
| | 05:14 | applicationDescriptor, so
that's going to be in my var appXml.
| | 05:19 | Let's also create a variable for the namespace.
| | 05:22 | So I will say var ns:Namespace, like
so, and I will say appXml.namespace,
| | 05:33 | choose that method to get the
Namespace, and then I will take the current
| | 05:38 | version, so I will say var
currentVersion, and will make that a number, so I
| | 05:43 | will say colon, number is equal to
appXml, and then we will reference ns for
| | 05:53 | the namespace. So I will say appXml,
and let's actually read this and go ahead
| | 05:57 | and get the version that we just looked
at, so we can use that in my code, and
| | 06:02 | I will just say version 0, so that will
get the current version, and then let's
| | 06:08 | get the new version. So I will say var
newVersion, and I will say :Number is
| | 06:17 | equal to. Let's cast this as number,
and this is what the user is going to type
| | 06:22 | in the actual text field.
| | 06:24 | So in this case, I will say version.text.
| | 06:26 | Remember, whenever I have a text input
field in Flex, it's automatically cast as
| | 06:31 | a string, so I am going to have to go
back out and caste out as a number, so it
| | 06:35 | can actually do the comparison.
| | 06:37 | And now, I am just going to simply say,
inside of if control here, I am just
| | 06:43 | going to simply say if (newVersion >
currentVersion), return true, and that will
| | 06:53 | then return true is the newVersion that
the user has entered is greater than the
| | 06:58 | existing currentVersion that's going to
return true, else it is going to return
| | 07:05 | false, as you see there.
| | 07:07 | So, now let's play around with
this a little bit, and understand how
| | 07:11 | updating actually works.
| | 07:12 | So I am going to save that. You should see
that it compiles with no problem, and
| | 07:16 | then what I am going to do is
actually export this as a release.
| | 07:20 | So I am going to click Project.
| | 07:21 | I am going to choose Export Release Build.
| | 07:24 | Let's export it to my desktop, just
to make life easier, and I will just
| | 07:28 | call this securing_v2, so this is my version2,
and I am going to just export it to the desktop.
| | 07:37 | I am going to click Next.
| | 07:38 | For those of you who have been
following along the course, you should see that
| | 07:41 | you have a digital certificate, a P12 file.
| | 07:43 | If you have obtained your own P12 file
from a company like VeriSign, feel free
| | 07:47 | to use that, or you can create your own,
and we have learned how to create those
| | 07:51 | certificates in a earlier unit.
| | 07:53 | So, now I am just going to choose password.
| | 07:56 | That's the password of the
certificate that I am using here.
| | 07:59 | I am going to click Next.
| | 07:59 | I am going to choose the Assets to
include, and then I am going to click Finish,
| | 08:06 | and that will create me an
Installer here for securing_v2.
| | 08:11 | The next thing I want you to do
is also create an Installer for v3.
| | 08:18 | So, go back here to your SecuringAIR4-
appXml, and then you should change the
| | 08:25 | version number here to version 3.0, and
then also go back to your SecuringAIR4
| | 08:34 | and just change the version up here in
the text field, so we know when we are
| | 08:37 | actually running it, that this is in
fact version 3.0, and do the same thing.
| | 08:42 | Export another Release Build, so I am
going to click Project > Export Release
| | 08:47 | Build > SecuringAIR4.
| | 08:49 | We are going to just export this as version3.
| | 08:53 | I am going to say .AIR, and
then I am going to say Password.
| | 08:58 | I am going to click Next, and again, Finish.
| | 09:04 | So, now I am going to minimize Flash Builder.
| | 09:07 | So you will see we have two
versions of the application here.
| | 09:11 | We have securing_v2, and we have securing_v3.
| | 09:14 | Let's go ahead and install securing_v2,
so I am going to click here, and again,
| | 09:19 | it's going to tell me, are you sure you want
to install this application to your computer?
| | 09:23 | It says the publisher is unknown, since I
didn't use the VeriSign signed certificate.
| | 09:27 | So I will click Install.
| | 09:28 | It's going to ask me where I'd
like to install it. I will click OK.
| | 09:31 | It's going to prompt me, do
I want to make this change?
| | 09:34 | And you should see that
it installs securingAIR4.
| | 09:39 | So now this is obviously the older version
of the application, and you will see now.
| | 09:44 | So what I am going to do is I am going
to update this to version 3.0, and I am
| | 09:49 | going to just simply say Update
Application, and I am going to choose my
| | 09:54 | securing_v3, and I am going to update
this to the newer version. So, watch this.
| | 10:01 | When I click Open, it's going to say,
hey, do you want to allow the following
| | 10:04 | program to make changes to your
computer, and notice instead of reinstalling it,
| | 10:08 | it's updating the application, and
now you can see that I have version_3.0
| | 10:14 | actually installed here,
and I am trying to do that.
| | 10:18 | So, you could see that the application
has been updated to the latest version.
| | 10:23 | Now, watch what happens here if I try
to downgrade and go back to securing_v2.
| | 10:30 | It's going to tell me it's an invalid
version number if I try to downgrade and
| | 10:34 | do a downgrade attack. I get that
little alert that says Invalid version number,
| | 10:39 | that that doesn't work.
| | 10:41 | So, we have seen how Adobe AIR
applications could programmatically update themselves.
| | 10:45 | We can determine the AIR Application
version information and any application
| | 10:49 | description information
programmatically at runtime.
| | 10:52 | We cannot downgrade to an earlier
version, and this can help prevent hacker
| | 10:56 | attacks because some hackers might try
to move to a less secure version of the
| | 11:00 | application and then hack in.
| | Collapse this transcript |
|
|
ConclusionGoodbye| 00:00 | Thank you for taking the time to
attend the Adobe AIR 2.0 Essential Training
| | 00:05 | for Flash and Flex.
| | 00:07 | We've worked with the Adobe AIR APIs
to be able to create cross-platform
| | 00:12 | applications, and we can build these
applications either utilizing Flash CS5,
| | 00:18 | Flash Builder, or we can even build
prototypes in Flash Catalyst and import
| | 00:24 | these applications into Flash Builder.
| | 00:26 | We've also worked extensively in being
able to create both online and offline
| | 00:32 | applications, utilizing the database,
utilizing network connectivity, as well as
| | 00:38 | being able to open up native windows
and being able to replicate that operating
| | 00:42 | system functionality.
| | 00:44 | The beautiful part of this is we
can do it without having a whole Linux
| | 00:47 | development team, a whole
Windows development team, and a whole
| | 00:50 | Macintosh development team.
| | 00:52 | All we have to do is develop for Adobe
AIR, and AIR handles all the complexity,
| | 00:58 | even if we are utilizing AIR on a mobile device.
| | Collapse this transcript |
|
|