When a 'z' just doesn't cut it... (Oren Nachman's random notes from Microsoft)

December, 2010

  • Randomisation

    WP7 Silverlight Gotcha: Setting the Source on a MediaElement will stop background music playback


    Applies To: Silverlight (the restriction applies to XNA, but the MediaElement is only Silverlight)

    Quick Bits

    Simply setting the Source of a MediaElement to a valid source will stop any current background playback, causing you to fail Marketplace certification, according to section 6.5.1 from the certification guide.

    The Fine Print

    From the certification guide:

    6.5.1  Initial Launch Functionality 

    When the user is already playing music on the phone when the application is launched, the application must not pause, resume, or stop the active music in the phone MediaQueue by calling the Microsoft.Xna.Framework.Media.MediaPlayer class. If the application plays its own background music or adjusts background music volume, it must ask the user for consent to stop playing/adjust the background music (e.g. message dialog or settings menu). 

    Note: This requirement does not apply to applications that play sound effects through the Microsoft.Xna.Framework.Audio.SoundEffect class, as sound effects will be mixed with the MediaPlayer. The SoundEffect class should not be used to play background music. 

    Note: This requirement does not apply to Music + Videos Hub applications that are described in Section 6.4 

    The Setup

    You have a MediaElement which only used to play back one file, so you set the Source in your XAML.

    The Sting

    The user starts playing some music in Zune, then launches your XAP. As soon as your XAML loads and the MediaElement's Source is set, the background music stops playing, even if the MediaElement is not playing. That's right, even if you set AutoPlay = "False", the background music will still be stopped.

    Since you must ask the user for consent, you will have failed certification.

    The Solution

    1. Never set a MediaElement's Source in XAML, unless that XAML is on a page that you navigate to after asking the user for consent.
    2. Check to see if background music is playing and then set the source (in code).
      Note: If you set the source and then immediately call Play(), the Play() will have no affect since the MediaElement will still be in the "Opening" state, instead set "AutoPlay = true" (works from code)
  • Randomisation

    WP7 Dev Tip: Detecting whether or not the user is playing music in the background


    Applies To: Silverlight & XNA

    Quick Bits


    The Setup

    Your app does some sort of music playing that doesn't make sense to blend into any already playing background music (for example, you're going to stream your own music) or you simply want to show a video.

    Why You Care?

    If you just start playing music you will fail certification according to section 6.5.1 of the certification guide if you don't ask the user if you can stop the background music, but how can you stop the background music if you don't know it's playing? Hence, you care!

    The Solution

    Query Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl (it's a bool) - if you have control, then you're good to go. If you don't have control, then there is something in the background and you need to prompt the user before continuing. 

    Silverlight Note: you'll need to link in Microsoft.Xna.Framework.dll for this to work, but make sure you don't distribute this file with your XAP by mistake (or you'll also fail certification for redistributing phone assemblies)

  • Randomisation

    WP7 Gotcha: Showing a Launcher or Chooser will crash while Navigating


    Applies To: Silverlight & XNA (anyone using Launchers / Choosers)

    Quick Bits

    Always wrap [some launcher object].Show() with a try/catch block which catches InvalidOperationException, since running Show() while navigating (for example, if the user clicks your button multiple times quickly in succession) will cause this Exception to be thrown.

    The Setup

    You have a button that says "Purchase Me" which launches the Marketplace or one that says "Send Feedback" which launches Outlook to send an email. For example:

    EmailComposeTask emailComposeTask = new EmailComposeTask();
    emailComposeTask.To = "feedback@awesomeapps.contoso.com";
    emailComposeTask.Subject = "Feedback for AwesomeApp";

    The Sting

    The user hits the button multiple times, quickly. The app crashes.

    The Cause

    If you debug this you'll find that you can't reproduce this behaviour on the Emulator (at least, I couldn't) but that it reproduces pretty consistently on the phone. 

    On the phone you'll get an InvalidOperationException with the following message:

    Navigation is not allowed when the task is not in the foreground. Error: -2147220989

    The Solution

    There are a couple of solutions - you could remember your state, so that if you clicked the button once and haven't navigated back yet then you just don't call Show(). Alternatively you could check if you were currently Navigating, and not call Show(). I personally prefer to wrap the statement in a try/catch block since it's the easiest to have to worry about and the cost for the try/catch block is minimal (performance wise).


Page 1 of 1 (3 items)