tag:blogger.com,1999:blog-29725492431941322272024-03-05T05:22:57.167+01:00Mobile DevelopmentDan Ardeleanhttp://www.blogger.com/profile/01964238896617209618noreply@blogger.comBlogger107125tag:blogger.com,1999:blog-2972549243194132227.post-51062398187291514332017-06-07T13:33:00.001+02:002017-06-07T13:38:57.287+02:00Enable TLS 1.2 & 1.1 Xamarin.Android JellyBean & KitKat<br />
<div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;">
</div>
<br />
TLS or Transport Layer Security is a cryptographic protocol that provides communication security over a computer network. If you develop for both iOS and Android you probably know that on iOS by default enforces TLS v1.2 for any application (that, for the moment, you can disable).<br />
When developing for iOS and Android using Xamarin you will probably end up using the <b>HttpClient</b> class. The default implementation of HttpClient on Mono only has built-in support for TLS v1.0. This is why, in order to use the newer versions of TLS, you would had to implement a class derived from HttpClientHandler that under the hood uses the native classes included in the platform that already support newer TLS versions . The first choice, for a while, was the <a href="https://github.com/paulcbetts/ModernHttpClient">ModerHttpClient</a> that NSUrlSession class on iOS and OkHttp on Android.<br />
Recently Xamarin added its own native HttpClientHandler in both iOS and Android. You can are free to switch from the fully managed one or the native one (which imho is recommended). To set the default implementation you will have to go in the project's settings dialog.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_NI0NvXQrDRCwvH248jbV5urWsME0QxJpcpS6TYFvL1SFdUE2ZoFcwRmK8Eh4vyig065lUgyVJXP5eC0UFiEoQFeoGTLB2bk1AB9qNGHK8hyphenhyphenyEuTY2qkI3Uyqn1Zz6tH7xN5rVe1MH9M/s1600/AndroidProjectsSettings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="721" data-original-width="752" height="306" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_NI0NvXQrDRCwvH248jbV5urWsME0QxJpcpS6TYFvL1SFdUE2ZoFcwRmK8Eh4vyig065lUgyVJXP5eC0UFiEoQFeoGTLB2bk1AB9qNGHK8hyphenhyphenyEuTY2qkI3Uyqn1Zz6tH7xN5rVe1MH9M/s320/AndroidProjectsSettings.png" width="320" /></a></div>
There a small detail for the Android native implementation. The <a href="https://developer.xamarin.com/guides/cross-platform/transport-layer-security/">Xamarin TLS document</a> tells you that v1.2 is only supported for Android >= 5.0 . On the other side if you go to <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">Wikipidia TLS Document</a> you will see that TLS v.1.1 & v1.2 are supported by Android >= 4.1 but they are not enabled by default until Android 5.0.<br />
If you try to use TLS v1.1& 1.2 on an Android device version >4.0 & <5.0, as these protocols are not enabled by default you will get an "Connection closed by peer" exception.<br />
There is actually a simple solution for this problem: in order to enable TLS v1.1 & 1.2 in Android JellyBean & KitKat you will have to implement a class derived from SSLSocketFactory and enable the protocols and than change the factory that AndroidClientHandler uses by default. This can easily be achieved by using a implementing a class derived from AndroidClientHandler where you will override the method SetupRequest and change the SSLSocketFactory with our own implementation that enables TLS v1.1 & 1.2 on the SSLSocket it creates:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">AndroidCustomClientHandler</span>:AndroidClientHandler
{
CustomTlsSSLSocketFactory _customTlsSSLSocketFactory=<span style="color: #008800; font-weight: bold;">new</span> CustomTlsSSLSocketFactory();
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #008800; font-weight: bold;">override</span> System.Threading.Tasks.Task SetupRequest(System.Net.Http.HttpRequestMessage request, Java.Net.HttpURLConnection conn)
{
<span style="color: #008800; font-weight: bold;">if</span> (conn <span style="color: #008800; font-weight: bold;">is</span> HttpsURLConnection)
{
<span style="color: #008800; font-weight: bold;">if</span> (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
<span style="color: #888888;">//Enable support for TLS v1.2</span>
((HttpsURLConnection)conn).SSLSocketFactory = _customTlsSSLSocketFactory;
}
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">base</span>.SetupRequest(request, conn);
}
}
</pre>
</div>
<br />
<br />
where CustomTlsSSLSocketFactory is this:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">CustomTlsSSLSocketFactory</span> : SSLSocketFactory
{
<span style="color: #008800; font-weight: bold;">readonly</span> SSLSocketFactory factory = (SSLSocketFactory)Default;
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> <span style="color: #333399; font-weight: bold;">string</span>[] <span style="color: #0066bb; font-weight: bold;">GetDefaultCipherSuites</span>()
{
<span style="color: #008800; font-weight: bold;">return</span> factory.GetDefaultCipherSuites();
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> <span style="color: #333399; font-weight: bold;">string</span>[] <span style="color: #0066bb; font-weight: bold;">GetSupportedCipherSuites</span>()
{
<span style="color: #008800; font-weight: bold;">return</span> factory.GetSupportedCipherSuites();
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket(Java.Net.InetAddress address, <span style="color: #333399; font-weight: bold;">int</span> port, Java.Net.InetAddress localAddress, <span style="color: #333399; font-weight: bold;">int</span> localPort)
{
SSLSocket socket = (SSLSocket)factory.CreateSocket(address, port, localAddress, localPort);
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket(Java.Net.InetAddress host, <span style="color: #333399; font-weight: bold;">int</span> port)
{
SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket(<span style="color: #333399; font-weight: bold;">string</span> host, <span style="color: #333399; font-weight: bold;">int</span> port, Java.Net.InetAddress localHost, <span style="color: #333399; font-weight: bold;">int</span> localPort)
{
SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port, localHost, localPort);
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket(<span style="color: #333399; font-weight: bold;">string</span> host, <span style="color: #333399; font-weight: bold;">int</span> port)
{
SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket(Java.Net.Socket s, <span style="color: #333399; font-weight: bold;">string</span> host, <span style="color: #333399; font-weight: bold;">int</span> port, <span style="color: #333399; font-weight: bold;">bool</span> autoClose)
{
SSLSocket socket = (SSLSocket)factory.CreateSocket(s, host, port, autoClose);
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #008800; font-weight: bold;">override</span> <span style="color: #008800; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">Dispose</span>(<span style="color: #333399; font-weight: bold;">bool</span> disposing)
{
factory.Dispose();
<span style="color: #008800; font-weight: bold;">base</span>.Dispose(disposing);
}
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">override</span> Java.Net.Socket CreateSocket()
{
SSLSocket socket = (SSLSocket)factory.CreateSocket();
socket.SetEnabledProtocols(socket.GetSupportedProtocols());
<span style="color: #008800; font-weight: bold;">return</span> socket;
}
}
</pre>
</div>
<br />
<br />
You can see that I've chosen to enable all the supported protocols, but a better approach would be to enable just the ones that you actually use.<br />
<br />
Hope you will find it useful!<br />
<br />
I almost forgot the most important part: When you initialize your HttpClient you will have to pass an instance of your AndroidCustomClientHandler class:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> HttpClient _client = <span style="color: #008800; font-weight: bold;">new</span> HttpClient(<span style="color: #008800; font-weight: bold;">new</span> AndroidCustomClientHandler()) { BaseAddress = _baseAddr };
</pre>
</div>
<br />Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-7726765196980553412017-02-18T12:32:00.000+01:002017-02-18T12:32:14.875+01:00UWP Shake Gestures The Accelerometer class available in UWP starting with version 10240 has an event called Shaken that should be raised when a shake event occurs without having to subscribe to the Accelerometer raw data. This event was never implemented so if you try to use it, it won't work. <br />
On my quest for starting from something already validated I've came along an old post from the Windows Blog for a <a href="https://blogs.windows.com/buildingapps/2011/02/22/windows-phone-shake-gestures-library/#ArspzMiKThPRVItH.97">Windows Phone Shake Gesture Library</a>. <br />
After finding the source code of the library I did a simple port to the UWP which you can find on the <a href="https://github.com/mahiz/ShakeGestures.UWP">ShakeGestures.UWP</a> GitHub repository.<br />
Hope that some of you will find it useful. Btw there is also the Sample application in the same repository.<br />
<br />
P.S. Still planning some posts on the new Bluetooth functionality available in UWP SDK for the Creators Update and some from the Anniversary Update and hopefully I will find some spare time soon.<br />
<br />
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-5720339021823216192015-09-27T02:27:00.004+02:002015-09-27T02:27:56.363+02:00Using iBeacons with Windows 10 - Part I<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">It’s been a while since my last post on the
blog, but it was such a busy period and sadly my blog is not one of my main
priorities. Would really love to find more time for writing.<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">This post is focused on “consuming” iBeacon
devices around us and also configuring your device as an iBeacon using the
newly added functionality in the Universal Windows Platform target Windows 10
Build 10240. </span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">A little bit of introduction to the beacon/Bluetooth
technology. The iBeacon functionality is built on-top of the Bluetooth Low
Energy (BLE) and enables to create a region around an object. This
allows client devices (Android, Windows, iOS) to determine when it has entered
or left a region along with an estimation of proximity to the beacon. The BLE
standard architecture (and not only) is a client-server one. The device that
exposes the functionality is the server (in our case the beacon) and our device
(phone, tablet) is the client. In order for a client to know that a server is
in range the server advertise itself (sending bytes packages at certain
intervals times on different radio channels). The battery life of an BLE device
depends mainly of the advertising interval (this is because usually the device
is idle and advertising). With one advertising packages each second the
lifetime of a beacon device running on a CR2032 battery is about 1 year. The
client on the other side is scanning the communications channels for Bluetooth
advertising.<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNAGj5DtyK_as8-6l_pTEAcSHIjD-phv13HShsXQWbaWNwvSv82bDNiY5oyeK0kGQdg6OofUxx0JblFWZvwqdxOqm_RUouGiFnafMbRUaA10CGRrAp0L2MtW8uSQx81cl-qIQtqbybZAM/s1600/Advertising.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="395" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNAGj5DtyK_as8-6l_pTEAcSHIjD-phv13HShsXQWbaWNwvSv82bDNiY5oyeK0kGQdg6OofUxx0JblFWZvwqdxOqm_RUouGiFnafMbRUaA10CGRrAp0L2MtW8uSQx81cl-qIQtqbybZAM/s640/Advertising.png" width="640" /></a></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<br /></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">Here is how an advertising package looks like:<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYrs2oWXhF3D6tLo3eSjMtzH_OCu4vgbARewd70BXQd95jInqWkUtf5oij302585PH3P2FQ79sTTHPPe8TpDpAtkUOqEB1M9tAghorHZja1kUx45heN1Bnq69GjbXv0zIZfpeqWWr-9Ac/s1600/ble_advertisement_packet_format_payload.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="408" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYrs2oWXhF3D6tLo3eSjMtzH_OCu4vgbARewd70BXQd95jInqWkUtf5oij302585PH3P2FQ79sTTHPPe8TpDpAtkUOqEB1M9tAghorHZja1kUx45heN1Bnq69GjbXv0zIZfpeqWWr-9Ac/s640/ble_advertisement_packet_format_payload.png" width="640" /></a></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">The “standard sequence” includes: </span><br />
<br />
<ul>
<li><span style="text-indent: 35.4pt;">Preamble and Access Address is always the same </span></li>
<li><span style="text-indent: 35.4pt;">Packet Data Unit</span></li>
<li><span style="text-indent: 35.4pt;">CRC to understand if the received package is correct or not.</span></li>
</ul>
</div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">The PDU can have a length between 8 and 39 bytes where the first 4 bits is the PDU
type. For this post we are interested in two types ADV_IND – Connectable
Undirected Advertising meaning a device that is advertising and it can be
connected to and ADV_NONCONN_IND Non connectable undirected advertising is a
device advertising but not connectable. If you want to better understand the
advertising package read this post </span><a href="http://j2abro.blogspot.it/2014/06/understanding-bluetooth-advertising.html"><span lang="EN-US">http://j2abro.blogspot.it/2014/06/understanding-bluetooth-advertising.html</span></a><span lang="EN-US"> and the complete list of AD
Type can be found here: </span><a href="https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile"><span lang="EN-US">https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile</span></a><span lang="EN-US"> <o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">
</span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">So we could consider a Beacon any Bluetooth Low
Energy that is advertising. The iBeacon (and EddyStone but that we will address in another post) is just a standard advertising package. </span><br />
<span lang="EN-US"><br /></span>
<span lang="EN-US">The structure of the iBeacon packages is:<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDkG1rQBODlDyAcu7BoI10Wkf2InOW0f6ZRPnnBGdrk5ARPZntMK6ESsvcR3XORkyxMkhz_rGs0vCGtvKTd7giyzWC1G5DHhWNic8VS4tDj5q2ztYpf05Xbpgzrdg4P_sEqxu7dQRvlNs/s1600/xdiagramredo_png_pagespeed_ic_COtMlcH3ls.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDkG1rQBODlDyAcu7BoI10Wkf2InOW0f6ZRPnnBGdrk5ARPZntMK6ESsvcR3XORkyxMkhz_rGs0vCGtvKTd7giyzWC1G5DHhWNic8VS4tDj5q2ztYpf05Xbpgzrdg4P_sEqxu7dQRvlNs/s640/xdiagramredo_png_pagespeed_ic_COtMlcH3ls.png" width="640" /></a></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">The iBeacon prefix bytes are always the same:<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US"><br /></span></div>
<div align="center">
<table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td colspan="2" style="background: #E7E6E6; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 332.8pt;" valign="top" width="777"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">iBeacon Prefix<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">02<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Number of bytes that
follow (AD Length)<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">01<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">AD Type<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">06<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Flags type<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">1A<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">26 bytes that follow
in the second AD structure (AD Length)<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">FF<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Manufacturer
specific data AD Type<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">4C 00<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Company identifier
0x004C = Apple<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">02<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US" style="color: #222222; font-family: "Helvetica",sans-serif; font-size: 10.5pt; mso-ansi-language: EN-US;">S</span><span lang="EN" style="color: #222222; font-family: "Helvetica",sans-serif; font-size: 10.5pt; mso-ansi-language: EN;">econdary ID that denotes a proximity beacon, which is
used by all iBeacons</span><span lang="EN-US"><o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 92.1pt;" valign="top" width="215"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">15<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 240.7pt;" valign="top" width="562"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN" style="color: #222222; font-family: "Helvetica",sans-serif; font-size: 10.5pt; mso-ansi-language: EN;">defines the remaining length to be 21
bytes</span><span lang="EN-US"><o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
</div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<br /></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">
</span></div>
<div class="MsoNormal">
<span lang="EN-US"> </span><span style="text-indent: 47.2px;">The developers can configure for each iBeacon (using the tools that manufacturers provide) the UUID, Major, Minor and TX Power.</span><span style="text-indent: 47.2px;"> </span><br />
Here is how the advertising looks like from an Estimote iBeacon. The package was captured using Packet Sniffer
from Texas Instruments:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxOyDkJcbhqusj8qB2ZN3tMxqimZYGuSDUz-ECQdNGi-IBvts6AVZhDkCoFXU7biI2_rVq9HM3AohYvyNPbOnVO8AC_Os60bHBRVL3LEi8bKR89c4h7jDx9TpHYjTRJveHVE-JUewf1uk/s1600/EstimoteAdvertising_preamble.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="42" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxOyDkJcbhqusj8qB2ZN3tMxqimZYGuSDUz-ECQdNGi-IBvts6AVZhDkCoFXU7biI2_rVq9HM3AohYvyNPbOnVO8AC_Os60bHBRVL3LEi8bKR89c4h7jDx9TpHYjTRJveHVE-JUewf1uk/s640/EstimoteAdvertising_preamble.png" width="640" /></a></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US"></span></div>
<div class="MsoNormal">
<span lang="EN-US"> As you can see the device can be
connected to because the advertising type is ADV_IND but this is not always true. If you
have a generation 1 Texas Instruments SimpleLink SensorTag with the iBeacon
firmware flushed you can switch between “normal” mode and iBeacon mode and the
device in iBeacon mode cannot be connected (it is only an iBeacon without any service).
Here is the package captured by the sniffer:<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtKCy2NVaWZDPPICJpSFRpWmwQ__ojITB_AA9R-N_RmsmXtd62bGcGC6clPWpgtExL92upW4bW4OLyPSAfcM8cQ0vj6qi-gtRHTOhxjkZqduPHiECmdgOTNTcL6Ez5O0DdQw5OCqTOK3w/s1600/SensorTag+advertising.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="42" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtKCy2NVaWZDPPICJpSFRpWmwQ__ojITB_AA9R-N_RmsmXtd62bGcGC6clPWpgtExL92upW4bW4OLyPSAfcM8cQ0vj6qi-gtRHTOhxjkZqduPHiECmdgOTNTcL6Ez5O0DdQw5OCqTOK3w/s640/SensorTag+advertising.png" width="640" /></a></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<br /></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">Btw if you want to update the Gen 1 SensorTag to the iBeacon firmware you can follow <a href="http://processors.wiki.ti.com/index.php/SensorTag_with_iBeacon">these instructions</a></span><span lang="EN-US">. I haven’t compiled the source code but
downloaded the firmware from </span><a href="http://www.xup.to/dl,73249384/SensorTag_iBeacon_Switch_1v0.zip"><span lang="EN-US">this link</span></a><span lang="EN-US">. You will need an Android or an iOS
device even if right now the TI application is broken for both Android 5 and iOS 9
(I had to roll back to iOS 8 in order to update the SensorTag firmware). If you look at the two packges you will see that the SensorTag is missing and ADV sequence 02 01 06 but because we are going to filter using the ManufacturerData we will still intercept this type of iBeacona correctly.<o:p></o:p></span></div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">Also remember that the only Beacon standard supported by all the mobile platforms iOS, Android, Windows is iBeacon. Windows 10 and Android can actually support natively any type of Beacon.<o:p></o:p></span><br />
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US">
</span></div>
<div class="MsoNormal">
<span lang="EN-US"> After the standard Prefix we have
the actual data of the iBeacon:</span></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US"></span></div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td style="background: #E7E6E6; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 99.0pt;" valign="top" width="231"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">Field<o:p></o:p></span></b></div>
</td>
<td style="background: #E7E6E6; border-left: none; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 2.0cm;" valign="top" width="132"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">Size<o:p></o:p></span></b></div>
</td>
<td style="background: #E7E6E6; border-left: none; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 325.7pt;" valign="top" width="760"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">Description<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 99.0pt;" valign="top" width="231"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">UUID<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 2.0cm;" valign="top" width="132"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<span lang="EN-US">16 bytes<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 325.7pt;" valign="top" width="760"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Application
developers should define a UUID specific to their app and deployment use
case.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 99.0pt;" valign="top" width="231"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">Major<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 2.0cm;" valign="top" width="132"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<span lang="EN-US">2 bytes<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 325.7pt;" valign="top" width="760"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Further specifies a
specific iBeacon and use case. For example, this could define a sub-region
within a larger region defined by the UUID.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 99.0pt;" valign="top" width="231"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">Minor<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 2.0cm;" valign="top" width="132"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<span lang="EN-US">2 bytes<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 325.7pt;" valign="top" width="760"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">Allows further
subdivision of region or use case, specified by the application developer.<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 99.0pt;" valign="top" width="231"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<b><span lang="EN-US">TX Power<o:p></o:p></span></b></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 2.0cm;" valign="top" width="132"><div align="center" class="MsoNormal" style="margin-bottom: 0.0001pt; text-align: center;">
<span lang="EN-US">1 bytes<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0cm 5.4pt 0cm 5.4pt; width: 325.7pt;" valign="top" width="760"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span lang="EN-US">The
calibrated(known) measured signal strength in Rssi at 1 meter<o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
<br />
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">You might find on some websites that the Tx Power
length is 2 bytes but it is not true. The Tx Power is 1 byte signed.<o:p></o:p></span></div>
<div class="MsoNormal" style="text-align: justify; text-indent: 35.4pt;">
<span lang="EN-US">For the tests and development, I
have used both an Estimote beacon and the SensorTag with the iBeacon firmware.<o:p></o:p></span><br />
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal" style="text-align: justify; text-indent: 35.4pt;">
<span lang="EN-US">So now let’s get back to Windows 10 and the new SDK. We now have support for:</span></div>
<div class="MsoNormal" style="text-align: justify;">
</div>
<ul>
<li><b><span lang="EN-US">BluetoothLEAdvertisementWatcher</span></b><span lang="EN-US"> - capturing advertising packages in
the foreground</span></li>
<li><b><span lang="EN-US">BluetoothLEAdvertisementPublisher</span></b><span lang="EN-US"> – set a new advertising package for
the</span></li>
<li><b><span lang="EN-US">BluetoothLEAdvertisementWatcherTrigger</span></b><span lang="EN-US"> – the same as the watcher only that
it sets a trigger and the code associated with the trigger will run in the
background even if the application is not in the foreground or running</span></li>
<li><b><span lang="EN-US">BluetoothLEAdvertisementPublisherTrigger</span></b><span lang="EN-US"> – the counter part of the advertising
publisher for advertising in the background</span></li>
</ul>
<br />
<div style="text-align: justify; text-indent: 35.4pt;">
</div>
<div class="MsoNormal" style="text-align: justify; text-indent: 35.4pt;">
<span lang="EN-US">IMPORTANT: even if a device advertises ADV_IND meaning that a client can connect to
it the UWP <b>Bluetooth functionality for Windows 10 build 10240</b> is still <b>LIMITED</b> because it can only connect to the device if it was previously paired with Windows. For the moment
there is no way to pair to new devices from code so the application would open
the Bluetooth window, the user have to manually pair with the device and then, when
coming back to the application, we can connect to the device and enumerate services and characteristics.</span><br />
<div class="MsoNormal" style="text-indent: 35.4pt;">
<span lang="EN-US">If we want to monitor for iBeacons only in the
foreground (while our application is running) we will use the <b>BluetoothLEAdvertisementWatcher </b>class. </span></div>
</div>
<div class="MsoNormal" style="text-align: justify; text-indent: 35.4pt;">
<span lang="EN-US">IMPORTANT: when you create a new project in order to be able to interact with the iBeacons from your UWP project you have to open the Package.appxmanifest file and enable Bluetooth Capability:</span><br />
<span lang="EN-US"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtcoB4_pbDSqJ3dCc89Fez5QbPouvvsjZtrErD9O0gOWAEdF9WJ8yX7EZd0lo3BHvQieQ8T9CB2NL9chS8SzlazrCzFlKgRhL2nVGy7XzOfnGQ4HxFhueK1kLfUtn_HhT_B3C_aK6jxhE/s1600/AppxManifers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtcoB4_pbDSqJ3dCc89Fez5QbPouvvsjZtrErD9O0gOWAEdF9WJ8yX7EZd0lo3BHvQieQ8T9CB2NL9chS8SzlazrCzFlKgRhL2nVGy7XzOfnGQ4HxFhueK1kLfUtn_HhT_B3C_aK6jxhE/s640/AppxManifers.png" width="640" /></a></div>
<span lang="EN-US"><br /></span>
<span lang="EN-US">Using BluetoothLEAdvertismentWatcher we can monitor the advertisement packages from any BLE device around us. Of course this is a little bit excessive if we only want/need to monitor a certain class of iBeacon. This can be done using </span><span style="text-indent: 35.4pt;">the <b>AdvertisementFilter
</b>property of the watcher. To make things easier I have developed a small helper class (that hopefully will grow in time) that will actually set the BluetoothLEAdvertisment with the desired iBeacon sequence.</span><br />
<span style="text-indent: 35.4pt;"><br /></span>
<span style="text-indent: 35.4pt;">The extension method uses an iBeaconData class as input:</span><br />
<span style="text-indent: 35.4pt;"><br /></span>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">iBeaconData</span>
{
<span style="color: #008800; font-weight: bold;">public</span> Guid UUID { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">ushort</span> Major { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">ushort</span> Minor { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">short</span> TxPower { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">double</span> Distance { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">short</span> Rssi { <span style="color: #008800; font-weight: bold;">get</span>; <span style="color: #008800; font-weight: bold;">set</span>; }
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">iBeaconData</span>()
{
UUID = Guid.Empty;
Major = <span style="color: #6600ee; font-weight: bold;">0</span>;
Minor = <span style="color: #6600ee; font-weight: bold;">0</span>;
TxPower = <span style="color: #6600ee; font-weight: bold;">0</span>;
Distance = <span style="color: #6600ee; font-weight: bold;">0</span>;
Rssi = <span style="color: #6600ee; font-weight: bold;">0</span>;
}
}
</pre>
</div>
<div class="MsoNormal" style="text-indent: 35.4pt;">
<br />
To set the BluetootLEAdvertisement you just need to set the iBeacon data and pass it to the extension <span style="text-indent: 47.2px;"><b><span style="line-height: 16.25px;">iBeaconSetAdvertisement</span></b></span><span style="text-indent: 35.4pt;">. If we pass the class without setting any property we will monitor for all iBeacon advertisement. If we want to monitor the iBeacons with a certain UUID we just have to set the UUID property before calling the extension method. On the other hand if we set the Major property we will also have to set the UUID to which the Major corresponds. If you look at the source code you will see that the filters work in sequence: If we set the Minor we need to set the Major and UUID, if we set the Major we need to also set the UUID. This is because we are looking for certain patterns of bytes in the advertisement package. Here are some samples of the API callesìd:</span><br />
<br /></div>
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">// Create and initialize a new watcher instance.</span>
watcher = <span style="color: #008800; font-weight: bold;">new</span> BluetoothLEAdvertisementWatcher();
<span style="color: #888888;">// Monitor all iBeacons advertisment</span>
watcher.AdvertisementFilter.Advertisement.<span style="line-height: 125%; text-indent: 47.2px;">iBeaconSetAdvertisement</span><span style="line-height: 125%; text-indent: 35.4pt;">(</span><span style="color: #008800; font-weight: bold; line-height: 125%; text-indent: 35.4pt;">new</span><span style="line-height: 125%; text-indent: 35.4pt;"> iBeaconData());</span>
<span style="color: #888888;">// Monitor all iBeacons with UUID</span>
watcher.AdvertisementFilter.Advertisement.<span style="line-height: 125%; text-indent: 47.2px;">iBeaconSetAdvertisement</span><span style="line-height: 125%; text-indent: 35.4pt;">(</span>
<span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">iBeaconData</span>()
{
UUID = Guid.Parse(<span style="background-color: #fff0f0;">"{307f40b9-f8f5-6e46-aff9-25556b57fe6d}"</span>)
});
<span style="color: #888888;">// Monitor all iBeacons with UUID and Major </span>
watcher.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(
<span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">iBeaconData</span>()
{
UUID = Guid.Parse(<span style="background-color: #fff0f0;">"{307f40b9-f8f5-6e46-aff9-25556b57fe6d}"</span>),
Major=<span style="color: #6600ee; font-weight: bold;">18012</span>
});
<span style="color: #888888;">// Monitor all iBeacons with UUID and Major </span>
watcher.AdvertisementFilter.Advertisement.<span style="line-height: 125%; text-indent: 47.2px;">iBeaconSetAdvertisement</span><span style="line-height: 125%; text-indent: 35.4pt;">(</span>
<span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">iBeaconData</span>()
{
UUID = Guid.Parse(<span style="background-color: #fff0f0;">"{307f40b9-f8f5-6e46-aff9-25556b57fe6d}"</span>),
Major = <span style="color: #6600ee; font-weight: bold;">18012</span>,
Minor=<span style="color: #6600ee; font-weight: bold;">1040</span>
});
</pre>
<pre style="line-height: 125%; margin: 0;"></pre>
<pre style="line-height: 125%; margin: 0;"></pre>
</div>
The Advertisement filter is not the only filter that you can set for the watcher. You can have a look at all the other parameters of the class on <a href="https://msdn.microsoft.com/en-us/library/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher.aspx">MSDN.</a><br />
The other helper method, <b style="text-indent: 47.2px;">iBeaconParseAdvertisement,</b><span style="text-indent: 35.4pt;"> helps parsing the received advertisement package and retrieve the iBeacon data: UUID, Major, Minor, TxPower and Distance. The Distance is an approximate one and it is calculated using the TxPower (the Rssi level measured at 1m) and the actual Rssi level. To better understand why is hard to have a really precise value read this blog post about </span><a href="http://developer.radiusnetworks.com/2014/12/04/fundamentals-of-beacon-ranging.html" style="text-indent: 35.4pt;">Fundamentals of Beacon Ranging</a><span style="text-indent: 35.4pt;"> (on iOS devices the distance is more precise because Apple is the only manufacturer of its devices so he can tune the bluetooth chipset settings to have similar results on all the devices meaning the Rssi level measured on the iPhone at 1m would be almost the same for the iPad or iPod).</span><br />
In the sample I have subscribed the <b>Received </b>event handler of the watcher an simply called the method <b>iBeaconParseAdvertisement </b>to get the iBeacon data.<br />
<span style="color: #888888; line-height: 125%; text-indent: 35.4pt;"><br /></span>
<span style="color: #888888; line-height: 125%; text-indent: 35.4pt;">// Get iBeacon specific data</span><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #333399; font-weight: bold;">var</span> beaconData = eventArgs.Advertisement.iBeaconParseAdvertisement(eventArgs.RawSignalStrengthInDBm);</pre>
</div>
<br />
Now let's see how we can scan for iBeacons from the background (while our application is not running). The SDK adds a new background trigger specific for BLE advertisment that is why it is called <b>BluetoothLEAdvertisementWatcherTrigger</b>. If you don't know how the background tasks work read read this: <a href="https://msdn.microsoft.com/en-US/library/windows/apps/xaml/hh977055.aspx">Creating and register a background task</a> .<br />
The main difference between scanning in the foreground and in the background from the BLE point of view is the minimum sampling period: when scanning in the foreground the value can be 0, while in background the minimum sampling interval is 1 second. We cannot have more than one event/second in the background. If more than one iBeacon has advertised in that period we will find all the advertisements packages using the <b>Advertisements</b> property. Remember also that the background task runs in a different process but in the same container (so the storage is shared).<br />
Also in this case when setting the trigger I am calling the extension method that sets the filter for the advertisement data:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">// Create and initialize a new trigger to configure it.</span>
trigger = <span style="color: #008800; font-weight: bold;">new</span> BluetoothLEAdvertisementWatcherTrigger();
<span style="color: #888888;">// Add the manufacturer data to the advertisement filter on the trigger:</span>
trigger.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(<span style="color: #008800; font-weight: bold;">new</span> iBeaconData());
</pre>
</div>
<br />
I've published the sample project on GitHub (here is the <a href="https://github.com/danardelean/Beacons.Universal.git">link</a> ). The solution has 4 projects:<br />
<ul>
<li><span style="text-indent: 35.4pt;">Beacons.Helper - UWP library that contains the extension methods</span></li>
<li style="text-align: left;"><span style="text-indent: 35.4pt;">Beacons.Universal.Foreground - the sample for the </span><span style="text-indent: 47.2px;">BluetoothLEAdvertisementWatcher</span></li>
<li style="text-align: left;"><span style="text-indent: 47.2px;">Beacons.Tasks - the runtime component that contains the background tasks</span></li>
<li style="text-align: left;"><span style="text-indent: 47.2px;"><span style="text-indent: 47.2px;">Beacons.Universal.Background the sample for register/unregister and monitor a background task that scans for iBeacons</span></span></li>
</ul>
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;">The next blog post will be on configuring the device as an iBeacon. We will look at the new publisher API. </span></span><br />
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;"><br /></span></span>
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;">If you have questions don't hesitate to contact me (you can find me on twitter or email - I have disabled the comments on the blog because there was a lot of SPAM)</span></span><br />
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;"><br /></span></span>
<div style="text-align: left;">
I also recommend (if you have time) to watch the Build 2015 session of Kiran Pathakota : <a href="https://channel9.msdn.com/Events/Build/2015/3-739">Building Compelling Bluetooth Apps in Windows 10</a> . </div>
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;">Hope you've enjoyed the post!</span></span><br />
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;"><br /></span></span>
<span style="text-align: left; text-indent: 47.2px;"><span style="text-align: left; text-indent: 47.2px;">NAMASTE!</span>
</span></div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-42990546485812233732015-06-10T10:59:00.002+02:002015-06-10T10:59:42.613+02:00Manually install Google Apps on Hyper-V Android emulator<div style="text-align: justify;">
One of the "hot" new features of Visual Studio 2015 is the new Android Hyper-V emulator. It is an awesome feature as you have a highly performant Android emulator running on the same virtualization engine as the Windows Phone emulator. </div>
<div style="text-align: justify;">
It is an x86 virtual machine and similar to other Android Virtual machines like Genymotion, Xamarin Android Player the Google applications and services are not installed by default.</div>
<div style="text-align: justify;">
For the other engines they usually support installing Google applications by drag-drop. You just have to download the Google Apps specific for the version of Android your emulator is running (you can download it from <a href="http://www.teamandroid.com/gapps/">here </a>) and drop the package on the emulator running. For the moment this feature is not supported in the Hyper-V version (might still coming) but you can do it manually with a simple sequence of instructions. </div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
This is what you need to do:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
1. Download the GApps packages specific for the Android version your emulator is running<br />2. Unzip the file<br />3. Open an adb command prompt (if you have the Xamarin Tools installed in Visual Studio 2015 open the menu Tools->Android->Android Adb Command Prompt) and navigate where you have unzipped your files and go to the system folder from the archive.<br />4. Execute this set of commands:</div>
<div style="text-align: justify;">
</div>
<ul>
<li>adb remount</li>
<li>adb shell chmod 777 /system</li>
<li>adb push . /system</li>
</ul>
<br />
<div style="text-align: justify;">
What this commands do is remount the system partition of the emulator to be writable and pushes the contents of the system folder from the unzipped package to the system folder on the emulator. This is the only things that you have to do. Just wait a little bit and you will see that the emultator starts to install everything needed. You might need to soft reset the Hyper-V emulator to make everything work (you should be actually prompted to login with your Google account). Before pushing the System folder content you can also delete the packages that you are not using.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let me know if you have problems or if i works via email or twitter (disabled the comments on the blog because of all the SPAM I am getting)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
P.S. If the links to the google apps package are not working just copy the package name and paste it in a search engine of you choice and you will easily find a mirror for the package.</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-75484875197668269382015-01-01T16:36:00.001+01:002015-01-01T16:37:12.795+01:00Using the Android Hyper-V Preview with Visual Studio 2013 Happy New Year to you all! While I am anxiously waiting to know if I will be renewed today as an Microsoft MVP (btw being MVP is an awesome experience, the MVPSummit was a great experience even if I was expecting to see more new things so if you can get involved and try this experience). Still planning to do the post on BLE background agents but there are so many things to write that I have to find time to write it. Hopefully this will happen soon.<br />
So this small post is all about running the Android Hyper-V Preview Emulator that comes with the Visual Studio 2015 Preview as a stand-alone emulator and use it with your production machine running Visual Studio 2013 and the Xamarin tools. Even if the emulator is still in preview if you are doing Android and Windows Phone development on the same machine you won't have to reboot your machine without Hyper-V support in order to have a decent Android emulator. Strangely Microsoft decided for this preview that the emulator can install only if you have the preview of Visual Studio 2015. In theory you could run the preview along with Visual Studio 2013 but things are not always perfect so many of you will keep two different instances for VS 2013 and the Preview. In oreder to get the emulator work you will still have to install the preview of Visual Studio 2015 on some virtual machine or secondary machine and copy the needed files.<br />
The method is pretty simple. All you will need to do is to copy the folder "Microsoft Visual Studio Emulator for Android" that is located inside Program Files (x86) [ %PROGRAMFILES(X86)%] folder to the machine you want to run the emulator on. At this point you have everything you need. Copy the folder at the same location on the other machine. We still need to take two steps before launching the emulator for the first time. Inside the folder that you've just copied there are two files <strong>vsemu.vhd</strong> and <strong>sdcard.vhd</strong> that will be used to "generate" the two virtual machines (phone and tablet). Here are the two steps that you have to take:<br />
<ol>
<li> Make sure that adb.exe is in your Path as it will be used by XDE.exe</li>
<li>Create a new folder called Android inside the folder "%userprofile%\AppData\Local\Microsoft\XDE" and copy the two vhd each of them two times with the following names:</li>
</ol>
vsemu.vhd copied as: <strong>vsemulator.phone.android.vhd</strong> and <strong>vsemulator.tablet.android.vhd</strong><br />
sdcard.vhd copied as <strong>vsemulator.phone.android.sdcard.vhd</strong> and <strong>vsemulator.tablet.android.sdcard.vhd</strong><br />
<br />
Now we are ready to start the emulator. You won't be able to start the emulator from Visual Studio 2013 the way VS 2015 Preview does but you can start it manually and once you've started it and the adb automatically connects to the emulator you will see it in Visual Studio as a deployable device. Let's not mention that you can actually use the accelerometer, the location, battery simulation and the screenshot (awesome).<br />
<br />
Here are the two commands that you need to run (make a batch on your desktop):<br />
<br />
<strong>Phone Android Emulator</strong>:<br />
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Phone" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.phone.android.vhd /video "720x1280" /memsize 1024 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ=="<br />
<br />
<strong>Tablet Android Emulator</strong>:<br />
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Tablet" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.tablet.android.vhd /video "1080x1920" /memsize 2048 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ==" /noStart<br />
<br />
You won't probably need the /telemetrySession but this way you could give back some feedback (I guess). Also the first time you run the emulator it will ask permission to configure the Internet on the device and of course you will have to accept.<br />
<br />
Also while digging to make this work I found out that the source code of the Android Preview Emulator is published here: <a href="http://aka.ms/getsource"><span style="font-family: "Tahoma",sans-serif; font-size: 10pt; font-weight: normal;"><span style="color: blue;">http://aka.ms/getsource</span></span></a> . In the same place there is also the source code for the Microsoft Wireless Display Adapter. It looks like it is running on Linux kernel with a pretty decent CPU and we might get some new features other than a simple Miracast adapter.<br />
<br />
Until my next blog post: NAMASTE and again HAVE A GREAT NEW YEAR!<br />
<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-18795494772697808042014-10-24T17:53:00.000+02:002014-10-24T18:03:52.481+02:00Using Cordova/PhoneGap with Xamarin Android<div style="text-align: justify;">
Since I haven't found a lot of informations on this matter searching with Google I've decided to share my solution and, maybe, save some time for some of you. The target of this post is to get the Cordova / Phonegap running inside an Xamarin Android project on an Android device.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In order to use Cordova inside an Xamarin project you would first need to build the Cordova framework. What I did was to clone the repository <a href="https://github.com/apache/cordova-android.git">Cordova Android</a> and then follow the Building without the Tooling instructions.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Once you have the cordova*.jar we can start binding the library using Xamarin. Do to that you will have to create a new Project using Xamarin Studio (this does not work in Visual Studio) and select the Android Java Bindings project type:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7zYclZdEBAsLu7qw_OOKQE71i0gzvLDy8Wp8xIjwQVJ_p9VCUvaH_6icZVrFG24WKrFL1nfTQfCq74HinSudZ3miq_AWjkqQ37GZ0aOs8DbOm0_m-ul0PPhHc1iB7rhOSyIv27488H9E/s1600/Android+Java+Bindings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7zYclZdEBAsLu7qw_OOKQE71i0gzvLDy8Wp8xIjwQVJ_p9VCUvaH_6icZVrFG24WKrFL1nfTQfCq74HinSudZ3miq_AWjkqQ37GZ0aOs8DbOm0_m-ul0PPhHc1iB7rhOSyIv27488H9E/s1600/Android+Java+Bindings.png" height="240" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The structure of the project is pretty simple. Add the Jar to the Jars folder and ensure the Build action is set to EmbeddedJar and try to build the project.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggi_b5z8obcWJwq_jnPDFx-XppneTcbrLYC-3ZiBa2QPH1YeRle8cMzJ6tYQviQ-WLuw99tg-oJqnM76zVaPUGA33TKZyWWp53qNgQ7Tscs5le-GyszaY-KFK7fQhtoDUvXyzJ567XPt0/s1600/Cordova+Jar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggi_b5z8obcWJwq_jnPDFx-XppneTcbrLYC-3ZiBa2QPH1YeRle8cMzJ6tYQviQ-WLuw99tg-oJqnM76zVaPUGA33TKZyWWp53qNgQ7Tscs5le-GyszaY-KFK7fQhtoDUvXyzJ567XPt0/s1600/Cordova+Jar.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You will get some errors compiling but luckily these errors are on components we don't need to bind to. So what you have to to is to edit the Metadata.xml file inside the Transforms folder and add the these two internal packages that we want to ignore:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnnLqY91lmleJlbLdW-eiSh7KJxHGrZ3xagMV94Ub0eujg1cHy_O1yPiqAw9Rl_O74glfycZMwyGp21PxaA_4jXi4e9GNhPExKZtbtRWHGlj9Xthy68EN3PE6As7Qk0IU0AjcHdTrQLbo/s1600/ignore.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnnLqY91lmleJlbLdW-eiSh7KJxHGrZ3xagMV94Ub0eujg1cHy_O1yPiqAw9Rl_O74glfycZMwyGp21PxaA_4jXi4e9GNhPExKZtbtRWHGlj9Xthy68EN3PE6As7Qk0IU0AjcHdTrQLbo/s1600/ignore.png" height="107" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Doing that will enable to correctly build the binding project.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now that we have the binding we can test it. For this I have build a test Project and copied the test www container from the github repository. It took some while to make it work but everything seems to run as expected. I didn't have time to implement all the activities from the sample but only some of them. It should be pretty easy to port also the others if needed. This sample also uses a custom plugin that launches activities when the button on the main screen get pressed so you should basically have all that you need to start using Cordova with Xamarin. When you launch the project you should see this screen on your device/emulator:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4Z0nccgK-_BoUPPQ1Y9rKYrq6HhiZqu1Lk4npzKpfgjGRslUT0nSJgtHuB2b4GgHKGQ2iN9Zke6XDJiAxBAYsBlDEl4a6CKoUa78u1k6ZCwo7b5UTaLJzWww0eVHLr8GJ1UKmkujbOUE/s1600/Nexus+4+(KitKat)%2BScreentshot%2B1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4Z0nccgK-_BoUPPQ1Y9rKYrq6HhiZqu1Lk4npzKpfgjGRslUT0nSJgtHuB2b4GgHKGQ2iN9Zke6XDJiAxBAYsBlDEl4a6CKoUa78u1k6ZCwo7b5UTaLJzWww0eVHLr8GJ1UKmkujbOUE/s1600/Nexus+4+(KitKat)%2BScreentshot%2B1.png" height="400" width="240" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These are the items implemented in the Test project: Backgroundcolor, Basic Authentification, Full Screen, HTML not found, Iframe Lifecycle, Menus & Splashscreen</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here is the link to my Github repository that contains the Binding project and the Test project. This sample is using Cordova 3.7.0</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="https://github.com/apache/cordova-android">Xamarin Android Cordova Binding</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Contact me if you need help</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
P.S. Still preparing the 3rd post on BLE and it will be the most interesting one as it will be on running in the background.<br />
<br /></div>
<div style="text-align: justify;">
NAMASTE!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-74125784780151414062014-06-22T10:06:00.002+02:002014-06-22T10:06:34.407+02:00BLE for developers in Windows 8.1 Part II<div style="text-align: justify;">
I am sorry that it took me a while to get the second part ready, but better late than ever.</div>
<div style="text-align: justify;">
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: </div>
<ul>
<li><div style="text-align: justify;">
no support real beacon scenario as the user have to manually pair the BLE device before it is accessible to the application</div>
</li>
<li><div style="text-align: justify;">
no support for server mode. Windows Phone 8.1 supports only client mode</div>
</li>
</ul>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
To better illustrate the new API I have created and published an Windows Phone XAML application that is already available in the <a href="http://www.windowsphone.com/s?appid=1f32e5a3-7208-47c2-96fe-6acbe0183c5d">Store and</a> I've uploaded the source code on <a href="https://github.com/danardelean/BLEExplorer.WP.git">Github.</a> </div>
<div style="text-align: justify;">
In order to be able to develop/test for BLE devices you will need and LE device (see the devices from my <a href="http://sviluppomobile.blogspot.it/2014/02/ble-for-windows-81-part-i.html">previous post</a> and since then my collection just got bigger as I've got an <a href="http://www.amazon.com/Polar-Bluetooth-Smart-Heart-Sensor/dp/B007S088F4/ref=sr_1_1?ie=UTF8&qid=1402850470&sr=8-1&keywords=Polar+H7">Polar H7</a> heart rate monitor, and the <a href="http://www.amazon.it/Nokia-WS-2-Treasure-Sensore-Prossimit%C3%A0/dp/B00ILP2E9G/ref=sr_1_4?ie=UTF8&qid=1402850549&sr=8-4&keywords=Nokia+Treasure+tag">Nokia Treasure Tag</a>) 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 <a href="http://www.windowsphone.com/en-us/features-8-1">cool features</a> available in the new release . The Lumia 630 and 930 are awesome as they have support for <a href="http://conversations.nokia.com/2014/04/04/tapping-into-your-phones-sensors-nokia-sensorcore/">Nokia Sensor Core</a> 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.</div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
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 <a href="https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.generic_access.xml">Generic Access</a> is a good choice. The lines we will have to manually add inside the <strong>Package.appxmanifest</strong> are:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> <Capabilities>
<Capability Name="internetClientServer" />
<m2:DeviceCapability Name="bluetooth.genericAttributeProfile">
<m2:Device Id="any">
<m2:Function Type="name:genericAccess" />
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
</code></pre>
</div>
<div style="text-align: justify;">
<br />
Then just like in Windows 8.1 we can enumerate the paired devices using DeviceInformation.FindAllAsync and use the predefined GenericAccess UUID: <br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> bleDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));
</code></pre>
<br />
The output of this method is a DeviceInformationCollection of paired devices that expose the Generic Access service. <br />
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:<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:", UriKind.RelativeOrAbsolute));
</code></pre>
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 <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.devices.bluetooth.bluetoothledevice(v=win.10).aspx">BluetoothLEDevice</a>. 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 <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.enumeration.deviceinformation(v=win.10).aspx">DeviceInformation</a> to instantiate the class. <br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> BluetoothLEDevice _device = await BluetoothLEDevice.FromIdAsync(((DeviceInformation)e.Parameter).Id);
</code></pre>
The BluetoothLEDevice exposes a property called GatServices of type IReadOnlyList<<a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.devices.bluetooth.genericattributeprofile.gattdeviceservice.aspx">GattDeviceService</a>> 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 <strong>000018</strong> and end with <strong>-0000-1000-8000-00805f9b34fb</strong> are probably standard LE services and you can find further details about them <a href="https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx">here</a>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDZCSmnFkhD98d4p1K9Z_L7JqL6g6OErfeeO52-gZ7VtLuSnwGn3K9Cf0jAjs58cAT7xeyE1w_wqspGlfYu6qcyh3VAo9mF811BGs6xg_OySb_2j0hzwq1gs54BcmZJLdx-0tEw8HxSzs/s1600/wp_ss_20140622_0001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDZCSmnFkhD98d4p1K9Z_L7JqL6g6OErfeeO52-gZ7VtLuSnwGn3K9Cf0jAjs58cAT7xeyE1w_wqspGlfYu6qcyh3VAo9mF811BGs6xg_OySb_2j0hzwq1gs54BcmZJLdx-0tEw8HxSzs/s1600/wp_ss_20140622_0001.png" height="320" width="192" /></a></div>
<br />
Once we've identified the service we are interested in (we have an instance of the class) we will use the newly added method <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.devices.bluetooth.genericattributeprofile.gattdeviceservice.getallcharacteristics.aspx">GetAllCharacteristics()</a> (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,....<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyY4j2WxNEZBJnszV69VJL67pB66gOPJpLbA8aTMLNfCpE103gZeAawxxgCOvWtHWlkLbGPjKLjPbQhDdIC4fngWXEktG6CTIDz9Af0C8L80BbWDQ6FxB2yowG92D7mfpjGb591ywve8M/s1600/wp_ss_20140622_0002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyY4j2WxNEZBJnszV69VJL67pB66gOPJpLbA8aTMLNfCpE103gZeAawxxgCOvWtHWlkLbGPjKLjPbQhDdIC4fngWXEktG6CTIDz9Af0C8L80BbWDQ6FxB2yowG92D7mfpjGb591ywve8M/s1600/wp_ss_20140622_0002.png" height="320" width="192" /></a></div>
<br />
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 <span id="goog_166628151"></span><span id="goog_166628158"></span><span id="goog_1859943884"></span><a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.bluetooth.genericattributeprofile.gattcharacteristicuuids(v=win.10).aspx">GattCh<span id="goog_166628147"></span><span id="goog_166628148"></span>aracteristicUuids </a>name:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> 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();
}
}
</code></pre>
<br />
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).<br />
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.<br />
<br />
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. <br />
<br />
NAMASTE!<br />
<br />
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-18360952676992775352014-02-16T18:37:00.001+01:002014-02-16T21:44:52.993+01:00BLE for developers in Windows 8.1 Part I<div style="text-align: justify;">
For who doesn't know Bluetooth Smart/Low Energy devices are devices optimized for low power consumption. Devices can act as an GATT Server, GATT client or both at the same time. In Server mode the device exposes one or more services. Each service has one or more characteristics with properties attached to it (read, write, notify, broadcast,...). The GATT Client connects to the Server and "consumes" its services.<br />
<br />
Windows 8.1 has added support for communicating with Bluetooth devices from the store applications. This opened the development for a lot of accessories including the Bluetooth Low Energy devices. Windows 8.1 supports only GATT client mode. This is the first iteration of the Bluetooth api and, from some points of view, it is not complete and kinda rushed out to be available. Here are some missing features:<br />
<br />
<ol>
<li>The User eXperience when connecting to an Bluetooth device is bad. The common scenario for this kind of device is that you buy the device you see the application for the Windows Store is available, download it and run the app to play with the device. Here comes the "fun" part: form inside the store application you cannot connect to devices that were not previously paired from PC Settings - Devices - Bluetooth. So, for the first connection, when the user launches the application and you don't find any device to connect to, you will have to find a way to explain and convince the user to open Settings ->Change PC Settings->.... Bluetooth and then come back to your application. Also it is not possible to launch the Bluetooth screen directly like in Windows Phone case.</li>
<li>For the BLE devices the whole idea of the application is to consume less but have a connection between the device (server) and the application (client). Too bad that is there is no to make teh application run in the background or receive notifications from the devices when the application is suspended. This missing feature "kills" a little bit the BLE principles and without it the protocol from the app side is not better than the classical SPP. The application should be able to connect, receive notifications in the background, be aware when the device disconnects and to be able to reconnect when available again.</li>
<li>Without being able to connect to devices that were not previously paired beacon scenarios are not possible.</li>
<li>Missing api's to discover the services and the characteristics of each service for any BLE device. </li>
</ol>
<div>
Beside that let's have a first look at how the new apis work. I have bought several BLE devices: The Texas Instruments <a href="http://www.ti.com/tool/cc2541dk-sensor">CC2541 SensorTAG</a>, <a href="http://estimote.com/">Estimote tag</a>, <a href="http://www.amazon.com/Kensington-Proximo-Bluetooth-Tracker-K39567US/dp/B00APEG8N4/ref=sr_1_3?ie=UTF8&qid=1392475473&sr=8-3&keywords=kensington+proximo">Kensington Proximo TAG</a>. (I actually bought the devices in inverse order: Kensington, Estimote TI ).</div>
<div>
If you want to start testing/demo the BLE api I think the SensorTAG is the best choice. The Texas Instruments chipset CC2540/1 is one of the most used chipset in BLE devices and the price of this kit is around 25$. It includes 6 sensors inside: IR temperature Sensor, Humidity Sensor, Pressure Sensor, Accelerometer, Gyroscope, Magnetometer so you can simulate various scenarios.</div>
</div>
<div style="text-align: justify;">
The first step would be to understand if your system supports BLE devices. For this you will have to open Device Manager-> Bluetooth and see if the "Microsoft Bluetooth LE Enumerator" is present. If it is your system can connect to Bluetooth Smart devices. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYyVd878yvTlqW6e7XnxCIPKOFGdDiAehQrJHhXZqRcB62BZhrFw0RKYSsXWE3Y6jjdtcGSyrnUYDO1NS25LDvZdcpWOZxwSpCKdgUOhp5_MMkvOHSWWvBBmH7wYWkdSk1cQKHMNmhHEw/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYyVd878yvTlqW6e7XnxCIPKOFGdDiAehQrJHhXZqRcB62BZhrFw0RKYSsXWE3Y6jjdtcGSyrnUYDO1NS25LDvZdcpWOZxwSpCKdgUOhp5_MMkvOHSWWvBBmH7wYWkdSk1cQKHMNmhHEw/s320/Capture.PNG" height="160" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br />
The second step would be to pair with the device (actually you could skip the first step and if you don't see your device in the list see if your system supports BLE). To make the device visible for pairing just push the button on the left side of the device.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjyuFNCT3-mPff2r7j0g1LU8wYe8fitFckX8DVN0SJjQl2iWcr5OovxTckz8wwVW-VU8Ho6yz1w1neiDYmlmtHX9fu2cTfm8XhIxVjl0E2scg3d0aie7cuCOQgZmKVXG4NjqDzLPijuf4/s1600/Devices.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjyuFNCT3-mPff2r7j0g1LU8wYe8fitFckX8DVN0SJjQl2iWcr5OovxTckz8wwVW-VU8Ho6yz1w1neiDYmlmtHX9fu2cTfm8XhIxVjl0E2scg3d0aie7cuCOQgZmKVXG4NjqDzLPijuf4/s1600/Devices.png" height="211" width="320" /></a></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
<br />
If the device you are looking for is present pair with it (used 0000 as pin). The system configures all the GATT services internally. Here is how your windows Bluetooth devices look internally before and after the pair:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPiYetZhX97x-O4gx9J1v3caVDGaEJYbFLPH6YWHfm8vctLpxOgZlRPD1u8kgVapjQJJ1Pwo1WxG0W-Ht21yPtewN0KRMRcVbTPTO-oGpCRyHKX7cplgbV-5RdTgjUSubWLW8Ndfy1UBM/s1600/Before.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPiYetZhX97x-O4gx9J1v3caVDGaEJYbFLPH6YWHfm8vctLpxOgZlRPD1u8kgVapjQJJ1Pwo1WxG0W-Ht21yPtewN0KRMRcVbTPTO-oGpCRyHKX7cplgbV-5RdTgjUSubWLW8Ndfy1UBM/s1600/Before.PNG" height="86" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhzV4cqcjbLZrwcnuKdnYRMbLziFTE73sFF6EbHlpoWT2Tk7ZnnFxHgI_kqqDQC90TdxM7UTWuOElrhWUblJspaAGgJQWlb73rwOiRBDAPPXM3HZBoNPlJUgQFUeBDHAFDCSQU5ythzUA/s1600/After.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhzV4cqcjbLZrwcnuKdnYRMbLziFTE73sFF6EbHlpoWT2Tk7ZnnFxHgI_kqqDQC90TdxM7UTWuOElrhWUblJspaAGgJQWlb73rwOiRBDAPPXM3HZBoNPlJUgQFUeBDHAFDCSQU5ythzUA/s1600/After.PNG" height="200" width="195" /></a></div>
<br />
You can actually see that we have new GATT services added to our system.<br />
<br />
When using the GATT api you will actually have to know the service you want to connect to and also the characteristics that the service exposes. There are several ways to do that:<br />
<br />
<ol>
<li>The most obvious one you have the documentation of the device and see all the services and their characteristics. Here is the pdf of the <a href="http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf">TI Development KIT</a></li>
<li>You can actually get the Service UUID's from the Device Manager:</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2d1pOLpwjHaW5qaGNMPHtfFjfM4kq9Olbr1oYrqoN9yYg_wslGfMUcZ8FJYrRFVtK6yXeUQlZQLJNJNxblA74PWi1eEZoeR0H4LhA26j90Y7J1yxnpBHeyTiN4-mrTvaw_Rh_tjOaEys/s1600/HID.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2d1pOLpwjHaW5qaGNMPHtfFjfM4kq9Olbr1oYrqoN9yYg_wslGfMUcZ8FJYrRFVtK6yXeUQlZQLJNJNxblA74PWi1eEZoeR0H4LhA26j90Y7J1yxnpBHeyTiN4-mrTvaw_Rh_tjOaEys/s1600/HID.PNG" height="320" width="283" /></a></div>
<div>
<br /></div>
<br />
and then you could hope it is one of the <a href="https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx">standard BLE profile</a>s so you could have the characteristics for that service. In the picture above the UUID of the GATT service is f000aa40-0451-4000-b000-000000000000 and it doesn't fit any standard profile. The standard profiles fit this pattern: 0000XXXX-0000-1000-8000-00805f9b34fb where XXXX is the id of the profile (for example 0x1800 is the generic access profile). There are some GATT Services that are not showed in the Device List even if present and, as far as I tested, these are the Generic Access 0x1800 and Generic Attribute 0x1801 and Device Information 0x180A. You can always try to add these services to the list of services you want to connect to as it will enable you to have more information on the device you are connecting to.<br />
<br />
So here is the list of the GATT services exposed by the SensorTAG:<br />
Custom:<br />
Thermometer <b>"f000aa00-0451-4000-b000-000000000000"</b><br />
Accelerometer <b>"f000aa10-0451-4000-b000-000000000000"</b><br />
Humidity <b>"f000aa20-0451-4000-b000-000000000000"</b><br />
Magnetometer <b>"f000aa30-0451-4000-b000-000000000000"</b><br />
Barometer <b>"f000aa40-0451-4000-b000-000000000000"</b><br />
Gyroscope<b> "f000aa50-0451-4000-b000-000000000000"</b><br />
<b>Standard:</b><br />
Key Service <b>"0000ffe0-0000-1000-8000-00805f9b34fb"</b><br />
+ standard and hidden in device manager:<br />
Generic Access: 00001800-0000-1000-8000-00805f9b34fb<br />
Generic Attribute: 00001801-0000-1000-8000-00805f9b34fb<br />
Device Information: 0000180A-0000-1000-8000-00805f9b34fb<br />
<div>
<br /></div>
<div>
Now that we know what services our device exposes we can start creating the Store Application and add the necessary capabilities which will enable us to connect to the device. Start Visual Studio and create an Windows Store application then edit the Package.appxmanifest file using View Code option. Add the following capabilities:</div>
</div>
<div style="text-align: justify;">
<div>
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <Capabilities>
<Capability Name="internetClient" />
<m2:DeviceCapability Name="bluetooth.genericAttributeProfile">
<m2:Device Id="any">
<m2:Function Type="serviceId:f000aa00-0451-4000-b000-000000000000"/>
<m2:Function Type="serviceId:F000AA10-0451-4000-B000-000000000000"/>
<m2:Function Type="serviceId:F000AA20-0451-4000-B000-000000000000"/>
<m2:Function Type="serviceId:F000AA30-0451-4000-B000-000000000000"/>
<m2:Function Type="serviceId:F000AA40-0451-4000-B000-000000000000"/>
<m2:Function Type="serviceId:F000AA50-0451-4000-B000-000000000000"/>
<m2:Function Type="serviceId:0000ffe0-0000-1000-8000-00805f9b34fb"/>
<m2:Function Type="serviceId:00001800-0000-1000-8000-00805f9b34fb"/>
<m2:Function Type="serviceId:00001801-0000-1000-8000-00805f9b34fb"/>
<m2:Function Type="serviceId:0000180A-0000-1000-8000-00805f9b34fb"/>
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
</code></pre>
<br />
When interacting with the device you will have to find the devices that expose the services we want to connect to and then connect to the desired service. For this we will call Enumeration.DeviceInformation.FindAllAsync passing an AQS string to filter the devices. Let's say we want to connect to the devices that expose the Generic Access Service as it is an standard service. We can actually generate the AQS in 3 different ways for this service:<br />
<br /></div>
<div>
<ol>
<li style="text-align: left;">Using the the standard implemented <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.bluetooth.genericattributeprofile.gattserviceuuids.aspx">GattServiceUuids</a> GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess)</li>
<li>Generating an standard UUID from an shortID GetDeviceSelectorFromShortId(0x1800) -what it actually does is to add "-0000-1000-8000-00805f9b34fb" to the id</li>
<li>When the service is not a standard one you will have to use GetDeviceSelectorFromUuid(new Guid(serviceGuid)) and pass the custom service guid in our case serviceGuid="00001800-0000-1000-8000-00805f9b34fb"</li>
</ol>
<div>
The code below shows how to read the device name using the Generic Access Service of the Sensor Tag. Here are the standard characteristics of the generic access service <a href="https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.generic_access.xml">link</a>.</div>
<div>
<br /></div>
<div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> //Find the devices that expose the service
var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));
if (devices.Count==0)
return;
//Connect to the service
var service = await GattDeviceService.FromIdAsync(devices[0].Id);
if (service == null)
return;
//Obtain the characteristic we want to interact with
var characteristic = service.GetCharacteristics(GattCharacteristic.ConvertShortIdToUuid(0x2A00))[0];
//Read the value
var deviceNameBytes=(await characteristic.ReadValueAsync()).Value.ToArray();
//Convert to string
var deviceName=Encoding.UTF8.GetString(deviceNameBytes,0,deviceNameBytes.Length);
</code></pre>
</div>
<div>
<br />
Now let's see how to interact with an non standard service and a characteristic that notifies when changing. I've chosen the <a href="http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf">accelerometer service</a> of the SensorTAG:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> //Find the devices that expose the service
var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(new Guid("F000AA10-0451-4000-B000-000000000000")));
if (devices.Count==0)
return;
//Connect to the service
var accService = await GattDeviceService.FromIdAsync(devices[0].Id);
if (accService == null)
return;
//Get the accelerometer data characteristic
var accData = accService.GetCharacteristics(new Guid("F000AA11-0451-4000-B000-000000000000"))[0];
//Subcribe value changed
accData.ValueChanged += accData_ValueChanged;
//Set configuration to notify
await accData.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
//Get the accelerometer configuration characteristic
var accConfig = accService.GetCharacteristics(new Guid("F000AA12-0451-4000-B000-000000000000"))[0];
//Write 1 to start accelerometer sensor
await accConfig.WriteValueAsync((new byte[]{1}).AsBuffer());
</code></pre>
<br />
In this case we connect to the service, we subscribe to the data characteristic notifications (we also ensure that the characteristic is in notify mode), and then we start the accelerometer sensor. Once the sensor starts it will notify us every 1000 ms. (default value that can be changed).<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> async void accData_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
var values = (await sender.ReadValueAsync()).Value.ToArray();
var x = values[0];
var y = values[1];
var z = values[2];
}
</code></pre>
<br />
We can do the same with all the other services exposed by the device.<br />
<br />
Till next post NAMASTE!<br />
<br />
<br />
<br /></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-38709052611654990422014-01-02T04:10:00.000+01:002014-01-02T04:10:04.256+01:00I am an MVP Rookie<div style="text-align: justify;">
I am so excited so, even if I am really tired after more than 30 hours travel and just 1 hour of sleep, I have to write this small post and share my achievement with everyone. Today Microsoft awarded me my first MVP award in the Client Development category. I am really honored and can only improve in 2014. I would also like to thank all members of the Italian communities that gave me the opportunity to speak at events and included me in this wonderful world. Hope I am not missing anyone and the order is random: Roberto Freato, Lorenzo Barbieri, Matteo Pagani, DotNetLombardia, Alessandro Scardova, Massimo Bonanni, Daniele Bochicchio, Daniele Pagani for the Nokia events, Marco dal Pino and everyone else I am not remembering (sorry but I am really tired).</div>
<div style="text-align: justify;">
Wish everyone a GREAT 2014 !</div>
<div style="text-align: justify;">
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com3tag:blogger.com,1999:blog-2972549243194132227.post-34839444033901744362013-11-19T22:01:00.001+01:002013-11-19T22:05:21.277+01:00Add/Remove Music and Video folders from Windows 8.1 Store Applications<div style="text-align: justify;">
This is a functionality so buried inside the MSDN documentation that I had to "look" at another application that uses it and only after I was able to find the documentation for it. For the moment (guess because it was not given enough visibility yet) I think there is only one store application that uses it and it is, of course, built by Microsoft (not even Nokia Music application uses it). </div>
<div style="text-align: justify;">
So what is this all about? If you develop a store application that uses the MusicLibrary capability, you can access to the audio files inside the Music library folders. The problem, until now, was that there was no way to add/remove folders to/from the Music library inside a store application so, in case the user did not had any folder added to the Music library the developers had to find a way to explain how to manually add folders to the Music library (a mess believe me).</div>
<div style="text-align: justify;">
The missing functionality is implemented by the NEW <a href="http://msdn.microsoft.com/en-US/library/windows/apps/windows.storage.storagelibrary">StorageLibrary</a> class available for Windows 8.1 store applications. The class is actually a diamond in the rough:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGNX5hAhZX5QVDLf0PdiI8WcszzlObMYEYllIdSYk1lHEMWmMDKNy8y_MAfJAPYSXJpXpBykgZxCNUfS9lkk3ZMEAoeXFYVnC8oBDKRU0zmKjUODNd81VsYjV79k5JdpjYSuq8Qzy9Bo/s1600/StorageLibrary.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="365" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsGNX5hAhZX5QVDLf0PdiI8WcszzlObMYEYllIdSYk1lHEMWmMDKNy8y_MAfJAPYSXJpXpBykgZxCNUfS9lkk3ZMEAoeXFYVnC8oBDKRU0zmKjUODNd81VsYjV79k5JdpjYSuq8Qzy9Bo/s400/StorageLibrary.PNG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The usage is basic but it is exactly what I needed. You need to use the GetLibraryAsync method to retrieve the StorageLibrary you need. Once you have it you can retrieve the StorageFolders currently added to the library and for the Music and Videos libraries, you can add or remove folders from this library. If removing a folder from the library the user will be prompted if he agrees with the removal. For adding a folder using the async method the user will be prompted with a folder picker and returns the newly added StorageFolder, otherwise null.</div>
<div style="text-align: justify;">
As usually I really hope that, if you need it, this blog post will spare you the hours I've spent in finding out how it is done.</div>
<div style="text-align: justify;">
<br />
Update: There is also a code sample available on msdn <a href="http://code.msdn.microsoft.com/windowsapps/Library-management-Sample-05ef6912/">Library management sample</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
NAMASTE</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com1tag:blogger.com,1999:blog-2972549243194132227.post-22734384326193438152013-11-17T21:43:00.001+01:002013-11-17T22:31:28.078+01:00What Windows Phone Start screen should learn/inherit from Windows 8.1<div style="text-align: justify;">
Last week I did a session on live tiles and it got me thinking on how Microsoft and the Windows Phone team could actually improve the Start screen experience and also the application list that, in my opinion, lacks design and more important it is not very practical to use. Please consider that i am not a designer and i did not have time to invest in doing the screenshots (did cut and paste using Paint.Net). I am doing this post just to illustrate my ideas.</div>
<div style="text-align: justify;">
Let me start with the start screen. The live tiles are an awesome feature and really differentiate Windows and Windows Phone from their competitors. I think that, for certain functionality,the Windows 8.1/8 start screen is better than the Windows Phone one. First of all (and the most important) the Scroll Direction. The windows phone have the start screen in vertical compared to Windows 8 which is horizontal. Horizontal scrolling would be better and here are some reasons why I think this:</div>
<ul>
<li style="text-align: justify;">the main reason why you scroll is because you did not find what you were looking for so you would like to reach the part you are interested as fast as possible. All Windows Phone have the height > width in Pixels so scrolling horizontally you actually scroll MORE information than scrolling vertically </li>
<li style="text-align: justify;">If scrolling would be horizontal it would be possible to implement grouping just like Windows 8 and enable a functionality similar to semantic zoom or jump list to easily reach the tile/tiles you need</li>
<li style="text-align: justify;">It would be also more familiar to people coming from other platforms (like Android or iOs) where the scrolling is horizontal</li>
<li style="text-align: justify;">Different from Windows 8 or tablet UI I think that this scroll should be Paged and not continuous similar to what you have on iOS e Android. This is because the user would be faster to search what he needs (if it is not on the page I see now better scroll a whole page and not a part of it). This won't minimize in any way the live tiles functionality but would give better speed in seeing all I am interested in. </li>
<li style="text-align: justify;">If the user gives titles to the various pages then in the JumpList/SemanticZoom he would see those names otherwise he sees the number of pages and he can easily reach any page (even the last one) without scrolling and scrolling and scrolling.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgskGOCMmvoNpf5DkTHtl16fC_ArfmchyphenhyphenKgURG-uEjRWbASEoeOlL5fvCkSONt2IA5ps2kMa1tHhnRUDIQcrhxljLENTCWocLl-J3XnMO62iPLNUjr8QsWXZ6d3TPVyunvA11tooBjHIwo/s1600/Start+Screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="355" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgskGOCMmvoNpf5DkTHtl16fC_ArfmchyphenhyphenKgURG-uEjRWbASEoeOlL5fvCkSONt2IA5ps2kMa1tHhnRUDIQcrhxljLENTCWocLl-J3XnMO62iPLNUjr8QsWXZ6d3TPVyunvA11tooBjHIwo/s400/Start+Screen.png" width="400" /></a></div>
<div>
<ul>
<li style="text-align: justify;">The last page of the start screen that is not full would have the arrow orientated down just to give the hint to the user that the Application full list is "under" the start screen just like in Windows 8.1</li>
</ul>
<div>
<div style="text-align: justify;">
Other aspect where Windows 8.1 start screen is better is the tile templates. Windows 8.1, in comparison with windows Phone, has much more templates that fit better the needs of the developers. In Windows Phone you can actually build your own images with everything on it but it would be better to have more standard templates. The current templates when used "as is" are pretty limited:</div>
</div>
</div>
<div>
<ul>
<li style="text-align: justify;">The flip template is "slow" to change from one side to the other and this way not everything you need to see is right in front of you. You should actually put secondary informations on the back and expect that 70% of the time the user would not wait for the tile to flip</li>
<li style="text-align: justify;">The iconic template in small and medium sizes have the same informations so it is a "waste" of space to keep the iconic tiles in medium size when you could have them little </li>
<li style="text-align: justify;">The cyclic template is more decorative then functional. Even if you build the images I am curious how many people will actually wait for the images to finish a cycle instead of launching the application. For something like photos app it is ok if the user just want to add decorative items to your start screen</li>
</ul>
<div>
<div style="text-align: justify;">
If the Start Screen would be horizontal in this case the application list should be accessed by scrolling vertically just like in the Windows 8.1. The current design of the application list is not optimal it doesn't take advantage of the space it has and because of that you would have to scroll a lot. Even with the Jumplist it is a lot of scrolling. It would be actually better (in my opinion) a paged grid + Jumplist/semantic zoom to easily jump the pages+ Search to easily find an app. Grid design it would even scale better on higher resolutions as it could have more columns. Here is a small comparison (I repeat I am not a designer). Again paged scrolling would give you better speed than continuous scrolling.</div>
</div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_70z8SPW1eCfbeX1XGGl8tk5Ygt4GOhztOyt06y9iwYxUw5ngus4sc39C8JVeWymq0sD9XVDn5Wxgx2HRYr9bhNx0LlGFr1K_GkHTgQ1GJ2-9jlRpnXj0xKpVTi9cESqxxYGChW08cCE/s1600/wp_ss_20131117_0003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_70z8SPW1eCfbeX1XGGl8tk5Ygt4GOhztOyt06y9iwYxUw5ngus4sc39C8JVeWymq0sD9XVDn5Wxgx2HRYr9bhNx0LlGFr1K_GkHTgQ1GJ2-9jlRpnXj0xKpVTi9cESqxxYGChW08cCE/s320/wp_ss_20131117_0003.png" width="180" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3HzEbPloQnLua7p3AGY0JHWZbqtPoY90Fg7hedIKYe_80EWsI0yE6DoHX2jXdP1t_aI42c-mrB2ppUhGpxKVY6ZQswdSjJ-Xi7WUqr7lOpzJ9Ltx-72xNmBLekqA310dC2GkbanEayqE/s1600/Test+list.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3HzEbPloQnLua7p3AGY0JHWZbqtPoY90Fg7hedIKYe_80EWsI0yE6DoHX2jXdP1t_aI42c-mrB2ppUhGpxKVY6ZQswdSjJ-Xi7WUqr7lOpzJ9Ltx-72xNmBLekqA310dC2GkbanEayqE/s320/Test+list.png" width="180" /></a></div>
<div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Near the search there could actually be a button that enables the user to change the grouping (alphabetical, most used, recently downloaded,...).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you read this post and have observations (maybe I am missing something) or ideas please let me know. There is always room to improve the user experience and my only wish is that Windows Phone get better and better each year.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
UPDATE: And the most important when implementing horizontal scrolling, new templates apart from better functionality is better transition and familiarity (don't really find the right word) between desktop and phone</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
NAMASTE</div>
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com1tag:blogger.com,1999:blog-2972549243194132227.post-30071988904967722702013-11-14T08:13:00.002+01:002013-11-14T08:13:28.175+01:00HID communication for Windows 8.1 Store applications<div style="text-align: justify;">
I've started thinking about this post a while ago when Windows 8.1 was still in preview (I actually did some testing at that time because I was really excited abouth this new "cool" scenario store applications) and after seeing this Build 2013 session: <a href="http://channel9.msdn.com/Events/Build/2013/2-924b">Apps for HID Devices</a>. </div>
<div style="text-align: justify;">
As I did not had the cool missle launcher to play with I have chosen the XBOX360 Wireless controller connected to my PC using an USB adapter similar to <a href="http://www.amazon.com/Xbox-360-Wireless-Gaming-Receiver-Windows/dp/B000HZFCT2/ref=pd_sim_misc_3">this one</a>. One of the reasons why I did this, apart from proof of concept post, is because I have some bluetooth toys that I like to "drive" using the Xbox360 controller (starting with version 8.1 we have full bluetooth support for the Store applications: SPP, OBEX, GATT/BLE ). The Xbox360 controller gives one of the best gaming experience, way better than any touchscreen, keyboard or motion controllers and also enables multiplayer gaming on the same device/screen. </div>
<div style="text-align: justify;">
In order to be able to connect to the Xbox controller we will need to find the VID, PID and UsagePage specific for our device. As I did not know these values I've used the <a href="http://code.msdn.microsoft.com/windowshardware/HClient-HID-Sample-4ec99697">HClient Sample</a> application to retrieve them. To run the HClient sample you will need Microsoft Visual Studio 2013 and, more important, <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg454513">Windows Driver Kit (WDK) 8.1</a>. HClient gives you detailed informations on all the HID devices connected to your PC and to easily find out which HID device is the one you are looking for just disconnect the device from the computer, look at the items inside the list, reconnect the device and identify the new device. This way I identified that my XBOX360 controller has VID: 0x045E, PID: 0x02A1, UsagePage: 0x1, Usage: 0x5 (there might be multiple hardware versions of the desktop adapter that might have different PIDs): </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh12tqzKScojZw1GjVIwEH555FqbQav5aBf1JDE8Z0Mm7zub4hEvtTFBUnEGNnxILskUv-On9U-r0HxTHe2nhQDEziOPlYr65aaJou3g9lfHLtLPcu3qcMU527yXTZGHhc-QTgJ-Q3jQRY/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh12tqzKScojZw1GjVIwEH555FqbQav5aBf1JDE8Z0Mm7zub4hEvtTFBUnEGNnxILskUv-On9U-r0HxTHe2nhQDEziOPlYr65aaJou3g9lfHLtLPcu3qcMU527yXTZGHhc-QTgJ-Q3jQRY/s320/Capture.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
Selecting the HID Caps for the controller we will see that the input report is 15 bytes long and we don't have an output or a feature report available for this device. This is one of the reasons why, in this case, it would be better to use XInput instead of HID because it would give you access to the lights and the motors inside the controller.<br />
<br />
Now that we have the needed values we can start to build our Windows Store application. The first thing we need to do is to set the necessary Capabilities that enable communication between our application and the Xbox controller (manually edit the Package.appxmanifest inside your project using the View code option). In want to know more about the options you can set read <a href="http://msdn.microsoft.com/en-us/library/windows/apps/dn263091.aspx">How to specify device capabilities for HID</a>.<br />
<br />
So I've have added:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <m2:DeviceCapability Name="humaninterfacedevice">
<m2:Device Id="vidpid:045E 02A1">
<m2:Function Type="usage:0001 *"/>
</m2:Device>
</m2:DeviceCapability>
</code></pre>
<br />
This way we specify that we only want our application to communicate with devices that have VID 045E and PID 02A1.<br />
<br />
Now that we have setup the capabilities we can try to find and connect to and Xbox controller. We will use HidDevice.GetDeviceSelector to generate the query that we will pass to the method DeviceInformation.FindAllAsync that returns an array with all the XBox360 controllers connected to our PC.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public class Xbox360Controller
{
public const UInt16 Vid = 0x045E;
public const UInt16 Pid = 0x02a1;
public const UInt16 UsagePage = 0x01;
public const UInt16 UsageId = 0x05;
}
</code></pre>
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> string selector = HidDevice.GetDeviceSelector(Xbox360Controller.UsagePage,Xbox360Controller.UsageId,Xbox360Controller.Vid,Xbox360Controller.Pid);
var deviceCollection = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(selector);
if (deviceCollection.Count == 0)
return "No Xbox360 controller found!";
for (int i = 0; i < deviceCollection.Count && i < MaxControllers;i++)
{
var _device = await Windows.Devices.HumanInterfaceDevice.HidDevice.FromIdAsync(deviceCollection[i].Id, Windows.Storage.FileAccessMode.ReadWrite);
if (_device == null)
{
try
{
var deviceAccessStatus = DeviceAccessInformation.CreateFromId(deviceCollection[i].Id).CurrentStatus;
switch (deviceAccessStatus)
{
case DeviceAccessStatus.DeniedByUser:
return "User denied the access!";
case DeviceAccessStatus.DeniedBySystem:
return "System denied the access!";
}
}
catch { }
return "Failed to connect to the controller!";
}
Controllers.Add(new Controller(_device));
}
</code></pre>
<br />
We can connect to any of the devices in the returned array using <span style="background-color: #f0f0f0; font-family: arial; font-size: 12px; line-height: 20px; text-align: left;">HidDevice.FromIdAsync </span>by just passing the Id of the HID device. The first time we connect to a new device the user will be prompted to grant permission to the application to communicate with that specific device. Keep in mind that the user can later change the access permissions to each device using the Settings -> Permisssions flyout so you should always check why the connection failed (_device==null) and if DeniedByUser ask him to reenable access to the device.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFPnzDpsqp2D4pjAavetJcyuoJg9STGaqoJp3V4sYcGSxhBNphJJLlIwbUhKSHYjHcHxxC_43ACfRzzkYIzrQTFB9PjGKg8yGEEvlokTlw_eqcXQ4my-KqSubeRXDUmMaE0qCP6wpTF6c/s1600/Permissions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFPnzDpsqp2D4pjAavetJcyuoJg9STGaqoJp3V4sYcGSxhBNphJJLlIwbUhKSHYjHcHxxC_43ACfRzzkYIzrQTFB9PjGKg8yGEEvlokTlw_eqcXQ4my-KqSubeRXDUmMaE0qCP6wpTF6c/s320/Permissions.png" width="228" /></a></div>
<br />
If everything went fine we are now connected to at least one Xbox360 Controller and we can subscribe the InputReportReceived event. The input report contain all the 15 bytes that we need and we can manually parse the bytes or, even better, we can use the defined structures. In our case we have 10 BooleanControls which are our buttons :<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> /*
* Buttons Boolean ID's mapped to 0-9 array
* A - 5
* B - 6
* X - 7
* Y - 8
* LB - 9
* RB - 10
* Back - 11
* Start - 12
* LStick - 13
* RStick - 14
*/
</code></pre>
<br />
and 6 numerical controls :<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> _leftStickX = args.Report.GetNumericControl(0x01, 0x30).Value;
_leftStickY = args.Report.GetNumericControl(0x01, 0x31).Value;
_rightStickX = args.Report.GetNumericControl(0x01, 0x33).Value;
_rightStickY = args.Report.GetNumericControl(0x01, 0x34).Value;
_DPAD = args.Report.GetNumericControl(0x01, 0x39).Value;
_LT = Math.Max(0, args.Report.GetNumericControl(0x01, 0x32).Value - 32768);
_RT = Math.Max(0, (-1) * (args.Report.GetNumericControl(0x01, 0x32).Value - 32768));
</code></pre>
<br />
The usageId for the GetNumericalControl method are the ones listed under "INPUT VALUE" section in the "Sample HID client" app.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAK6VLQp7sZrWJ1VCevo821hRLccat10pufr_vLMSqVBu5etL2XmkCZiFnx2c8AX7znIzmE5RAVVNK-jFArjmZxVrYyAskJBv-SyUoXyITB9FN81Q2TuL6-dkxn0Elmwl7eio36i09t5I/s1600/xbox_360_controller_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAK6VLQp7sZrWJ1VCevo821hRLccat10pufr_vLMSqVBu5etL2XmkCZiFnx2c8AX7znIzmE5RAVVNK-jFArjmZxVrYyAskJBv-SyUoXyITB9FN81Q2TuL6-dkxn0Elmwl7eio36i09t5I/s320/xbox_360_controller_2.png" width="320" /></a></div>
The Left Trigger and Right Trigger are returned as an unique numerical control value equal to LR-RT value. This is the second reason why XInput is a better choice for communicationg with the Xbox controller (using XInput you have distinct values for RT and LT).<br />
<br />
Here is a screenshot from the attached sample application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPs8x7RZEZn0ywKlmYrqBOD8eb_3xFAa2J_9tnIGHXcj0ZRU7SAeVQ74-VD_jEEd0FTPPYuvT9MSXKqcXgEM4EID9yqPvtbK0eDXf7B6A4h89jK5IAiVwSEDkCOkIUUzBkJwGxkgibMRo/s1600/screenshot_11132013_084921.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPs8x7RZEZn0ywKlmYrqBOD8eb_3xFAa2J_9tnIGHXcj0ZRU7SAeVQ74-VD_jEEd0FTPPYuvT9MSXKqcXgEM4EID9yqPvtbK0eDXf7B6A4h89jK5IAiVwSEDkCOkIUUzBkJwGxkgibMRo/s320/screenshot_11132013_084921.png" width="320" /></a></div>
<br />
<br />
<a href="http://sdrv.ms/HMUCeF">SOURCE CODE of XBox360_HID.cs</a><br />
<br />
<a href="http://sdrv.ms/1apE9GY">SAMPLE CODE</a><br />
<div>
<br />
NAMASTE</div>
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-48608976205540042812013-09-21T23:51:00.000+02:002013-11-06T08:17:36.611+01:00Retrieve pitch and roll from the accelerometer data [Update]<div style="text-align: justify;">
UPDATE:<br />
You will find an updated version of this post <a href="http://developer.nokia.com/Community/Wiki/How_to_get_pitch_and_roll_from_accelerometer_data_on_Windows_Phone">HERE</a><br />
<br />
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 <a href="http://theccontinuum.wordpress.com/2012/09/24/arduino-imu-pitch-roll-from-accelerometer/">LINK</a>.</div>
<div style="text-align: justify;">
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)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 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);
}
</code></pre>
</div>
<div style="text-align: justify;">
<br />
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.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifzz9cLA8mDfPzVKK8qEbJw3TDxwDPlffMumflD4C8_gDZMZPGp-YucSwcTe51cLhndFTGiXwdA3EZKt1EWb-xUahCmwCubz0K-Z9SEFmbjvDTBWjK3m_SbvPXEXLBlBF5plMX3L73ztc/s1600/wp_ss_20130921_0005%5B1%5D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifzz9cLA8mDfPzVKK8qEbJw3TDxwDPlffMumflD4C8_gDZMZPGp-YucSwcTe51cLhndFTGiXwdA3EZKt1EWb-xUahCmwCubz0K-Z9SEFmbjvDTBWjK3m_SbvPXEXLBlBF5plMX3L73ztc/s320/wp_ss_20130921_0005%5B1%5D.png" width="192" /></a></div>
<div style="text-align: justify;">
<br />
<br />
Here is the <a href="http://sdrv.ms/1fnQzCi">SOURCE CODE</a> of the sample.</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-34976901382299767532013-08-31T18:24:00.001+02:002013-08-31T23:11:37.223+02:00Add side menus to an Windows Phone application (similar to the Facebook app)<div style="text-align: justify;">
It is been a while since my last post, but I have a good reason (on the 20th of July - so tired that the first time I've mistaken the date by one month - my son Mattia was born and between work and my duties and no sleep there is not much time left for writing on my blog even if I have a lot of posts that I want to do). </div>
<div style="text-align: justify;">
I will get right to the subject (the title is not one of the best chosen). A few days ago I was talking with my friend <a href="http://www.alessandro.scardova.it/">Alessandro Scardova</a> about the possibility of implementing side menus inside an Windows Phone application (similar to the ones in the Facebook application). Even if not 100%"Modern UI" design it is a good approach for applications that have multiple options that need to be accessed quickly (also the approach can be applied cross-platform). So I took it as a challange and tried to implement it.</div>
<div style="text-align: justify;">
My initial thought was that I might be able to implement it using an templated panorama or pivot, but after some tests I was not able to get the desired behaviour:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYmwl5Sg-MMXl9svQUtrj37zSr3swdifZ8t9kLr12qZh6MPPJ550cTnkGWEk-_SiLFbT_FpkMRqUUi9rc6xLYg7Jm9odpDhyrFwlDvQFuACoejDZrneSN36WeNutQws2ZleQq4tUjhr1s/s1600/wp_ss_20130831_0005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYmwl5Sg-MMXl9svQUtrj37zSr3swdifZ8t9kLr12qZh6MPPJ550cTnkGWEk-_SiLFbT_FpkMRqUUi9rc6xLYg7Jm9odpDhyrFwlDvQFuACoejDZrneSN36WeNutQws2ZleQq4tUjhr1s/s400/wp_ss_20130831_0005.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<ul>
<li>when we start the application we will have the selected ViewPort selected</li>
<li>swiping left or right we can open/close the side menus</li>
<li>also using the buttons on the upper left and on the right corners we can also close and open the side menus</li>
<li>the side menus have a width smaller than 480 this way, when opened, we can still see a part of main viewport (including the upper button)</li>
<li>when opening the menus the ApplicationBar is not visible</li>
</ul>
<div>
<div style="text-align: justify;">
The solution I have implemented (doesn't use MVVM pattern) it is more a proof of concept on how to implement the functionality. The approach is pretty simple. We have the whole view that we move inside a canvas using manipulations and animations. Initially I thought that I can use only grid without the canvas and animate the margin of the grid but, as Windows Phone doesn't have ThicknessAnimation, my animations for opening and closing the menus were not very smooth. Also I've tried implementing the swipe behaviour using the Touch.FrameReported event but the results I got were not very good.</div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
So how does my implementation work:</div>
</div>
<div>
<ul>
<li style="text-align: justify;">I have a canvas/grid that has a width of 1320 and the height stretches to the whole available height that contains my whole view</li>
<li style="text-align: justify;">The view is inserted in a canvas with initial Canvas.Left position set to -420 this way we see the main view port (component)</li>
<li style="text-align: justify;">The "stable" positions inside the canvas are: 0: left menu opened, -420: main view and -840:right menu opened</li>
<li style="text-align: justify;">When pressing the buttons we will use a resource Storyboard with a DoubleAnimation to set the the Canvas.Left position inside the canvas to 0,-420 or -840:</li>
</ul>
</div>
<div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <Canvas.Resources>
<Storyboard x:Name="moveAnimation">
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True" />
</Storyboard>
</Canvas.Resources>
</code></pre>
</div>
<div>
<br />
Use the animation to open/close the menus:</div>
<div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> void MoveViewWindow(double left)
{
_viewMoved = true;
if (left==-420)
ApplicationBar.IsVisible = true;
else
ApplicationBar.IsVisible = false;
((Storyboard)canvas.Resources["moveAnimation"]).SkipToFill();
((DoubleAnimation)((Storyboard)canvas.Resources["moveAnimation"]).Children[0]).To = left;
((Storyboard)canvas.Resources["moveAnimation"]).Begin();
}
</code></pre>
<br />
<ul>
<li>To implement the swipe I use the ManipulationStarted, ManipulationDelta and ManipulationEnded on the canvas container. On delta we set the Canvas.Left value directly (no need for animations) between a maximum of 0 and a minimum of -840.</li>
</ul>
<div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> private void canvas_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
if (e.DeltaManipulation.Translation.X != 0)
Canvas.SetLeft(LayoutRoot, Math.Min(Math.Max(-840, Canvas.GetLeft(LayoutRoot) + e.DeltaManipulation.Translation.X), 0));
}
</code></pre>
</div>
<div>
<br />
<ul>
<li>when swiping we also memorize the initial Canvas.Left position. If substracting the final Canvas.Left and the initial one the absolute value is lower then 100 (not a long swipe) we bounce back to the initial position. Otherwise we move to the next position.</li>
</ul>
<div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> private void canvas_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
var left = Canvas.GetLeft(LayoutRoot);
if (_viewMoved)
return;
if (Math.Abs(initialPosition - left) < 100)
{
//bouncing back
MoveViewWindow(initialPosition);
return;
}
//change of state
if (initialPosition - left > 0)
{
//slide to the left
if (initialPosition > -420)
MoveViewWindow(-420);
else
MoveViewWindow(-840);
}
else
{
//slide to the right
if (initialPosition< -420)
MoveViewWindow(-420);
else
MoveViewWindow(0);
}
}
</code></pre>
</div>
<div>
<br />
<br />
<ul>
<li>_viewMoved is used to see if the view was already moved by another event since our manipulation started (like a button was pressed)</li>
</ul>
<div>
Here are some screenshots from the sample that you can download and play with:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfZbhgm7MMPYfMiF1Pab8ocl77K0BYq8OfvBS1rZWnDue9Y3oVBjjN0wimZdr2hO8MMxJ6aVzhQPAxohAUMbs4e5pbnikTUY52dSwHn4nb5SiFM38XCl0D1iYKWlLUjxbm8NiE0JzhKk/s1600/wp_ss_20130831_0010%5B1%5D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfZbhgm7MMPYfMiF1Pab8ocl77K0BYq8OfvBS1rZWnDue9Y3oVBjjN0wimZdr2hO8MMxJ6aVzhQPAxohAUMbs4e5pbnikTUY52dSwHn4nb5SiFM38XCl0D1iYKWlLUjxbm8NiE0JzhKk/s200/wp_ss_20130831_0010%5B1%5D.png" width="120" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgshLHXvbesNqkQVwNCGL_yxpvbJ85v4Pl-9Y5QdDWy_msIGnyb9g9576ZdWVNwsDeFszdojEKBHjYdB7B-bT3QOssNrr7g5rlr_6LxRwDCGQgKvucEfNIDwEHYBwgR8xCHOdDwfwz-Ymk/s1600/wp_ss_20130831_0011%5B1%5D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgshLHXvbesNqkQVwNCGL_yxpvbJ85v4Pl-9Y5QdDWy_msIGnyb9g9576ZdWVNwsDeFszdojEKBHjYdB7B-bT3QOssNrr7g5rlr_6LxRwDCGQgKvucEfNIDwEHYBwgR8xCHOdDwfwz-Ymk/s200/wp_ss_20130831_0011%5B1%5D.png" width="120" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiLrzYOhLZ6rdTLIr5m1pUhZ4b1EUhK2CxB9DVCwcSkbDlVwMc7DmFEfavJomiYN1Me7INMBfcsKS7u4NvRZQ9AsQfZ9F3GMuIMfRG1jRnxAotGStvLqmiKlu0k3CoHio9iefDTDYbt7g/s1600/wp_ss_20130831_0012%5B1%5D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiLrzYOhLZ6rdTLIr5m1pUhZ4b1EUhK2CxB9DVCwcSkbDlVwMc7DmFEfavJomiYN1Me7INMBfcsKS7u4NvRZQ9AsQfZ9F3GMuIMfRG1jRnxAotGStvLqmiKlu0k3CoHio9iefDTDYbt7g/s200/wp_ss_20130831_0012%5B1%5D.png" width="120" /></a></div>
<div>
<br /></div>
<div>
Hope you will find it useful.</div>
<div>
<br /></div>
<div>
Here is the <a href="http://sdrv.ms/1dvUygG">SOURCE CODE</a></div>
</div>
<div>
<br /></div>
</div>
NAMASTE!<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com10tag:blogger.com,1999:blog-2972549243194132227.post-20944548005027519232013-07-13T17:30:00.000+02:002013-07-13T17:30:06.007+02:00Embed YouTube videos into your Windows Phone/Windows 8 app<div style="text-align: justify;">
That was quite a long time with no blog post, but I am coming back. Recently I had to investigate the possibility to embed youtube videos in an Windows Phone application. The easy way is to simply launch IE with the Uri of the video, but this way you have no control over the video as your app will get suspended. I then had a look at the Youtube client apps available in the Windows Phone Store and saw that some of them integrate the video directly into the app. So wanna know how they are doing this?</div>
<div style="text-align: justify;">
Well there is a library availabe on codeplex called <a href="http://mytoolkit.codeplex.com/wikipage?title=YouTube">MyToolkit</a>. This library has a class that is able to retreieve the Uri of the video stream directly from the YouTube video id. You can then download the stream for offline access or can directly play the video using the <span style="color: #2b91af; font-family: Consolas; font-size: 13px;">MediaPlayerLauncher. </span>MyToolkit is also available as a nu-get component so you can directly add a reference to it.<br />
The MyToolkit library is really nice, but what if we could improve it a little bit more and have more control over the video? If we would be able to play the video inside our application page would give us the possibility, for example, to add advertising on top of the video (video apps have a good chance of monetizing using advertising as the user, just like in games, would probably stay longer on that page). For this task we can use <a href="http://playerframework.codeplex.com/">Microsoft Player Framework</a> that is available for both Windows Phone 8 and Windows 8. Even more the Player Framework will handle the buffering depending on your connection speed, it is a control inside your page and also will give you full-control over the video playback. (the Player Framework is awesome and is expandible).<br />
So let's create a small test application. First download and install the Player Framework as it is not available on nu-get (yet). I have used the version <a href="http://playerframework.codeplex.com/downloads/get/695764">1.3 beta</a>. Then create a new Windows Phone 8 project add reference to the Media Player Framework Windows Phone extension and then, from nu-get, get the MyToolkit.Extended library. For simplicity my MainPage looks like this :<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <Grid x:Name="LayoutRoot" Background="Transparent">
<mmppf:MediaPlayer x:Name="player">
</mmppf:MediaPlayer>
</Grid>
</code></pre>
<br />
where mmpf is:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> xmlns:mmppf="clr-namespace:Microsoft.PlayerFramework;assembly=Microsoft.PlayerFramework" </code></pre>
<br />
Now on Loaded event I use MyToolkit to retrieve the YouTube stream Uri and then pass it to the MediaPlayer:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> private async void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
var videoUri = await MyToolkit.Multimedia.YouTube.GetVideoUriAsync("PQVlW4xbNuI", MyToolkit.Multimedia.YouTubeQuality.Quality480P, MyToolkit.Multimedia.YouTubeQuality.Quality480P);
if (videoUri != null)
player.Source = videoUri.Uri;
}
</code></pre>
<br />
For convenience the page is set to landscape. I don't know if playing Youtube video using this method is 100% legal as it bypasses the advertising (it is what every other windows phone YouTube app is using including the one from Microsoft that was pulled out of the store).<br />
Also pay attention that there are some videos where the resulting stream is protected/encoded and cannot be played by the Player Framework. One of these videos is <a href="https://www.youtube.com/watch?v=J91ti_MpdHA">Girl on fire by Alicia Keys</a>. Also Microsoft's Youtube app (if you still have it installed ) was not able to open this type of streams and just gives an error while MetroTube, after realizing that it cannot open the stream inside the app, it launches Internet Explorer with the "classic" link to the video.<br />
The same method and libraries can be used for your Windows 8 store application.<br />
<br />
Here is the <a href="http://sdrv.ms/12yH8G6">Source Code</a>. (the video I use is my own).<br />
<br />
NAMASTE</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com9tag:blogger.com,1999:blog-2972549243194132227.post-54972217215843884742013-05-15T21:34:00.000+02:002013-05-17T09:32:57.857+02:00Why setting a control Height and Width to 0 is not the brightest idea inside a Windows Phone project<div style="text-align: justify;">
I am doing this small post because I have battled the whole morning with this bug and finally got it and it might save you some time if you read it and have the same problem. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Scenario: Pivot with two items and at some point the swipe on one of the items doesn't work anymore. Putting a button on the PivotItem that doesn't swipe I can still change the selected item and the second item still swipes correctly.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Cause: I was setting the Height=0 and Width=0 on a control inside the PivotItem (in my project I don't want my control to be collapsed). The problem presents itself if you set any of the controls inside a PivotItem to Height and Width = 0 when the PivotItem is selected. If on the other hand you set the Height and the Width to anything >1 the PivotItem continues to swipe correctly. Even more strange: if the PivotItem is not selected when you set the Width and Height to 0 and swipe to the control's PivotItem everything will still work correctly. So pay attention better not use set Width and Height =0 on UI controls. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you want to test it yourself and maybe tell me what really happens I am attaching a small project created from a Windows Phone Pivot application where I've added a menu that will set the Height and Width of the list inside the first PivotItem to 0. I also set the background of the first PivotItem to green so you will see that it is still expanded. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSbHVNY8Db6NUGGphRoDYf3dup0_E5zGcWqDaqDOGFqHvpiA2sXQTUsjyo1LbB_s3QwkLsBZQrY29Os_q2kG0sKZkt5UcG9yoEmI6lEDYJBpyT6AP2Bt9xwdUProqXorYATar2NlCj4eM/s1600/Pivot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSbHVNY8Db6NUGGphRoDYf3dup0_E5zGcWqDaqDOGFqHvpiA2sXQTUsjyo1LbB_s3QwkLsBZQrY29Os_q2kG0sKZkt5UcG9yoEmI6lEDYJBpyT6AP2Bt9xwdUProqXorYATar2NlCj4eM/s320/Pivot1.png" width="192" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
How to reproduce the problem: If you execute the menu command with the first PivotItem selected you will see that the pivot doesn't swipe anymore. If you change the values to 1, run the app again and execute the menu with the first PivotItem selected you will see that the pivot still swipes correctly. If, on the other hand, you let the values set to 0 but when executing the menu you have the second PivotItem selected you will see that the first item stil swipes correctly. Bug? Feature? Just pay attention to setting controls to Width and Height 0 because you might have problems with the UI and you won't know what is causing it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="http://sdrv.ms/1433Fyw">SOURCE CODE</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
NAMASTE</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-8295772245332193972013-05-13T19:24:00.000+02:002013-05-17T09:32:47.171+02:00Fix Panorama layout when upgrading your project to OS 8.0 SDK<div style="text-align: justify;">
This will be a really short blog post but might save you some time if you have an OS 7.1 Panorama project and decide to upgrade the project to 8.0 SDK. After the upgrade you might see that the layout of your old page changed and you have less content available for the items and also the header looks different. Don't try to fix the problem by changing the margin of the control on the OS 8.0 SDK. The reason why this happens is because the Windows Phone SDK team decided to "tweak" a little bit the default style for the Panorama control, to be more precise the TitleLayer part of the style.</div>
<div style="text-align: justify;">
On Windows Phone OS 7.1 projects the TitleLayer looks like this:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <controlsPrimitives:PanningTitleLayer x:Name="TitleLayer" CacheMode="BitmapCache" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" FontSize="187" FontFamily="{StaticResource PhoneFontFamilyLight}" HorizontalAlignment="Left" Margin="10,-76,0,9" Grid.Row="0"/>
</code></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
while on OS 8.0 we have:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <Primitives:PanningTitleLayer x:Name="TitleLayer" CharacterSpacing="-35" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" FontSize="170" FontFamily="{StaticResource PhoneFontFamilyLight}" HorizontalAlignment="Left" Margin="10,-34,0,0" Grid.Row="0"/>
</code></pre>
<br />
<br />
You can see that not only the margin have changed (the reason why on OS 8.0 version we have less space in the content -44px ), but also the font size changed from 187 to 170 producing these visual differences:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKfHuaB5DeR9daZln6Bvqm_ggPve3xexFb22Mmb3jepeuPmT_0dl-q9xfklGqO6fUEDyie6SXbxTtCMBhT4q444eMOB2k-qEJEFqUsIyi9mCy5xa4ee-9hHKAPpWshkyL2zQ_KxIHGnFE/s1600/WP71.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKfHuaB5DeR9daZln6Bvqm_ggPve3xexFb22Mmb3jepeuPmT_0dl-q9xfklGqO6fUEDyie6SXbxTtCMBhT4q444eMOB2k-qEJEFqUsIyi9mCy5xa4ee-9hHKAPpWshkyL2zQ_KxIHGnFE/s400/WP71.png" width="240" /></a></div>
<br />
The solution to this problem is pretty simple: extract the old style of the Panorama control (the easiest way is using Blend) and apply to both WP7.1 and OS 8.0 versions of your project. This way the UI will be consistent between the two versions of the app. If you don't want to use Blend I am attaching the default OS 7.1 style so you can directly copy/paste it in your project and apply it to your Panorama control.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <Style x:Key="PanoramaStyleWP71" TargetType="controls:Panorama">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<controlsPrimitives:PanoramaPanel x:Name="panel"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Panorama">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<controlsPrimitives:PanningBackgroundLayer x:Name="BackgroundLayer" HorizontalAlignment="Left" Grid.RowSpan="2">
<Border x:Name="background" Background="{TemplateBinding Background}" CacheMode="BitmapCache"/>
</controlsPrimitives:PanningBackgroundLayer>
<controlsPrimitives:PanningTitleLayer x:Name="TitleLayer" CacheMode="BitmapCache" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" FontSize="187" FontFamily="{StaticResource PhoneFontFamilyLight}" HorizontalAlignment="Left" Margin="10,-76,0,9" Grid.Row="0"/>
<controlsPrimitives:PanningLayer x:Name="ItemsLayer" HorizontalAlignment="Left" Grid.Row="1">
<ItemsPresenter x:Name="items"/>
</controlsPrimitives:PanningLayer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</code></pre>
<br />
<br />
NAMASTE</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-37190491854648669582013-05-09T19:41:00.001+02:002013-05-17T09:32:40.164+02:00Type forwarding and XAML sharing between WP OS 7.1 and 8.0 projects<div style="text-align: justify;">
This post is about a new feature available in Windows Phone OS 8.0 SDK called Type Forwarding.<br />
<br />
Have you ever wondered how does the Windows Phone 8.0 SDK handles the fact that the Panorama, Pivot controls changed the namespace and the assembly from OS 7.1 SDK to OS 8.0 SDK? (80% that you haven't :) ). I recently had to migrate an OS 7.1 project to OS 8.0, but also keep the old one (duplicated the old project and upgrade the duplicated one).<br />
<br />
Here is the story of what happens when you upgrade an OS 7.1 project that uses Panaroma or Pivot to OS 8.0:<br />
If you start a new Windows Phone Pivot App with the target OS 8.0 inside MainPage.xaml the prefix <b>"phone"</b> is used for the Pivot control where "phone" is:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
</code></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If, on the other hand, you create a new Windows Phone Pivot App with the target OS 7.1 inside MainPage.xaml the prefix <b>"controls"</b> is used for the Pivot/Panorama control where "controls" is:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
</code></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The real "magic" happens when you upgrade the Windows Phone 7.1 project to OS 8.0. The MainPage.xaml page doesn't change (you will still see the "controls" tag is kept in order to be able to better share the code between the versions), but instead a reference to <b>Microsoft.Phone.Controls.dll</b> is added to the OS 8.0 reference that is not used if you create a new project with target OS 8.0. If you wonder if by adding this reference you use the old version of the controls the answer is NO. What this assembly does is that is uses a really neat and new feature of the .Net compiler called Type Forwarding. This feature can be used when you move a class from one namespace/dll (assembly) to another and you don't want to recompile the application to reference the new dll but you will only deploy the two dlls where the first one (the one that the application already knew uses the Type Forwarding to tell the application that a certain class/es moved to another assembly). In the case of Windows Phone OS 8.0 SDK the usage is even "cooler" as it enables you to use the same XAML for both OS 7.1 projects and OS 8.0 ones. Inside AssemblyInfo.cs of Microsoft.Phone.Controls.dll OS 8.0 version we have all the declarations needed to forward the types to their new locations:<br />
<br />
<div style="text-align: center;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> [assembly: TypeForwardedTo(typeof(Panorama))]
[assembly: TypeForwardedTo(typeof(PanoramaItem))]
[assembly: TypeForwardedTo(typeof(Pivot))]
[assembly: TypeForwardedTo(typeof(PivotItem))]
[assembly: TypeForwardedTo(typeof(PivotItemEventArgs))]
[assembly: TypeForwardedTo(typeof(AnimationDirection))]
[assembly: TypeForwardedTo(typeof(PanningBackgroundLayer))]
[assembly: TypeForwardedTo(typeof(PanningLayer))]
[assembly: TypeForwardedTo(typeof(PanningTitleLayer))]
[assembly: TypeForwardedTo(typeof(PanoramaPanel))]
[assembly: TypeForwardedTo(typeof(PivotHeaderItem))]
[assembly: TypeForwardedTo(typeof(PivotHeadersControl))]
</code></pre>
</div>
<br />
I am attaching a small project called TypeForwarding that implements the same functionality as Microsoft.Phone.Controls.dll OS 8.0 version.<br />
<br />
Other usages that I can thing of:<br />
<br />
<ul>
<li>Flurry SDK changes the name of the namespace for the Api class for WP7SDK to WP8SDK (bad choice when you need code sharing). If you want to keep the same code for the OS 7.1 and the OS 8.0 version of the app you will have to use conditional compiling for every file where you use the Api class. Much easier would be to create an OS 8.0 library project with the default namespace WP7SDK and forward the Api class to the WP8SDK added as a reference to the library project. This way the old WP7SDK will continue to work as it was on the OS 8.0 using the OS 8.0 version of the Flurry SDK.</li>
<li>MVVM Light. If you use inside your XAML the EventToCommand this is not xaml shareable between OS 7.1 and OS 8.0 because the assemblies changes from GalaSoft.MvvmLight.Extras.WP71.dll to GalaSoft.MvvmLight.Extras.WP8.dll. The easiest approach in this case (an open source) would be to recompile the dll and use the same name for both versions of the dll. But if you don't have access to the source code of the dll you could use type forwarding. Also a third approach would be to derive your on class like MyEventToCommand and use this inside the xaml.</li>
</ul>
<div>
Keep in mind this neat feature because you might need it. I would also love to see, in the next version of the SDK, the possibility to use MarkupExtension this way we could conditionally compile parts of the XAML depending on the version of the SDK the app is running on. Have a look at <a href="http://joshsmithonwpf.wordpress.com/2008/06/12/conditionally-adding-elements-declared-in-xaml-to-the-element-tree/">this blog post</a> that explains how it works on WPF projects.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<a href="http://sdrv.ms/18wqfT0">SOURCE CODE</a></div>
</div>
<br />
Till next post NAMASTE and have fun coding for Windows Phone!Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com1tag:blogger.com,1999:blog-2972549243194132227.post-76718181619829771462013-05-01T15:33:00.000+02:002013-05-02T10:49:54.396+02:00Enable Azure Mobile Services for "pure" Windows Phone 7.1 Xna Games<div style="text-align: justify;">
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 <a href="http://nuget.org/packages/WindowsAzure.MobileServices">NuGet</a> as I remembered that the prerelease version works also for Windows Phone OS 7.x applications. <br />
<br />
The "problem" is that the library will not install if the game is a pure Xna Windows Phone project. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRD_H5f6JRRuYHlGd5cp3Y_tYxVQqnFkyv6Fr_0dnlo6j64GFGsMv11hIO1c0Xhkj7Q09D60KOSjSEBpVqHkJMMDQHTt-E2sTmE4kFWslEUU6sSxG0JGPNZeoSGYYbwiz7vuK41eUrHdQ/s1600/PackageConsole.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRD_H5f6JRRuYHlGd5cp3Y_tYxVQqnFkyv6Fr_0dnlo6j64GFGsMv11hIO1c0Xhkj7Q09D60KOSjSEBpVqHkJMMDQHTt-E2sTmE4kFWslEUU6sSxG0JGPNZeoSGYYbwiz7vuK41eUrHdQ/s400/PackageConsole.PNG" width="400" /></a></div>
<br />
There are 2 (maybe 3 :) ) solutions to this problem:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
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:</div>
<ul>
<li><div style="text-align: justify;">
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):</div>
</li>
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
</code></pre>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDsccUsdWEqBb-yXcLAwHWla0AB_b27u-ZzcWa-Gt_ag2MS-cGHSu6dZeeUSjpvvnPNPZkbmjO2S5iijjHfOZxP0UouX1uheHB_JfD-A3lqCOLOiW28V6hq-VydXjYVPpY87eQ2JZsI3Y/s1600/Proj.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDsccUsdWEqBb-yXcLAwHWla0AB_b27u-ZzcWa-Gt_ag2MS-cGHSu6dZeeUSjpvvnPNPZkbmjO2S5iijjHfOZxP0UouX1uheHB_JfD-A3lqCOLOiW28V6hq-VydXjYVPpY87eQ2JZsI3Y/s400/Proj.png" width="400" /></a></div>
<ul>
<li><div style="text-align: justify;">
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: </div>
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> Install-Package WindowsAzure.MobileServices -Pre
</code></pre>
the package should now install. </li>
<li>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.</li>
</ul>
<br />
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:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="-ms-word-wrap: normal; color: black;"> void TestAzureMobile()
{
todoitem item = new todoitem { Text = "Awesome item XNA" };
ms.GetTable<todoitem>().InsertAsync(item).ContinueWith((task)
=>
{
//do what you need here
});
}
</code></pre>
<br />
<div style="text-align: justify;">
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'.<br />
<br />
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).<br />
</div>
<div style="text-align: justify;">
</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com5tag:blogger.com,1999:blog-2972549243194132227.post-65621047831476662722013-04-24T21:59:00.000+02:002013-05-17T09:32:31.260+02:00Detect the screen resolution for Windows Phone OS 7.1 applications<div style="text-align: justify;">
As you probably know Windows Phone 7.1 applications run perfectly on Windows Phone 8 devices. This means that your application/s could run on multiple display resolutions (which are the resolutions supported by Windows Phone 8 devices). If you want to take advantage of the new resolutions (for example downloading higher quality images for higher resolutions devices, fix some minor UI anomalies on higher resolutions) you will need to know the ScaleFactor of the device. The property is only available in the Windows Phone 8.0 SDK, but the good news is that you can access it using reflection.<br />
<br />
Solution:</div>
<div style="text-align: justify;">
We retrieve the Get method of the ScaleFactor property and invoke it only if the application is running on an Windows Phone 8 device.</div>
<div style="text-align: justify;">
<br />
Here is the source code:</div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public static Size DisplayResolution
{
get
{
if (Environment.OSVersion.Version.Major<8)
return new Size(480,800);
int scaleFactor=(int) GetProperty(Application.Current.Host.Content, "ScaleFactor");
switch (scaleFactor)
{
case 100:
return new Size(480, 800);
case 150:
return new Size(720, 1280);
case 160:
return new Size(768, 1280);
}
return new Size(480, 800);
}
}
private static object GetProperty(object instance, string name)
{
var getMethod= instance.GetType().GetProperty(name).GetGetMethod();
return getMethod.Invoke(instance, null);
}
</code></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I am also attaching a small sample Windows Phone OS 7.1 test project.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqK4cKDzcSoxxCS5Cm4U-0g6yxYmNRr9T7CSkM4boeTZwt2fqp2g_6BTahEaQdcJFG6bbaCwOoAxhNqOJSZxyPu4b6Wpx0UGnVgzxrxm1XIEuPb7SKsMzoVGxKam2Gj11Vxku3ymOSz3Y/s1600/DisplayResolution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqK4cKDzcSoxxCS5Cm4U-0g6yxYmNRr9T7CSkM4boeTZwt2fqp2g_6BTahEaQdcJFG6bbaCwOoAxhNqOJSZxyPu4b6Wpx0UGnVgzxrxm1XIEuPb7SKsMzoVGxKam2Gj11Vxku3ymOSz3Y/s320/DisplayResolution.png" width="192" /></a></div>
<br />
<a href="http://sdrv.ms/YiuEXH">SOURCE CODE</a><br />
<br />
P.S. I think Telerik could use this method to fix this RadToolTip visual anomaly (the 1 pixel width lines that I have filled with blue for contrast) :<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiskNh4BZzZtTbtpnwr-2Q8S75f78sATrcH-xjjrXhKBfKzb1LtDMX9Vefh2zJZmPpkS2idSOkndSMlRLONOuLQHCfL06PcakT_xepW4BUfV1PAU8pa0KNeyIlBI2iAVcrldSJhY_OPshk/s1600/Anomaly.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="103" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiskNh4BZzZtTbtpnwr-2Q8S75f78sATrcH-xjjrXhKBfKzb1LtDMX9Vefh2zJZmPpkS2idSOkndSMlRLONOuLQHCfL06PcakT_xepW4BUfV1PAU8pa0KNeyIlBI2iAVcrldSJhY_OPshk/s320/Anomaly.png" width="320" /></a></div>
<div>
<br /></div>
</div>
<br />
NAMASTEAnonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com3tag:blogger.com,1999:blog-2972549243194132227.post-90645875835340724522013-04-17T08:00:00.000+02:002013-05-17T09:32:10.350+02:003 ways to force the WebBrowser control to logout from Facebook<div style="text-align: justify;">
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): </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Method 1</b>: described by Rene Schulte in this <a href="http://kodierer.blogspot.it/2012/01/let-me-out-facebook-logout-in-windows.html">blog post </a> </div>
<div style="text-align: justify;">
The method constructs the logout Uri using your AppId and a SessionKey that is obtained from the AccessToken you got when the user authenticated.</div>
<div style="text-align: justify;">
<br />
Get the SessionKey:</div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> private static string ExtractSessionKeyFromAccessToken(string accessToken)
{
if (!String.IsNullOrEmpty(accessToken))
{
var parts = accessToken.Split('|');
if (parts.Length > 2)
{
return parts[1];
}
}
return String.Empty;
}
</code></pre>
</div>
<div style="text-align: justify;">
<br />
Obtain the logout Uri:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 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);
}
</code></pre>
<br />
Make the WebBrowser navigate to the logout Uri:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Browser.Navigate(FacebookService.GetLogoutUri(EndpointData.Settings.Facebook));
</code></pre>
<br />
<b>Method 2:</b><br />
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 <span style="color: blue;">https://www.facebook.com/logout.php</span> and after the page gets loaded you just execute the script <span style="color: blue;">document.forms['logout_form']</span>:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> wb.LoadCompleted += wb_LoadCompleted;
wb.Navigate(new Uri("https://www.facebook.com/logout.php"));
</code></pre>
Once the page gets loaded:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 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();");
}
</code></pre>
<br />
<b>Method 3:</b><br />
This is the easiest one, but will only work on Windows Phone 8: call the new WebBrowser async method <span style="color: blue;">ClearCookiesAsync(). </span>This method works for every OAuth provider (Dropbox, Box, Skydrive, Picasa, Flickr, Google Drive... infinite list).<br />
<br />
NAMASTE</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com1tag:blogger.com,1999:blog-2972549243194132227.post-13080838175099900452013-04-02T20:26:00.001+02:002013-05-17T09:31:55.272+02:00Smooth scrolling content on Windows Phone<div style="text-align: justify;">
Gotta say that I am not 100% satisfied about the title of this blog post, but since I haven't found a better one I will use this one (don't get it wrong windows phone has smooth scrolling implemented). This post is focusing on how to smooth scroll the content of a <b>ScrollViewer</b>. If you are using the ScrollViewer you know that it already has the method <b>ScrollToVerticalOffset </b>that can be used to manually scroll the content but this method doesn't have any animation implemented so you will see only a fast redraw of the new content without getting the "feeling" that the content scrolled to the new position. The easiest way to achieve this task would be using a StoryBoard with an Animation on the property VerticalOffset of the ScrollViewer, but VerticalOffset is a read-only property so it cannot be set and therefore cannot be used for animation.</div>
<div style="text-align: justify;">
The solution I found was to build a custom control and add a custom property that can be used as a target for a DoubleAnimation. The attached sample (see the link at the end of the post) is using a ListBox as the content of my Custom Control but you can use anything else inside the control (a better approach for the ListBox would be to create a custom control derived directly from ListBox and use the built-in ScrollViewer). </div>
<div style="text-align: justify;">
Let's start from the XAML part of the User Control:<br />
<br /></div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <ScrollViewer x:Name="scroller">
<ContentPresenter Content="{Binding ContentArea, ElementName=userControl}"/>
</ScrollViewer>
</code></pre>
</div>
<div style="text-align: justify;">
<br />
So we have a ScrollViewer which inside has a ContentPreseter that has its content binded to the control's property ContentArea. Now let us have a look at the .cs code.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register("VerticalOffset",
typeof(double), typeof(SmoothScroller), new PropertyMetadata(VerticalOffsetPropertyChanged));
public double VerticalOffset
{
get { return (double)this.GetValue(VerticalOffsetProperty); }
set { this.SetValue(VerticalOffsetProperty, value); }
}
private static void VerticalOffsetPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
{
SmoothScroller cThis = sender as SmoothScroller;
cThis.scroller.ScrollToVerticalOffset((double)args.NewValue);
}
public static readonly DependencyProperty ContentAreaProperty = DependencyProperty.Register("ContentArea", typeof(object), typeof(SmoothScroller), null);
public object ContentArea
{
get { return (object)GetValue(ContentAreaProperty); }
set { SetValue(ContentAreaProperty, value); }
}
</code></pre>
<br />
The property that we will use for animation is the VerticalOffset that uses the method VerticalOffsetPropertyChanged to scroll to a vertical offset inside the control's scroller. The property VerticalOffset can be animated and we will use it to smooth scroll the ListBox content.<br />
Here is the content of the MainPage.xaml<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <uc:SmoothScroller x:Name="smoothScroller">
<uc:SmoothScroller.ContentArea>
<ListBox x:Name="lstItems" ItemsSource="{Binding Items}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemTemplate="{StaticResource DataTemplate}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</uc:SmoothScroller.ContentArea>
</uc:SmoothScroller>
</code></pre>
<br />
So we have the SmoothScroller control which inside its ContentArea has a ListBox (the ListBox has it's scrollviewer disabled). What the sample does is it is changing the selected item every second (incrementing the selectedindex) and scrolls the content so that the newly SelectedItem is centered in the ScrollViewer. Here is the code used for scrolling:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> void dt_Tick(object sender, EventArgs e)
{
((ListBox)smoothScroller.ContentArea).SelectedIndex = idx;
var container = ((ListBox)smoothScroller.ContentArea).ItemContainerGenerator.ContainerFromIndex(idx) as FrameworkElement;
var transform = container.TransformToVisual(smoothScroller.scroller);
var elementLocation = transform.Transform(new Point(0, 0));
double newVerticalOffset = elementLocation.Y + smoothScroller.scroller.VerticalOffset - smoothScroller.scroller.ActualHeight / 2 ;
//Animate transition
DoubleAnimation verticalAnimation = new DoubleAnimation();
verticalAnimation.From = smoothScroller.scroller.VerticalOffset;
verticalAnimation.To = newVerticalOffset;
verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
var sb = new Storyboard();
sb.Children.Add(verticalAnimation);
Storyboard.SetTarget(verticalAnimation, smoothScroller);
Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(SmoothScroller.VerticalOffsetProperty));
sb.Begin();
idx++;
if (idx >= 56)
dt.Stop();
}
</code></pre>
<br />
Pretty basic: select the new index in the ListBox, calculate the new VerticalOffset so that the newly selected item is centered in our scrollviewer and create and start a 500ms animation for the SmoothScroller.VerticalOffsetProperty. Anyway I am sure that you will better understand how it works when you will try the sample code.<br />
The sample is far from perfect (before starting a new animation I should check if the old one finished, should not automatically scroll when the user is manipulating the list,...).<br />
Here is a screenshot from the sample:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg135mQ17yNJ08RCkYcYm1XMIEZM32lRZsV0XzttI3RK2M_L6nKKUKFBwVE6i5SI1KaKA_mdKfy8hmnAePwWFfrsGYnLCSULiUPyQLiGimexjBQKKyAhHI1b2oz-iuHCLhTeydNyOFyo7o/s1600/SmoothScrolling.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg135mQ17yNJ08RCkYcYm1XMIEZM32lRZsV0XzttI3RK2M_L6nKKUKFBwVE6i5SI1KaKA_mdKfy8hmnAePwWFfrsGYnLCSULiUPyQLiGimexjBQKKyAhHI1b2oz-iuHCLhTeydNyOFyo7o/s320/SmoothScrolling.png" width="192" /></a></div>
<br />
As usual let me know if you need help. The code works on both Windows Phone 7.1 and Windows Phone 8 SDK.<br />
<br />
<a href="http://sdrv.ms/12b8p7i"><b>SOURCE CODE</b></a><br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com1tag:blogger.com,1999:blog-2972549243194132227.post-16010075682438508192013-03-24T18:58:00.001+01:002013-03-24T18:58:46.269+01:00Small tip on XAudio2 for Windows Phone<div style="text-align: justify;">
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:</div>
<br />
<ul>
<li><span style="font-family: inherit; text-align: justify;">When your app is suspended, call </span><a href="http://go.microsoft.com/fwlink/?LinkId=272565" style="color: #1155cc; font-family: inherit; text-align: justify;" target="_blank">IXAudio2::StopEngine</a><span style="font-family: inherit; text-align: justify;">.</span></li>
<li><span style="font-family: inherit; text-align: justify;">When your app is resumed, call </span><a href="http://go.microsoft.com/fwlink/?LinkId=272566" style="color: #1155cc; font-family: inherit; text-align: justify;" target="_blank">IXAudio2::StartEngine</a><span style="font-family: inherit; text-align: justify;">.</span></li>
</ul>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
NAMASTE</div>
<br />
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-16427825838399160332013-03-22T17:20:00.000+01:002013-05-17T09:26:27.305+02:00How to add songs to the emulator's MediaLibrary<div style="text-align: justify;">
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:</div>
<br />
[ExtensionAttribute]<br />
<br />
<pre><span style="color: blue;">public</span> <span style="color: blue;">static</span> Song SaveSong (
MediaLibrary library,
Uri filename,
SongMetadata songMetadata,
SaveSongOperation operation
)
</pre>
<pre></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;"> The method requires the </span><b>ID_CAP_MEDIALIB_AUDIO</b><span style="font-family: 'Times New Roman'; white-space: normal;"><b> </b>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 </span><span style="font-family: Times New Roman;"><span style="white-space: normal;">InvalidOperationException</span></span><span style="font-family: 'Times New Roman'; white-space: normal;">. 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.</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;">
</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;"> To copy the file to the IsolatedStorage you can use the:</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;"><pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> var resource = Application.GetResourceStream(new Uri(@"Assets/Songs/"+fileName, UriKind.Relative));
resource.Stream.CopyTo(fileStream, 4096);
</code></pre>
</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;">
</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;">
</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;">or you can use the WinRT Api to read the asset file:</span></pre>
<pre style="text-align: justify;"><span style="font-family: 'Times New Roman'; white-space: normal;"><pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> songUri=new Uri("ms-appx:///Assets/Songs/"+fileName,UriKind.Absolute);
var file=await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(songUri);
</code></pre>
</span></pre>
<pre style="text-align: justify;"></pre>
<div style="text-align: justify;">
<br />
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 <b>null </b>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 <a href="http://id3.codeplex.com/">ID3.NET</a> 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:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Id3.Mp3Stream mp3 = new Id3.Mp3Stream(resource.Stream);
if (mp3.HasTags)
{
}
</code></pre>
</div>
<div style="text-align: justify;">
<br />
<br /></div>
<div style="text-align: justify;">
NAMASTE</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com0tag:blogger.com,1999:blog-2972549243194132227.post-37616116357863542132013-03-18T20:26:00.000+01:002013-05-17T09:31:41.345+02:00How to debug Windows Phone HTML5 Apps<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
The "secret" tool for debugging the html content inside our applications is called <a href="http://people.apache.org/~pmuellr/weinre-docs/latest/" target="_blank">WEINRE</a> 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. </div>
<div style="text-align: justify;">
In order to install Winre you will need to download and install <a href="http://nodejs.org/" target="_blank">NodeJS</a><br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg23KLs113JgBEFM1HvoHs7bwH6A2D_P2DzH292ycMVg_M4HmzIZmOf1pXodluuuiqrUGsYspgnRDUK_o0KNEGNA5iirOWQvFoYSNn8pmJ1ucvmpRxRmTSXHTi9JBJpD40V5ox6FuDceJo/s1600/NodeJS.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg23KLs113JgBEFM1HvoHs7bwH6A2D_P2DzH292ycMVg_M4HmzIZmOf1pXodluuuiqrUGsYspgnRDUK_o0KNEGNA5iirOWQvFoYSNn8pmJ1ucvmpRxRmTSXHTi9JBJpD40V5ox6FuDceJo/s320/NodeJS.PNG" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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:</div>
<div style="text-align: center;">
<pre style="background-color: #f0f0f0; background-position: initial initial; background-repeat: initial initial; border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: center; width: 99%;"><code style="color: black; word-wrap: normal;"> npm install weinre -g
</code></pre>
</div>
<div style="text-align: justify;">
This will install the Weinre package globally. This is what you should see in the Command Prompt window:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVMOYcnDz1XJrNAwgAcS6TQPmcs01ZvUu2gCJtVXVhcaDi4SkcQWoyAinYyyLaJ19Knz_TsKjkS8HbVk4Dzd5ICHVkyNn4YRLJCv5Snk_EBfpsGOZHQ3z0UKezKDMqoJlqsI52qA4E7vo/s1600/InstallWeinre.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVMOYcnDz1XJrNAwgAcS6TQPmcs01ZvUu2gCJtVXVhcaDi4SkcQWoyAinYyyLaJ19Knz_TsKjkS8HbVk4Dzd5ICHVkyNn4YRLJCv5Snk_EBfpsGOZHQ3z0UKezKDMqoJlqsI52qA4E7vo/s400/InstallWeinre.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
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:</div>
<div style="text-align: center;">
<pre style="background-color: #f0f0f0; background-position: initial initial; background-repeat: initial initial; border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: center; width: 99%;"><code style="color: black; word-wrap: normal;"> weinre --boundHost -all- --debug -true
</code></pre>
</div>
<div style="text-align: justify;">
With these parameters Weinre should also open the firewall port. For more parameters have a look at this <a href="http://people.apache.org/~pmuellr/weinre-docs/latest/Running.html" target="_blank">page</a>. 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:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYUmnNcVWS2MvPCiUttuY4Iyg7hRvuquQTn_T6SFi9P836Zkea_QJXEsaNa6D1RiIJwaP_vuAsaAIZiAxQmzQJfazco2N6Wxb00GhfDshyphenhyphen1Ach8-q-Oeiw6Hj1knB5h7jeM7nl1nVQp5Q/s1600/Remote.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYUmnNcVWS2MvPCiUttuY4Iyg7hRvuquQTn_T6SFi9P836Zkea_QJXEsaNa6D1RiIJwaP_vuAsaAIZiAxQmzQJfazco2N6Wxb00GhfDshyphenhyphen1Ach8-q-Oeiw6Hj1knB5h7jeM7nl1nVQp5Q/s400/Remote.PNG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
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.</div>
<div class="separator" style="clear: both; text-align: left;">
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:</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPdmzy_x1WcOtyNW8SKSWexACMmIGE8nY6NNLYur4RsOlcz5c54j6TASv5iDXgImbt-6wqVMlJvjL8NX4QqTqDcbXlQdViH92Tddg29nNBgfUNQJXbMOH99bfnZ1PErcPq7k92BsEnvg8a/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <script src="http://[the server ip]:8080/target/target-script-min.js#anonymous"></script>
</code></pre>
<div style="text-align: justify;">
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:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifYfJC_9B1t1ZUDm0tAT2f_WNPaWKKeRuxX3U3V_R4331D5KeD-dXCoPASMurXSYVVhCw0iNGTFDnHMy7SE8NtIxHx3Y1Q4XnF2BQtB5oFxB6YhbsY9iUl0fHgE5fr25cAZF_FL08PCdg/s1600/Connected.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifYfJC_9B1t1ZUDm0tAT2f_WNPaWKKeRuxX3U3V_R4331D5KeD-dXCoPASMurXSYVVhCw0iNGTFDnHMy7SE8NtIxHx3Y1Q4XnF2BQtB5oFxB6YhbsY9iUl0fHgE5fr25cAZF_FL08PCdg/s400/Connected.PNG" width="400" /></a></div>
Once the target Windows Phone page is connected you can inspect and change the DOM in real-time, execute javascripts:<br />
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAhXOSWlynjW9WlGTj5zGdujpbP1icmCPyTrPd91H9ebB-oUhzY1HnB3dlVXWF9fte0L2mJL8Y6kwJqLHF_6BlcQdVyMGOfK9kVjDsYxTuXyPTMnhXDGGiJFDzihCTRudLT0BtNg-lqf8/s1600/Debug.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="433" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAhXOSWlynjW9WlGTj5zGdujpbP1icmCPyTrPd91H9ebB-oUhzY1HnB3dlVXWF9fte0L2mJL8Y6kwJqLHF_6BlcQdVyMGOfK9kVjDsYxTuXyPTMnhXDGGiJFDzihCTRudLT0BtNg-lqf8/s640/Debug.PNG" width="640" /></a> </div>
<br />
In this particular case I've only changed the background of the page but you can do whatever you want. <a href="http://people.apache.org/~pmuellr/weinre-docs/latest/UserInterface.html">Here </a>you can find further details on how to use the Server User Interface.<br />
Using the Console panel you can execute arbitrary JavaScript expressions/statements. It also shows the output from various console methods, like console.log().<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivR8ZQq9VfUNdD8gtqbKRsoyn09bJ6F4NnD-CLpu6yR20zerh7wteikwjc3FxwIy_Mji8EABY6DZk3Vq6HE4RH9IKZMX8qcamcfztLuNLGKWjlE1Px1eKAQapd8EF2ci5QM-wCgfpN5Xg/s1600/HtmlCommands.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivR8ZQq9VfUNdD8gtqbKRsoyn09bJ6F4NnD-CLpu6yR20zerh7wteikwjc3FxwIy_Mji8EABY6DZk3Vq6HE4RH9IKZMX8qcamcfztLuNLGKWjlE1Px1eKAQapd8EF2ci5QM-wCgfpN5Xg/s320/HtmlCommands.PNG" width="320" /></a></div>
<br />
<br />
This is pretty much everything. Simple and veryyyyyy useful if you need to debug your HTML5 windows phone applications.<br />
As usual don't hesitate to contact me if you have further questions.<br />
<br />
NAMASTE</div>
Anonymoushttp://www.blogger.com/profile/06272690182889611423noreply@blogger.com8