MediaCapture和Window VisibilityChanged

时间:2015-01-23 15:25:02

标签: windows-runtime windows-phone-8.1 winrt-xaml

[问题]

在Windows Phone 8.1上,在用户离开应用程序和OnSuspended事件触发之间到底发生了什么?我无法管理该范围内的对象,尤其是MediaCpture对象。

为了更好地解释问题,这里是场景:

  1. 用户位于将视频预览提取到CaptureElement
  2. 的页面上
  3. 用户点按“开始”按钮
  4. 用户点击“返回”按钮并返回到MediaCapture损坏的页面
  5. 使用WinRT时,除非您要转到同一帧中的其他页面,否则 ObscuredEvent 并且 OnNavigatingFrom 不会触发。经过一番调查后,我发现唯一发生的事件是 Window.Current.VisibilityChanged

    当页面 NavigatedTo 并且在 OnNavigatedFrom 中取消挂钩时,我已经将其挂起并挂钩(请参阅下面的ex2)。在事件内部,我检查参数,该参数告诉应用程序是否隐藏或显示并相应地处理/初始化(参见下面的例1)。

    [问题]

    但是, only 适用于附加的调试器。如果我在没有附加调试器的情况下执行此操作,则不会重新初始化并且 经常崩溃相机 ,我必须重新启动设备。

    代码示例1(注意:e.Visible == false离开应用程序,返回时为true)

    async void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
    {
         if (!e.Visible) //means leaving the app
         {
             await DisposeAll(); //cleans the MediaCapture and CaptureElement
         }
         else
         {
             if(mediaCaptureManager != null) await DisposeAll();
    
             await Initialization(); //set up camera again
         }
    }
    

    示例2(挂钩事件)

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        Window.Current.VisibilityChanged += Current_VisibilityChanged;
    
        this.navigationHelper.OnNavigatedTo(e);
    }
    
    protected async override void OnNavigatedFrom(NavigationEventArgs e)
    {
        Window.Current.VisibilityChanged -= Current_VisibilityChanged;
    
        this.navigationHelper.OnNavigatedFrom(e);
    }
    

    [更新:决议]

    而不是使用VisibilityChanged,挂钩到页面构造函数的Window.Current.Activated。在完全分离调试器的情况下,Activated事件将在WindowActivatedEventArgs中提供WindowActivationState参数。像这样:

    private async void CurrentOnActivated(object sender, WindowActivatedEventArgs e)
    {
        if(e.WindowActivationState == CoreWindowActivationState.Deactivated)
        {
            //dispose MediaCapture here
        }
        else if(e.WindowActivationState == CoreWindowActivationState.CodeActivated || e.WindowActivationState == CoreWindowActivationState.PointerActivated)
        {
            //initialize MediaCapture here
        }
    }
    

2 个答案:

答案 0 :(得分:2)

请参阅https://stackoverflow.com/a/28592882/3998132中的答案。将Window.VisibilityChanged与Page \ UserControl Loaded \ Unloaded处理程序结合使用可以解决您的问题。

使用Window.ActivatedWindow.VisibilityChanged更不可取,因为Activated与可见性和焦点相关,而VisibilityChanged只与可见性有关。用于显示具有焦点的预览不适用。由于Windows Phone上的Windows应用商店应用只能有一个窗口显示使用任何一个窗口没有区别,但是如果你的应用程序变得通用并运行在Windows 8+ Modern shell上(可以显示具有Snap窗口功能的多个Store应用程序)或Windows 10桌面(可以支持同时显示的多个商店应用)当用户从您的应用更改焦点但您的应用仍在显示时,您不希望停止预览。

答案 1 :(得分:0)

我不确定使用暂停/恢复事件是否更合适。请注意,在这种情况下,您必须正确调试它 - behaves little different while being run with/without debugger attached

至于代码 - 在 OnNavigatedTo / OnNavigatedFrom 中挂钩你的事件不是一个好主意 - 当操作系统暂停应用程序而你正在使用 SuspensionManager 然后将调用OnNavigatedFrom ,但当您返回应用程序(恢复它)时,将不会调用 OnNavigatedTo

使用 Window 事件也可以在这里工作,但为什么不在构造函数中的某处订阅它? - 它在窗口范围内,因此在手机中只有一个窗口,代表app,然后订阅一次。在这种情况下,您可以在窗口中添加一行识别当前页面的行,如果该页面包含mediacapture,则处理(创建类似)。然后,您还可以处理/初始化导航事件,以防用户未离开您的应用程序并进行导航。