MediaCapture and Window VisibilityChanged

狂风中的少年 提交于 2019-12-11 07:15:30

问题


[Question]

On Windows Phone 8.1, what exactly happens in between the time when the user leaves the app and the OnSuspended event fires? I'm having trouble with the ability to manage objects in that span, in particular MediaCpture object.

To better explain the problem, here is the scenario:

  1. The user is on a page with a video preview being pumped to a CaptureElement
  2. The user taps the Start button
  3. The user taps Back button and returns to the page with a broken MediaCapture

With WinRT there isn't an ObscuredEvent and OnNavigatingFrom doesn’t fire unless you’re going to another page in the same Frame. After some investigation, I've found that the only event that fires is Window.Current.VisibilityChanged

I've gone ahead and hook it when the page is NavigatedTo and unhooked in OnNavigatedFrom (see ex2 below). Inside the event, I check for parameter that tells if the app is hiding or showing and dispose/initialize accordingly(see ex.1 below).

[Problem]

However, this only works with the debugger attached. If I do this without the debugger attached, it doesn't reinitialize and frequently crashes the camera and I have to literally reboot the device.

Code Example 1 (note: e.Visible == false is leaving the app and true when returning)

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
     }
}

Example 2 (hooking into the event)

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);
}

[Update: Resolution]

Instead of using VisibilityChanged, hook into Window.Current.Activated on the page's constructor. With the debugger completely detached, the Activated event will provide the WindowActivationState parameter in the WindowActivatedEventArgs. Like this:

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
    }
}

回答1:


I'm not sure if it wouldn't be more suitable to use Suspending/Resuming events. Note only that in this case, you will have to debug it properly - it behaves little different while being run with/without debugger attached.

As for the code - hooking your event in OnNavigatedTo/OnNavigatedFrom is not a good idea - when the OS suspends the app and you are using SuspensionManager then OnNavigatedFrom will be called, but when you go back to your app (resume it), then OnNavigatedTo will not be called.

Using Window events may also work here, but why not subscribe it once, somewhere in constructor? - it's window-wide and hence in phone there is only one window, which stands for app, then subscribe once. In this case, you may add a line that recognizes the current page in window and if that page contains mediacapture then dispose (create similar). Then you can also dispose/initialize in navigation events in case user doesn't leave your app and just navigate.




回答2:


See my answer in https://stackoverflow.com/a/28592882/3998132. Using Window.VisibilityChanged in conjunction with your Page\UserControl Loaded\Unloaded handler should solve your issue I believe.

Using Window.Activated is less desirable than Window.VisibilityChanged because Activated relates to being visible AND having focus where as VisibilityChanged only pertains to visibility. For showing a preview having focus is not applicable. Since Windows Store apps on Windows Phone can only have one Window showing there is no difference in using either however if your app becomes universal and runs on let's say on Windows 8+ Modern shell (which can show multiple Store apps with the Snap window feature) or Windows 10 desktop (which can support multiple Store apps showing at the same time) you will not want to stop preview when a user changes focus from your app but your app is still showing.



来源:https://stackoverflow.com/questions/28113120/mediacapture-and-window-visibilitychanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!