消防系统事件控制其他应用程序MediaPlayer

时间:2017-01-06 12:55:21

标签: c# uwp

我目前正在开发能够控制其他应用程序的后台媒体播放器实例的UWP项目,i。 E:

MediaPlayer player = BackgroundMediaPlayer.Current;

正如我在MSDN official documentation of MedaPlayer class上找到的那样 - 没有任何直接的方法可以跳过歌曲或转移到上一首歌。

我自己一直在寻找解决方案几天,直到我做到这样的事情:
(来自here的FireEvent - 修改了一行以便在uwp上工作)

private async void button3_Click(object sender, RoutedEventArgs e)
{
    MediaPlayer player = BackgroundMediaPlayer.Current;
    SystemMediaTransportControls d;
    await Task.Factory.StartNew(() => { d = player.SystemMediaTransportControls; });

    await FireEvent(d, "ButtonPressed", new FakeEventArgs(SystemMediaTransportControlsButton.Next));
}

public async Task FireEvent(object onMe, string invokeMe, params object[] eventParams)
{
    MulticastDelegate eventDelagate = (MulticastDelegate)onMe.GetType().GetField(invokeMe,
                                        BindingFlags.Instance |
                                        BindingFlags.NonPublic).GetValue(onMe);

    Delegate[] delegates = eventDelagate.GetInvocationList();

    foreach (Delegate dlg in delegates)
    {
        dlg.DynamicInvoke(dlg.Target, eventParams);
    }
}

虽然我确信,在我的测试手机上有一个音乐播放,在行定义eventDelegate之后我得到了:

Exception thrown: 'System.NullReferenceException' in foo.exe

我做错了什么?有没有其他的射击方式和事件?甚至,一些控制其他应用程序的MediaPlayer的不同方法?

编辑1 FakeEventArgs与SystemMediaTransportControlsButtonPressedEventArgs等效,因为这个类不可构造,如下所示:

public sealed class FakeEventArgs
{
    SystemMediaTransportControlsButton Button = SystemMediaTransportControlsButton.Pause;

    public FakeEventArgs (SystemMediaTransportControlsButton But)
    {
        Button = But;
    }
}

2 个答案:

答案 0 :(得分:0)

这里有很多问题。

首先,我期待流程隔离和安全模型阻止任何应用程序(不仅仅是你的)能够执行此类任务。控制音乐播放是Metro / Modern / UWP应用程序具有非常有限的能力。您可以播放自己的音乐,但在系统级别无法做很多事情或影响正在播放音乐的其他应用。如果你正在播放音乐,你可以暂停它,或者如果另一个应用正在播放音乐,你可以控制播放音乐。作为一般规则,如果您不希望其他应用程序执行潜在的恶意攻击,或者系统UI控制某些内容,则您自己无法做很多事情。

无论如何,你的代码看起来很有趣,所以我觉得值得探索。您可能已经找到了一个有趣的解决方法 以下是我发现的具体问题。

  1. d的分配不需要异步完成。我无缘无故地看到,您创建并开始一项新任务,为d分配值。因为它不需要异步完成,所以你可以将其作为click方法中正常代码流的一部分。
  2. FireEvent方法不需要是异步的,您不希望它返回任务,您只是想让它运行。如果签名为public void FireEvent(...,则代码将更加简单。
  3. 现在我们了解为什么代码永远不会工作。类型SystemMediaTransportControls没有名为"ButtonPressed"的字段。 (或者任何字段。)当代码GetValue(onMe)运行时,它将始终通过NullReferenceException。从那以后,没有什么可以动态调用。
  4. 我认为您需要重新考虑您的应用创意。除非目标应用程序明确地提供了一种方法,否则不可能从另一个UWP应用程序中任意控制一个UWP应用程序。
    您在原始问题中提到的另一个问题可能适用于WPF应用程序,其中应用程序模型限制较少,但我无法保证。你需要自己尝试一下。

答案 1 :(得分:0)

我认为你可能在这里徘徊,没有办法控制另一个应用音频。您只能使用传输控件。

 MediaPlayer player = BackgroundMediaPlayer.Current;

此行将关闭正在播放音乐的其他应用程序后台任务,并创建一个供您使用的新实例。