Ludovic ROLAND

Blog technique sur mes expériences de développeur.

Windows Phone 7 : Gérer la musique et les vidéos dans vos applications

26 avril 2012

Récemment, j’ai développé l’application iTrafic Info sur Windows Phone 7 et j’ai eu la mauvaise surprise de voir l’application refusée par Microsoft au nom de l’ exigence technique 6.5.1.

L’exigence technique 6.5.1

Pour faire simple, cette exigence technique stipule que lorsqu’un utilisateur est entrain d’écouter de la musique sur son téléphone, l’application ne doit en aucun cas l’affecter (mettre en pause, mettre en lecture ou l’arrêter). Si l’application souhaite diffuser sa propre musique en arrière plan, elle doit explicitement en demander l’autorisation à l’utilisateur. Cette demande d’autorisation doit se faire à chaque fois que l’application est lancée ou doit pouvoir être configurée dans les options de l’application.

Mon problème

Une page de l’application iTrafic Info affiche une vidéo. Bien que cette vidéo n’est pas de son, elle prend le dessus sur la musique de l’utilisateur et l’arrête sans rien lui demander. D’où le refus de Microsoft.

Vous l’aurez deviné, le but de ce billet sera donc de gérer cette demande d’autorisation !

On ira même plus loin en remplissant les critères de l’exigence technique 6.5.3 qui dit que si l’application interrompt la musique de l’utilisateur, elle se doit de la relancer au moment où la page est quittée.

La solution

La solution que je vais vous proposer demande l’autorisation à l’utilisateur de couper sa musique à chaque fois qu’il affiche la page et tant qu’il n’a pas accepté. Une fois acceptée, l’autorisation n’est plus demandé jusqu’au prochain lancement de l’application. A noter que nous allons également gérer le cas de la radio.

Les variables

Bien évidemment, il nous faut des variables.

private static bool accept = false;
private bool radio = false;
private bool media = false;

Les booléens radio et media nous vont nous permettre de savoir si oui ou non l’utilisateur écoute la radio ou la musique.La variable accept va nous permettre de savoir si l’utilisateur a déjà accepté qu’on coupe sa musique au profil de la notre. Cette variable est static car comme précisé plus haut, une fois la demande d’autorisation acceptée, on ne lui demandera plus.

La détection de la musique

Dans cette étape, nous allons détecter si l’utilisateur écoute de la musique ou la radio. Bien évidemment, ces vérifications doivent être faites en tout premier, c’est pourquoi tout doit être fait dans la méthode OnNavigatedTo.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    //On met à jour l'état des médias
    FrameworkDispatcher.Update();

    /*
    * On commence par statuer sur l'utilisation des média
    */

    //On regarde si l'utilisateur à la radio allumée
    if (FMRadio.Instance.PowerMode == RadioPowerMode.On || FMRadio.Instance.SignalStrength > 0.0)
    {
        media = true;
        radio = true;
    }
    //On regarde si l'utilisateur écoute de la musique
    else if (MediaPlayer.State == MediaState.Playing)
    {
        media = true;
    }

    /*
    * Maintenant qu'on connait l'état des médias, on peut faire les traitements
    */

    //L'utilisateur n'écoute aucun média
    if (media == false)
    {
        /* Chargement de la page */
    }
    //L'utilisateur utilise un des médias
    else
    {
        //L'utilisateur n'a pas encore accepté notre demande d'autorisation
        if (accept == false)
        {
             /* On pose la question */
         }
         //Il a accepté notre demande d'autorisation
         else
         {
             /* Chargement de la page */
         }
    }
}

Exploiter les résultats

Le but est maintenant de remplacer les commentaires «Chargement de la page» et «On pose la question» du morceau de code précédent par du code C#.

En ce qui concerne le «Chargement de la page», libre à vous de passer par une fonction, du code en dure, etc. Le but est ici d’initialiser sa page avec les bonnes informations. Je vous fais confiance !

On va plutôt s’intéresser au commentaire «On pose la question». Mon premier réflexe a été de demander à l’utilisateur son autorisation via l’utilisation d’une MessageBox. Oui mais voilà, j’ai vite rencontré un problème. Si on ne fait rien et qu’on laisse la MessageBox ouverte pendant environ une dizaine de secondes, l’application quitte subitement et lève une System.InvalidOperationException.

Ma solution consiste donc à superposer dans ma page deux Grids :

  • le premier contient la demande d’autorisation et deux boutons «Accepter» et «Refuser» ;
  • le second contient mon MediaElement et les différents éléments de ma page.

Le but est de jongler en fonction de la réponse de l’utilisateur sur l’affichage des Grids pour afficher ou non le contenu de notre page.

Ainsi, si par défaut c’est le grid de notre page qui est visible, il faut remplacer le commentaire «On pose la question» par le code suivant :

//On rend invisible le grid qui contient les éléments de notre page
ContentPanelPage.Visibility = Visibility.Collapsed;

//On rend visible la demande d'autorisation
ContentPanelAutorisation.Visibility = Visibility.Visible;

Il ne nous reste plus qu’à gérer l’action de l’utilisateur sur les boutons «Accepter» et «Refuser».

//L'utilisateur accepte
private void btnAccepter_Click(object sender, RoutedEventArgs e)
{
    //On met à jour la variable accept
    accept = true;

    //On affiche le contenu de la page
    ContentPanelAutorisation.Visibility = Visibility.Collapsed;
    ContentPanelPage.Visibility = Visibility.Visible;

    /* On charge la page */
}

//L'utilisateur refuse
private void btnRefuser_Click(object sender, RoutedEventArgs e)
{
    //On quitte la page
    NavigationService.GoBack();
}

La reprise

Afin de respecter l’exigence technique 6.5.3, il convient de rallumer la musique de l’utilisateur une fois qu’il quitte notre page. Tout se passe donc dans la méthode OnNavigatedFrom.

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    //On regarde si un média était lancé
    if (media == true)
    {
        //On regarde s'il s'agissait de la radio
        if (radio == true)
        {
            FMRadio.Instance.PowerMode = RadioPowerMode.On;
        }
        //Ou de la musique
        else
        {
            MediaPlayer.Resume();
        }
    }
}

C’est terminé ! Votre application devrait maintenant passer tous les tests Windows sans soucis !

Commentaires