19 avril 2024

Mémoriser qu’un utilisateur a déjà voté

Mémoriser le deviceID sur une base MySQLStocker sur une base MySQL qu’un utilisateur a, normalement, voté.
Le vote pour une application est très important pour la notoriété c’est pourquoi il faut sollicité notre cher utilisateur à donner son avis.

Alors voici ce que je fais : Au bout de trois lancements de l’application je lui ouvre un popup comme l’illustration à droite l’invitant à voter pour mon application. S’il clique sur non, je lui redemanderai dans trois démarrages. S’il clique sur le bouton de vote je l’invite sur la page de vote du Windows Phone Store et je mémorise dans l’IsolatedStorage qu’il a cliqué sur « voter ». Malheureusement, je ne sais pas s’il l’a vraiment fait.

Jusque là, tout va bien seulement si mon utilisateur change de smartphone ou qu’il désinstalle puis réinstalle l’application pour une raison quelconque et bien je vais lui redemandé de voter ?

L’idée que je montre ici est alors de stocker l’information sur une base MySQL en mémorisant le DeviceUniqueId du téléphone (On peut aussi pourquoi pas prendre le WindowsLiveAnonymousID)

Côté hébergement, MySQL et page PHP

Du côté de votre hébergement, il faut une base avec ceci :

    CREATE TABLE `evaluate_application` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `deviceID` text NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Puis créer une page .PHP où on passera 2 arguments, le DeviceID et un paramètre informant d’ajout ou l’interrogation :

<?php
//recupere le deviceID
isset($_GET['qr']) ? $qr = $_GET['qr'] : $qr = 0;
isset($_GET['id']) ? $id = $_GET['id'] : $id = "";

if ($id != "")
{
	$host     = 'votrehost';
	$login    = 'votrelogin';
	$password = 'votrepassword';
	$base     = 'votrebase';

	//connexion à la base de données
	$db = mysql_connect($host, $login, $password);
	$db_selected=mysql_select_db($base,$db);

	//protection
	$id = mysql_real_escape_string($id);

	if ($qr==0) {
		$sql= "SELECT id FROM evaluate_application WHERE deviceID='$id' LIMIT 0,1";

		$query=mysql_query($sql);
		$result=mysql_fetch_array($query);

		if ($result== FALSE)
			echo "";
		else
			echo " ";
	}
	else {
		//le client a certainement voté
		$sql = 'INSERT INTO evaluate_application(deviceID) VALUES("'.mysql_escape_string($id).'")';
		mysql_query($sql);
	}

	mysql_close();
}
?>

Voilà, pour l’essentiel, c’est tout côté site…

Côté code C#

Dans votre projet Windows Phone, votre fichier WMAppManifest.xml doit absolument avoir ID_CAP_IDENTITY_DEVICE et ID_CAP_IDENTITY_USER :

    <Capabilities>
      <Capability Name="ID_CAP_IDENTITY_DEVICE"/>
      <Capability Name="ID_CAP_IDENTITY_USER"/>
    </Capabilities>

Pour identifier l’utilisateur, il y a WindowsLiveAnonymousID ou le DeviceUniqueId. WindowsLiveAnonymousID est certainement un choix plus judicieux car si l’utilisateur achète un nouveau smartphone, et qu’il réinstalle l’application on ne va pas lui redemander de voter (quoique un vote en plus ça se prend, :)) alors que l’utilisation du DeviceUniqueId reste bien évidement propre au téléphone.

Voici la méthode pour obtenir le DeviceUniqueId :

using Microsoft.Phone.Info;
public static string GetDeviceUniqueID()
{
    object _DeviceUniqueID;
    byte[] uniqueId = null;

    if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out _DeviceUniqueID))
    {
        uniqueId = (byte[])_DeviceUniqueID;
    }
    return BitConverter.ToString(uniqueId).Replace("-", "");
}

Ou alors la méthode pour obtenir le WindowsLiveAnonymousID. Attention, bien évidement dans l’émulateur elle retourne rien. Ci après la version pour Windows Phone OS 7.0 et Windows Phone OS 7.1. Pour Windows Phone 8 utiliser ANID2 : ANID2 est comme ANID sauf qu’il est unique par publisher en plus d’être unique par user (Merci Rudy !!)

public static string GetWindowsLiveAnonymousID()
{
    object _anid;
    string anonymousUserId = "";
    if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue("ANID", out _anid))
    {
        if (_anid != null)
        {
            anonymousUserId = _anid.ToString().Substring(2, 32);
        }
    }

    return anonymousUserId;
}

Moi j’ai créé un Usercontrol Popup.. bon ok parait que c’est gourmand en ressource mais y’a rien de méchant là, dans la source que j’ai mis bas de ce document, vous retrouverez le code complet avec son code behind C#

<Grid Background="White" Opacity="0.9" >
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="90"/>
    </Grid.RowDefinitions>
    <Border Grid.Row="0">
        <TextBlock VerticalAlignment="Center" TextWrapping="Wrap" FontSize="32" Padding="10,0,20,0"
                Text="Pour encourage le développement, merci d'évaluer cette application" Foreground="Black" />
    </Border>
    <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
        <Button x:Name="btnNon" Content="Non" Click="btnNon_Click" Margin="0,0,30,0" 
                Foreground="Black" BorderBrush="Black" Width="220" />
        <Button x:Name="btnEvaluate" Width="220"  Content="Evaluer" Click="btnEvaluate_Click"
                Foreground="Black" BorderBrush="Black" />
    </StackPanel>
</Grid>

Puis il suffit d’interroger la page PHP qui me retourne rien si ce DeviceID a déjà voté ou un espace (ou ce que vous voulez) si elle a trouvé ce DeviceID

WebClient Client = new WebClient();
Client.DownloadStringCompleted += new 
                 DownloadStringCompletedEventHandler(Client_DownloadStringCompleted);
Client.DownloadStringAsync(
                 new Uri("http://www.votredomaine.tld/evaluatemyapplication.php?id=" + GetDeviceUniqueID().ToString())
);

void Client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null)
        return;

    //si cela retourne rien, alors le DeviceID n'a pas été trouvé dans la bdd
    if (e.Result == "")
    {
        Popup popup = new Popup();
        EvaluateNow content = new EvaluateNow(popup);
        content.Width = Application.Current.Host.Content.ActualWidth;
        popup.Child = content;
        popup.VerticalOffset = 300;
        popup.IsOpen = true;
    }
}

Enfin si alors l’utilisateur clique sur le bouton [Voter] je passe en plus à la page PHP l’argument qr=1 (ou ce que vous voulez) afin qu’elle ajoute dans la table le DeviceID

"evaluatemyapplication.php?qr=1&id=" + GetDeviceUniqueID()

Voilà comment j’ai fait.

Source du projet : MemoEvaluate.zip