locked
Help getting App Certified - Failed on 6.5.1 & 6.5.2 RRS feed

  • Question

  • Hey Everyone,

    Was wondering if anyone could give me a little bit of help getting my first windows phone App certified. I have failed due to the 6.5.1 and 6.5.2 requirements due to my use of sound. My App is a very simple game and only utilizes four mp3 sounds files, these are only small two second event sounds. Here is how I am implementing my sounds....

    In the .xmal....

    <MediaElement x:Name="sound1" Source="Sounds/Sound1.mp3" AutoPlay="False" />
    <MediaElement x:Name="sound2" Source="Sounds/Sound2.mp3" AutoPlay="False" />
    <MediaElement x:Name="sound3" Source="Sounds/Sound3.mp3" AutoPlay="False" />
    <MediaElement x:Name="sound4" Source="Sounds/Sound4.mp3" AutoPlay="False" />

    In the xmal.cs....

    sound1.Stop();
    sound1.Play();

    The requirements state....


    6.5.1

    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). This prompt must occur each time the
    application launches, unless there is an opt-in
    setting provided to the user and the user has used

    and also....


    6.5.2

    If an application plays background music, the
    application must provide the user with
    configurable settings for both the background
    music, and the background music volume.


    Do I need to implement sound options or am I using an incorrect class to call the sounds ?

    Any help would be much appreciated.

    Thanks,

    Kev







    Tuesday, May 22, 2012 9:00 PM

All replies

  • Hey Kev,
    When I first started out I got caught in this a couple of times
    what you need to do is
    to
    1) provide your end user with the ability to adjust the volume in the App

    2) detect if the end user has music already playing before they launch your App
    ie they are playing an mp3 song or smething.

    you can use

     

     

    if (Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl == false)
    {
    then there is outside music playing what I do is let their musc play but you can also
    code in options.
    }

    else
    {
    there is no backgorund music playing and you can play the background music in App no asking permisions required
    }

    You can place and assign the result of above to a public getter ; setter in your app.cs
    public static bool OutsideMusic { get; set; }

     

     

     

    if (Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl == false)
    {
    OutsideMusic=false;
    }
    else
    {
    OutsideMusic=true;
    }

    You can then reference OutsideMusic throughout your App.






    Tuesday, May 22, 2012 10:23 PM
  • As far I could understand the app certification rules, no audio confusion/mix between "background audio" and your "app audio playbacks" should happen.

    I did this test with "angry birds"... here's the result:

    1. when you have BG audio running, the app's audio does not play (but the app's sound effects does)

    2. when you stop the BG audio, the app's audio starts playing

    3. when you restart the BG audio, the app's audio stops


    So I think you should implement this in code... there's no need for a "audio options page"



    Regards,
    Victor Reboucas
    Tuesday, May 22, 2012 10:33 PM
  • MediaElement interferes with the phone's radio/music, it also adds entries in Zune's nowplaying tile. So if you're not creating a multimedia app you should avoid this class.

    For sound effects you should use XNA's SoundEffect class, for background music you can use XNA's MediaPlayer class. To use XNA stuff in Silverlight, you need to call FrameworkDispatcher.Update() every so often. To find out if the user plays radio / music, query MediaPlayer.GameHasControl;

    Here's what I did in my first Silverlight game: I play sounds no matter if radio/music is on. I don't start my own music if radio / music is on. I decided that the requirement to set the volume is fulfilled with providing a mute/unmute button.

    Some old code (which works, but access to ApplicationSettings is not thread safe):

    using System; 
    using System.ComponentModel; 
    using System.IO; 
    using System.Threading; 
    using Microsoft.Xna.Framework; 
    using Microsoft.Xna.Framework.Audio; 
    using Microsoft.Xna.Framework.Media; 
     
    namespace HDW.Audio 
        public class AudioManager 
        { 
            /// <summary> 
            /// Identifies the IsMuted boolean in System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings 
            /// </summary> 
            private const string ApplicationSettingsAudioManagerIsMutedKey = "AudioManager.IsMuted"
     
            /// <summary> 
            /// The current playing song if set through AudioManager.PlayMusic(). 
            /// </summary> 
            private static Song mySong; 
     
            static AudioManager() 
            { 
                MediaPlayer.MediaStateChanged += new EventHandler<EventArgs>(MediaPlayer_MediaStateChanged); 
     
                try 
                { 
                    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.TryGetValue<bool>(ApplicationSettingsAudioManagerIsMutedKey, out _IsMuted); 
                    IsMuted = _IsMuted; 
                } 
                catch (Exception) 
                { 
                    // fails in VisualStudios UI designer since there's no ApplicationStorage 
                } 
            } 
     
            /// <summary> 
            /// Just here to allow instanciating in ResourceDictionaries 
            /// </summary> 
            public AudioManager() 
            { 
            } 
     
     
            /// <summary> 
            /// PlaySound("Resources\\Sounds\\beep.wav"); 
            /// beep.wav must have the build action "Content" 
            /// </summary> 
            /// <param name="path"></param> 
            public static void PlaySound(string path) 
            { 
                if (IsMuted) 
                    return
     
                if (!string.IsNullOrEmpty(path)) 
                { 
                    using (Stream stream = TitleContainer.OpenStream(path)) 
                    { 
                        if (stream != null
                        { 
                            SoundEffect effect = SoundEffect.FromStream(stream); 
                            try 
                            { 
                                FrameworkDispatcher.Update(); 
                            } 
                            catch (Exception) 
                            { 
                            } 
     
                            try 
                            { 
                                effect.Play(); 
                            } 
                            catch (Exception) 
                            { 
                            } 
                        } 
                    } 
                } 
            } 
     
            /// <summary> 
            /// Returns true if music or FM radio is playing. Check this before calling PlayMusic() to prevent your app's music interfere with the user's currently playing music. 
            /// </summary> 
            public static bool IsPlayingExternally
            { 
                get 
                { 
                    try 
                    { 
                        FrameworkDispatcher.Update(); 
                    } 
                    catch (Exception) 
                    { 
                    } 
                    return !Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl; 
     
     
     
                    // the following probably leads to rejection: 
     
                    //// see also http://gdwp7dev.wordpress.com/2010/10/19/resume-the-users-music-after-mediaplay/ - however everything stated there is wrong .... 
                    //// note that Radio.FMRadio.Instance.PowerMode seems to always be "Off". 
                    //// also if radio is "on", the MediaPlayer.Queue.Count may be zero - so SignalStrength is used instead. 
     
                    //FrameworkDispatcher.Update(); 
                    //bool isPlaying = MediaPlayer.State == MediaState.Playing; 
     
                    //if (isPlaying) 
                    //    return true; 
     
                    //isPlaying = (Microsoft.Devices.Radio.FMRadio.Instance.PowerMode == Microsoft.Devices.Radio.RadioPowerMode.On) || (Microsoft.Devices.Radio.FMRadio.Instance.SignalStrength > 0); 
     
                    //if (isPlaying) 
                    //    return true; 
     
     
                    //return false; 
                } 
            } 
     
            private static bool _IsMuted = false
            /// <summary> 
            /// Gets/Sets wether the AudioManager is muted. Setting this value sets MediaPlayer.IsMuted, affecting the entire system. This setting also determines if PlaySound() has an effect. 
            /// </summary> 
            public static bool IsMuted 
            { 
                get { return _IsMuted; } 
                set 
                { 
                    _IsMuted = value; 
                    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings[ApplicationSettingsAudioManagerIsMutedKey] = value; 
     
                    try 
                    { 
                        FrameworkDispatcher.Update(); 
                    } 
                    catch (Exception) 
                    { 
                    } 
     
                    try 
                    { 

                        MediaPlayer.IsMuted = _IsMuted; 


                    } 
                    catch (UnauthorizedAccessException) 
                    { 
                        // crashes when Zune is active 
                    } 
                } 
            } 
     
            /// <summary> 
            /// Just here to be referenced in XAML. 
            /// </summary> 
            public bool Muted 
            { 
                get { return IsMuted; } 
                set { IsMuted = value; } 
            } 
     
            /// <summary> 
            /// PlayMusic("Resources\\Music\\song.mp3"); 
            /// song.mp3 must have the build action "Content" 
            /// </summary>    
            public static void PlayMusic(string path, bool repeating) 
            { 
                PlayMusic(path, MediaPlayer.Volume, repeating); 
            } 
     
            /// <summary> 
            /// PlayMusic("Resources\\Music\\song.mp3"); 
            /// song.mp3 must have the build action "Content" 
            /// </summary>    
            public static void PlayMusic(string path, float volume, bool repeating) 
            { 
                try 
                { 
                    if (mySong != null
                        mySong.Dispose(); 
     
                    mySong = Song.FromUri(System.IO.Path.GetFileNameWithoutExtension(path), new Uri(path, UriKind.Relative)); 
                    MediaPlayer.IsRepeating = repeating; 
                    MediaPlayer.Volume = volume; 
                    MediaPlayer.Play(mySong); 
                    try 
                    { 
                        FrameworkDispatcher.Update(); 
                    } 
                    catch (Exception) 
                    { 
                    } 
                } 
                catch (InvalidOperationException) 
                { 
                    // crashes when Zune is active 
                } 
            } 
     
     
     
            public static void StopMusic() 
            { 
                if (MediaPlayer.Queue.ActiveSong != mySong) 
                    return
     
                MediaPlayer.Stop(); 
            } 
     
     
            private static void MediaPlayer_MediaStateChanged(object sender, EventArgs e) 
            { 
                if (MediaPlayer.Queue.ActiveSong != mySong) 
                    return
     
                switch (MediaPlayer.State) 
                { 
                    case MediaState.Paused: 
                        StopFrameworkDispatcher(); 
                        break
                    case MediaState.Playing: 
                        StartFrameworkDispatcher(); 
                        break
                    case MediaState.Stopped: 
                        StopFrameworkDispatcher(); 
                        break
                    default
                        break
                } 
            } 
     
     
            static BackgroundWorker worker; 
            private static void StartFrameworkDispatcher() 
            { 
                if (worker == null || worker.CancellationPending) 
                { 
                    worker = new BackgroundWorker(); 
                    worker.WorkerSupportsCancellation = true
                    worker.DoWork += new DoWorkEventHandler((sender, e) => 
                    { 
                        using (ManualResetEvent mre = new ManualResetEvent(false)) 
                        { 
                            while (!worker.CancellationPending) 
                            { 
                                mre.WaitOne(33); // wait 33ms, which means 30 fps. 
                                FrameworkDispatcher.Update(); 
                            } 
                        } 
                    }); 
                    worker.RunWorkerAsync(); 
                } 
            } 
     
     
            private static void StopFrameworkDispatcher() 
            { 
                if (worker != null
                    worker.CancelAsync(); 
            } 
        } 
     


    Tuesday, May 22, 2012 10:39 PM
  • Hey Guys,

    I really appreciate the help, you've made this much clearer for me now and I think I understand what I should amend. Going to bed now but will try and implement this to my program after work tomorrow. I'll post up my code so you guys can tell me what you think if that's ok.

    Thanks again,

    Kev
    Tuesday, May 22, 2012 10:58 PM
  • Maybe a message box when a music is being played in the background asking the user if they want to disable their music or your app's music.
    That'll pass the certification straight :)
    Tuesday, May 22, 2012 11:37 PM