MediaPlayer.GameHasControl не работает должным образом - PullRequest
0 голосов
/ 17 января 2012

Мое приложение не прошло сертификацию из-за рекомендации 6.5.1: «Приложение может перейти в состояние, в котором оно приостанавливает воспроизведение музыки пользователя без запроса».

Я нашел решение этой проблемы в Google и обнаружил, что вынеобходимо использовать MediaPlayer.GameHasControl, чтобы проверить, воспроизводит ли пользователь музыку перед запуском приложения.

Когда я его реализовал, он не работал.Это действительно подсказывало о приостановке музыки, НО это также приостанавливало это прежде, чем у меня была какая-либо возможность отреагировать.Я попытался поместить MediaPlayer.GameHasControl в OnNavigatedTo (), Loaded () и в конструкторе, и это работает какое-то время, но приложение вылетает через несколько секунд, так что это не вариант.Затем я попытался поместить в событие MediaOpened обработанные три моих элемента MediaElements, но безуспешно.Теперь я просто застрял.Если бы кто-нибудь мог пролить свет на это, я буду очень признателен.

Вот код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Xml.Linq;
using System.Windows.Navigation;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework;

namespace RhythmCoach
{
  public partial class BeginnerExercisePage : PhoneApplicationPage
  {
    public BeginnerExercisePage()
    {
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        XDocument beginnerExerciseData = XDocument.Load("XML/BeginnerXML.xml");

        string name = string.Empty;

        if (NavigationContext.QueryString.TryGetValue("name", out name))
        {

            var exercise = (from Exercised in beginnerExerciseData.Descendants("Exercised")
                            where Exercised.Attribute("name").Value == name
                            select new Exercise
                            {
                                ExImage = (string)Exercised.Element("image").Value,
                                ExGuitarAudio = (string)Exercised.Element("GuitarAudio").Value,
                                ExPianoAudio = (string)Exercised.Element("PianoAudio").Value,
                                ExSnareAudio = (string)Exercised.Element("SnareAudio").Value,
                                ExTitle = (string)Exercised.Element("title").Value
                            }).Single();

            im.Source = new BitmapImage(new Uri(exercise.ExImage, UriKind.Relative));
            pageTitle.Text = exercise.ExTitle;

            guitarAudioPlayer.Source = new Uri(exercise.ExGuitarAudio,UriKind.Relative);
            pianoAudioPlayer.Source = new Uri(exercise.ExPianoAudio, UriKind.Relative);
            snareAudioPlayer.Source = new Uri(exercise.ExSnareAudio, UriKind.Relative);
        }

        rbBegSnare.IsChecked = true;
        base.OnNavigatedTo(e);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        if (rbBegGuitar.IsChecked == true)
        {
            guitarAudioPlayer.Play();

        }
        else if (rbBegPiano.IsChecked == true)
        {
            pianoAudioPlayer.Play();

        }
        else
            snareAudioPlayer.Play();

    }

    private void button2_Click(object sender, RoutedEventArgs e)
    {
        if (rbBegGuitar.IsChecked == true)
        {
            guitarAudioPlayer.Stop();
            pianoAudioPlayer.Stop();
            snareAudioPlayer.Stop();
        }
        else if (rbBegPiano.IsChecked == true)
        {
            pianoAudioPlayer.Stop();
            guitarAudioPlayer.Stop();
            snareAudioPlayer.Stop();
        }
        else
            snareAudioPlayer.Stop();
            guitarAudioPlayer.Stop();
            pianoAudioPlayer.Stop();
    }

    private void button3_Click(object sender, RoutedEventArgs e)
    {
        if (rbBegGuitar.IsChecked == true)
        {
            guitarAudioPlayer.Pause();
            pianoAudioPlayer.Pause();
            snareAudioPlayer.Pause();
        }
        else if (rbBegPiano.IsChecked == true)
        {
            pianoAudioPlayer.Pause();
            guitarAudioPlayer.Pause();
            snareAudioPlayer.Pause();
        }
        else
            snareAudioPlayer.Pause();
            guitarAudioPlayer.Pause();
            pianoAudioPlayer.Pause();
    }

    private void rbBegGuitar_Checked(object sender, RoutedEventArgs e)
    {
        pianoAudioPlayer.Stop();
        snareAudioPlayer.Stop();
    }

    private void rbBegPiano_Checked(object sender, RoutedEventArgs e)
    {
        guitarAudioPlayer.Stop();
        snareAudioPlayer.Stop();
    }

    private void rbBegSnare_Checked(object sender, RoutedEventArgs e)
    {
        guitarAudioPlayer.Stop();
        pianoAudioPlayer.Stop();
    }

    private void guitarAudioPlayer_MediaOpened(object sender, RoutedEventArgs e)
    {
        if (!MediaPlayer.GameHasControl)
        {
            MessageBoxResult Choice;
            Choice = MessageBox.Show("Media is currently playing, do you want to stop it?", "Stop Player", MessageBoxButton.OKCancel);
            if (Choice != MessageBoxResult.OK)
            {
                if (NavigationService.CanGoBack)
                    NavigationService.GoBack();
                else
                    NavigationService.Navigate(new Uri("/Menu.xaml", UriKind.Relative));
                return;
            }
        }
    }

    private void pianoAudioPlayer_MediaOpened(object sender, RoutedEventArgs e)
    {
        if (!MediaPlayer.GameHasControl)
        {
            MessageBoxResult Choice;
            Choice = MessageBox.Show("Media is currently playing, do you want to stop it?", "Stop Player", MessageBoxButton.OKCancel);
            if (Choice != MessageBoxResult.OK)
            {
                if (NavigationService.CanGoBack)
                    NavigationService.GoBack();
                else
                    NavigationService.Navigate(new Uri("/Menu.xaml", UriKind.Relative));
                return;
            }
        }
    }

    private void snareAudioPlayer_MediaOpened(object sender, RoutedEventArgs e)
    {
        if (!MediaPlayer.GameHasControl)
        {
            MessageBoxResult Choice;
            Choice = MessageBox.Show("Media is currently playing, do you want to stop it?", "Stop Player", MessageBoxButton.OKCancel);
            if (Choice != MessageBoxResult.OK)
            {
                if (NavigationService.CanGoBack)
                    NavigationService.GoBack();
                else
                    NavigationService.Navigate(new Uri("/Menu.xaml", UriKind.Relative));
                return;
            }
        }
    }
}

}

И XAML

 <Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="242*" />
        <ColumnDefinition Width="243*" />
        <ColumnDefinition Width="243*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="163*"/>
        <RowDefinition Height="245*" />
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Margin="12,17,0,28" Grid.ColumnSpan="3">
        <TextBlock x:Name="ApplicationTitle" Text="BEGINNER EXERCISES" Style="{StaticResource PhoneTextNormalStyle}" Foreground="Black" />
        <TextBlock x:Name="PageTitle" Text="{Binding ExTitle}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" Foreground="Black" />
    </StackPanel>

    <!--ContentPanel - place additional content here-->

        <Image x:Name="im" Grid.Row="1" Margin="12,0,12,155" Grid.RowSpan="2" Grid.ColumnSpan="3" />

    <Button Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="41,13,0,0" x:Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" BorderBrush="Black" Foreground="Black" ClickMode="Release">
        <Button.Background>
            <ImageBrush ImageSource="/RhythmCoach;component/Images/appbar.transport.play.rest.png" Stretch="None" />
        </Button.Background>
    </Button>
    <MediaElement Grid.Row="2" Height="120" HorizontalAlignment="Left" Name="guitarAudioPlayer" VerticalAlignment="Top" Width="160" Source="{Binding ExGuitarAudio}"  AutoPlay="False" Volume="100" MediaOpened="guitarAudioPlayer_MediaOpened" />
    <MediaElement Grid.Row="2" Height="120" HorizontalAlignment="Left" Name="pianoAudioPlayer" VerticalAlignment="Top" Width="160" Source="{Binding ExPianoAudio}"  AutoPlay="False" Volume="100" MediaOpened="pianoAudioPlayer_MediaOpened" />
    <MediaElement Grid.Row="2" Height="120" HorizontalAlignment="Left" Name="snareAudioPlayer" VerticalAlignment="Top" Width="160" Source="{Binding ExSnareAudio}"  AutoPlay="False" Volume="100" MediaOpened="snareAudioPlayer_MediaOpened" />
    <Button Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="41,13,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="button2_Click" Grid.Column="2" BorderBrush="Black" Foreground="Black" HorizontalContentAlignment="Center">
        <Button.Background>
            <ImageBrush ImageSource="/RhythmCoach;component/Images/appbar.transport.stop.rest1.png" Stretch="None" />
        </Button.Background>
    </Button>
    <Button Grid.Column="1" Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="41,13,0,0" Name="button3" VerticalAlignment="Top" Width="160" Click="button3_Click" Foreground="Black" BorderBrush="Black">
        <Button.Background>
            <ImageBrush ImageSource="/RhythmCoach;component/Images/appbar.transport.pause.rest.png" Stretch="None" />
        </Button.Background>
    </Button>
    <RadioButton Content="Guitar" Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="41,101,0,0" Name="rbBegGuitar" VerticalAlignment="Top" Foreground="Black" Background="#BFADADAD" BorderBrush="#BFFFFFFF" Checked="rbBegGuitar_Checked" />
    <RadioButton Content="Piano" Grid.Column="1" Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="41,101,0,0" Name="rbBegPiano" VerticalAlignment="Top" Background="#BFA3A3A3" Foreground="Black" Checked="rbBegPiano_Checked" />
    <RadioButton Content="Snare Drum" Grid.Column="2" Grid.Row="2" Height="72" HorizontalAlignment="Left" Margin="32,101,0,0" Name="rbBegSnare" VerticalAlignment="Top" Background="#BF939393" Foreground="Black" Checked="rbBegSnare_Checked" />
    <my:AdControl AdUnitId="10029089" ApplicationId="05ab3750-df60-4e42-9939-ab68de9f424b" Height="50" HorizontalAlignment="Left" Margin="186,17,0,0" Name="adControlSmall" VerticalAlignment="Top" Width="300" Grid.ColumnSpan="2" Grid.Column="1" />
    <Grid.Background>
        <ImageBrush ImageSource="/RhythmCoach;component/Images/bg1.png" Stretch="Fill" />
    </Grid.Background>
</Grid>

Ответы [ 3 ]

1 голос
/ 27 апреля 2013
    public MainPage()
    {
        InitializeComponent();

        bool canPlayMusic = true;

        FrameworkDispatcher.Update();

        if (!MediaPlayer.GameHasControl)
        {
            if (MessageBox.Show("Is it ok to stop currently playing music?",
                "Can stop music?", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
            {
                canPlayMusic = false;
            }
        }

        if (canPlayMusic)
        {
            MediaPlayer.Pause();

            runBackgroundMusic();
        }
    }
1 голос
/ 17 января 2012

Я обновлю этот ответ кодом, который я использую для подсказок после возвращения домой. Я думаю, что мой находится в Loaded (). Я вижу, что ваши mediaElements не настроены на автозапуск, так что это не должно быть проблемой. Если вы вообще удалите подсказку, фоновая музыка все еще приостанавливается без нажатия каких-либо кнопок на странице?

Еще один способ, которым я видел, как люди справляются с этим, - вместо того, чтобы запрашивать каждый запуск приложения, вы спрашиваете их при запуске, хотят ли они всегда приостанавливать фоновую музыку при запуске приложения. Сохраните эту настройку, а затем просто проверьте ее при последующих запусках. Похоже, у вас есть главное меню, поэтому одной из возможностей было бы не позволить им перейти на ваши страницы с музыкой, если они не согласились приостановить фоновую музыку.

Я собирался вставить свой код, но, возможно, это немного сбивало с толку, поэтому я извлек мясо, которое вам нужно:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    //remember don't show MessageBoxes in OnNavigatedTo..
    // better to move stuff over to Loaded as much as you can anyway
    this.Loaded += RunOnPageLoaded; //you could hook up to this event via the Designer too
}

void RunOnPageLoaded(object sender, RoutedEventArgs e)
{
    bool doLoad = true;
    FrameworkDispatcher.Update();
    if (!MediaPlayer.GameHasControl)
    {
        doLoad = PromptUserAboutBackgroundMusic();
        if (doLoad) MediaPlayer.Pause();
    }

    if (doLoad)
    {
        LoadMediaFiles();
    }
}

private bool PromptUserAboutBackgroundMusic()
{
    var result = MessageBox.Show("Do you want to stop your background music to play this recording?",
                                 "Stop music?", MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.OK) return true;
    return false;
}

private void LoadMediaFiles()
{
    //load your media files into your mediaelements here
    //mediaElement.AutoPlay = true;
    //mediaElement.Source = ...
}

Хотя это может быть тем, о чем вы просили, но, посмотрев на то, что вы делаете, я не уверен, что MediaElements - это то, что вам лучше всего использовать. Если вместо этого вы использовали SoundEffectInstance, то фоновая музыка не приостанавливается, и вам даже не придется беспокоиться об этом, если вы не хотите добавить эту функцию.

0 голосов
/ 17 января 2012

Перед вызовом MediaPlayer.GameHasControl вы можете вызвать FrameworkDispatcher.Update (); это поможет предотвратить сбой вашего приложения в Exception.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...