Nouvelle propriété de GDR3 : PowerSavingModeEnabled

GDR3 apporte peu de nouveautés au niveau SDK, toutefois, quelques propriétés ont été ajoutés. Comme le SDK n’a pas changé, on ne peut y avoir accès qu’en utilisant la reflection.

Une de ces nouvelles propriétés est PowerSavingModeEnabled, propriété permettant de savoir si l’utilisateur à activé le mode « économie d’énergie ». Attention, on parle bien d’activation et non si le téléphone est en train d’utiliser le mode économie qui est représenté par la propriété PowerSavingModeEnabled (http://msdn.microsoft.com/en-US/library/windowsphone/develop/windows.phone.system.power.powermanager.powersavingmode(v=vs.105).aspx).

Accéder à cette méthode

Première chose à faire, tester si GDR3 est bien sur le téléphone :


if(Environment.OSVersion.Version>= new Version(8, 0, 10492))

ensuite il suffit d’utiliser la reflection pour accéder à cette nouvelle propriété :


var props = (bool)typeof (Windows.Phone.System.Power.PowerManager).GetProperty("PowerSavingModeEnabled").GetValue(null,null);

Conclusion

J’avoue, ce n’est pas la propriété la plus utile, mais elle saura satisfaire tous les créateurs d’app « tuile raccourci vers les settings ».

Modulo dans tous ses états

Une de mes autres passions est les mathématiques, outil indispensable à l’informaticien .

Nous allons nous pencher aujourd’hui sur un élément assez controversé dans l’algorithmique et dans les mathématiques : le modulo.

Classiquement, on sait qu’un modulo est le reste de la division de deux nombres. Pour l’instant, on a juste, mais comment doit se comporter notre modulo quand on a des nombres négatifs ?

Imaginons que nous souhaitons faire la rotation d’une image selon un angle donné en argument. La fonction rotation de la librairie Imaging SDK par exemple, prend en paramètre uniquement des nombres compris entre 0 et 360. Solution : utiliser un modulo.

angle % 360

Si nous avons en entrée l’angle de 375°, un petit modulo 360 et nous passons à 15°, logique et normal. Maintenant imaginons que l’on passe l’angle de -15° en paramètre. Nous allons nous attendre à avoir 345°, mais non… le modulo nous retourne -15. Alors bug ou pas ?

Les modulos

En fait non, la subtilité est qu’il n’y a pas un type de modulo mais trois :

  • le modulo entier qui retourne un nombre entre 0 et le diviseur (si celui-ci est négatif, le résultat sera négatif)
  • le modulo tronqué qui retourne un nombre du même signe que le dividende
  • le modulo euclidien qui retourne toujours un nombre positif

Au niveau algorithmique, à titre personnel, je préfère le modulo euclidien mais dans le cas du framework .Net,c’est un modulo tronqué, dommage pour nous, c’est le seul qui ne respecte pas la loi modulaire : (x+n) mod n = x mod n

En effet,

-5 % 11 == -5

(-5+11) % 11 = 6

Le modulo euclidien en .Net

Dans notre exemple précédent, nous souhaitons utiliser un modulo euclidien, qui retourne toujours un résultat positif.

Voici une implémentation :

a<0?((a % n) + n) % n:a%n

Un peu plus lourd, mais plutôt efficace.

Et C++?

Jusqu’à C++/11, le comportement du modulo negatif n’était pas indiqué (et de façon explicite), c’était au compilateur/processeur de choisir, pas top pour la portabilité.

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.

 

Ceci dit, dans la majorité des cas, le modulo suivait les règles héritées par le Fortran, c’est à dire, le modulo tronqué.

Avec C++/11 les choses sont devenus plus clair et le choix a été fait d’utiliser obligatoirement le modulo tronqué.

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded;81 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.

 

Bilan

Attention aux a priori et vérifiez toujours ce que les fonctions .Net retournent

Tester l’in-app purchase dans son application like a boss

Lorsque l’on développe une application avec in-app purchase, viens le moment où on veut la tester.

Pour cela, deux méthodes sont proposées par microsoft, histoire de gagner du temps, je vous conseille de lire l’article de Florian Rousselet qui résume très bien avec détails les deux solutions : http://blog.soat.fr/2013/09/windows-phone-8-ajouter-lin-app-purchase-a-votre-application/

Je n’aime pas la première méthode, elle est très bien pour tester rapidement, mais ce n’est pas un test en situation réelle. La seconde méthode est mieux, mais est longue (2h) et surtout impossible de déboguer son app depuis visual.

Personnellement, j’utilise une 3ème méthode, non documentée et beaucoup plus efficace. Nous allons passer par une application beta mais sans les inconvénients (attendre 2h, pas de déboguage, etc…)

Explication

Commençons par créer notre application beta, puis ajoutons lui des in-app purchase. Pour l’instant c’est très classique. Voici donc l’astuce : récupérez le product-id de votre application beta et utilisez le dans votre projet visual. C’est très simple mais pourtant « terriblement efficace ». Mieux encore, il n’est même pas nécessaire de soumettre votre application beta, voire même d’envoyer un xap.

Une fois votre application déployée sur votre téléphone, elle va interroger les serveurs de microsoft en utilisant son product-id pour savoir quels sont les in-app purchase qui lui sont accessible, mais comme le product-id correspond à une vrai application (beta), le serveur va bel et bien vous retourner les in-app purchase de votre application beta.

Vous pourrez ainsi déboguer votre application dans des vrais conditions, sans attendre et surtout directement depuis votre visual.

Comment récupérer le product id de mon application beta.

  • Créer une nouvelle application et indiquez bien que c’est une application beta.
  • Ne passez pas par l’étape 2, retournez sur le dashboard puis dans apps et retournez sur la fiche de votre application

Capture

 

  • cliquez sur « Products » et sur « add products »

Capture

 

  • ajoutez vos in-app purchase
  • une fois tout ceci fait, regardez l’url de votre page, celle-ci doit ressembler à :

https://dev.windowsphone.com/en-us/ApplicationDetails?productId=2017469a-6b04-467f-b57d-90a892a7ed8b&applicationDetailsView=2

Votre product-id est dedans, dans notre cas : 2017469a-6b04-467f-b57d-90a892a7ed8b

  • changez la valeur du product-id dans votre WMAppManifest.xaml
  • dites vous que vous avez gagnez bcp de temps et d’énergie

La surprise du chef

Une chose que l’on oublie souvent, c’est qu’il est possible de transformer une application beta en application normale, donc inutile de re-entrer vos in-app purchases, vos descriptions, etc…

How to upload a picture on instagram from your app using 6tag

6tag, my new client application for Instagram is now released. It enables you to upload pictures and video on instagram, but also facebook, flickr, tumblr, etc… as well as use filters to get the best picture ever.

If you want add this functionality to your windows phone 8 app, no problem, I created a uri protocol for that !

The uri protocol

Here is the uri protocol to use to share image using 6tag

sixtag://upload/[action]/[picture-name]/[your-app-id]
action:
  • crop : display the crop/zoom page to create a 612*612 picture, then filter, then upload page
  • filter : display directly the filter page, picture must be square, then the upload page
  • direct : display directly the upload page, picture must be a square
picture-name: name of the picture in the media library
your-app-id: the product id of your app, to promote it in a upcoming page « app that use 6tag »

How to save picture in media library?

To share an image with 6tag, the image must be saved in the media library of the phone.


Microsoft.Xna.Framework.Media.MediaLibrary medialibrary = new Microsoft.Xna.Framework.Media.MediaLibrary();
medialibrary.SavePicture("MonApp-" + imageId, streamOfThePicture);

How to launch 6tag to share picture ?

 

Windows.System.Launcher.LaunchUriAsync(new System.Uri("sixtag://upload/crop/"+HttpUtility.UrlEncode(picturename)+"/"+HttpUtility.UrlEncode(appid)));

How much it costs ?

Nothing for the developer, nothing for the user, upload pictures is included in 6tag for free without in-app purchase and without limit.

 

Comment empêcher le scrolling d’une page quand on sélectionne un textbox

Lorsque l’on sélectionne un textbox dans une application windows phone, la page va automatiquement scroller avec d’afficher le textbox au dessus du clavier. Bien que souvent très utile, il y a des cas où on ne souhaite pas ce comportement et c’est le besoin que j’ai rencontré avec 6Sec.

On trouve beaucoup de solutions sur internet, la plupart ayant comme principe d’utiliser un translatetransform et de s’enregistrer sur les rendertransform de la frame principale de l’application sur la page pour « compenser » le déplacement de la page. Bonne idée en soit mais catastrophique en fait, car à chaque fois que l’utilisateur saisira un caractère, le système va recalculer le déplacement idéal, or comme on aura déplacé la page pour compenser, il va recalculer une nouvelle position idéal, que l’on va ensuite compenser, puis il va recalculer, etc… en ne faisant pas attention, on arrive vite à des translatetransform de 1000 sur la page et de -1000 sur la frame avec des performances qui diminue au fur et à mesure de la congestion.

Comment faire alors ?

En fait, c’est très très simple, il suffit juste de supprimer temporairement le rendertransform de la frame, ainsi, elle ne sera plus dans la capacité de se déplacer.

frame.RenderTransform = null;

Sauf que l’on ne veut pas perturber le fonctionnement des autres pages, on va donc le faire uniquement quand on affiche la page.

Dans la méthode OnNavigatedTo on va supprimer ce rendertransform et le stocker dans une variable locale :


PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
_exrender = frame.RenderTransform;
frame.RenderTransform = null;

puis dans OnNavigatingFrom, on va réaffecter l’ancienne transformation :


PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
frame.RenderTransform = _exrender;

Et voilà ! Votre page ne se déplacera plus automatiquement maintenant !

 

 

How to launch the official youtube app from your app

 

YouTube

Since this morning, ‘metro tube’ developers enable third-party developers to use their app to play youtube video instead of embed a custom youtube player in their applications.

http://lazywormapps.com/metrotube-URI-schema.html

This is cool, but personally, I won’t do that, cause I trust only the official player for several reasons:

  • It’s supported by Microsoft, more stable and less risky, ‘Metro tube’ using a hack to retrieve Urls of the mp4 video, it happened several times in the past that the application no longer works for days, a good way to have negative comments in your own application.
  • There is a risk that the application be removed by Youtube for non-compliance with the youtube TOS
  • Metro tube is a paid application, I do not want to impose this on my users.
  • Other apps can use the same protocol extension and can be crappy
The question now is:

How to launch the official player?

For this, you only need to use the protocol extension of the official application: vnd.youtube.

So create a launcher et use the youtube video id as a parameter.

For example, the video id of http://www.youtube.com/watch?v=9bZkp7q19f0 is ’9bZkp7q19f0′ :


Windows.System.Launcher.LaunchUriAsync(

new System.Uri("vnd.youtube:9bZkp7q19f0")

);

Commencer lancer le player officiel Youtube depuis son application ?

 

YouTube

Les développeurs de l’application Metro tube font actuellement la promo de leur app en proposant aux développeurs tierces d’utiliser le protocole d’extension pour lancer leurs apps au lien d’intégrer un player youtube directement dans son application.

http://lazywormapps.com/metrotube-uri-schema.html

La chose est louable, mais personnellement, je ne ferais confiance qu’au player officiel pour plusieurs raisons :

  • Il est supporté par Microsoft, donc beaucoup plus stable, Metro tube utilisant un hack pour récupérer les uri des vidéos, il est arrivé plusieurs fois dans le passé que l’application ne fonctionne plus pendant des jours, un bon moyen pour avoir des commentaires négatifs dans sa propre application sans en être la case
  • Un risque existe que l’application soit retiré du jour au lendemain du Store pour non respect des TOS de youtube
  • Metro tube est une application payante, je ne souhaite pas imposer cela à mes utilisateurs.
  • N’importe quel autre app peut se brancher sur le même protocole que metro tube et avoir une qualité bcp moindre

La question maintenant est :

Comment lancer le player officiel ?

Pour cela, il suffit d’utiliser le protocole d’extension réservé à l’application officielle youtube : vnd.youtube.

Créez juste un launcher et passez en paramètre l’identifiant de votre vidéo youtube.

Par exemple, pour la vidéo http://www.youtube.com/watch?v=9bZkp7q19f0, son id est 9bZkp7q19f0 et on peut la lancer en écrivant :


Windows.System.Launcher.LaunchUriAsync(

new System.Uri("vnd.youtube:9bZkp7q19f0")

);

Jouons avec le webbrowser

Dans la communauté développeurs Windows Phone, je reçois régulièrement des questions sur le webbrowser.

Ce mini article va mettre en avant quelques fonctionnalités cachées du webbrowser en passant notammment par la classe d’extension WebBrowserExtensions.

WebBrowserExtensions contient 3 méthodes qui rendraient jaloux tous les développeurs Windows 8

 

GetCookies 

Cette méthode permet de récupérer les cookies d’un contrôle browser de votre application. Il vous sera impossible de récupérer les cookies de l’application « Internet Explorer » du téléphone, votre application et l’application Internet Explorer étant toutes les deux sandboxées. Même s’il faut passer un webbrowser en paramètre, les cookies sont gérées de façon globale dans votre application. Il sera impossible de récupérer les cookies http only via cette méthode.

ClearCookiesAsync

Cette méthode va vous permettre d’effacer les cookies, c’est l’antagonisme de la première, elle permet d’effacer l’ensemble des cookies de votre application. A noter, c’est un tout ou rien, impossible de supprimer qu’une partie des cookies.

ClearInternetCacheAsync

La dernière et non des moindres va vous permettre de supprimer l’ensemble du cache http de votre application, celui-ci étant utilisé quand une page/un script/une image est retournée avec l’attribut cache-control. Comme ClearCookiesAsync, c’est tout ou rien, attention donc.

 

Lister les applications installées de l’auteur sur le téléphone, les lancer, etc…

Comme souvent, je me balade sur  MSDN à la recherche d’un morceau de l’API pas encore explorée. Ce soir, à force de cliquer sur des liens, je suis tombé sur une petite pépite assez intéressante donc autant la partager donc !

Saviez-vous que depuis Windows Phone 8, il est possible de récupérer la liste de vos applications que l’utilisateur possède sur son téléphone ? Maintenant oui, et plus fort il est possible d’avoir aussi des informations afin de savoir si l’application est en cours d’installation ou déjà installée et encore mieux ! Vous pourrez récupérer la date d’installation de l’application ou encore le numéro de version et même l’icone de l’app : MAGIQUE !

Et le meilleur pour la fin : vous avez la possibilité de lancer l’application sans recourir à l’extension de protocole !!!!

Lister les applications de l’auteur sur le téléphone

Cela se fait très simplement :

foreach(var package in InstallationManager.FindPackagesForCurrentPublisher())
{
MessageBox.Show(package.InstallDate + " " + package.Id.Name);

}

Rechercher une application


Package SearchApp(String productId)
{
return InstallationManager.FindPackagesForCurrentPublisher().FirstOrDefault(app => app.Id.ProductId == productId);
}

Lancer une application


{

var package=SearchApp("{91000C5C-9943-43B7-AB65-7609D91057EF}");
package.Launch();

}

Allons encore un peu plus loin, on sait maintenant lancer une application, maintenant voyons comment lancer une page bien précise de votre application !

lancer une page spécifique d’une application


{

var package=SearchApp("{91000C5C-9943-43B7-AB65-7609D91057EF}");
package.Launch("/AboutPage.xaml);

}

On a donc une possibilité de manipulation assez extraordinaire ! En plus de spécifier la page, vous pouvez aussi spécifier des paramètres comme par exemple :


{

var package=SearchApp("{91000C5C-9943-43B7-AB65-7609D91057EF}");
package.Launch("/FluxRSSPage.xaml?uri=rudyhuyn.com");

}

Récupérer l’icône de l’application


{

var package=SearchApp("{91000C5C-9943-43B7-AB65-7609D91057EF}");

var token = package.GetThumbnailToken();

var name = SharedStorageAccessManager.GetSharedFileName(token);

await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, name, NameCollisionOption.ReplaceExisting, token);

using (var file = IsolatedStorageFile.GetUserStoreForApplication().OpenFile(name, FileMode.Open, FileAccess.Read))
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(file);
MonImage.Source = bitmap;
}

}

Et comment faire fonctionner ceci quand mon application n’est pas sur le store ?

En effet, il y a de grandes chances que votre publisher Id de vos application ne correspond pas avec votre publisher id du Store.

Lorsque vous soumettez une application, le Store remplace automatiquement le publisher id de vos apps par celui du store, nous allons donc tout simplement remplacer le publisher ID que visual studio a généré par le votre, pour cela commencez par le récupérer sur la page suivante :

https://dev.windowsphone.com/en-us/account

Capture2

 

puis ouvrez le fichier WMAppManifest.xml de votre application, allez dans l’onglet Packaging et remplacez le Publisher Id par le votre (en n’oubliant pas les accolades)

 

Capture

 

Vous aurez maintenant la possibilité de lister vos autres applications provenant du store.

 

Puis je lancer une application ne m’appartenant pas ?

Non, pour des raisons évidente de sécurité !

Conclusion

Énormément de scénario peuvent découler de ces APIs, quelques exemples en vrac :

- permettre l’accès à des fonctionnalités uniquement si l’utilisateur possède une autre de vos apps

- afficher un message de remerciement : « vous utilisez 4 de nos applications, merci beaucoup, voulez-vous découvrir nos autres applications ? »

- permettre le lancement d’une de vos apps sans exposer publiquement une extension de protocole, vous sécurisez ainsi les communications

- avoir des pages cachées dans vos applications, uniquement accessible depuis une autre de vos apps

- etc…

ff

Rendre vos pages dynamiques en injectant du XAML !

Si vous utilisez mon application Wikipedia, vous avez surement remarqué que la partie supérieure de la page d’accueil varie avec le temps. Quelques exemples :

 

Invitation à lancer un webbrowser pour participer à un concours
wp_ss_20130330_0001

Ouvre le Windows Phone Store pour télécharger une application
wp_ss_20130330_0002

Pour cela la technique est assez simple, à chaque démarrage, l’application fait une requête sur mon serveur en passant sa culture (anglais, français, etc…), et récupère des variables : image url, texte descriptif et le lien.

Selon le type du lien, je lance alors : une page interne de l’application (pour faire découvrir un article bien précis, pour faire découvrir les settings, etc…), un lien internet via un WebBrowserTask ou une page du Windows Phone Store via un MarketplaceDetailTask.

Toutefois, la mise en forme reste assez statique et pour la prochaine version je veux aller en plus en injectant directement du XAML dans la page ! On pourra alors imaginer avoir des animations spécifiques, des sliders, etc…

Comment le faire ?

C’est très très simple, il suffit en fait d’utiliser un XamlReader, et notamment  sa méthode Load qui va permettre de lire du code xaml depuis une string et de générer les différents objets XAML.

Dans l’exemple suivant, nous allons appeler une page php qui va nous fournir du code xaml selon notre culture. Nous donnerons le résultat de cette requête au XamlReader et nous afficherons le résultat dans un panel XAML nommé CommentPanel.

WebClient web = new WebClient();
web.DownloadStringCompleted += (sender, e) =>{
try
{
var xaml = XamlReader.Load(e.Result);
CommentPanel.Content = xaml;
}
catch
{
}

};
web.DownloadStringAsync(new Uri(uri+"?culture="+CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,UriKind.Absolute));

et du côté PHP :


<?php
$culture=$_GET['culture'];
if($culture=='fr'){
?>

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Button Content="Click Me" />
<Slider Minimum="0" Maximum="100" />
</StackPanel>
<?php }else
{
?>
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Background="Red" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<TextBox />
</Grid>
<?php } ?>

Et ça fonctionne !!

wp_ss_20130330_0003

A noter : pensez bien à définir les namespaces sans oublier le namespace par défaut, sinon vous recevrez une exception pendant le chargement du XAML.

 

Comment rendre ceci interactif ?

Il n’est pas possible en effet d’inclure du code-behind dans cette injection afin d’interagir avec les nouveaux éléments XAML (par exemple afficher une page web quand on clique sur un bouton ou lancer une animation), il y a plusieurs solutions.

Pour afficher une page web ou une page interne de votre application, vous pouvez vous reposer sur les spécificités du contrôle HyperlinkButton par exemple :


<HyperlinkButton NavigateUri="http://www.bing.com" />

Une autre solution est de binding vos contrôles à des commandes, en effet, il n’est pas possible de se lier à des event handlers directement comme :

<Button Click="ClickAction" />

Binding ?

Les bindings fonctionnent évidemment ! Vous pouvez écrire sans soucis :

<Button Content="{Binding MyTitle}" />

Toutefois, vous ne pourrez faire référence à des éléments de votre page dans vos bindings (mais vous pouvez référer des éléments de votre XAML dynamique.

Note

Evidemment, vous ne pouvez pas injecté tout et n’importe quoi, il va falloir faire attention à quelles assemblies vous faites appellent et les capabilities de vos applications. Par exemple, pour inclure dynamiquement une pub PubCenter dans votre app, il va falloir que celle-ci contienne déjà une référence à la librairie PubCenter et que vous disposez de toutes les capabilities nécessaire à l’exécution de ce contrôle.