Showing posts with label windows phone. Show all posts
Showing posts with label windows phone. Show all posts

Sunday, June 22, 2014

BLE for developers in Windows 8.1 Part II

      I am sorry that it took me a while to get the second part ready, but better late than ever.
     This second part will be actually about discovering services and characteristics using the new API's available in Windows Phone 8.1 release. As you probably remember this was not possible using the Windows 8.1 BLE API as it is not directly exposed for the store applications. The good news is that things started to move in the right direction with Windows Phone 8.1: possibility to query the services and the characteristics available in a device, support for background tasks and triggers for Bluetooth events, possibility to open the Bluetooth pairing window from inside of our applications (this feature was already available in Windows Phone 8.0 and, luckily, it is still there in 8.1) . There are still some missing features like: 
  • no support real beacon scenario as the user have to manually pair the BLE device before it is accessible to the application
  • no support for server mode. Windows Phone 8.1 supports only client mode
     Hopefully we will see better API in the next release of Windows and at some point the two API's will aliogn. In this moment Windows Phone has better support for BLE devices than it's bigger brother.
     To better illustrate the new API I have created and published an Windows Phone XAML application that is already available in the Store and I've uploaded the source code on Github.
     In order to be able to develop/test for BLE devices you will need and LE device (see the devices from my previous post and since then my collection just got bigger as I've got an Polar H7 heart rate monitor, and the Nokia Treasure Tag) and you will need an Windows Phone 8.1 device that supports the new LE stack. Regarding the device there are good news and a bad news. The good news is that all the Windows Phone 8 devices have hardware that support LE and will support the feature once they will receive the official update. The bad news is that with the Developer Preview this feature is not supported (on the Nokia devices there is an stack conflict between the GDR3 Nokia LE driver and the Microsoft one, Samsung Ativ S it needs a firmware upgrade, and maybe, from what I've heard, it works on the HTC 8x devices but I don't have one and I cannot confirm). So if you have an Windows Phone 8 device you will need to wait for the official release. On the other hand if you have a new Windows Phone 8.1 device like the Lumia 930 or 630 these feature is already supported along with all the other cool features available in the new release . The Lumia 630 and 930 are awesome as they have support for Nokia Sensor Core a technology similar to the one present in the iPhone 5S. The easiest way to see if your device supports LE is to buy an LE device, open the system Bluetooth pairing window and see if you are able to see the device in the list of devices you can pair with.
     In this post I will use the Nokia Treasure Tag. Our goal is to find out as much as we can about the services and characteristics exposed by this device. We will use the new Windows Phone XAML projects available in Visual Studio 2013 Update 2.
     Just like Windows 8 in order to be able to list LE devices from inside of our application we will have to specify in the Package.appxmanifest the type of Device we would like to connect to. As we don't know the services a priory we would choose the a generic service that is implemented in most of the devices and, from my tests, I think Generic Access is a good choice. The lines we will have to manually add inside the Package.appxmanifest are:
 
 <Capabilities>  
   <Capability Name="internetClientServer" />  
   <m2:DeviceCapability Name="bluetooth.genericAttributeProfile">  
    <m2:Device Id="any">  
     <m2:Function Type="name:genericAccess" />  
    </m2:Device>  
   </m2:DeviceCapability>  
  </Capabilities>  

   Then just like in Windows 8.1 we can enumerate the paired devices using DeviceInformation.FindAllAsync and use the predefined GenericAccess UUID:

  bleDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));  

     The output of this method is a DeviceInformationCollection of paired devices that expose the Generic Access service.
     If no devices were found that exposes this service it means that no device was paired with our phone or the Bluetooth is disabled on the device. In this case we can easily open the Bluetooth settings window:
 Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:", UriKind.RelativeOrAbsolute));  
     Once we have the devices we can select one of them and create a new instance of the newly added class in Windows Phone 8.1 SDK BluetoothLEDevice. This class can be usedto enumerate all the services available on the device. If you look at the description of the class you will see that it is only supported on Windows Phone (no support for Windows Store applications). We will use the Id property available inside the DeviceInformation to instantiate the class.
  BluetoothLEDevice _device = await BluetoothLEDevice.FromIdAsync(((DeviceInformation)e.Parameter).Id);  
     The BluetoothLEDevice exposes a property called GatServices of type IReadOnlyList<GattDeviceService>  that will give us the list of all the services available on the device. GetDeviceService is a class that is already implemented in Windows 8.1 but it was extended on Windows Phone 8.1. To get a friendly name of the device service (not only the Guid) you could use reflection, but I have created a helper class BLEHelper.cs (see the github project) that can be easily extended to cover more known services. Remember that all the LE services that have an id that start with 000018 and end with -0000-1000-8000-00805f9b34fb are probably standard LE services and you can find further details about them here.

     Once we've identified the service we are interested in (we have an instance of the class) we will use the newly added method GetAllCharacteristics() (another method available only for Windows Phone) to get the list of all the characteristics the services exposes and for each characteristic we can get its properties, values, type,....

     Each characteristic have an unique id and, int his case, for mapping the Guid to a known name on the UI I have created a simple converter that uses reflection to search and map the Guid to a GattCharacteristicUuids name:

 public class CharacteristicName : DependencyObject, IValueConverter  
   {  
     public object Convert(object value, Type targetType, object parameter, string language)  
     {  
       if (value != null && (value.GetType() == typeof(GattCharacteristic)))  
       {  
         var c = (GattCharacteristic)value;  
         if (c.UserDescription != "")  
           return c.UserDescription;  
         foreach (var prop in typeof(GattCharacteristicUuids).GetRuntimeProperties())  
         {  
           object v = prop.GetValue(null);  
           if (v != null && v.GetType() == typeof(Guid) && ((Guid)v) == c.Uuid)  
             return prop.Name;  
         }  
       }  
       return "Unknown";  
     }  
     public object ConvertBack(object value, Type targetType, object parameter, string language)  
     {  
       throw new NotImplementedException();  
     }  
   }  

     If you download the BLEExplorer app you can also use share to export all  the data (services+characteristics) to any application that support text sharing (like email).
     In the next post I will explain how to create background tasks that subscribe notifications from an BLE device, manage connection lost and reconnect in the backgroun.

P.S. If you have questions please do contact me by email and I will be glad to help. I have disabled the comments on the blog because there was a huge amount of Spam.

NAMASTE!

 

Saturday, September 21, 2013

Retrieve pitch and roll from the accelerometer data [Update]

UPDATE:
You will find an updated version of this post HERE

    So what happens if you designed your application to drive a bluetooth device using the Motion class (because the output is less noisy) and then you realize that on the Lumia 520 and Lumia 625 the Motion class is not supported and you have to use the accelerometer. In my case, as i only use pitch and roll,  the solution was pretty simple as it is actually possible to calculate the pitch and roll values directly from the accelerometer data. This way I can still use the Motion class and when not available fallback on the data extracted from the accelerometer. To better understand the algorithm behind this transformation have a look at this LINK.
     Before applying the transformation I also apply a low-pass filter to remove short-term fluctuations. The difference between the Arduino sample is that the pitch and roll are inverted and also the pitch was 180 degrees off so I remapped the values (when holding in postion 0 it was telling 180 degrees). I also transformed from radians to degrees for easier visualization (the multiplication with 180/Math.Pi)

     const double alpha = 0.5;  
     double fXg = 0;  
     double fYg = 0;  
     double fZg = 0;  
     void acc_ReadingChanged(Windows.Devices.Sensors.Accelerometer sender, AccelerometerReadingChangedEventArgs args)  
     {  
       //Low Pass Filter  
       fXg = args.Reading.AccelerationX * alpha + (fXg * (1.0 - alpha));  
       fYg = args.Reading.AccelerationY * alpha + (fYg * (1.0 - alpha));  
       fZg = args.Reading.AccelerationZ * alpha + (fZg * (1.0 - alpha));  
       //Roll & Pitch Equations  
       double pitch = (Math.Atan2(-fYg, fZg) * 180.0) / Math.PI;  
       double roll = (Math.Atan2(fXg, Math.Sqrt(fYg * fYg + fZg * fZg)) * 180.0) / Math.PI;  
       //rotate 180 degrees  
       pitch=(pitch>=0)?(180-pitch):(-pitch-180);  
     }  

     I have also built a small sample that does comparative plots of the two values using the motion class and the transformation from accelerometer data. Initially I have added also the Microsoft.Devices.Sensors.Accelerometer but the data is almost the same with Windows.Devices.Sensors.Accelerometer with small delays between updates.
  


 
    Here is the  SOURCE CODE of the sample.

Wednesday, May 1, 2013

Enable Azure Mobile Services for "pure" Windows Phone 7.1 Xna Games

     Recently somebody asked me for an advice on what library should he use to communicate with an Azure Mobile Service for an Windows Phone OS 7.1 and Windows 8 Xna game. My answer was, of course, the Windows Azure Mobile Services client library available on NuGet as I remembered that the prerelease version works also for Windows Phone OS 7.x applications.

The "problem" is that the library will not install if the game is a pure Xna Windows Phone project.

There are 2 (maybe 3 :) ) solutions to this problem:
1. Migrate your XNA project to an "Windows Phone XAML and XNA App" and on this type of project the client library will install correctly.
2. You could use a small hack in order to force NuGet to install the Azure Mobile Services client library on your XNA project. The hack is pretty simple:
  • open the YourProject.csproj file with an text editor (like Notepad) and add these 3 line (not sure if all 3 of them are needed but doesn't matter as it is only done to force the library to install):
  •  <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>  
     <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>  
     <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>  
    
  •  Visual Studio will see that the project has been modified so it will ask to Reload the project. Reload it (don't try to build the project as it won't), open the Package Manager Console and write:
     Install-Package WindowsAzure.MobileServices -Pre   
    
    the package should now install.
  • Reopen the .csproj file in Notepad and remove the 3 lines we've previously added, save and reload the project in Visual Studio. The project should compile correctly and you should be able to use the Azure Mobile Services client library.

The only thing that doesn't seem to work is make Visual Studio recognize the await keyword for the XNA project. You will have to use the ContinueWith syntax:

 void TestAzureMobile()  
     {  
       todoitem item = new todoitem { Text = "Awesome item XNA" };  
       ms.GetTable<todoitem>().InsertAsync(item).ContinueWith((task)  
         =>  
       {  
         //do what you need here  
       });  
     }  

3. Came to me while writing the post. Guess the most "elegant" way is to add an Windows Phone Class library to your project, add and use the Azure Mobile Service client library from the class library, reference the class library from your XNA project. Tried this one but the MobileServiceClient seems to fail initialization with 'System.TypeInitializationException'.

Take in consideration that the Azure Mobile Services client library is still a pre-release version in this moment so for the release they might fix/enhance it and you could install it on XNA projects without any hack needed (it is a PCL library).

Wednesday, April 17, 2013

3 ways to force the WebBrowser control to logout from Facebook

     Decided to write this post because it took me some time to find the answer. Maybe you already know that if you use OAuth Facebook connect inside your Windows Phone application there is one step where you use the WebBrowser control to let the user authenticate on the Facebook server and authorize your app. The "problem" presents itself when you want to link another user because the WebBrowser control has already memorized the old credentials and will automatically use them. What needs to be done is to logout the old user from the WebBrowser without actually telling the user to go on the web page and click logout. I have found 3 easy ways to do that: the first two will work on both Windows Phone 7.x and Windows Phone 8 and are Facebook specific and the third one will only work on Windows Phone 8 (generic method for OAuth providers). The 3 methods can use the WebBrowser control headless (you don't actually have to show the WebBrowser control to the user and don't even have to have the webbrowser attached to a Page):  

Method 1: described by Rene Schulte in this blog post  
The method constructs the logout Uri using your AppId and a SessionKey that is obtained from the AccessToken you got when the user authenticated.

Get the SessionKey:
  private static string ExtractSessionKeyFromAccessToken(string accessToken)  
     {  
       if (!String.IsNullOrEmpty(accessToken))  
       {  
         var parts = accessToken.Split('|');  
         if (parts.Length > 2)  
         {  
           return parts[1];  
         }  
       }  
       return String.Empty;  
     }  

Obtain the logout Uri:
  public Uri GetLogoutUri(FacebookCredentials credentials)  
     {  
       var sessionkey = ExtractSessionKeyFromAccessToken(credentials.AccessToken);  
       var url = String.Format("http://facebook.com/logout.php?app_key={0}&session_key={1}&next={2}", EndpointData.FacebookAppId, sessionkey, EndpointData.FacebookLogoutCallbackUrl);  
       return new Uri(url);  
     }  

Make the WebBrowser navigate to the logout Uri:
 Browser.Navigate(FacebookService.GetLogoutUri(EndpointData.Settings.Facebook));  

Method 2:
If for some reason you don't have the Facebook AppId available (my case) you can use the WebBrowser to navigate to the Logout page https://www.facebook.com/logout.php and after the page gets loaded you just execute the script document.forms['logout_form']:
 wb.LoadCompleted += wb_LoadCompleted;  
 wb.Navigate(new Uri("https://www.facebook.com/logout.php"));  
Once the page gets loaded:
 void wb_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)  
     {  
       wb.LoadCompleted -= wb_LoadCompleted;  
       if (wb.SaveToString().Contains("logout_form"))  
         wb.InvokeScript("eval", "document.forms['logout_form'].submit();");  
     }  

Method 3:
This is the easiest one, but will only work on Windows Phone 8: call the new WebBrowser async method ClearCookiesAsync(). This method works for every OAuth provider (Dropbox, Box, Skydrive, Picasa, Flickr, Google Drive... infinite list).

NAMASTE

Sunday, March 24, 2013

Small tip on XAudio2 for Windows Phone

     While debugging one of my Windows Phone applications on the device I've noticed that after the debug session the battery of the device drained faster than usual (so I always restarted the device after using it for debugging). Initially I thought it was the Bluetooth driver but I saw that if I stop the XAudio2 engine when my application gets suspended and re-enable it when the application resumes my battery drains "normally". This should be a best practice as your application doesn't really need the engine when it gets suspended. So:


NAMASTE

Friday, March 22, 2013

How to add songs to the emulator's MediaLibrary

    One of the new features of the Windows Phone 8 SDK is the ability to save(add) songs to the phone's MediaLibrary. This is a really nice when you add songs to the MediaLibrary any other music application that you have installed on your phone can play the songs that your application has saved.. The SaveSong method is found in the MediaLibraryExtensions class. Here are the parameters of this method:

[ExtensionAttribute]

public static Song SaveSong (
         MediaLibrary library,
         Uri filename,
         SongMetadata songMetadata,
         SaveSongOperation operation
)

    The method requires the ID_CAP_MEDIALIB_AUDIO capability and will return a reference to the newly saved song. One of the things that the documentation forgot to mention is that the filename Uri has to be an Uri to a file on the IsolatedStorage. You cannot give a direct Uri to an asset file (this I think because using the SaveSongParameter you can choose if you want to copy or move the file to the MediaLibrary) as you will get InvalidOperationException. If you want to add a song deployed as an asset you will first have to copy the file to the IsolatedStorage and then save it to the MediaLibrary.

    To copy the file to the IsolatedStorage you can use the:
 var resource = Application.GetResourceStream(new Uri(@"Assets/Songs/"+fileName, UriKind.Relative));  
 resource.Stream.CopyTo(fileStream, 4096);  


or you can use the WinRT Api to read the asset file:
  songUri=new Uri("ms-appx:///Assets/Songs/"+fileName,UriKind.Absolute);  
  var file=await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(songUri);  

 
    One interesting parameter is the SongMetadata. This enables you to "mess" with the metadata that will be saved to the MediaLibrary. If this parameter is null then the function will automatically import the file's metadata. If you still want to verify/import just some of the files metadata you can use the PCL ID3.NET and read the metadata of the file you have on the Isolated Storage. The portble dll is Id3.dll. You just have to pass the Stream to the Mp3Stream method:

 Id3.Mp3Stream mp3 = new Id3.Mp3Stream(resource.Stream);  
 if (mp3.HasTags)  
 {  
 }  


NAMASTE

Monday, March 18, 2013

How to debug Windows Phone HTML5 Apps

  Debugging HTML applications is never an easy task and until today I did not know how to approach this for Windows Phone HTML5. The technique I will describe in this post can be applied also for Windows Phone 7.1 applications using Phonegap or Android/iOS applications.
   The "secret" tool for debugging the html content inside our applications is called WEINRE which comes from WEb INspector REmote. Weinre is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it's designed to work remotely, and in particular, to allow you debug web pages on a mobile device such as a phone. 
    In order to install Winre you will need to download and install NodeJS


    Once you have installed NodeJS restart your machine this way you will be able to run the NodeJS commands from the command prompt. After restart open a command prompt window and run this command:
 npm install weinre -g  
This will install the Weinre package globally. This is what you should see in the Command Prompt window:


    When the installer has finished its work you are ready to run the Weinre server on your PC. Execute this command from the Command Prompt:
 weinre --boundHost -all- --debug -true  
    With these parameters Weinre should also open the firewall port. For more parameters have a look at this page. You can verify if the server started by opening a browser page and loading 127.0.01:8080 (8080 is the default port for Weinre). If you are seeing this page then the server is running:


   Now click on the Debug Client User Interface link where you will be able to see if any client is connected and debug the connected clients.
    Let's create the Windows Phone HTML5 application. Use the SDK template to create a new project, open the page index.html inside the folder Html and add this line to the head section:
 <script src="http://[the server ip]:8080/target/target-script-min.js#anonymous"></script>  
replace [the server ip] with the IP of the PC running the Winre server and run the application. If everything went as we expected in the Debug Client user Interface on the Server we should see one Target connected:
    Once the target Windows Phone page is connected you can inspect and change the DOM in real-time, execute javascripts:

 
 
    In this particular case I've only changed the background of the page but you can do whatever you want. Here you can find further details on how to use the Server User Interface.
    Using the Console panel you can execute arbitrary JavaScript expressions/statements. It also shows the output from various console methods, like console.log().

 

    This is pretty much everything. Simple and veryyyyyy useful if you need to debug your HTML5 windows phone applications.
    As usual don't hesitate to contact me if you have further questions.

NAMASTE

Tuesday, March 12, 2013

Share localization files between Windows Phone and Windows 8

    As I wrote in my previous post I am getting back with a post on how to share the localization files between Windows Phone and Windows 8. This should be a simple task, but in the current version of the Windows Phone SDK and Windows 8 it cannot be easily done. The target is to have only one of the two projects (Windows Phone or Windows 8) that manages the localized (in this sample I am only taking in consideration localized strings but the concept can be easily extended) and use it in the other project. Also I wanted to use the Multilingual App Toolkit to easily manage the translations inside the project.
    First let's see what we have:
  • Windows Phone + Multilingual App Toolkit
    1. The main resource file is called AppResources.resx and is inside the Resources folder 
    2. The AppResources.resx automatically generates the AppResources class
    3. The files generated by the Multilingual App Toolkit for the Windows Phone project are also inside the "\Resources" folder and the name look like AppResources.[culture].xlf
    4. We have a class called LocalizedStrings.cs that helps us with the binding inside xaml files
  • Windows 8 + Multilingual App Toolkit
    •  The main resource file is called Resources.resw and it is inside the \strings\[Default language] folder
    • The Resources.resw doesn't have .cs class in code behind generated (it uses the ResourceLoader class to load the localized values). We can also have values with "." like MainButton.Text to directly use inside xaml with the x:Uid.
    • The files generated by the Multilingual App Toolkit for Windows 8 are inside the "\MultilingualResources" folder and the names are [AppName]_[culture].xlf
    So we cannot directly use the files from one project to another.  There are a lot of differences but the couples (AppResources.resx, Resources.resw) and all the (AppResources.[culture].xlf, [AppName]_[culture].xlf) have different names but share very similar structure (they share most of the structure). 

     My approach and idea is to automatically generate the set of localized files needed by one solution directly from the set of files of the other project at compilation time. As source I have chosen the Windows Phone resource files (the other way around is more difficult as we could have resources not supported by Windows Phone). In order to automatically generate the resource files I have created a console application that would be run as a Post-build event on the Windows Phone project and write the necessary files to the Windows 8 project. the Windows 8 project build will be set to depend on the Windows Phone project this way we will always have updated resources when we run it. The console application needs three parameters/inputs: the folder of the Windows Phone project (source), the folder of the Windows 8 project (destination), and the name of the Windows 8 project as we will need it when we generate the [AppName]_[culture].xlf files for the Windows 8 project. The console application also automatically generates the AppResources.cs class inside the Windows 8 projects which is a class similar to the one used by Windows Phone. The source code for the Console Application is also included in case you need to do some changes and also the full sample.
     So let's see what would be the steps you will have to make if you want to use the solution.
  1. Create a Windows Phone application (in the attached sample the project WindowsPhoneApp). Using the Tools menu enable the Multilingual App Toolkit and using right-click on the project name select "Add translation languages..." to support more languages (in the sample is italian)
  2. Create the Windows 8 projects (in the attached sample the project called WindowsStoreApp). Create the the folder structure \strings\en and add the file Resources.resw to it. Inside the Package.appxmanifest set the default language as en. Now use the Tools menu and enable the Multilingual App Toolkit on the Windows 8 project and add the same languages that you have added to the Windows Phone Project. 
    If later you want to add another language support remember to add it to both Windows 8 and Windows Phone projects.
This is how our solution looks :
two different projects each of one with its localization part. Now we will set that the Windows 8 project build depends on the Windows Phone project and set the post-build action of the Windows Phone project to be:

$(SolutionDir)ConvertAppResources\$(OutDir)ConvertAppResources.exe "$(SolutionDir)WindowsPhoneApp" "$(SolutionDir)WindowsStoreApp" WindowsStoreApp

where ConvertAppResources is the project that converts the resources. We pass 3 parameters to the console application:
  1. the folder of the Windows Phone application which is the source - "$(SolutionDir)WindowsPhoneApp"
  2. the folder of the Windows 8 app which is the destination - "$(SolutionDir)WindowsStoreApp"
  3. the name of the Windows 8 app- WindowsStoreApp
In our case the console application will generate and overwrite Resources.resw, WindowsStoreApp_it.xlf and WindowsStoreApp_qps-ploc.xlf. It will also generate the file AppResources.cs in the Windows 8 application folder which you will have to include in the project after the first compilation of the Windows Phone application.
To keep things even more similar to Windows Phone method I have added the class:

 using Localization;  
 namespace WindowsStoreApp  
 {  
   /// <summary>  
   /// Provides access to string resources.  
   /// </summary>  
   public class LocalizedStrings  
   {  
     private static AppResources _localizedResources = new AppResources();  
     public AppResources LocalizedResources { get { return _localizedResources; } }  
   }  
 }  

and inside App.xaml added the resource:

 <Application.Resources>  
     <ResourceDictionary>  
       <local:LocalizedStrings x:Key="LocalizedStrings"/>  
       <ResourceDictionary.MergedDictionaries>  
         <!--   
           Styles that define common aspects of the platform look and feel  
           Required by Visual Studio project and item templates  
          -->  
         <ResourceDictionary Source="Common/StandardStyles.xaml"/>  
       </ResourceDictionary.MergedDictionaries>  
     </ResourceDictionary>  
   </Application.Resources>  

This way you could easily bind in Windows Phone style and even reuse xaml and cs that you already have from your Windows Phone project:
Xaml Binding
  <Button Content="{Binding Path=LocalizedResources.ButtonText, Source={StaticResource LocalizedStrings}}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="517,302,0,0" Height="100" Width="283" Click="Button_Click"/>  
and/or code-behind:
 MessageDialog md = new MessageDialog(AppResources.ButtonMessage);  

If you want to know more on how the conversion works look inside Program.cs. The steps I do is save the Resx to Resw and generate the class AppResources.cs. After that for every .xlf file in the Windows Phone Resources folder  I generate and write the corresponding Windows 8 .xlf file (there are some conversions involved). If you want you don't have to add the project ConvertAppResources to your solution but only add the output .exe file to one of the projects and be very careful when you write the post-build action command.

Once everything is setup-ed you will only have to modify the Windows Phone resource strings and the Windows 8 ones will get updated. If you want to use specific Windows 8 resources you can add more resource files and use the ResourceLoader to load them - for example if you've added the file Errors.resw to the \strings\en folder of the Windows 8 project you will access it like this:

                var resourceLoader = new ResourceLoader("Errors");
                this.Scenario5TextBlock.Text = resourceLoader.GetString("InvalidOperation");


Be careful:

  • before adding the post-build action verify that the localization of both Windows Phone and Windows 8 project work (independent from each other) 
  • if the post-build command is not right the Windows 8 application will not get the updated resources when you compile the windows phone project
  • the Window 8 project has to depend on the Windows Phone project this way you will be sure that Windows 8 gets the updated resources
  • modify ONLY the Windows Phone .resx and .xlf files

Some limitations of the Multilingaul App Toolkit:

  • If you modify the Resx file and add a new resource you will have compile the project before you will see the new string in the .xlf files
  • If you are modifying the Resx file for a resource that you have already localized when you compile you will loose the localization and you will have to modify the .xlf files again.  


Let me know if you have problems understanding or making it work (I don't think that I was really good at explaining the process but the hack works).


SOURCE CODE

NAMASTE

Friday, March 8, 2013

Easily localize your Windows Phone applications using the Multilingual App Toolkit

  Great news for Windows Phone developers. Today Microsoft released an updated version of its Multilingual App Toolkit for Visual Studio 2012 that supports also Windows Phone projects (the previous version only supported Windows Store projects). You can download the Visual Studio Extension from HERE. The extension itself is multilingual:
   So why is this extension so great in my opinion? As you probably know Windows Phone projects in Visual Studio already support multilingual localization for the applications based on .resw files. The Multilingual App Toolkit adds support for localization industry-standard XLIFF file format and also connects with the Microsoft Translator for quick translation suggestions.
  Lets have a quick looks on how it works. After you have installed the extension you will find a new menu entry inside the Visual Studio 2012 Tools menu with which you can enable or disable the Multilingual App Toolkit for your Windows Phone project.

 Once you have enabled the Multilingual App Toolkit Visual Studio added the XLIFF support and also generates the AppResources.qps-ploc.xlf which is the pseudo-language engine that helps identify translation issues during development. 
   From this moment you will USE ONLY the AppResources.resx file to add new resource strings and the extension (at compilation) will add the missing strings to the corresponding .xlf file. 
    To add new languages to your application you will only have to select the desired language as supported in the project Properties inside the Application section. Once a language is selected the extension automatically generates the corresponding Xlf file.

    You can then double click on the xlf file and Visual Studio will open the Multilingual Editor that enablesyou to edit the translation. If you add new strings to your AppResources.resx file remember to compile the project before opening the .xlf file or you will not see the newly added strings.

  Now with these 3-4 easy simple steps we have localized our application. You can use the the Microsoft Translator in order to have some suggestions but you should always double-check the translation in order to avoid strange translations and situations ("My Application" in italian is translated as "La mia domanda" which actually means My question).


  If you are building a test application remember to add the binding to the resource strings inside your .xaml and .cs files ({Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextNormalStyle} for Xaml or AppResources.value for .cs  )
 Some words about the AppResources.qps-ploc.xlf pseudo language file. Pseudo Language is an artificial modification of the software product intended to simulate real language localization. The pseudo language can be used to detect potential localizability issues or bugs early in the project cycle, before the actual localization starts. For more details about localizability testing with Pseudo Language see Localizability Testing. Inside Visual Studio if you right click on the Pseudo Language file you can select the Generate pseudo translations. 

In order to test it you will have to set the qps-ploc culture for the Application UI. Just add these 3 lines to your Application constructor (but remember to take them out when you don't need them anymore):

  public App()  
     {  
       var ci = new System.Globalization.CultureInfo("qps-ploc");  
       Thread.CurrentThread.CurrentCulture = ci;  
       Thread.CurrentThread.CurrentUICulture = ci;  


 More details on how to use the Multilingual App Toolkit can be found HERE.

 It is really great that Microsoft is migrating the localization of the apps to an open standard. I will get back to this subject with a post on how to share the same xlf files between windows phone and windows 8 projects)

NAMASTE

Wednesday, February 20, 2013

How to build a multi-touch control for Windows Phone

     What I intend for multi-touch? Windows Phone is already a multi-touch device but for some reason (I guess it is legacy of Silverlight) the standard Xaml controls don’t have a real multi-touch behavior. Real multi-touch means that I should be able to interact with two different objects at the same time with multiple fingers. What happens now for the XAML standard controls is that once a control start receiving touch events (ManipulationStarted, ManipulationEnded, ManipulationDelta) all the other controls will not receive touch events. The easiest test to do is add a standard button on the page, put one finger on the screen outside the button and try to press the button with another finger. You will see that the button does not respond to your commands. For Xaml applications this might not be a problem, but for games it becomes one. Xaml (I mean Xaml+C# or XAML+VB.NET) is fast to develop easy games.

The solution would be to build your own control and use Touch.FrameReported to “drive” it. In this sample I will build a multi-touch button. I will call it ButtonEx (some of you remember OpenNETCF J ?) and I will just add three events to it: TouchDown, TouchUpInside, TouchUpOutSide (iOs MonoTouch event names). With this three events I should have better control (Click in reality is a TouchUpInside event) .
So I've created a new Windows Phone Class Library called ControlsEx and I added the control ButtonEx derived from ContentControl. I copied the standard style of the Button control (you can easily generate it from a standard button using Blend and Edit Copy command on the Button Template). I've then added the style to the /Themes/generic.xaml file inside our project.  When I create the control I will subscribe Loaded and Unloaded events as I want to start receiving Touch events when the control loads and unsubscribe the Touch events when the control gets unloaded.

  public ButtonEx()  
     {  
       DefaultStyleKey = typeof(ButtonEx);  
       this.Loaded += ButtonEx_Loaded;  
       this.Unloaded += ButtonEx_Unloaded;  
       IsEnabledChanged += ButtonEx_IsEnabledChanged;  
       IsPressed = false;  
     }  
     void ButtonEx_Loaded(object sender, RoutedEventArgs e)  
     {  
       Touch.FrameReported += Touch_FrameReported;  
     }  
     void ButtonEx_Unloaded(object sender, RoutedEventArgs e)  
     {  
       Touch.FrameReported -= Touch_FrameReported;  
     }  

     Now everything we need “happens” inside the Touch_FrameReported  method. For my button I am interested to trace only one finger(using its id) from TouchAction.Down until TouchAction.Up. Once the first finger is down on the surface of my control I memorize the id and track it’s actions till it leaves the screen. Depending of the control that you are building you might have to take in consideration multiple fingers. One thing that is pretty important when starting to track a finger is to see if your control is in front or not (imagine an MessageBox over your controls and when you press the Ok button you will also press the button which is in the back). To resolve this issue I’ve used TouchDevice.DirectlyOver property of the TouchPoint and the VisualTreeHelper to see if the UIElement returned by DirectlyOver is a member of my control or not.
  bool IsControlChild(DependencyObject element)  
     {  
       DependencyObject parent = element;  
       while ((parent != this) && (parent != null))  
         parent=VisualTreeHelper.GetParent(parent);  
       if (parent == this)  
         return true;  
       else  
         return false;  
     }  
Here is the method Touch_FrameReported method:

 void Touch_FrameReported(object sender, TouchFrameEventArgs e)  
     {  
       if (Visibility == Visibility.Collapsed)  
         return;  
       TouchPointCollection pointCollection = e.GetTouchPoints(this);  
       for (int i = 0; i < pointCollection.Count; i++)  
       {  
         if (idPointer == -1)  
         {  
           if (IsEnabled&&(Visibility==Visibility.Visible) && (pointCollection[i].Action == TouchAction.Down) && IsControlChild(pointCollection[i].TouchDevice.DirectlyOver))  
           {  
             //start tracing this finger  
             idPointer = pointCollection[i].TouchDevice.Id;  
             IsPressed = true;  
             VisualStateManager.GoToState(this,"Pressed", true);  
             if (TouchDown != null)  
               TouchDown(this, pointCollection[i].Position);  
           }  
         }  
         else if ((pointCollection[i].TouchDevice.Id == idPointer) && (pointCollection[i].Action == TouchAction.Up))  
         {  
           idPointer =-1;  
           IsPressed = false;  
           UpdateIsEnabledVisualState();  
           if ((pointCollection[i].Position.X > 0 && pointCollection[i].Position.X < ActualWidth) && (pointCollection[i].Position.Y > 0 && pointCollection[i].Position.Y < ActualHeight))  
           {  
             if (TouchUpInside != null)  
               TouchUpInside(this, pointCollection[i].Position);  
           }  
           else  
           {  
             if (TouchUpOutside != null)  
               TouchUpOutside(this, pointCollection[i].Position);  
           }  
         }  
       }   
     }  
    For the button control we don’t have to trace the movements of the finger until Up action but we might need to if we are writing a Slider control for example. The sample application that you will find in the source code uses 2 ButtonEx controls and a standard Button control. The ButtonEx should always respond to your commands (fingers).

    I’ve also used this approach to develop an multi-touch XAML game for flying an Bluetooth BeeWi helicopter. I will also have a session on the 27th February at Community Days here in Italy where I will present a session on developing a game for Windows Phone and I will use this game as a starting point. This application has multi-touch buttons, slider and joystick control.

Also have to thank the TTT (Train The Trainer) program which awarded me a beautiful Sphero for my multi-touch controls.

As always don’t hesitate to contact me if you have further questions.
NAMASTE

Wednesday, February 6, 2013

Update the HTC Mazaa to Windows Phone 7.8

 HTC Mazaa was the first ever Windows Phone to run the 7.5 build of the OS. It is a really great development device (as performance it is somewhere between the gen 1 devices and the gen 2 devices) but unfortunately it haven't received any updates since the RTM release build 7.10.7720.68. If you still have RTM build on it you will probably see that you are not even able to access the Store anymore. The bad news is that it will not receive any automatic updates but if you want you can still manually update it to the Windows Phone 7.8 version on it.
   To manually update the device you will need :
  1. Zune 4.8 final (build 4.8.2345.0)
  2. Download the WP7_update_tool.rar and install the UpdateWP package for your platform (x86 or x64). This is version 4.8.2134.0. You can download the Update tool from this post
   What you will need to do is simulate the steps that Zune does when it updates your phone. At each step there are a number of cab that you can send to the phone at the same time. BACKUP YOUR PHONE before updating. This tutorial starts the update from the version 7.10.7720.68 up to 7.10.8858.136. If you have a heigher version than 7.10.7720.68 just start from the step of the version you have. We assume that your Mazaa has the following language packs installed (if you have less just remove the corresponding cabs from each step):
  • German (0407)
  • English - United States (0409)
  • French (040C)
  • Italian (0410)
  • English - United Kingdom (0809)
  • Spanish (0C0A)
   At each step just run:
 updatewp /iu [concatenate cab's from step here with space between]

Here are the cabs for each step:

1) 7.10.7720.68-7.10.7740.16

2) 7.10.7740.16-7.10.8107.79


3) 7.10.8107.79-7.10.8112.7

4) 7.10.8112.7-7.10.8773.98


5) 7.10.8773.98-7.10.8779.8 

6) 7.10.8779.8-7.10.8783.12

7) 7.10.8783.12-7.10.8858.136

If you have problems updating please let me know.

BTW I am not responsible if you BRICK your phone :) . Here is mine updated:



NAMASTE

Wednesday, January 2, 2013

Saving the Windows Phone 8 Emulator State

    Saving the emulator state between runs was one of the feature needed for the Windows Phone emulator, but till now it is not officially supported. It even makes more sense now when the Windows Phone 8 emulator is a full working operating system and not a trimmed one like Windows Phone 7/7.5 was. You could configure an email account, personalize the start screen, install some applications, install certificates or even save the state of an application that requires a lot of data to synchronize before the actual debugging and have everything ready the next time you start the emulator.
   Today I was trying to run the Windows Phone 8 emulator on a Parallels 8 machine using this post because I hate Windows 8 performance in Bootcamp (the disk access is crappy and the UEFI mode still needs drivers for sound, video and a way to enable Hyper-V). I observed that the first time you run an Windows Phone emulator it took more than 40 seconds to start. The reason is that the SDK creates a new Virtual Machine in Hyper-V and saves a "clean" snapshot of it.

       On every subsequent run of that emulator the XDE automatically starts the virtual machine and immediately applies the snapshot (or starts the virtual machine from the snapshot directly). What caught my attention was the name of the snapshot for each virtual machine: 
  1. Emulator 720P - snapshot.720x1280.1024
  2. Emulator WVGA 512MB - snapshot.480x800.512
  3. Emulator WVGA - snapshot.480x800.1024
  4. Emulator WXGA - snapshot.768x1280.1024
     I tried and messed up the names and observed that XDE, if it doesn't see a certain Snapshot, it starts the Virtual Machine and creates a new snapshot with the required name. So in order to save the state it would be enough to alter/change the snapshot XDE uses to start the virtual machine. 
      First we need to start the emulator we want to personalize (in this post i will mess up the 512 WVGA emulator). This can be done in two ways:
  1. From Visual Studio by running a program on that emulator or from Application Deployment (the emulator is easy to personalize because you can zoom the content and you have the hardware buttons but will require a subsequent reset of the Virtual Machine from Hyper-V) 
  2. From Hyper-V manager by starting the Emulator WVGA 512MB virtual machine and applying the saved snapshot for a fast start. After the machine starts you will have to connect to it:

    Once connected to the emulator/virtual machine you can personalize/modify the way you want it to be. If you connected using Hyper-V these keyboard shortcuts will prove helpful (they also work in the emulator):


  • F1 - the same as pressing the back button
  • F2 – the same as pressing the home button
  • PageUp  - enables physical keyboard and minimizes the software keyboard
  • PageDown – disables physical keyboard and maximizes the software keyboard
  • F9 - volume up
  • F10 - volume down
  • F7 – invoke camera
  • F3 – invoke Bing search
If you want/need to install some xap's you can use Application Deployment with the Emulator. 
When you've reached the desired state go to the Hyper-V manager, select the Virtual machine that you are personalizing and hit Snapshot. This will create a new Snapshot(save state for the emulator).

If you've started the emulator from Visual Studio or Application Deployment App before you create the snapshot you will have to connect to the Virtual Machine from Hyper-V and from the menu Action select Reset (this will clean the ports used for debugging and the state you will save will be usable for Visual Studio and XDE).

After saving the new state the only thing you have to do is to rename the snapshot with the same name of the parent snapshot and delete the parent by right-clicking on it and select Delete Snapshot (DO NOT select Delete Snapshot Subtree).

You are now ready to go:  Turn Off the virtual machine from Hyper-V and try it from Visual Studio. Everything should work. If it doesn't it means that the state has some ports that Visual Studio uses still opened and in this case you will have to connect to the Virtual Machine from Hyper-V, Reset the machine from Action and save a new Snapshot.


My personalized emulator looks like this:


If you want to get back to an "unaltered" state just delete the snapshot of the corresponding Virtual Machine from Hyper-V Manager.


Hope saving the emulator state will help you in some scenarios.

NAMASTE!