Tag Archives: PTM

TeamTool – Flash Lite Mobile Communication Application

TeamTool is a concept application for promoting collaboration and handling communication between team members. Apart from bringing an unique all-in-one tool for team communication, TeamTool bridges the team members' social location with their physical location using mobile GPS capabilities.

TeamTool - Loading

TeamTool - Loading

Registered users can send messages to team members and add landmarks to TeamTool server. Landmarks are one of the biggest features in TeamTool. User can write text, take picture, record audio and take video (or select earlier taken materials from phone - TeamTool materials), and set all of these media to landmark with GPS information. Created landmark can be send to TeamTool server and it is available to all TeamTool members. Members and landmarks are sorted with distance data, so user can easily see which team members or stored landmarks are the nearest to users current location.

TeamTool - Menu

TeamTool - Menu

TeamTool is designed to run in mobile phones which has 640x360 display and Flash Lite 3.1 Player or newer installed. TeamTool is tested with Nokia 5800 xpressmusic with the latest firmware and updated Flash Lite 3.1 Player. TeamTool is my entry (with Mobiletools' and JAMK University of Applied Sciences) to Forum Nokia Calling All Innovators Competition 2009 and Adobe MAX 2009 Awards Mobile category.

See more: TeamTool.

Contacts Demo – S60 Platform Services API example with Flash Lite

Here is my first Nokia S60 Platform Services API test with Adobe Flash Lite. This demo is designed to run 360x640 screens (like Nokia 5800 and N97). Application first loads contacts name, phone number, work and home addresses and shows all informations nicely in interactive scrollable menu.

Contacts Demo scr 1 Contacts Demo scr 2

  1.  
  2. // create contacts service object
  3. var contact = new Service("Service.Contact","IDataSource");
  4. var inParams = {Type:"Contact"};
  5. // get contacts from phone
  6. var outParams = contact.GetList(inParams);
  7. if (outParams.ErrorCode == 0) {
  8. var outList = outParams.ReturnValue;
  9. var outputEntry = null;
  10. var i:Number = 0;
  11. var step:Number = 40;
  12. do {
  13. outputEntry = outList.next();
  14. if (null != outputEntry) {
  15. // add a new contact to container list
  16. i++;
  17. var mc:MovieClip = container_mc.attachMovie("ContactItem","Contact"+i,
  18. container_mc.getNextHighestDepth());
  19. container_mc.addMC(mc);
  20. container_mc["Contact"+i].init(outputEntry, container_mc, i,
  21. contactheader_fmt, contactdata_fmt);
  22. container_mc["Contact"+i]._y = (i-1)*step;
  23. } else { break; }
  24. } while (true);
  25. // show contact list
  26. gotoAndStop("show");
  27. } else {
  28. info_txt.text = outParams.ErrorCode;
  29. }

Details of contact information are displayed when user presses contacts name. Multiple contacts can be open at the same time. If contact has work or home address, this demo applications can load static JPG from Google Maps to show address in a map.

Contacts Demo scr 2 Contacts Demo scr 3

  1.  
  2. // data objects to server and back
  3. var sendDataLV:LoadVars;
  4. var loadDataLV:LoadVars;
  5. // show map loading info to user
  6. var info_mc:MovieClip;
  7.  
  8. //start loading request
  9. function showInMap(street:String,city:String,country:String):Void {
  10. sendDataLV = new LoadVars();
  11. loadDataLV = new LoadVars();
  12. info_mc = _level0.attachMovie("info","info_mc",
  13. _level0.getNextHighestDepth());
  14. info_mc._x = 5;
  15. info_mc._y = 70;
  16. loadDataLV.onLoad = latLonLoaded;
  17. sendDataLV.address = street+" "+city+" "+country;
  18. _level0.info_mc.text_txt.text += "street : " + street + "\n";
  19. _level0.info_mc.text_txt.text += "city : " + city + "\n";
  20. _level0.info_mc.text_txt.text += "country : " + country + "\n";
  21. // send lat and lng request to server
  22. sendDataLV.sendAndLoad(phpUrl,loadDataLV,"POST")
  23. _level0.info_mc.text_txt.text += "Get lat and lng...\n";
  24. back_mc._visible = true;
  25. }
  26.  
  27. // lat and lng returned from server
  28. function latLonLoaded(ok:Boolean):Void {
  29. if (ok) {
  30. if (loadDataLV.latitude != undefined &&
  31. loadDataLV.longitude != undefined) loadMap();
  32. else _level0.info_mc.text_txt.text += "No Lat and Lng!\n";
  33. } else {
  34. loadDataLV = null;
  35. sendDataLV = null;
  36. _level0.info_mc.text_txt.text += "Can't connect server to get Lat and Lng!\n";
  37. }
  38. }
  39.  
  40. // start loading map from Google
  41. function loadMap():Void {
  42. // show info
  43. _level0.info_mc.text_txt.text += "Loading map...\n";
  44. _level0.info_mc.text_txt.text += "Latitude: "+loadDataLV.latitude+"\n";
  45. _level0.info_mc.text_txt.text += "Longitude: "+loadDataLV.longitude+"\n";
  46. // map size
  47. var mapWidth = 350;
  48. var mapHeight = 520;
  49. // lat and lng
  50. var lat = loadDataLV.latitude;
  51. var lng = loadDataLV.longitude;
  52. var apiKey = 'API_KEY';
  53. // JPG loader
  54. var loader:MovieClipLoader = new MovieClipLoader();
  55. // url
  56. var mapUrl:String = 'http://maps.google.com/staticmap?center=' +
  57. lat + ',' + lng + '&format=jpg&zoom=15&size=' +
  58. mapWidth + 'x' + mapHeight + '&key=' + apiKey +
  59. "&markers="+lat+","+lng+","+"greena";
  60. // start map load
  61. loader.loadClip(mapUrl, _level0.info_mc.map_mc);
  62. _level0.info_mc.text_txt.text += "Loading, please wait...\n";
  63. }

Contacts Demo scr 4 Contacts Demo scr 5

Look more detailed informations in source codes:
- ContactsDemo_PTM.zip (include CS4 FLA, AS class files and PHP files)
- ContactsDemo_PTM.zip (includes only CS3 FLA):
- ContactsDemo.fla
- Contact.as
- Menu.as
- and a few PHP files to get Lat and Lng values from Google Maps.

Testing Adobe Mobile Packager with Distributable Player Solution

Flash Lite Distributable Player Solution

Adobe Flash Lite 3.1 Distributable Player Solution is now public and available on Adobe labs. The distributable player solution enables developers to create rich applications for the latest version of Adobe® Flash Lite™ and directly distribute their content to millions of open OS smartphones, providing a better on-device user experience. With this solution you can be confident that your users’ devices will always have the latest Flash Lite runtime. Unfortunately this solutions works only now over the air in selected coutries: India, Italy, Spain, UK, and the U.S. (why not in Finland too) and small set of supported S60 and Windows Mobile Devices. There are also number of content providers offering paths to market your applications.

Installing Adobe Mobile Packager

Adobe Mobile Packager is Windows desktop applications tool, which can package your SWF and other materials into a SIS and CAB file. When user installs your SIS or CAB file to mobile, the Flash Lite 3.1 Distributable Player will be automatically installed if required. Now (for unsupported countries like here in Finland) we have to install FL3.1 Distributable Player manually to local phone to test own made packages.

1. Download Adobe Mobile Packager from Adobe Labs
2. Run Adobe Mobile Packager
2.1 You can use Download SDK links (in the right side of window) to get needed SDK installer files to your computer
3. Installing CAB SDK
3.1 Download the Windows Cab SDK
3.2 Unpack it into C:\Program Files\Adobe\Adobe Mobile Packager\cabsdk
3.3 Add C:\Program Files\Adobe\Adobe Mobile Packager\cabsdk\bin to the user PATH
4. Installing Active Perl
4.1 Download Active Perl and install it to your computer (for example c:\Perl)
4.2 Add C:\Perl\bin to the user PATH
5. Installing Symbian SDK
5.1 Download Symbian SDK 3rd Edition(262MB) and install it

Now all should be done and you can restart your Adobe Mobile Packager.

Adobe Mobile Packager

Creating a new Package:
1. Create a simple Flash Lite Application with Flash
1.1 I created a small test application which displays version number of Flash Lite Player to textfield
1.2 You can download sources and other files here: vChecker.zip
2. Fill the Adobe Mobile Packager Form with your own data
3. Create Package

Here is screenshot what I have done here:

Adobe Mobile Packager

First I tested vChecker.swf in Nokia E51 (which has Flash Lite 2.0 Player preinstalled) and it showed that the Flash Lite Player version is FL7,1,90,9 (FL 2.0 player).  Then I installed manually Adobe Distributable Player from Adobe Labs to E51 and installed just created SIS-file to phone. After running my little application it showed that it uses Flash Lite Player version AFL 9,1,120,0 (Flash Lite 3.1 Distributable Player).

So it seems to work as expected, hope Finland is listed in supported coutries soon. If you are in supported countries, can you write some comment here how it works for you!

More info: Flash Lite Distributable Player tutorials on Adobe TV

I’m now Adobe Community Expert

Adobe Community Expert

I'm really happy to be selected for the Adobe Community Experts (Mobile and Devices) program. I *really* want to say thanks all of you Flash Lite folks over there about your support and feedback what you have given to me in past years about my journey with Flash Lite (specially to Bill Perry who made this happen to me).

I want to be more active here in my blog..., now I have been working really hard (in the evenings) with mobiletools M-Kit eLearning Flash Lite application which is now a quite good with supporting different screen sizes and screen rotations and so on with dynamic data (texts, images, videos, swf learning materials, quizes, ...). Hope you can see this application some day.

One more thing - I will get Nokia 5800 in a few days and I will start to make test with Services API then, so stay in tune for a new demos and source codes!

SWF2NFL – Application for packaging Flash Lite apps to Series 40 Devices

Dale has released an AIR application that allows you to create NFL files for Nokia Series 40 devices. SWF2NFL application is really easy to install directly from Moket's site. Application is also really easy to use, just drop your SWF content folder and icon to application and press Build - and that is all, your NFL file is ready.

I tested it to my old Flash Lite project - qTile.
You can download qTile.nfl for Nokia Series 40 here.

qTile for Nokia Series 60 devices

Nokia N95 firmware v30.0.015 and Flash Lite

I tested new Nokia N95 v30.0.015 firmware with KuneriLite Accelerometer plugin. In v21.0.0.16 there was problems with socket connections. LoadVars connection took then about 1 second with KuneriLite Accelerometer plugin in Flash Lite 3.0 Player (and it hangs UI drawing also for same time). Now in new firmware LoadVars calls seems to take same time but UI doesn't hangs anymore.

v30.0.015 firmware

One another note is that now playing streaming video with Flash Lite 3.0 doesn't rotate Flash Lite application to landscape automatically - great!

Testing KuneriLite plugins part three: Take, play and send video file from Flash Lite to server

In my earlier Flash Lite article I've tested KuneriLite Camera plugin to take picture (klMode=picture). This time I've it's video support (klMode=video) to record video and store it to mobile phone. I've modified my ActionScript source code a little and it worked very nicely on the Nokia N95. This Flash Lite test application sends videos to my server http://ptm.fi/temp/videos folder, so check you uploaded videos from there.

PTM Video pic 1 PTM Video pic 2 PTM Video pic 3

Setting up system
This time I've tested KuneriLite wizard in Microsoft Vista. I've installed Active Perl and Symbian S60 3rd edition SDK Maintenance Release as I did earlier in my Camera and Upload plugins -article. I had to make small modifications to get KuneriLite Wizard working on vista. You can find these modifications on the KuneriLite Wiki: Microsoft Vista Support.

Flash Lite application
The idea of this application is take video, play it to user and send it to a remote server (if the user wants to send it). All the ActionScript code is written to first frame of timeline. I'll describe here only needed lines to understand how to take, show and send video file to the remote server. Please see the FLA source code for more information.

Initialize application
There is one major bug in my previous example with taking picture, have you noticed it? I haven't thought on the situation where a user start to take picture and then press back when Kuneri Lite Camera plugin is active. The application is trying to make a thumbnail picture, which fails if there is no picture taken. In this video example this situation is handled with Camera plugin Status operation (klStatus).

A few variables are defined to handle video filename and KuneriLite plugin gateway errors.

var vidName:String = "";          // video name
var klError:Number = -99;         // klError number
var klStatus:String = "";         // klStatus string
var process:Number = 0;           // process number
var intervalId:Number;            // interval number
var path:String = "\\Data\\Others\\Trusted\\PTMVideo\\";

Preparing Camera
KuneriLite offers optional prepare command which prepares the camera resource and checks the presence of camera device. I'll check this first and let then user take video.

// check camera condition
process = 1;
intervalId = setInterval(checkProcess,1000);
status_txt.text = "status: preparing camera...";
loadVariables("http://127.0.0.1:1001/Basic/camera?
               klCommand=prepare&klIndex=0","");

Taking video
This stage is very similar to the sending picture example from the previous article. The only visible modification is with Video instance. I’ve added one video symbol to the library and dragged it to the timeline (instance name is video). When a user presses the device’s number one key, KuneriLite uses loadVariables()-function to call Camera plugin in order to take video. Here I just take a full size video with main camera.

//Take video
function takeVideo(){
  // videoname
  vidName = giveDateAndTimeString();
  var command:String = "";
  command += "http://127.0.0.1:1001/Basic/camera?klCommand=start";
  command += "&klMode=video";
  command += "&klPath="+path+vidName+".3gp";
  command += "&klSize=full";
  command += "&klIndex=0";
  status_txt.text = "status: taking video...";
  process = 2;
  klError = -99;
  intervalId = setInterval(checkProcess,1000);
  loadVariables(command,"");
}

Did user take video or not
As I wrote earlier, I didn’t check if the user had taken a picture in my previous example. Here I will do it after the video screen is closed in KuneriLite plugin. I have one function which checks processes to see what had happened in my application. When Kuneri Lite Camera plugin is closed, I’ll start to check if there’s a video file taken or not.

// .. part of my prosess function
// check if video is taken
case 2:
  if (klError == -99) return;
  clearInterval(intervalId);
  if (klError == 0) {
    status_txt.text += "done!";
    intervalId = setInterval(checkVideo,2000);
  }
  process = 0;
  break;
//check is video taken
function checkVideo() {
  clearInterval(intervalId);
  var command:String = "http://127.0.0.1:1001/Basic/camera?klCommand=status";
  status_txt.text = "status: checking video...";
  process = 3;
  klError = -99;
  klStatus = "";
  intervalId = setInterval(checkProcess,1000);
  loadVariables(command,"");
}

If video is available, just start to play it.

// .. part of my prosess function
// is videofile available
case 3:
  if (klError == -99) return;
  clearInterval(intervalId);
  if (klError == 0) {
    status_txt.text += "done!";
    if (klStatus == "complete") {
      intervalId = setInterval(playVideo,2000);
    } else if (klStatus == "exit") {
      status_txt.text = "status: No video!";
    }
  } else {
    status_txt.text = "status: klError = "+klError;
  }
  process = 0;
  break;

Play video
After video is taken, it will be showed to user with video instance.

// Load and play video
function playVideo(){
  clearInterval(intervalId);
  status_txt.text = "status: playing video...";
  video.play(vidName+".3gp");
}

video.onStatus = function(info){
  if (info.code=="completed") status_txt.text += "done!";
}

Sending video file to remot server
Sending is handled the same way I used in my photo example. I added upload status checking to this example. First video will be sent to server and uploading is checked with own made checking function

function checkUploading() {
  clearInterval(intervalId);
  var command:String = "http://127.0.0.1:1001/Basic/uldl?klCommand=status";
  command += "&klTrId=1234";
  process = 5;
  klError = -99;
  klStatus = "";
  intervalId = setInterval(checkProcess,1000);
  loadVariables(command,"");
}

and process function is checking what is going on with uploading. KuneriLite sends a few different status, I used only two of them: complete if uploading is successfully completed or failed if there where some problems.

case 5:
  if (klError == -99) return;
    clearInterval(intervalId);
    if (klError == 0) {
      status_txt.text = "status:" +klStatus;
      if (klStatus == "complete" || klStatus == "failed") {
        process = 0;
      } else {
        intervalId = setInterval(checkUploading,1000);
      }
    } else {
      status_txt.text = "status(5): klError = "+klError;
      process = 0;
    }
  break;

Source and SIS files
This application is designed to run 240×320 screens and for testing purposes only. It uses KuneriLite’s default generated SIS package, so if you have my other examples installed you have to remove these first.

Sources: PTMVideo.zip (Flash Lite 2.0 Application)
SIS: PTMVideo_3rd_edition_signed.sis (install it to memory card!)

Feel free to try this example and send video greetings to me with Flash Lite!

Note! I have 20MB upload limit per file with PHP at my server, so dont take too long videos!

Image Gallery with Flex, PHP and MySQL

There are many Image Galleries available on web, but time to time I want to make one of me own. This time I used Flex, PHP and MySQL. I found one excellent Flex Component from Doug McCune - CoverFlow Component and created my Image Gallery Menu with it.

Image Gallery Menu

Selected gallery is displayed with own state in Flex, thumbnails and image information are displayed in bottom of the screen.

Image Gallery Pictures

New galleries can be uploaded to server with Admin tool. Admin tool sends gallery information to PHP which adds gallery information to MySQL table. After gallery is initialized, all selected pictures will be send to server and thumbnails will be generated with PHP.

Image Gallery Admin

Here are sources and installation instructions:

1. MySQL tables
- create following tables
- if you change table names, edit PHP-files also

mysql> describe ptm_imagegallery;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| gallery_ID  | int(11)      | NO   | PRI | NULL    | auto_increment |
| name        | varchar(50)  | YES  |     | NULL    |                |
| description | varchar(100) | YES  |     | NULL    |                |
| date        | date         | YES  |     | NULL    |                |
| password    | varchar(45)  | NO   |     |         |                |
| count       | int(11)      | YES  |     | NULL    |                |
| size        | int(11)      | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

mysql> describe ptm_imagegalleryimages;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| image_ID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| gallery_ID | int(11)     | YES  |     | NULL    |                |
| filename   | varchar(30) | YES  |     | NULL    |                |
| date       | date        | YES  |     | NULL    |                |
| width      | int(11)     | YES  |     | NULL    |                |
| height     | int(11)     | YES  |     | NULL    |                |
| views      | int(11)     | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

2. PHP files
- copy PHP files to your server and edit needed MySQL variables

3. Flex project
- edit and compile Flex sources, use your own domain and path's

You can test my Image Gallery here:

PTM Image Gallery

Testing KuneriLite plugins part two: Accelerometer plugin

I want to test N95 Accelerometer and I installed Nokia N95 Accelerometer plugin package and made a small test with KuneriLite Accelerometer plugin. After a few test I noticed that getting a new axis values takes around one second. Oh it is ok I think but finally I noticed that all redrawing of the UI is hang also for a second. I have installed a new firmware to my N95 with Flash Lite 3.0 Player, which seems to have XML Socket bug and very slow. You can read more from Forum Nokia thread and Kuneri bloggy.

Like you can see at below picture, calling XML Socket in KuneriLite Accelerometer plugin in Flash Lite 3.0 Player takes about 1 second, and it hang UI drawing also to same time.

True and sad :-(

Edit:
Getting a new axis values:
- Nokia N95 (V 21.0.0.16, Flash Lite 3.0 Player) about 1101 ms. (left)
- Nokia N95 (V 20.0.015, Flash Lite 2.0 Player) about 100 ms. (right)

PTM Accel Pic 1 PTM Accel Pic 2

Sources: PTMAccel.zip (Flash Lite 2.0 Application)
SIS: PTMAccel_3rd_edition_signed.sis (install it to phone memory)

Testing KuneriLite plugins part one: Camera and Upload plugins

Finally I got time to test KunerLite plugins. They have done 11 nice plugins to extend Flash Lite applications. Now I am going to test a few of them and write some lines here in my blog.

My first test is to do Flash Lite application which takes pictures and sends those to server side. This testing application sends pictures to my server http://ptm.fi/temp folder, so check you uploaded photos from there.

PTM Camera pic 1 PTM Camera pic 2 PTM Camera pic 3

Setting up system
I recently reinstalled Windows again, so I have to install Active Perl and Symbian S60 3rd edition SDK Maintenance Release back to my computer to get KuneriLite working. You can find all necessary information’s from KuneriLite Wizard Beginner's Guide (they have done excellent wiki for you which helps setting up KuneriLite to your computer). After Perl and S60 SDK is ready in your computer, you have to install KunerLite, you can download free Basic version from Kuneri’s web site.

Flash Lite application
The idea of application is to take picture and send it to server side. I decided to program Flash Lite 2.0 application because I don’t want to mess with old Flash Lite 1.1 code anymore :-) . All code is written to first frame of timeline, I will describe here only needed lines to understand taking and sending picture to server side. Please see source code for more information.

Initialize application
A few variables are defined to handle picture name and KuneriLite plugin gateway errors. I have made small delays between taking/storing picture, making thumbnail and loading thumbnail because you have to wait a little time to get picture ready to resize or loading. These processes are handled with process and intervalId variables and setIntervals. Pictures and thumbnails are stored in application installation directory.

var picName:String = "";
var klError:Number = -99;
var process:Number = 0;
var intervalId:Number;
var path:String = "\\Data\\Others\\Trusted\\PTMCamera\\";

Taking picture
When user press mobile phones number one key, a new mc is created to store and show picture’s thumbnail. KuneriLite uses loadVariables()-function to call Camera plugin to take picture. You can find more information about Camera plugin from their web site. Here I just take full size picture with main camera.

/* take picture */
function takePicture(){
  // create new mc to display new image
  if (image_mc != undefined) {
    removeMovieClip(image_mc);
    picture_txt.text = "";
  }
  this.createEmptyMovieClip("image_mc",this.getNextHighestDepth());
  image_mc._x = 40; image_mc._y = 105;
  picName = giveDateAndTimeString();
  var command:String = "";
  command += "http://127.0.0.1:1001/Basic/camera?klCommand=start";
  command += "&klMode=picture";
  command += "&klPath="+path+picName+".jpg";
  command += "&klSize=full";
  command += "&klIndex=0";
  status_txt.text = "status: taking picture...";
  bottom_mc.image_txt.text = "";
  process = 1; klError = -99;
  loadVariables(command,"");
}

Making thumbnail and show it to user
After picture is taken it will be resized and loaded to Flash Lite application. You can resize pictures with KuneriLite Camera plugin and load pictures with MovieClipLoader.

/* make thumbnail */
function resizePicture() {
  clearInterval(intervalId);
  var command:String = "";
  command += "http://127.0.0.1:1001/Basic/camera?klCommand=resize";
  command += "&klPath="+path+picName+".jpg";
  command += "&klSize=160*120";
  command += "&klTargetFile="+path+picName+"_thumb.jpg";
  status_txt.text = "status: resizing picture...";
  process = 2; klError = -99;
  loadVariables(command,"");
}

/* load picture */
var mcLoader:MovieClipLoader = new MovieClipLoader();
mcLoader.addListener(this);
function loadPicture(){
  clearInterval(intervalId);
  status_txt.text = "status: loading thumbnail...";
  mcLoader.loadClip(picName+"_thumb.jpg",image_mc);
  picture_txt.text = picName+".jpg";
}

function onLoadError(mc:MovieClip) {
  status_txt.text = "status: error loading thumbnail!";
}

function onLoadComplete(mc:MovieClip) {
  status_txt.text += "done!";
}

Sending original picture to server side
Sending is very similar process, just call KuneriLite Upload plugin and it sends picture to server. In server side you have to use for example PHP to get and store picture (you can find example PHP code from Kuneri’s web site). Remember give write permission to folder where images will be uploaded.

/* send picture */
function sendPicture(){
  var command:String = "";
  command += "http://127.0.0.1:1001/Basic/uldl?klCommand=upload";
  command += "&klTrId=1234";
  command += "&klUrl=http://www.ptm.fi/flashlite/kuneri/getImage.php";
  command += "&klFile="+path+picName+".jpg";
  command += "&klType=image/jpeg";
  status_txt.text = "status: sending picture...";
  process = 3; klError = -99;
  loadVariables(command,"");
}

There are also function which handles user interactivity with mobile keys and function which just check processes what is happening in Flash Lite application and updates dynamic status textfield. Please see those in source codes.

Creating SIS-file
You can create SIS file with KuneriLite Wizard. It is very easy process – create project, select plugins, add files to your project and finally create SIS file. I have made own cer and key files with makekeys command. More info to sign SIS files can be found for example from Adobes site.

Creating SIS file

Source and SIS files
This application is designed to run 240x320 screens and for testing purposes only. It uses KuneriLite’s default generated UID in SIS package.

Sources: PTMCamera.zip (Flash Lite 2.0 Application)
SIS: PTMCamera_3rd_edition_signed.sis (install it to phone memory)

It is amazing easy to do this kind of application with KuneriLite plugin’s, thanks to all KuneriLite team members!