[Windows 8] How to launch an app using NFC tags?

May 6th, 2013 | Posted by Tom in .NET | Article | Windows 8 | WinRT - (0 Comments) | Read: 285

Here is a quick (but quite useful) tip for anyone who want to use NFC tags on its application.

NFC tags can be used on Windows (Phone) to open Internet links but they can also be used to open a particular application on your system.

For that, you just need to use/create a LaunchApp message that will be written on the tag:

var proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();
if (proximityDevice) {
    proximityDevice.ondevicearrived = function(device) {
        var launchArgs = "user=Thomas LEBRUN";

        // Package.manifest -> View XML Source -> <Application Id="...">
        var appId = "App";

        var appName = Windows.ApplicationModel.Package.current.id.familyName + "!" + appId;

        var launchAppArgs = launchArgs + "\tWindows\t" + appName;

        var dataWriter = new Windows.Storage.Streams.DataWriter();
        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
        dataWriter.writeString(launchAppArgs);

        var launchAppId = proximityDevice.publishBinaryMessage("LaunchApp:WriteTag", dataWriter.detachBuffer());
       proximityDevice.stopPublishingMessage(launchAppId);
   };
}

The content of the tag is a string, where all the items are separated by “\t”:

  1. Some arguments that you want to use when the app starts
  2. The plateform (in our case, we need to specify “Windows”)
  3. The application name, which contains:
    1. The application id (this one can be found in the manifest file, under the attribute Id of the tag Application)
    2. The current package family name

Using this parameters, we can publish a particular message: LaunchApp:WriteTag. This tag/message will be recognize by the platform which will then ask for the user to open the dedicated application.

So you can easily imagine use this technique to create an new kind of authentification in your application (at least to provide the username).

 

Happy coding!

Scrolling in Windows Store applications is mostly done in horizontal mode. This is something quite easy to do with the GridView which support scrolling with mouse wheel but this can be a quite more complicated to do in Webview.

Indeed, in the Webview control, the mouse wheel scroll is done in vertical mode so here is a quick fix to perform the same scroll in horizontal mode.

To do this, you can use a JQuery plugin like JQuery.MouseWheel: https://github.com/brandonaaron/jquery-mousewheel

In your Webview, load JQuery and this plugin:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" scriptJQuery + scriptJQueryMouseWheel + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Once this is done, we can just add a small JavaScript function to handle the “MouseWheel” event:

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

So the complete code is the following one:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" + scriptResize + scriptVideo + scriptJQuery + scriptJQueryMouseWheel + mouseWheelScript + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Now, each time the Webview will get the focus, user will be able to perform a horizontal scrolling using the mousewheel.

Pretty simple when you know!

Please note that the plugin’s file is loaded from ms-appx-web to allow Webview to load it correctly.

 

Happy coding!

Here is a problem we met recently with my colleague Jonathan.

Indeed, in one of the Windows 8 applications we are working, we have a Webview that is loaded thanks to the method NavigateToString:

WebviewNews.NavigateToString(content);

(where content is the HTML fragment that will be displayed in the Webview).

On that HTML, we wanted to insert a custom CSS file so we tried the following:

 var content =
    "<html><head><link rel=\"stylesheet\" href=\"ms-appx:///Views/web/web.css\" type=\"text/css\" media=\"screen\" /></head>" +
         "<font face=\"Segoe UI\">" +
             NewsDetailPageViewModel.SelectedNews.Description +
         "</font>" +
     "</html>";
 WebviewNews.NavigateToString(content);

Unfortunately, this does not work: the code is correct but the CSS rules were not applied.

After a quick look, it appears that the fix is simple: instead of using ms-appx, we needed to use ms-appx-web. Content referenced via this scheme is loaded from the local package, but runs with the abilities and restrictions of the web context.

The correct code was:

 var content =
    "<html><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" /></head>" +
         "<font face=\"Segoe UI\">" +
             NewsDetailPageViewModel.SelectedNews.Description +
         "</font>" +
     "</html>";
 WebviewNews.NavigateToString(content);

Using this syntax, the CSS rules were correctly loaded and the HTML content was correctly modified according to our CSS rules.

 

Happy coding!

I’m glad to announce that my first MSDN article (Building and Validating Windows Store Apps with Team Foundation Service) is now available !

It’s a topic I’ve already covered on my blog but I hope you’ll get more information and details in the new and revisited version!

The article is available here: http://msdn.microsoft.com/en-us/magazine/dn166931.aspx

Happy coding (and building) !

A small tip for anyone who look for the information.

Using a custom font in any Windows Store apps (C# / XAML) is easy and the same as you can do in WPF or Silverlight application.

Indeed, the first step is to add the font file to your solution and mark it as “Content” (on the file’s properties). Then, when you want to use your new font, just set the FontFamily property:

 <TextBlock Text="u"
                    FontSize="72"
                    Foreground="Red"
                    FontFamily="Assets/MyNewFont.ttf#My Font Name"/>

As you can see, you just need to point to the right file and add the font name after the # character (this is because a single file can contains multiple fonts so using this syntax, you know exactly which font will be used).

Note that Visual Studio and Expression Blend both support the feature so you’ll be able to see the change directly in the designers.

 

Happy coding!

[Windows 8] How to transcode an audio/video file?

March 1st, 2013 | Posted by Tom in .NET | Article | Windows 8 | WinRT - (0 Comments) | Read: 404

Windows 8 provide a new Transcoding API that can help you to transcode an audio or video file from one format to another one.

The API is really simple to use and consist of two majors classes:

  1. MediaEncodingProfile, which contains the settings that will determine how the destination file will be transcoded
  2. MediaTranscoder, which will perform the transformation

First, you need to create a profile to indicate how to transcode the file:

var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);

MediaEncodingProfile contains factory methods like CreateMp4 or CreateWmv. The parameter of the methods gives the target resolution (in our case 1080p).

Next, you can call PrepareFileTranscodeAsync to transcode the file (after checking if the source can really be transcoded):

var prepareTranscodeResult = await transcoder.PrepareFileTranscodeAsync(sourceFile, destinationFile, encodingProfile);

if (prepareTranscodeResult.CanTranscode)
{
    await prepareTranscodeResult.TranscodeAsync();
}

And voila! Again, you can see that the API is very simple and flexible (you can, if you want, load a profile from a file or trim the destination file using the properties TrimStartTime and TrimStopTime!).

For my tests, I’ve worked with a WMV file of 30 seconds for 25Mb. After converted it in MP4 (1080p), the result file was 65Mb (more bigger for more quality) and another conversion to VGA gave a file of 11Mb: as you can see, the result file depend of the quality you decide to use.

So now, you’re ready to create you own audio/video editor in a cool Windows Store app!

 

Happy coding!

Windows Azure Mobile Services is a awesome product that will help you to deliver great apps using a Windows Azure backend.

One of the feature I like is the possibility to send push notifications to modify tiles in just few lines of code. There is just a small drawback to this technique: as the queue notification must be enable from the client code, you won’t be able to get animated tiles.

But (as there is always a “but” ;), the next part of this post will provide you a simple but useful technique to get animated tiles for you Windows Store app.

In fact, instead of of send a classic notification, we’ll use the sendRaw method of the wns object to send a Raw notification. As a reminder, a raw notification is a notification that’s not displayed on the screen: as a developer, your code is notified that the notification is coming and you have to perform what you want/need.

So first, you have to create your server script (here is mine as an example):

var LASTEST_QUOTES_NUMBER = 5;

var payload;
var idx;

function cleanChannels(callback) {
    var channelsTable  = tables.getTable('Channel');

    channelsTable.read({
        success: function(channels) {
            if(channels.length > 0) {
                channels.forEach(function(channel){
                    if(channel.expirationTime < new Date()){
                        channelsTable.del(channel.id);
                    }
                })
            }

            if(callback) {
                callback();
            }
        }
    })
}

function preparePayload(movie, quote){
     payload += "<QuoteWithMovie>" +
                    "<Movie Title=\"" + movie.title + "\" FrontCover=\"" + movie.poster_path + "\" BackCover=\"" + movie.backdrop_path + "\" />" +
                    "<Quote Text=\"" + quote.text.substring(100) + "\" />" +
                "</QuoteWithMovie>";

    idx++;

    if(idx == LASTEST_QUOTES_NUMBER) {

        payload += "</Results>";

        cleanChannels(function() {
            var channelsTable  = tables.getTable('Channel');

            channelsTable.read({
                success: function(channels) {
                    if(channels.length > 0) {
                        for (var i = 0; i < channels.length; i++) {
                            var channel = channels[i];

                            push.wns.sendRaw(channel.uri, payload);
                        }
                    }
                }
            });
        });
    }
}

function sendLatestQuotes() {

    payload = "";
    idx = 0;

    var moviesTable = tables.getTable('Movie');
    var quotesTable = tables.getTable('Quote');

    quotesTable.where({ ispublished: true })
    .orderBy('date')
    .take(LASTEST_QUOTES_NUMBER)
    .read({
        success: function(latestQuotes) {
            payload += "<Results>";

            latestQuotes.forEach(function(quote) {
                moviesTable.where({ movieid: quote.movieid })
                .read({
                    success: function(movies) {
                       preparePayload(movies[0], quote);
                    }
                })
            })
        }
    })
}

As you can see, the code is pretty simple: a XML payload is construct from some database records and, when I have the number of notification I want (5 because notification queuing allow you to switch up to 5 notifications), I send a raw notification, using the payload constructed before.

On the client side, the code use the PushNotificationReceived event to be notified and, if a raw notification is coming, the code use the content (the XML payload) to update the tile:

 var currentChannel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
currentChannel.PushNotificationReceived += async (sender, args) =>
{
    if (args.NotificationType == PushNotificationType.Raw && args.RawNotification != null)
    {
        await MainTileUpdateTask.UpdateMainTileAsync(args.RawNotification.Content);

        // The raw notification should not be passed to its background task
        args.Cancel = true;
    }
};

The code to update the tile and animate it is dedicated to your application but, for you records, here is the one I’m using:

internal static async Task UpdateMainTile(string content)
{
    _isUpdatingTile = true;

    var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
    tileUpdater.EnableNotificationQueue(true);

    tileUpdater.Clear();

    var xElement = XElement.Parse(content);
    var quotesWithMovies = from q in xElement.Elements("QuoteWithMovie")
                                            let movie = q.Element("Movie")
                                            let quote = q.Element("Quote")
                                            select new QuoteWithMovie
                                            {
                                                  MovieTitle = movie.Attribute("Title").Value,
                                                  FrontCover = movie.Attribute("FrontCover").Value,
                                                  BackCover = movie.Attribute("BackCover").Value,
                                                  Text = quote.Attribute("Text").Value
                                            };

    var quoteWithMovies = quotesWithMovies as IList<QuoteWithMovie> ?? quotesWithMovies.ToList();
    if (quoteWithMovies.Any())
    {
        for (int index = 0; index < quoteWithMovies.Count; index++)
        {
            var quote = quoteWithMovies[index];

            var frontCoverFileFullUrl =
            await MoviesService.Current.GetFullCoverImageUrlAsync(quote.FrontCover, "w154");
            var backCoverFileFullUrl =
            await MoviesService.Current.GetFullCoverImageUrlAsync(quote.BackCover, "w300");

            var squareImageFilename = string.Format("Square_{0}.jpg", index);
            var wideImageFilename = string.Format("Wide_{0}.jpg", index);

            FileHelpers.DownloadFile(ApplicationData.Current.LocalFolder, squareImageFilename,
            frontCoverFileFullUrl);

            FileHelpers.DownloadFile(ApplicationData.Current.LocalFolder, wideImageFilename,
            backCoverFileFullUrl);

            var wideTile = Core.UI.Notifications.TileContentFactory.CreateTileWideImageAndText01();
            wideTile.Branding = TileBranding.None;
            wideTile.RequireSquareContent = false;
            wideTile.Image.Src = string.Format("ms-appdata:///local/{0}", wideImageFilename);
            wideTile.Image.Alt = quote.MovieTitle;
            wideTile.TextCaptionWrap.Text = quote.Text;

            var squareTile = Core.UI.Notifications.TileContentFactory.CreateTileSquareImage();
            squareTile.Branding = TileBranding.None;
            squareTile.Image.Src = string.Format("ms-appdata:///local/{0}", squareImageFilename);
            squareTile.Image.Alt = quote.MovieTitle;

            var wideTileNotification = wideTile.CreateNotification();
            var squareTileNotification = squareTile.CreateNotification();

             tileUpdater.Update(wideTileNotification);
             tileUpdater.Update(squareTileNotification);
         }
    }

    _isUpdatingTile = false;
}

The might be others techniques to perform the same results but I like this one for one reason: raw notification can be received by BackgroundTask!

So if you add a BackgroundTask (which set its trigger to PushNotificationTrigger) and put you server code in a Mobile Services Scheduler, you’ll be able to update the tile even if the app is not running!

 

Happy coding!

Student looking for internship? We want you!

January 15th, 2013 | Posted by Tom in Divers - (0 Comments) | Read: 360

If you are a student looking for an internship, here is a very great opportunity for you!

Indeed, Infinite Square, the company I’m currently working on, is looking for some interns to work on very cool projects using the following technologies:

  1. Windows 8
  2. Windows Phone 8
  3. Kinect
  4. ASP.NET MVC
  5. And more!

So, if you are interested and you already know one of those technology (or want to learn it), just drop me a line!

Note: The internship is based on Paris, France.

 

Happy coding !

[Windows 8] How to get the size of a StorageFile item ?

January 10th, 2013 | Posted by Tom in .NET | Article | Windows 8 | WinRT - (0 Comments) | Read: 403

Indeed, there are no Size or Length properties exposed by the StorageFile class. So a simple but useful trick is to read the content of the file as a Buffer and access to the Length property to access the basic properties of the file and use the Size property:

public async static Task<ulong> GetFileSizeAsync(this IStorageFile file)
{
    var properties = await file.GetBasicPropertiesAsync();

    return properties.Size;
}

Happy coding !

During my last holidays, I’ve started to work on a new Windows 8 project (more details on that later) that use Windows Azure Mobile Services as a backend.

During the development, I’ve encountered the following issue which, I suppose, is a bug that will be fixed later.

On my application, I used the following code:

var allItems = await ServiceClient.GetTable<Items>().Where(i => i.IsPublished).ToListAsync();

return allItems;

Unfortunately, this code thrown, every time, the following error:

image

After taking a look in Fiddler, I found the problem:

image

As you may know, Mobile Services use REST to access data on the server and the following REST query does not seem to be valid because there is no query operator (like eq for equal, etc.) and no value. So, I’ve tried to modify my code like this:

var allItems = await ServiceClient.GetTable<Items>().Where(i => i.IsPublished == true).ToListAsync();

return allItems;

As you can see, I’ve just append “== true” to the Where clause and all seems to work like a charm. Indeed, no exception was rise and, looking at the REST query, we can see that all is OK:

image

 

Happy coding!