You are Here:Home>>Old Posts>>Creating a video e-card application for mobile devices

Creating a video e-card application for mobile devices

Carlos Pinho
By | 2008-02-22T11:05:09+00:00 Feb 22, 2008|Old Posts|

This article outlines the process of building a basic Flash Lite 3 application that allows users to send Flash Video (FLV) clips with custom messages to other mobile device users. The recipients will be able to view the e-card greetings using a mobile client on their handsets. This article also provides an example of a real-world project designed to work with Flash Lite and any other server-side technology.

Sample files:

Prerequisite knowledge

Prior experience working with video content in the Flash authoring interface is useful. Familiarity with the FLV format, server-side scripts, and Microsoft Access is also helpful.

Getting started

This article covers the steps necessary to build a simple video e-card system for mobile phones with Flash Lite 3 installed. Like other web-to-mobile systems, this video e-card system uses a server-side script and database. For the purposes of this article, I’ll use ASP files and a Microsoft Access database.

Before diving into the technical details of building the application, let me provide an overview of the here components that make up a typical mobile e-card system for Flash Lite devices:

  • Back end: The back end is responsible for creating and updating user profiles, as well as tracking the e-card’s profiles. It is comprised of server-side scripts and a database. The back end is the core of the entire system—every transaction that occurs in the application takes place on the back end, and then the necessary data is sent to the e-card client.
  • Client: The e-card client is the part of the application that is installed on the user’s handset. This is the part that displays the user interface of the application and enables users to view or send cards, as well as other actions (depending on the functionality you add to the application).
  • E-cards: The e-cards contain the greeting messages. In this project, e-cards consist of FLV files. These files are stored on the server and are downloaded to the user’s handset as needed.

In this article, I’ll focus on building two parts of the e-card system:

  • Creating sample video e-cards. For this task, I’ll use some simple FLV files to create the e-cards. The e-cards will be downloaded to the server at runtime to be played inside an e-card client.
  • Building the e-card client, including setting up the communication between the server-side scripts and the e-card client.

Note: The step-by-step instructions for creating the ASP files and configuring the Microsoft Access database for the client-server communication are outside the scope of this article. However, I will discuss the input for each specific ASP file used in this project, and also describe the data returned from the server-side scripts to the FLA file, so that you can get a better understanding of how the whole system works.

If you haven’t done so already, download the sample files that accompany this article. The sample files contain the ASP server-side scripts that you will use as the back end for this project. In the following section, you’ll use FLV files to build some mobile e-card video greetings.

Creating the video e-cards

For this project, the e-cards consist of FLV clips that are 120 pixels wide and 90 pixels high. To convert digital videos to the FLV file format, you can use the Adobe Flash CS3 Video Encoder.

Step 1: Create the FLV files

Note: You can skip this step for this exercise. I’ve included some pre-made e-card FLV files in the sample files folder—you can use them for non-commercial demo purposes.

To create the FLV files, follow these steps:

  1. Launch the Adobe Flash CS3 Video Encoder.
  2. Click the Add button and select a standard digital video file from your local drive (see Figure 1).

    Use the Flash Video Encoder to select the video file you want to use as the mobile e-card.

    Figure 1. Use the Flash Video Encoder to select the video file you want to use as the mobile e-card.

  3. Click the Settings button to update the settings used to process the video, such as cropping, resizing, frame rate, and code.
  4. On the Crop and Resize tab, select the Resize check box and enter 120 in the Width and 90 in the Height text boxes. On the video tab, select Low from the Quality pop-up menu and 12 from the Frame rate pop-up menu. This frame rate matches the frames per second of the e-card client you are going to build in the next section.
  5. Click OK and then click the Start Queue button to generate the FLV file that you’ll use as an e-card in your application.
  6. Repeat the FLV encoding process as many times as desired, so that you can offer your application users a wide selection of video e-cards to choose from.

Step 2: Create thumbnails of the video e-cards

Note: If you want, you can skip this step and use the provided FLV e-cards and their respective thumbnail JPG images in the thumbnails folder of the sample files that accompany this article.

Thumbnails make it easier for users to select the cards they want. To create thumbnails of your video e-cards, follow these steps:

  1. Open the folder containing the e-cards (FLV files) that you’ve created. Alternately, you can locate the FLV files that are provided in the sample files folder.
  2. Launch Flash CS3 Professional and create a new ActionScript 3.0 file.
  3. Choose File > Import > Import Video.
  4. In the Import Video dialog box, browse to select one of the FLV files. When the file path field contains the path to your FLV file, click the Continue button three times (leaving the default settings on each screen untouched) and then click Finish.

    The FLV file is now displayed on the Stage.

  5. Choose Control > Test Movie to see the FLV video play back in the standalone Flash Player.
  6. Use the video controls to pause the playback at the desired location, then press the Print Screen key or use a third-party utility to capture a screenshot of the video.
  7. Repeat this process for each FLV e-card you want to include in the application.
  8. Use an image editing program, such as Fireworks, to crop the screenshots to only show the video content.
  9. Resize each of the resulting images to 20 pixels wide by 20 pixels high, and export the files in the JPG format. Be sure to name each file with the same name as its corresponding FLV video file.
  10. Create a new folder named thumbnails on your hard drive and copy all of the 20×20 pixel thumbnail JPG files into the thumbnails folder. These thumbnails will be used by the e-card client to allow users to browse through the gallery to review the available e-cards to send.

Next you need to list all the FLV files (or the e-cards) in an XML file. This file will be loaded into the gallery section of the e-card client where users can select any card of their choice by viewing the thumbnail images of the cards you just created.

Step 3: Update the XML file with the e-card information

To update the XML file with the e-card information, follow these steps:

  1. In the sample files, locate the file named gallerylist.xml and open it with a text editor. You’ll use this XML file to add your new e-cards as new nodes (see Figure 2).

    Locate the gallerylist.xml file and open it in a text editor to begin adding new nodes.

    Figure 2. Locate the gallerylist.xml file and open it in a text editor to begin adding new nodes.

  2. Add the following attributes to each node:
    • labelname: Represents the name of the e-card as it will appear to the user in the card list displayed within the e-card client.
    • itemvalue: Corresponds to the file name of the FLV file, excluding the .flv file extension.
    • type: Displays any additional information you might want to present to the user. For this example, I’ve indicated “No Audio” for FLV files without audio, and “With Audio” for FLV with audio. This is optional. You can also add more attributes with other descriptive types.
    • size: Indicates the file size of the FLV file so that the application displays this information to the user selecting an e-card. Using FLV video clips with the smallest file size possible is ideal, because they take less time to download to a handset.

Now that the video e-card files, thumbnails, and XML file are prepared, you can move on to the more complex part of this tutorial. In the next section, you’ll build the e-card client that will manage the user data and the e-card data with the help of a server-side script.

Building the video e-card client

In this section, you learn how to set up the e-card client, which contains the user interface that the application users will interact with as they select, send, and receive the e-card files.

Note: The process of setting up the e-card client is a bit time consuming. If you want, create your own FLA file from scratch so that you can experience the process yourself. Or, if you want to skip creating the interface in Flash you and prefer to focus on the ActionScript coding instead, you can use the provided FLA file (ecard_final.fla).

To begin, locate the FLA template named blank_ecard.fla that is part of the source files that accompany this tutorial. This Flash file contains all of the keyframes and layers needed for the project and includes movie clips that are already added to the Stage. You can either use this file as a guide to create your own client interface in a brand new FLA file or as reference as you follow along and begin adding the ActionScript code as described later in this article.

Before you start with the client, however, I’d like you to turn your attention to the back end of the application for a moment.

Step 1: Scope out your programming tasks

When you develop web-to-mobile applications, you can create the server-side scripts using a variety of scripting languages, such as PHP or ASP. Depending on your preference, you could also use more advanced frameworks like Java, .NET or ColdFusion. Since I am familiar with ASP, I have created the server-side scripts for this project with simple ASP programming.

  1. Locate the archive named backend.zip that is part of this tutorial’s sample files.
  2. Unzip the file and save the contents to a web directory named ecard on your Windows system (Note: Be sure you have IIS installed. Alternately, you could use an actual web server to test and run this application.)
  3. Copy the folders containing your FLV e-cards and thumbnail images, along with the updated gallerylist.xml file into the ecard folder so that all of the project files are in a central location on your hard drive (see Figure 3).

    Copy all of the project files into a web directory named ecard on your local drive

    Figure 3. Copy all of the project files into a web directory named ecard on your local drive

Since this application is web-based, you need to perform the following two common programming tasks:

  • Communicate with a server-side script (ASP). As mentioned previously, the functionality of the application is dependent on the server – side scripts, which are used to get data from and send data to the server. For this example, I’ve used the GET method to send the data to the ASP file. I used this method to make it easy for you to trace and evaluate the variables sent via this method. In a real-world situation, I recommend using the POST method, because it offers more security and flexibility when sending data to the server.
  • Display list of available e-cards in the Flash client. There are several places in the Flash client where you need to populate available card lists from corresponding XML files having the information such as e-card file name, e-card thumbnails and so on. . For example, the list of available e-cards in the gallery and the inbox list are populated using XML data. Adding functionality to populate the data from the XML file was a major part of this project’s development.

The following sub-sections discuss the modules of the e-card client:

  • Registration: Creating a unique user ID and updating the associated XML file.
  • Login/inbox: Populating the e-card gallery and inbox list with the XML data.
  • Send e-card: Updating the recipient’s XML file, creating a new database entry, and generating an e-mail to notify recipients that they’ve received an e-card message.

Step 2: Configure the registration module

Figure 4 illustrates the information flow in the registration module.

This diagram maps the flow of data in the registration module of the application.

Figure 4. This diagram maps the flow of data in the registration module of the application.

Open the ecard_blank.fla file in Flash. Review the layers of the Timeline and you’ll see a section marked with these frame labels: register, registering, regsuccess, regfail, and regfail2 (see Figure 5).

The Timeline contains frame labels that correspond to the different states of the registration process.

Figure 5. The Timeline contains frame labels that correspond to the different states of the registration process.

The frame labels are used to jump to the appropriate functionality based on the status of the registration process. The action of jumping to these keyframes makes it possible to display the corresponding feedback to the user in the Flash Lite application.

Update the keyframes of the login module

After ensuring that the frame labels are in place, you’ll complete the registration module by updating each labeled keyframe, as follows:

Update the frame label register

  1. Select the frame labeled register in the Content layer and create two input text fields on the Stage.
  2. Select the text fields one by one and use the Property inspector to assign the instance name email_txt to the first text field and assign the instance name password_txt to the second text field.
  3. Create a button on the Stage. Select the button and assign it the instance name enterBut (see Figure 6).

    While the button is selected, assign the instance name enterBut using the Property inspector

    Figure 6. While the button is selected, assign the instance name enterBut using the Property inspector

  4. In the ActionScript layer, on the frame labeled register, add the following code:
    password_txt.password = true;
    enterBut.onRelease = function() {
        _root.passwordReg = password_txt.text;
        _root.fromEmail = email_txt.text;
        play();
    };

Update the frame label registering

  1. Select the frame labeled registering in the Content layer and add static text to the Stage that reads: “Please wait…”
  2. In the ActionScript layer, on the frame labeled registering, add the following code:
    stop();
    errorFlag = "";
    rejobj = new LoadVars();
    rejobj.onLoad = regResponse;
    rejobj.email = _root.fromEmail.toLowerCase();
    rejobj.password = _root.passwordReg;
    rejobj.sendAndLoad(""+path+"/register.asp", rejobj, "GET");
    function regResponse() {
            if (this.errorFlag == 0) {
            gotoAndStop("regsuccess");
            } else if (this.errorFlag == 1) {
            gotoAndStop("regfail");
        } else {
            gotoAndStop("regfail2");
        }
    }
    // executed code
    init();

This frame of the FLA file sends the user’s e-mail and password data to the register.asp file. If the e-mail ID does not exist in the database, the register.asp file returns the error flag as 0 through the syntax errorFlag=0 to indicate a new user. the server-side script creates a new record in the database along with a unique file name (see Figure 7).

If the system finds that the user ID does not exist, a new record is created for that user in the database, along with a unique file name.

Figure 7. If the system finds that the user ID does not exist, a new record is created for that user in the database, along with a unique file name.

The system then uses the newly created file name to generate an XML file for the user’s profile on the server to store all the card-related data. The profile XML file holds the relevant data for that user (see Figure 8).

The system generates an XML file for each user, to hold their profile information

Figure 8. The system generates an XML file for each user, to hold their profile information

After registration, when the user logs into his or her inbox, the first message the user receives is the welcome e-card congratulating him or her for becoming a new user of the application. As each new profile is generated, the welcome e-card is entered in the user’s profile by default.

If the e-mail ID entered already exists in the database, register.asp returns errorFlag=1. When receiving this value, the playhead in the FLA file jumps to the regsuccessful frame label (to indicate that the registration is successful) or to the regfail frame label (to indicate that the registration is not successful), based on whether or not the submitted password data matches the password associated with the e-mail ID in the system.

Step 2: Configure the login and inbox modules

The main goal of the login module is to authenticate the submitted information on the server by verifying whether the user attempting to log in to the account is the same person who previously registered the e-mail address. After the user has been authenticated, the inbox level receives the unique file name (ID) from the user’s profile XML file. This information is then downloaded to the Flash Lite e-card application. After the data is loaded successfully, the e-card information is listed; enabling the user to select from a list of e-cards they’ve received.

Figure 9 illustrates the login and inbox information flow.

This chart maps the flow of data in the login and inbox modules of the application.

Figure 9. This chart maps the flow of data in the login and inbox modules of the application.

Now turn your attention back to the ecard_blank.fla file to review the Login section of the Timeline. When reviewing the layers of the Timeline, you’ll see a section marked with these frame labels: Login, logging, loginSuccess, and  loginFail (see Figure 10).

Frame labels are added to the Timeline that correspond to the different states of the login process.

Figure 10. Frame labels are added to the Timeline that correspond to the different states of the login process.

The frame labels are used to jump to the appropriate functionality based on the status of the login process. The action of jumping to these keyframes makes it possible to display the corresponding feedback to the user in the Flash Lite application.

Update the keyframes of the login module

When the frame labels are in place, you’ll complete the login module by updating each labeled keyframe, as follows:

Update the frame label Login

  1. Select and copy the text fields and button that are located on the frame labeled register on the Content layer. Then paste the copied items on the frame labeled Login on the Content layer.
  2. In the ActionScript layer, on the keyframe labeled Login, add the following code:
    stop();
    password_txt.password = true;
    enterBut.onRelease = function() {
        pass = password_txt.text;
        fromEmail = email_txt.text;
        play();
    };

Update the frame label logging

In the ActionScript layer, on the frame labeled logging, add the following code:

stop();
lo = new LoadVars();
lo.password = pass;
lo.email = fromEmail; 
lo.sendAndLoad(""+path+"/login.asp", lo, "GET");
lo.onLoad = function() {
    if (this.errorCode == 0) {
         nameFile = lo.nameFile
        _root.gotoAndStop("loginSuccess");
    } else if (this.errorCode > 0) {
        _root.gotoAndStop("loginFail");
    } else {
        _root.gotoAndStop("loginFail2");
    }
}
init();

The keyframe with the frame label logging contains the functionality to send the user’s e-mail and password data to the login.asp file on the server. The login.asp file verifies whether the e-mail ID and the password provided match those that exist in the database. If the e-mail ID and password submitted during the login process do not match any records in the database, login.asp returns the error flag as 0 through the syntax errorFlag=0 and then uses the unique file name in the user’s profile XML file to return the data as nameFile=[unique file name].

Conversely, if the e-mail ID and password match, then an existing record in the database, the login.asp file returns errorFlag=1. When the Flash client receives these flag values, the playback head in the Flash movie moves from the keyframe labeled logging to the keyframe labeled loginSuccess (indicating a successful login) or to the keyframe labeled regfail (indicating that the login was unsuccessful).

Add interactive buttons

Your next step is to create three buttons that enable users to access their inboxes, send an e-card, and log out of the system.

  1. Select the frame labeled loginSuccess on the Content layer of the Timeline.
  2. Create three buttons on the Stage and assign them the instance names inboxBut, galleryBut, and logoutBut. These buttons will allow users to view their inboxes, send e-cards, and log out of the system (see Figure 11).

    Add three buttons to the keyframe labeled loginSuccess to create the interface displayed to registered users

    Figure 11. Add three buttons to the keyframe labeled loginSuccess to create the interface displayed to registered users

To make these three buttons operational, follow these steps:

  1. Update the frame label loginSuccess. In the ActionScript layer on the frame labeled loginSuccess, add the following code:
    inboxBut.onRelease = function() {
        gotoAndStop("inbox");
    };
    galleryBut.onRelease = function() {
        gotoAndStop("gallery");
    };
    logoutBut.onRelease = function() {
        gotoAndStop("menu");
    };
  2. Add the inbox functionality. In the Timeline, you’ll notice there’s a section marked with these frame labels: inbox and inboxview (see Figure 12).

    Frame labels are added to the Timeline to facilitate the inbox functionality.

    Figure 12. Frame labels are added to the Timeline to facilitate the inbox functionality.

    These frame labels are used to jump the playhead to the appropriate functionality to access the contents of a user’s inbox. The action of jumping to these keyframes makes it possible to display the inbox data to the user in the Flash Lite application.

  3. Select the frame labeled inbox on the Content layer of the Timeline. You’ll see three movie clips on the Stage with the instance names list1, list2, and list0. Three rectangular transparent movie clips with instance names box1, box2 and box3 are positioned above the list movie clips (see Figure 13).

    Three transparent rectangles are overlaid on top of the three list Menu Item movie clips.Three transparent rectangles are overlaid on top of the three list Menu Item movie clips. 

    Figure 13. Three transparent rectangles are overlaid on top of the three list Menu Item movie clips.

Now you’re ready to add the functionality for the inbox feature.

Update the frame label login

  1. In the ActionScript layer on the frame labeled login, add the following code:
    stop();
    var cards:Array = new Array();
    var labelname:Array = new Array();
    var timestamp:Array = new Array();
    var date:Array = new Array();
    var messagebody:Array = new Array();
    var email:Array = new Array();
    var mobile:Array = new Array();
    var xmlFile:XML = new XML();
    xmlFile.ignoreWhite = true;
    xmlFile.load(""+path+"/xml/"+nameFile+".xml");
    xmlFile.onLoad = function() {
        var inboxArray:Array = this.firstChild.childNodes;
        for (i=0; i<inboxArray.length; i++) {
            cards.push(inboxArray[i].attributes.itemvalue);
            labelname.push(inboxArray[i].attributes.labelname);
            timestamp.push(inboxArray[i].attributes.timestamp);
            date.push(inboxArray[i].attributes.date);
            messagebody.push(inboxArray[i].attributes.messagebody);
            email.push(inboxArray[i].attributes.email);
            mobile.push(inboxArray[i].attributes.mobile);
        }
        cards.reverse();
        labelname.reverse();
        timestamp.reverse();
        date.reverse();
        messagebody.reverse();
        email.reverse();
        mobile.reverse();
        maxLength = ((_root.scrollBar_mc.track_mc._height)-44);
        moveValue = (maxLength/(cards.length));
        select = 1;
        list1.gotoAndStop(2);
        trace(cards[0]);
    
        loadMovie(""+path+"/thumbnails/"+cards[0]+".swf", "box1");
    
        loadMovie(""+path+"/thumbnails/"+cards[1]+".swf", "box2");
    
        loadMovie(""+path+"/thumbnails/"+cards[2]+".swf", "box3");
        if (email[0] != undefined && labelname[0] !=
        undefined && date[0] != undefined) {
            list1.secondLine = email[0];
            list1.labelnameValue = labelname[0];
            list1.dateValue = date[0];
            lo1._visible = 1;
        } else {
            list1.secondLine = "";
            list1.labelnameValue = "";
            list1.dateValue = "";
            list1.gotoAndStop(1);
            lo1._visible = 0;
        }
        if (email[1] != undefined && labelname[1] !=
        undefined && date[1] != undefined) {
            list2.secondLine = email[1];
            list2.labelnameValue = labelname[1];
            list2.dateValue = date[1];
            lo2._visible = 1;
        } else {
            list2.secondLine = "";
            list2.labelnameValue = "";
            list2.dateValue = "";
            list2.gotoAndStop(1);
            lo2._visible = 0;
        }
        if (email[2] != undefined && labelname[2] !=
        undefined && date[2] != undefined) {
            list0.secondLine = email[2];
            list0.labelnameValue = labelname[2];
            list0.dateValue = date[2];
            lo4._visible = 1;
        } else {
            list0.secondLine = "";
            list0.labelnameValue = "";
            list0.dateValue = "";
            list0.gotoAndStop(1);
            lo4._visible = 0;
        }
        _root.timestampValue = timestamp[0];
        _root.lablenameValue = lablename[0];
        _root.messageValue = messagebody[0];
        _root.bottomMsgValue = email[0];
        _root.dateValue = date[0];
        _root.secondLine = email[0];
        _root.mobileValue = mobile[0];
        _root.activeItemValue = cards[0];
        _root.cardValue.text =
        ""+select+"/"+i+" cards";
    };
  2. In the Content layer on the frame labeled inbox, create a simple button and place it outside the visible Stage area (see Figure 14).

    Create a button on the Stage and place it outside the visible area of the Stage.

    Figure 14. Create a button on the Stage and place it outside the visible area of the Stage.

  3. In the Content layer on the frame labeled inbox, add the following code:
    on (keyPress "<Down>") {
        if (select<cards.length) {
            _root["list"+select%3].gotoAndStop(1);
            setProperty("scrollBar_mc/thumb_mc", _y,
        getProperty("scrollBar_mc/thumb_mc", _y)+moveValue);
            _root.select = select+1;
            if ((select%3) == 1) {
        loadMovie(""+path+"/thumbnails/"+cards[select-1]+".swf", "box1");
                if (labelname[select-1] != undefined) {
                    list1.secondLine = email[select-1];
                    list1.labelnameValue = labelname[select-1];
                    list1.dateValue = date[select-1];
                    lo1._visible = 1;
                } else {
                    list1.secondLine = "";
                    list1.labelnameValue = "";
                    list1.dateValue = "";
                    lo1._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select]+".swf", "box2");
                if (labelname[select] != undefined) {
                    list2.secondLine = email[select];
                    list2.labelnameValue = labelname[select];
                    list2.dateValue = date[select];
                    lo2._visible = 1;
                } else {
                    list2.secondLine = "";
                    list2.labelnameValue = "";
                    list2.dateValue = "";
                    lo2._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select+1]+".swf", "box3");
                if (labelname[select+1] != undefined) {
                    list0.secondLine = email[select+1];
                    list0.labelnameValue = labelname[select+1];
                    list0.dateValue = date[select+1];
                    lo4._visible = 1;
                } else {
                    list0.secondLine = "";
                    list0.labelnameValue = "";
                    list0.dateValue = "";
                    lo4._visible = 0;
                }
            }
            _root["list"+select%3].gotoAndStop(2);
            _root.cardValue.text = ""+select+"/"+i+" cards";
        }
        _root.timestampValue = timestamp[select-1];
        _root.lablenameValue = lablename[select-1];
        _root.messageValue = messagebody[select-1];
        _root.bottomMsgValue = email[select-1];
        _root.dateValue = date[select-1];
        _root.secondLine = email[select-1];
        _root.mobileValue = mobile[select-1];
        _root.activeItemValue = cards[select-1];
    }
    on (keyPress "<Up>") {
        if (select>1) {
            _root["list"+select%3].gotoAndStop(1);
            _root.select = select-1;
            setProperty("scrollBar_mc/thumb_mc", _y,
        getProperty("scrollBar_mc/thumb_mc", _y)-moveValue);
            if ((select%3) == 0) {
        loadMovie(""+path+"/thumbnails/"+cards[select-1]+".swf", "box3");
                list0.secondLine = email[select-1];
                list0.labelnameValue = labelname[select-1];
                list0.dateValue = date[select-1];
    
        loadMovie(""+path+"/thumbnails/"+cards[select-2]+".swf", "box2");
                list2.secondLine = email[select-2];
                list2.labelnameValue = labelname[select-2];
                list2.dateValue = date[select-2];
            loadMovie(""+path+"/thumbnails/"+cards[select-3]+".swf", "box1");
                list1.secondLine = email[select-3];
                list1.labelnameValue = labelname[select-3];
                list1.dateValue = date[select-3];
            }
            _root.timestampValue = timestamp[select-1];
            _root.lablenameValue = lablename[select-1];
            _root.messageValue = messagebody[select-1];
            _root.bottomMsgValue = email[select-1];
            _root.dateValue = date[select-1];
            _root.secondLine = email[select-1];
            _root.mobileValue = mobile[select-1];
            _root.activeItemValue = cards[select-1];
            _root["list"+select%3].gotoAndStop(2);
            _root.cardValue.text = ""+select+"/"+i+" cards";
        }
    }
    on (keyPress "<Enter>") {
        gotoAndStop("inboxview");
    }

    Note: If you would like to learn more about how the inbox feature loads the XML data to populate the list in the Flash client, see my Developer Center article, Building an external XML-driven photogallery in Flash Lite 2.0.

When the user presses the UP or DOWN key buttons on the handset, it causes the highlighted region of the inbox to move up and down the list. When the user presses the ENTER button, the item currently highlighted in the inbox list is selected, causing the corresponding e-card to display (because the playback head jumps to the frame labeled inboxview in the Timeline).

Let’s review the contents of the frame labeled inboxview in the Timeline. This is the frame where the video e-card will load, which is displayed when the user selects a card from the inbox list. Since you created your e-card videos using simple FLV files, you can use a simple video object to serve as an FLV player to play the loaded FLV e-card.

When you select the frame labeled inboxview on the Content layer, you’ll see a video object placed on the Stage along with two text fields and a Replay button. The customized message from the sender is displayed in the text field with the instance name messagetxt. The e-mail ID of the sender is displayed in the text field with the instance name emailtxt (see Figure 15).

The frame labeled inboxview contains the video object and two text fields to display the selected data with the e-card information, as well as a Replay button.    The frame labeled inboxview contains the video object and two text fields to display the selected data with the e-card information, as well as a Replay button.

Figure 15. The frame labeled inboxview contains the video object and two text fields to display the selected data with the e-card information, as well as a Replay button.

Updating the frame label inboxview

In the ActionScript layer on the frame labeled inboxview, add the following code:

var nc = new NetConnection();
stop();
pctLoaded =0;
messagetxt.text = messageValue;
emailtxt = emailValue;
rewBut._visible = 0;
falserewbut._visible = 1;
var nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.onStatus = function(infoObject) {
    if (infoObject.level.toLowerCase == "error") {
        trace(infoObject.code);
    }
};
videoecard.attachVideo(ns);
ns.play(""+activeItemValue+".flv");
var loaded_interval:Number = setInterval(checkBytesLoaded, 500,
    ns);
function checkBytesLoaded(ns:NetStream) {
    var pctLoaded:Number = Math.round(ns.bytesLoaded/ns.bytesTotal*100);
    if (pctLoaded>=100) {
        //trace("loaded");
        rewBut._visible = 1;
        falserewbut._visible = 0;
        clearInterval(loaded_interval);
    }
}
rewBut.onRollOver = function() {
    _focusrect = false;
};
rewBut.onRelease = function() {
    ns.seek(0);
};

The script above adds the functionality to load the FLV video e-card from the server and play it in the video object of the Flash Lite client. The code also adds the functionality for the button with the instance name rewBut, which provides the functionality to the Replay button so that users can choose to watch the e-card again.

Step 3: Configure the send e-card module

Figure 16 illustrates the information flow when the system receives a request from a user to send an e-card.

The flow diagram maps the flow of data in the application when a user sends an e-card to another mobile user.

Figure 16. The flow diagram maps the flow of data in the application when a user sends an e-card to another mobile user.

In the send e-card module, the user has the ability to select a card from a list or thumbnail gallery. The information associated with the card (the card ID along with the customized message) is sent to the back end, where it is received by the server-side ASP script. When the server-side script receives the request, it first searches to see if the recipient’s e-mail ID matches any of the existing e-mail IDs in the database. If the search result is positive, then the server-side script adds this data to the recipient’s profile XML file. If the search is negative, the server-side script creates a new profile XML file and then adds the information to it.

Build the gallery list

This is very similar to the steps used to create the inbox list. The main difference is that the inbox lists the user’s profile XML data, which is populated with the e-cards that the user has received. The gallery is populated with data from the XML file that contains the list of available e-cards.

In the Timeline, select the frame labeled gallery. When you look at the Stage, you’ll see the movie clips displayed in a manner very similar to the movie clips used for the inbox section. To add the functionality for the gallery list, do the following:

Update the frame label gallery

  1. In the ActionScript layer, select the frame labeled gallery and add the following code:
    stop();
    var xmlFile:XML = new XML();
    xmlFile.ignoreWhite = true;
    var cards:Array = new Array();
    var labelname:Array = new Array();
    var timestamp:Array = new Array();
    var typename:Array = new Array();
    var sizename:Array = new Array();
    xmlFile.load(""+path+"/gallery_xml/catbirthday.xml");
    _root.messageEntered = "";
    xmlFile.onLoad = function(success) {
        var cardsGalleryArray:Array = this.firstChild.childNodes;
        for (i=0; i<cardsGalleryArray.length; i++) {
            cards.push(cardsGalleryArray[i].attributes.itemvalue);
    
        labelname.push(cardsGalleryArray[i].attributes.labelname);
            typename.push(cardsGalleryArray[i].attributes.type);
            sizename.push(cardsGalleryArray[i].attributes.size);
        }
        //Reverse the arrays
        cards.reverse();
        labelname.reverse();
        sizename.reverse();
        typename.reverse();
        maxLength = ((_root.scrollBar_mc.track_mc._height)-44);
        moveValue = (maxLength/(cards.length));
        select = 1;
        list1.gotoAndStop(2);
        loadMovie(""+path+"/thumbnails/"+cards[0]+".swf", "box1c");
    
        loadMovie(""+path+"/thumbnails/"+cards[1]+".swf", "box2c");
    
        loadMovie(""+path+"/thumbnails/"+cards[2]+".swf", "box4c");
        if (labelname[0] != undefined) {
            list1.secondLine = typename[0];
            list1.labelnameValue = labelname[0];
            list1.dateValue = sizename[0];
            lo1._visible = 1;
        } else {
            list1.secondLine = "";
            list1.labelnameValue = "";
            list1.dateValue = "";
            list1.gotoAndStop(1);
            lo1._visible = 0;
        }
        if (labelname[1] != undefined) {
            list2.secondLine = typename[1];
            list2.labelnameValue = labelname[1];
            list2.dateValue = sizename[1];
            lo2._visible = 1;
        } else {
            list2.secondLine = "";
            list2.labelnameValue = "";
            list2.dateValue = "";
            list2.gotoAndStop(1);
            lo2._visible = 0;
        }
        if (labelname[2] != undefined) {
            list0.secondLine = typename[2];
            list0.labelnameValue = labelname[2];
            list0.dateValue = sizename[2];
            lo4._visible = 1;
        } else {
            list0.secondLine = "";
            list0.labelnameValue = "";
            list0.dateValue = "";
            list0.gotoAndStop(1);
            lo4._visible = 0;
        }
        _root.lablenameValue = labelname[0];
            _root.activeItemValue = cards[0];
        _root.cardValue.text = ""+select+"/"+i+" cards";
    };
    stop();
  2. In the Content layer, select the frame labeled gallery. Create a simple button and place it on the Stage, but then drag it outside of the visible Stage area, just as you did on the inbox frame.
  3. In the ActionScript layer, select the frame labeled gallery and add the following code:
    on (keyPress "<Down>") {
        if (select<cards.length) {
            _root["list"+select%3].gotoAndStop(1);
            setProperty("scrollBar_mc/thumb_mc", _y,
        getProperty("scrollBar_mc/thumb_mc", _y)+moveValue);
            _root.select = select+1;
            if ((select%3) == 1) {
    
        loadMovie(""+path+"/thumbnails/"+cards[select-1]+".swf",
        "box1");
                list1.secondLine = typename[select-1];
                list1.labelnameValue = labelname[select-1];
                list1.dateValue = sizename[select-1];
                lo1._visible = 1;
                if (list1.labelnameValue == undefined) {
                    list1.labelnameValue = "";
                    list1.secondLine = "";
                    list1.dateValue = "";
                    lo1._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select]+".swf", "box2");
                list2.secondLine = typename[select];
                list2.labelnameValue = labelname[select];
                list2.dateValue = sizename[select];
                lo2._visible = 1;
                if (list2.labelnameValue == undefined) {
                    list2.labelnameValue = "";
                    list2.secondLine = "";
                    list2.dateValue = "";
                    lo2._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select+1]+".swf", "box3");
                list0.secondLine = typename[select+1];
                list0.labelnameValue = labelname[select+1];
                list0.dateValue = sizename[select+1];
                lo4._visible = 1;
                if (list0.labelnameValue == undefined) {
                    list0.labelnameValue = "";
                    list0.secondLine = "";
                    list0.dateValue = "";
                    lo4._visible = 0;
                }
            }
            _root["list"+select%3].gotoAndStop(2);
        }
        _root.lablenameValue = labelname[select-1];
        _root.activeItemValue = cards[select-1];
        _root.cardValue.text =
        ""+select+"/"+i+" cards";
    }
    on (keyPress "<Up>") {
        if (select>1) {
            _root["list"+select%3].gotoAndStop(1);
            _root.select = select-1;
            setProperty("scrollBar_mc/thumb_mc", _y,
        getProperty("scrollBar_mc/thumb_mc", _y)-moveValue);
            if ((select%3) == 0) {
    
        loadMovie(""+path+"/thumbnails/"+cards[select-1]+".swf", "box3");
                list0.secondLine = typename[select-1];
                list0.labelnameValue = labelname[select-1];
                list0.dateValue = sizename[select-1];
                lo4._visible = 1;
                if (list0.labelnameValue == undefined) {
                    list0.labelnameValue = "";
                    list0.secondLine = "";
                    list0.dateValue = "";
                    lo4._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select-2]+".swf", "box2");
                list2.secondLine = typename[select-2];
                list2.labelnameValue = labelname[select-2];
                list2.dateValue = sizename[select-2];
                lo2._visible = 1;
                if (list2.labelnameValue == undefined) {
                    list2.labelnameValue = "";
                    list2.secondLine = "";
                    list2.dateValue = "";
                    lo2._visible = 0;
                }
    
        loadMovie(""+path+"/thumbnails/"+cards[select-3]+".swf", "box1");
                list1.secondLine = typename[select-3];
                list1.labelnameValue = labelname[select-3];
                list1.dateValue = sizename[select-3];
                lo1._visible = 1;
                if (list1.labelnameValue == undefined) {
                    list1.labelnameValue = "";
                    list1.secondLine = "";
                    list1.dateValue = "";
                    lo1._visible = 0;
                }
            }
            _root.lablenameValue = labelname[select-1];
            _root.activeItemValue = cards[select-1];
            _root["list"+select%3].gotoAndStop(2);
            _root.cardValue.text = ""+select+"/"+i+" cards";
        }
    }
    on(keyPress "<Enter>"){    
        gotoAndStop("galleryview");
        }

    When the user presses the UP or DOWN key buttons on the handset, it causes the highlighted region to move up and down the gallery list. When the user presses the ENTER button, the e-card currently highlighted in the gallery list is selected is displayed (because the playback head jumps to the frame labeled galleryview in the Timeline).

  4. Select the frame labeled galleryview on the Content layer of the Timeline. You’ll load the video e-card to the video object on this frame, and the e-card is displayed when a user selects an e-card from the gallery list for preview before sending it to another user.
  5. Select the frame labeled loginview on the Content layer of the Timeline. When you look on the Stage, you’ll see a video object as well as a Replay button (see Figure 17).

    The frame labeled loginview contains the video object where the e-card will be previewed, along with a button that allows the user to replay the video if desired.

    Figure 17. The frame labeled loginview contains the video object where the e-card will be previewed, along with a button that allows the user to replay the video if desired.

Add interactivity to the send module

Next, you’ll add functionality to the gallery view, to allow users to select and preview the video e-cards they choose, before sending the e-card to another user.

To set up this functionality, do the following:

Update the frame label galleryview

  1. In the ActionScript layer of the frame labeled galleryview, add the following code:
    stop();
    pctLoaded =0;
    rewBut._visible = 0;
    falserewbut._visible = 1;
    var nc = new NetConnection();
    nc.connect(null);
    ns = new NetStream(nc);
    ns.onStatus = function(infoObject) {
        if (infoObject.level.toLowerCase == "error") {
            trace(infoObject.code);
        }
    };
    videoecard.attachVideo(ns);
    ns.play(""+path+"/cards/"+activeItemValue+".flv");
    var loaded_interval:Number = setInterval(checkBytesLoaded, 500, ns);
    function checkBytesLoaded(ns:NetStream) {
        var pctLoaded:Number =
        Math.round(ns.bytesLoaded/ns.bytesTotal*100);
        if (pctLoaded>=100) {
            rewBut._visible = 1;
            falserewbut._visible = 0;
            clearInterval(loaded_interval);
        }
    }
    rewBut.onRollOver = function() {
        _focusrect = false;
    };
    rewBut.onRelease = function() {
        ns.seek(0);
    };
  2. Add the feature to allow users to customize the messages that are sent along with the e-card videos.
  3. Select the frame labeled gallerycustomize on the Content Layer of the Timeline and add some text fields to allow the user to enter the recipient’s e-mail address and the custom message (see Figure 18).

    The frame labeled gallerycustomize contains text fields to enter the recipient's e-mail ID and to add a custom message that will accompany the e-card when it is sent

    Figure 18. The frame labeled gallerycustomize contains text fields to enter the recipient’s e-mail ID and to add a custom message that will accompany the e-card when it is sent

  4. Select the frame labeled gallerycustomize on the Content layer.
  5. Create three input text fields on the Stage and assign them the instance names: toname_txt, toemail_txt, and message_txt.
  6. Place a movie clip on the Stage that loads the thumbnail of the e-card the user is sending and assign the movie clip the instance name cardthumb.
  7. Add a button to the Stage and assign it the instance name submitBut.
  8. In the ActionScript layer, select the frame labeled gallerycustomize and add the following code:
    _focusrect = true;
    Selection.setFocus(toemail_txt);
    loadMovie(""+path+"/thumbnails/"+activeItemValue+".swf", "cardthumb");
    submitBut.onRollOver = function (){
            _focusrect = false;
    }
    submitBut.onRollOut = function (){
            _focusrect = true;
    }
    submitBut.onRelease = function (){
    toEmailID = toemail_txt.text;
    messageEntered = message_txt.text;
    }

After the user enters the recipient’s e-mail ID and custom message, he or she clicks the Submit button. This causes the playback head to jump to the frame labeled sending. The code on the sending frame sends the data to the server-side ASP script, which in turn updates the database and the recipient’s user profile XML file.

Update the frame label sending

In the ActionScript layer, select the frame labeled sending and add the following code:

errorCode ="";
lvobj = new LoadVars();
lvobj.labelname = lablenameValue;
lvobj.toEmail = toEmailID.toLowerCase();
lvobj.fromEmail = fromEmail.toLowerCase();
lvobj.message = messageEntered;
lvobj.cardID = activeItemValue;
lvobj.sendAndLoad(""+path+"/sendcard.asp", lvobj, "GET");
lvobj.onLoad = function() {
    if (this.errorCode>0) {
        gotoAndStop("sendingfail");
        } else {
        gotoAndStop("sentsuccess");
    }
}
init();

The frame labeled sending sends the user’s e-mail ID and password data to the sendcard.asp file, which verifies whether the e-mail ID and the password provided match any of the records that exist in the database. If the match is positive, the sendcard.asp file returns the error flag as 0 through the syntax errorFlag=0 and uses the unique file name from the user’s profile XML file to return it as nameFile=[unique file name].

If the sendcard.asp file does not find a matching record in the database, it returns the error flag as 1 in the syntax errorFlag=1. When the Flash client receives the error flag, the playback head jumps from the sending label to the frame labeled sentsuccess (indicating that the e-card was successfully sent) or to the frame labeled sendingfail (indicating that the attempt to send the e-card was unsuccessful).

A note about duplicate profiles

When a new user registers to begin using the application, an XML file is created and the database is updated with the user’s e-mail ID and password. Later, when a user sends an e-card to another user whose e-mail ID does not exist in the application, a profile is created for the recipient even if the recipient has not yet registered. So what happens in a scenario where a recipient’s e-mail ID was created in a profile (in order to send the e-card to them) and then later that same user logs into the application for the first time to create a profile so that she can send an e-card?

Will the user’s registration request be accepted because a profile already exists with the same e-mail ID? Will she receive an error?

To resolve this duplicate profile situation, the sendcard.asp file assigns a default password for the e-mail ID when the password data is not found. The sendcard.asp file adds this default password to the profile XML file that it creates for the recipient of the e-card message, if the recipient is not already registered in the system.

When you review the code in the sendcard.asp file, you’ll see that the default password uses this string of characters:

defaultpasswordset908###oiqkehjhe789254128992#

This long string of characters is used because it is very unlikely that a user of the application would choose the same password when she registers in the system. Theoretically, it is possible, but it is extremely unlikely. By assigning a very long string of random characters as the default password, you are basically eliminating the chance of an identical password being selected by a user attempting to register in the application.

When the default password is assigned, and the same user later visits the application to register their profile, the script compares the password entered by a new user to the default password. If the user’s password in her profile XML file matches the default password (which was set at the time another user sent them an e-card) the system can tell that registering user already has a profile XML file in the system, and determines that she still needs to choose a unique password to go with her e-mail ID. In this case, the new user can essentially re-register using her existing e-mail ID, by replacing the default password with the new password she enters during registration. This sneaky workaround ensures that duplicate profile XML files are not created, and also allows users who are in the system (as recipients) the ability to register as new users without an error occurring.

This little trick is not acceptable for a real-world production version of a mobile e-card application. However, for the purposes of building a working example of the project to learn how web-to-mobile applications are constructed, the scripts provided in the sample files include this workaround to avoid duplicity in registration.

At this point, you’ve finished building the application. Now you’re ready to run tests to see how the application performs and to check for any issues. To test the application, you can publish your e-card client (Control > Test Movie) and upload the SWF file to Device Central to see how it displays in the emulator. Alternately, you can upload the Flash client SWF file, the server files, and your FLV e-cards to a hosted server with a global IP address/domain name. If you’ve uploaded the application files to a server, you can test the application using a Nokia N95 handset that has GPRS support and Flash Lite Player 3 installed.

Where to go from here

The sample application described in this article illustrates a very basic way to create an e-card application in Flash Lite 3. You can use the provided sample files as the basis for your own application, which you could modify to add new functionality and increased security for use in a production scenario.

For example, you could add a Flash Media Server feature to stream the FLV files instead of using the progressive download method, because that approach would offer faster performance and make the distribution of the video e-cards more reliable. You could also add encryption at the server level to make user authentication process more secure.

Other ideas for updating this application include adding features such as reminders for forgotten passwords, the ability to delete the e-card from the inbox after viewing, and more robust gallery management to make the application easier to use. The possibilities are endless, and you are limited only by your imagination.

If you haven’t tried testing your mobile applications with Adobe Device Central yet, visit the Adobe Device Central resources page. You’ll find information about using the emulators in Device Central to preview your application before copying the SWF files to the actual mobile device.

Also, check out the Mobile & Devices Developer Center to find helpful articles, tutorials, and sample projects.

Here are some more helpful online resources for developing mobile content:

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.

About the author

Samir K. Dash is a systems consultant (creative content) for Enterprise System Solutions Pvt. Ltd., where he works on e-learning and interactive design using Flash technologies. Out of office he loves to spend his time with his wife, Sangeeta, and write poems.

About the Author:

Carlos Pinho
A father, a husband and a geek... Carlos was the founder of projects like The Tech Labs and Flash Enabled Blog. He is the founder of TekTuts He is passionate about technologies. Their main skills are in analytics, transport & logistics, business administration. He also writes about programming resources, trends, strategy and web development.