Creating a streaming MP3 player in WP7

I wrote a new article to Nokia Developer Wiki. In this article, I will show how you can create a streaming MP3 music player in Windows Phone 7. All the music files are stored in the server and are streamed to Windows Phone. Application first loads all the albums data from the server with JSON data. In server side, there are PHP script which loads ID3 tags from all the MP3 files and generates JSON string, which is returned to Windows Phone.

Latest, Favorite and Album songs are displayed in Panorama Page. User can play music in Player Page. This application uses Windows Phone Background Audio Agent to play MP3 music, so the music can be play in background like the original music player does in Windows Phone.

Net MP3 Player - latest song Net MP3 Player - Favorite songs Net MP3 Player - Albums
Net MP3 Player - Album songs Net MP3 Player

You can read whole article and download source code here: Streaming MP3 Player in WP7.

Picasa Image Gallery with JSON in WP7

I wrote a new article to Nokia Developer Wiki. In this article, I will show how you can access to your public and private image albums in Google Picasa (or albums which your friends has shared to you). Google offers many different ways to get image albums data, in this article I will cover JSON to get data from Google.

Windows Phone Application - MyPicasa Login Page Windows Phone Application - MyPicasa Albums Page Windows Phone Application - MyPicasa Album Page
Windows Phone Application - MyPicasa Images Page

You can read whole article and download source code here: Picasa Image Gallery with JSON in WP7

Namedays application available in Windows Phone Marketplace

I published Namedays application to Windows Phone Marketplace. This application show selected country's name days. Name days thought the year are visible in application and today's names are displayed in Live Tile. So it is really easy to see and remember if your friends has a name day.

There are 15 countries included: Austria, Czech, Finland, Finland Swedish, France, Germany, Hungary, Italy, Latvia, Poland, Slovak, Spain, Sweden, Uk and Usa.

Email me to get your country supported.

Here is a few screenshots:

Here is a few line in finnish: Lataa nimipäivät windows phone 7:lle tästä.

Nokia Developer Champion of the Month for March

I have been selected Nokia Developer Champion of the Month March - big thanks to Nokia Developer Champion program!

"Nokia Developer Champion Pasi Manninen shares his new Windows Phone skill in an award-winning series of Wiki articles. An independent publisher based in Jyväskylä, Finland, Pasi has successful titles in Nokia Store and Windows Phone Marketplace.

His Finnkino Elokuvat app in Windows Phone Marketplace allows users to see film times and movie trailers for the Finnkino Theatre chain in Finland. To create the app he loads and parses XML data from the theatre's web site, and he shares his techniques with the community. Pasi recently shared additional work he has done creating a Snake game and Weather Forecast app for Windows Phone 7.

As a Nokia Developer Champion since 2009, Pasi's creativity and willingness to share continue to inspire the entire developer community."

Snake game in Windows Phone 7

I wrote a new article to Nokia Developer Wiki. In this article, I will show how to create a simple Snake Game in Windows Phone. You can move snake to different direction with gestures. Game contains simple menu, game and complete Screens.

Snake Game in WP7

Weather Forecast in Windows Phone 7

I wrote a new article to Nokia Developer Wiki. In this article, I will show how to create Windows Phone application which loads Weather Forecast from World Weather Online 's XML service. You can add your own favourite cities to application and it will display weather forecasts in Panorama Views in Windows Phone application.

Weather Forecast Panorama Weather Forecast Panorama Weather Forecast Panorama Weather Forecast Panorama Weather Forecast Settings Page

You can read the whole article here: Weather Forecast in Windows Phone 7

More XML Based Articles in Nokia Developer Wiki: Movies in Finnkino Theatre’s

I wrote a new article to Nokia Developer Wiki. In that article, I will show how to create Windows Phone application which loads Movie's information from Finnkino's XML service. Loaded Theatre's and Movie's data will be parsed and displayed in a few different Pages in Windows Phone application.

Finnkino Elokuvat - Theatre Area List Finnkino Elokuvat - Theatre Shows Finnkino Elokuvat - Show Details

You can read the whole article here: Movies in Finnkino Theatre's

Edit: This article selected as a Featured Article of the Week (week 5 - January 29th 2012) in Nokia Developer Wiki.

Article in Nokia Developer Wiki: Employees from XML in WP7

I wrote a new article to Nokia Developer Wiki. In that article, I will show how to create Windows Phone application which loads Employee's information from server with XML data. Loaded Employees XML data will be parsed and displayed (image 1) in ListBox Control. Selected Employee's details will be shown in a new Employee Page (image 2). You can call, send SMS or Email messages to selected Employee.

Employees in ListBox Delails of the Employee Delails of the Employee

You can read the whole article here: Employees from XML in WP7

Edit: This article selected as a Featured Article of the Week (week 4 - January 22nd 2012) in Nokia Developer Wiki.

Flex 4.6 and SplitViewNavigator in AIR : Demo application – Finnkino Movies

Adobe Flex 4.6 includes several new and updated mobile-optimized Spark components (for example SplitViewNavigator, CallOutButton, SpinnerList, DateSpinner, Text Enhancements and ToggleSwitch).

In this example I used SplitViewNavigator to show Finnkino's Theatres in the first view of the SplitViewNavigator. Second view shows the selected Theatre's movies (what are running at this day) or all movies that are running in Finnkino's Theatres.

<s:SplitViewNavigator id="splitNavigator" width="100%" height="100%" autoHideFirstViewNavigator="true">
  <s:ViewNavigator id="areasView" width="200" height="100%" firstView="views.AreaCategory"/>
  <s:ViewNavigator id="detailView" width="100%" height="100%" firstView="views.MoviesTileView">
    <s:actionContent.portrait>
    <s:Button id="navigatorButton" label="Valitse Teatteri"
         click="splitNavigator.
         showFirstViewNavigatorInPopUp(navigatorButton);"/>
    </s:actionContent.portrait>
  </s:ViewNavigator>
</s:SplitViewNavigator>

Movies in Landscape mode

SplitViewNavigator is working very nicely and it hide's the first view in navigator when tablet is rotated to Portrait. You should add resize event handling to your application and use states in ActionContent in ViewNavigator.

<s:Application resize="resizeHandler(event);">
protected function resizeHandler(event:ResizeEvent):void {
  currentState = aspectRatio;
}
<s:states>
  <s:State name="portrait"/>
  <s:State name="landscape"/>
</s:states>

Movies in Portrait mode

List and ItemRenderers
I have used List to show all the movie items and own made ItemRenderer to display some basic information (or just movie image when all the movies are selected from the main list).

<s:List id="moviesList"
    dataProvider="{data}"
    itemRenderer="comps.MovieAreaTile"
    horizontalCenter="0"
    verticalCenter="0"
    width="100%" height="100%"
    contentBackgroundColor="#FFFFFF"
    change="moviesList_changeHandler(event)"
    >
  <s:layout>
    <s:TileLayout id="tileList"
     paddingLeft="5" paddingRight="5" paddingTop="5" paddingBottom="5" horizontalGap="5" verticalGap="5"
    columnAlign="justifyUsingWidth"
   />
  </s:layout>
</s:List>
// MovieAreaTile
<s:HGroup>
  <s:Image source="{data.Images.EventSmallImagePortrait}" />
  <s:VGroup>
    <s:Label id="title" styleName="title" text="{data.Title}" />
    <s:Label id="startTime" styleName="data" text="{data.dttmShowStart}" />
    <s:Label id="length" styleName="data" text="{data.LengthInMinutes} min" />
    <s:Label id="theatre" styleName="data" text="{data.TheatreAndAuditorium}" />
    <s:Label id="genre" styleName="data" text="{data.Genres}" />
  </s:VGroup>
</s:HGroup>

All the Movies in Finnkino's Theatres

SQLite: Automatically display same Theatre which was used in previous time
In this example I store theatreID and theatreName to SQLite database every time when a new Theatre is selected. Those values are used when application is started again.

Connection to database:

private function connect(type:Number):void {
  dbConn = new SQLConnection();
  if (type == CREATE_DB) dbConn.addEventListener(SQLEvent.OPEN, createTable);
  else dbConn.addEventListener(SQLEvent.OPEN, getTheatreData);
  dbConn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
  dbConn.openAsync(dbFile);
}

Create a table:

private function createTable(event:SQLEvent):void {
  var dbStatement:SQLStatement = new SQLStatement();
  dbStatement.sqlConnection = dbConn;
  dbStatement.addEventListener(SQLEvent.RESULT, theatreTableCreated);
  dbStatement.addEventListener(SQLErrorEvent.ERROR, errorHandler);
  dbStatement.text = "CREATE TABLE IF NOT EXISTS movieTable (id INTEGER PRIMARY KEY AUTOINCREMENT, theatreID TEXT, theatreName TEXT);";
  dbStatement.execute();
}

Table is created a first time -> add some sample data to table

private function theatreTableCreated(event:SQLEvent):void {
  var dbStatement:SQLStatement = new SQLStatement();
  dbStatement.sqlConnection = dbConn;
  dbStatement.addEventListener(SQLEvent.RESULT,theatreDataAdded);
  dbStatement.addEventListener(SQLErrorEvent.ERROR,errorHandler);
  // just set default data when table is created
  theatreID = 1015;
  theatreName = "Jyväskylä";
  dbStatement.text = "INSERT INTO movieTable (theatreID, theatreName) VALUES('"+theatreID+"','"+theatreName+"');";
  dbStatement.execute();
}

Theatre (id and name) data is added first time, load events with HTTPService

<fx:Declarations>
  <s:HTTPService id="finnkinoArea" showBusyCursor="true" url="{url}"
      result="areaHandler(event)"
      fault="areaFaultHandler(event)"
   />
</fx:Declarations>

private function theatreDataAdded(event:SQLEvent):void {
  loadEvents(theatreID);
}

private function getTheatreData(event:SQLEvent):void {
  var dbStatement:SQLStatement = new SQLStatement();
  dbStatement.sqlConnection = dbConn;
  dbStatement.addEventListener(SQLEvent.RESULT,theatreResult);
  dbStatement.addEventListener(SQLErrorEvent.ERROR,errorHandler);
  dbStatement.text = "SELECT theatreID, theatreName FROM movieTable where id=1";
  dbStatement.execute();
}

TheatreID and name is loaded from SQLite, start loading XML data from Finnkino's service

private function theatreResult(event:SQLEvent):void {
  var dbResult:SQLResult = SQLStatement(event.target).getResult();
  theatreID = dbResult.data[0].theatreID;
  theatreName = dbResult.data[0].theatreName;
  // load previous used theatre
  loadEvents(theatreID);
}
public function loadEvents(theatreID:uint):void {
  // one Teatre
  if (theatreID != -1) url = urlBase + theatreID;
  // all events from Finnkino
  else url = "http://www.finnkino.fi/xml/Events/";
  // call HTTPService
  finnkinoArea.send();
}

Movie Details
Movie details are shown when user clicks MovieTile from TileView. Finnkino's Service offers a lot of information about the movie. In this example I only display some sample data and movie trailer. Movie trailer can be played in fullscreen mode too (use this only in Landscape - there a some issues in portrait mode - in this example :-)

<s:Scroller width="100%" height="100%">
  <s:VGroup width="100%">
    <s:HGroup>
      <s:Image source="{data.Images.EventLargeImagePortrait}" />
      <s:VGroup>
        <s:Label text="{data.Title} ({data.OriginalTitle})" styleName="title"/>
        <s:Label text="{data.RatingLabel}" styleName="data" />
        <s:Label id="startTime" styleName="data" text="{data.dttmShowStart}" />
        <s:Label id="length" styleName="data" text="{data.LengthInMinutes} min" />
        <s:Label id="genre" styleName="data" text="{data.Genres}" />
        <s:Label id="showUrl" styleName="dataBlue" text="{data.ShowURL} - (osta liput)" click="showUrl_clickHandler(event)" />
        <s:Label id="eventUrl" styleName="dataBlue" text="{data.EventURL} - (lisätietoa elokuvasta)" click="eventUrl_clickHandler(event)" />
     </s:VGroup>
   </s:HGroup>
   <s:Label text="{movieData.Synopsis}" width="100%" styleName="synopsis" />
   <s:VideoPlayer id="myVideo" source="{movieData.Videos.EventVideo.Location}" autoPlay="false" visible="{isVideo}" width="{this.width-20}"/>
   <s:Button label="Takaisin" id="takaisin" click="takaisin_clickHandler(event)"/>
   </s:VGroup>
</s:Scroller>

Movie details in Landscape mode

Movie details in Portrait mode

Movie trailer in fullscreen

Source codes
- Movies.fxp, Movies.zip

Note
There are a few bugs in this example (too). Sometimes the date is missing from first views, and VideoPlayer is messing up if it is in fullscreen mode in Landscape and you turn the device to portrait.. but now it is working for my purposes :-) and finally I have only tested this in Samsung Galaxy Tab 10.1 not in mobile...

This example uses Finnkino's Services

Developing AIR application to run in different screen sizes

A few days ago I got Samsung Galaxy S 2 and Tab 10.1 in my hands and I want to test how to make an AIR application that runs in both of these (with different screen sizes). This demo application uses SQLite database to collect information about Interesting Places (place information and picture).

I decided to make mobile application with s:Application and first test is application running in mobile or tablet. After that different states are used in s:ViewNavigator to launch MainPhoneView or MainTabletView view depending on used device (mobile or tablet). (Michael Chaize has wrote excellent article about Adaptive UI: Mobile vs. Tablet).

<s:ViewNavigator
  id="mainNavigator"
  left="0" top="0"
  right="0" bottom="0"
  firstViewData="{places}"
  firstView="views.MainPhoneView" firstView.tablet="views.MainTabletView"
  resize="mainNavigator.scrollRect = new Rectangle(0, 0, mainNavigator.width, mainNavigator.height)">

MainPhoneView
MainPhoneView
draws PlaceList component (which is used in the left side of MainTabletView view also) which displays some already embeded Interesting Places from SQLite database (title and time) by default. PlaceView is opened when users clicks PlaceList item and place information data is show with PlaceComp component (which is used in the right side of MainTabletView view also). Sample SQLite database is embeded into Flex Project.

<comps:PlacesList id="placesList"
  places="{data}"
  width="100%" height="100%"
  click="placeslist1_clickHandler(event)"/>


MainTabletView

MainTabletView holds Placelist and PlaceComp components in a same view in tablet. So there are not View changes in tablet version of this application. All needed information can be show in one View.

<s:HGroup width="100%" height="100%">
  <comps:PlacesList id="placesList" places="{data}"
	width="33%" height="100%" click="placesList_clickHandler(event)">
  <comps:PlaceComp id="place" width="67%">
<s:HGroup>


Add Place

User can write some lines from interesting place and take one picture. All of these information are saved into SQLite database. Same component are used in mobile and tablet view.

Conclusion
Using your own made components in different views helps application development into different screen sizes. This is working quite a nicely in AIR development. Like in this small example same components are used in Tablet and Mobile views to build this example.

Files
- MobileInterestingPlaces.apk
- MobileInterestingPlaces.fxp

Note
There are a few bugs and limitations in this example.. I did this just for a testing purposes :-)