private async void DevicePicker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { // 更新 picker 上設備的 status sender.SetDisplayStatus(args.SelectedDevice, "connecting", DevicePickerDisplayStatusOptions.ShowProgress); // 取得目前選到設備的資訊 activeDevice = args.SelectedDevice; // 現在 view 的 Id 與 CoreDispatcher int currentViewId = ApplicationView.GetForCurrentView().Id; CoreDispatcher currentDispatcher = Window.Current.Dispatcher; // 建立新的 view, if (projectionInstance.ProjectionViewPageControl == null) { await CoreApplication.CreateNewView().Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // 建立新 viewe 的生命管理器 projectionInstance.ProjectionViewPageControl = ViewLifetimeControl.CreateForCurrentView(); projectionInstance.MainViewId = currentViewId; var rootFrame = new Frame(); rootFrame.Navigate(typeof(ProjectionPage), projectionInstance); // 這裏的 Window 代表是新建立這個 view 的 Window // 但是要等到呼叫 ProjectionManager.StartProjectingAsync 才會顯示 Window.Current.Content = rootFrame; Window.Current.Activate(); }); } // 直接切換到指定的 view id //bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(projectionInstance.ProjectionViewPageControl.Id); // 通知要使用新的 view projectionInstance.ProjectionViewPageControl.StartViewInUse(); try { txtViewId.Text = $"{projectionInstance.ProjectionViewPageControl.Id}, {currentViewId}"; await ProjectionManager.StartProjectingAsync(projectionInstance.ProjectionViewPageControl.Id, currentViewId, activeDevice); player.Pause(); sender.SetDisplayStatus(args.SelectedDevice, "connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } catch (Exception ex) { sender.SetDisplayStatus(args.SelectedDevice, ex.Message, DevicePickerDisplayStatusOptions.ShowRetryButton); if (ProjectionManager.ProjectionDisplayAvailable == false) { throw; } } }); }
private async void Picker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { string deviceId = args.SelectedDevice.Id; //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { //Update the display status for the selected device to connecting. picker.SetDisplayStatus(args.SelectedDevice, "Connecting", DevicePickerDisplayStatusOptions.ShowProgress); // BUG: In order to support debugging it is best to retreive the device from the local app instead // of continuing to use the DeviceInformation instance that is proxied from the picker. DeviceInformation device = null; try { if (deviceId.IndexOf("dial", StringComparison.OrdinalIgnoreCase) == -1) { device = await DeviceInformation.CreateFromIdAsync(deviceId, RequiredDeviceProperties.Props, DeviceInformationKind.DeviceContainer); } } catch { } try { if (device == null) { device = await DeviceInformation.CreateFromIdAsync(deviceId, RequiredDeviceProperties.Props, DeviceInformationKind.AssociationEndpoint); } } catch { } // In case the workaround did not work if (device == null) { device = args.SelectedDevice; } //Try casting using DIAL first bool castSucceeded = await TryLaunchDialAppAsync(device); //If DIAL did not work for the selected device, try the CAST API if (!castSucceeded) { castSucceeded = await TryCastMediaElementAsync(device); } if (castSucceeded) { //Update the display status for the selected device. try { picker.SetDisplayStatus(device, "Connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } catch { } disconnectButton.IsEnabled = true; // Hide the picker now that all the work is completed //picker.Hide(); } else { //Show a retry button when connecting to the selected device failed. picker.SetDisplayStatus(device, "Connecting failed", DevicePickerDisplayStatusOptions.ShowRetryButton); } }); }
private async void Picker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { string deviceId = args.SelectedDevice.Id; //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { //Update the display status for the selected device to connecting. try { picker.SetDisplayStatus(args.SelectedDevice, "Connecting", DevicePickerDisplayStatusOptions.ShowProgress); } catch { } //The selectedDeviceInfo instance is needed to be able to update the picker. DeviceInformation selectedDeviceInfo = args.SelectedDevice; #if DEBUG // The args.SelectedCastingDevice is proxied from the picker process. The picker process is // dismissmed as soon as you break into the debugger. Creating a non-proxied version // allows debugging since the proxied version stops working once the picker is dismissed. selectedDeviceInfo = await DeviceInformation.CreateFromIdAsync(args.SelectedDevice.Id); #endif bool castSucceeded = false; // If the ProjectionManager API did not work and the device id will have 'dial' in it. castSucceeded = await TryLaunchDialAppAsync(selectedDeviceInfo); // If it doesn't try the ProjectionManager API. if (!castSucceeded) { castSucceeded = await TryProjectionManagerCastAsync(selectedDeviceInfo); } //If DIAL and ProjectionManager did not work for the selected device, try the CAST API if (!castSucceeded) { castSucceeded = await TryCastMediaElementAsync(selectedDeviceInfo); } if (castSucceeded) { //Update the display status for the selected device. Try Catch in case the picker is not visible anymore. try { picker.SetDisplayStatus(selectedDeviceInfo, "Connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } catch { } // Hide the picker now that all the work is completed. Try Catch in case the picker is not visible anymore. try { picker.Hide(); } catch { } } else { //Show a retry button when connecting to the selected device failed. try { picker.SetDisplayStatus(selectedDeviceInfo, "Connecting failed", DevicePickerDisplayStatusOptions.ShowRetryButton); } catch { } } }); }
private async Task StopProjection(DevicePicker sender, DeviceInformation device) { // 關閉新建立的 view projectionInstance.Content.StopProjection(); //Update the display status for the selected device. sender.SetDisplayStatus(device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); //Update the display status for the selected device. sender.SetDisplayStatus(device, "Disconnected", DevicePickerDisplayStatusOptions.None); // Set the active device variables to null activeDevice = null; }
private async void Picker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { string deviceId = args.SelectedDevice.Id; //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { //Update the display status for the selected device to connecting. picker.SetDisplayStatus(args.SelectedDevice, "Connecting", DevicePickerDisplayStatusOptions.ShowProgress); // BUG: In order to support debugging it is best to retreive the device from the local app instead // of continuing to use the DeviceInformation instance that is proxied from the picker. DeviceInformation device = await DeviceInformation.CreateFromIdAsync(deviceId); bool castSucceeded = false; // The dial AssociationEndpoint ID will have 'dial' in the string. // If it doesn't try the ProjectionManager API. if (deviceId.IndexOf("dial", StringComparison.OrdinalIgnoreCase) == -1) { castSucceeded = await TryProjectionManagerCastAsync(device); } // If the ProjectionManager API did not work and the device id will have 'dial' in it. if (!castSucceeded && deviceId.IndexOf("dial", StringComparison.OrdinalIgnoreCase) > -1) { castSucceeded = await TryLaunchDialAppAsync(device); } //If DIAL and ProjectionManager did not work for the selected device, try the CAST API if (!castSucceeded) { castSucceeded = await TryCastMediaElementAsync(device); } if (castSucceeded) { //Update the display status for the selected device. Try Catch in case the picker is not visible anymore. try { picker.SetDisplayStatus(device, "Connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } catch { } // Hide the picker now that all the work is completed. Try Catch in case the picker is not visible anymore. try { picker.Hide(); } catch { } } else { //Show a retry button when connecting to the selected device failed. try { picker.SetDisplayStatus(device, "Connecting failed", DevicePickerDisplayStatusOptions.ShowRetryButton); } catch { } } }); }
private void Picker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { // Getting the selected device _selectedDeviceInformation = args.SelectedDevice; // Save a setting locally on the device ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; localSettings.Values[SelectedDeviceKey] = _selectedDeviceInformation.Id; _onDeviceSelected(_selectedDeviceInformation.Id); // Set status to Connecting _picker.SetDisplayStatus(args.SelectedDevice, "", DevicePickerDisplayStatusOptions.None); }
private async void DevicePicker_DisconnectButtonClicked(DevicePicker sender, DeviceDisconnectButtonClickedEventArgs args) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // 關閉新建立的 view projectionInstance.Content.StopProjection(); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnected", DevicePickerDisplayStatusOptions.None); // Set the active device variables to null activeDevice = null; }); }
private async void Picker_DisconnectButtonClicked(DevicePicker sender, DeviceDisconnectButtonClickedEventArgs args) { //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { rootPage.NotifyUser("Disconnect Button clicked", NotifyType.StatusMessage); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); bool disconnected = false; if (this.activeCastConnectionHandler is ProjectionViewBroker) { disconnected = TryStopProjectionManagerAsync((ProjectionViewBroker)activeCastConnectionHandler); } if (this.activeCastConnectionHandler is DialApp) { disconnected = await TryStopDialAppAsync((DialApp)activeCastConnectionHandler); } if (this.activeCastConnectionHandler is CastingConnection) { disconnected = await TryDisconnectCastingSessionAsync((CastingConnection)activeCastConnectionHandler); } if (disconnected) { //Update the display status for the selected device. try { sender.SetDisplayStatus(args.Device, "Disconnected", DevicePickerDisplayStatusOptions.None); } catch { } // Set the active device variables to null activeDevice = null; activeCastConnectionHandler = null; //Hide the picker sender.Hide(); } else { //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnect failed", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } }); }
private async Task StopDialConnection(DevicePicker picker, DeviceInformation device) { try { // 取得被選擇的 dial device DialDevice selectedDialDevice = await DialDevice.FromIdAsync(device.Id); // 更新 picker status picker.SetDisplayStatus(device, "connecting", DevicePickerDisplayStatusOptions.ShowProgress); // 取得 dial app DialApp app = selectedDialDevice.GetDialApp("castingsample"); // 請求斷綫 DialAppStopResult result = await app.StopAsync(); if (result == DialAppStopResult.Stopped) { picker.SetDisplayStatus(device, "Disconnected", DevicePickerDisplayStatusOptions.None); activeDevice = null; picker.Hide(); } else { if (result == DialAppStopResult.StopFailed || result == DialAppStopResult.NetworkFailure) { // 如果失敗的話要記得多 retry 的機制 picker.SetDisplayStatus(device, "Error", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } else { // 如果設備沒有支援 Stop 機制,則直接清楚連綫就好 activeDevice = null; } } } catch (Exception ex) { } }
private async Task SendDialParameter(DevicePicker sender, DeviceSelectedEventArgs args) { try { // 設定遠端設備現在要準備連綫 sender.SetDisplayStatus(args.SelectedDevice, "connecting", DevicePickerDisplayStatusOptions.ShowProgress); // 取得遠端設備中支援指定 app name 的 App DialDevice dialDevice = await DialDevice.FromIdAsync(args.SelectedDevice.Id); DialApp app = dialDevice.GetDialApp("castingsample"); if (app == null) { // 嘗試建立 DIAL device,如果失敗代表那個設備不支援 DIAL sender.SetDisplayStatus(args.SelectedDevice, "The app is not exist in the device.", DevicePickerDisplayStatusOptions.ShowRetryButton); } else { // 請求送出參數到遠端設備的 App DialAppLaunchResult result = await app.RequestLaunchAsync("Test"); if (result == DialAppLaunchResult.Launched) { activeDevice = args.SelectedDevice; sender.SetDisplayStatus(args.SelectedDevice, "connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); sender.Hide(); } else { sender.SetDisplayStatus(args.SelectedDevice, "Device Error", DevicePickerDisplayStatusOptions.ShowRetryButton); } } } catch (Exception ex) { sender.SetDisplayStatus(args.SelectedDevice, ex.Message, DevicePickerDisplayStatusOptions.None); } }
private async void Picker_DisconnectButtonClicked(DevicePicker sender, DeviceDisconnectButtonClickedEventArgs args) { //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { rootPage.NotifyUser("Disconnect Button clicked", NotifyType.StatusMessage); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); if (this.pvb.ProjectedPage != null) { this.pvb.ProjectedPage.StopProjecting(); } //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnected", DevicePickerDisplayStatusOptions.None); rootPage.NotifyUser("Disconnected", NotifyType.StatusMessage); // Set the active device variables to null activeDevice = null; }); }
private async void Picker_DeviceSelected(DevicePicker sender, DeviceSelectedEventArgs args) { //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { try { // Set status to Connecting picker.SetDisplayStatus(args.SelectedDevice, "Connecting", DevicePickerDisplayStatusOptions.ShowProgress); // Getting the selected device improves debugging DeviceInformation selectedDevice = args.SelectedDevice; thisViewId = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().Id; // If projection is already in progress, then it could be shown on the monitor again // Otherwise, we need to create a new view to show the presentation if (rootPage.ProjectionViewPageControl == null) { // First, create a new, blank view var thisDispatcher = Window.Current.Dispatcher; await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // ViewLifetimeControl is a wrapper to make sure the view is closed only // when the app is done with it rootPage.ProjectionViewPageControl = ViewLifetimeControl.CreateForCurrentView(); // Assemble some data necessary for the new page pvb.MainPageDispatcher = thisDispatcher; pvb.ProjectionViewPageControl = rootPage.ProjectionViewPageControl; pvb.MainViewId = thisViewId; // Display the page in the view. Note that the view will not become visible // until "StartProjectingAsync" is called var rootFrame = new Frame(); rootFrame.Navigate(typeof(ProjectionViewPage), pvb); Window.Current.Content = rootFrame; Window.Current.Activate(); }); } try { // Start/StopViewInUse are used to signal that the app is interacting with the // view, so it shouldn't be closed yet, even if the user loses access to it rootPage.ProjectionViewPageControl.StartViewInUse(); try { await ProjectionManager.StartProjectingAsync(rootPage.ProjectionViewPageControl.Id, thisViewId, selectedDevice); } catch (Exception ex) { if (!ProjectionManager.ProjectionDisplayAvailable || pvb.ProjectedPage == null) { throw ex; } } // ProjectionManager currently can throw an exception even when projection has started.\ // Re-throw the exception when projection has not been started after calling StartProjectingAsync if (ProjectionManager.ProjectionDisplayAvailable && pvb.ProjectedPage != null) { this.player.Pause(); await pvb.ProjectedPage.SetMediaSource(this.player.Source, this.player.Position); activeDevice = selectedDevice; // Set status to Connected picker.SetDisplayStatus(args.SelectedDevice, "Connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); picker.Hide(); } else { rootPage.NotifyUser(string.Format("Projection has failed to '{0}'", selectedDevice.Name), NotifyType.ErrorMessage); // Set status to Failed picker.SetDisplayStatus(args.SelectedDevice, "Connection Failed", DevicePickerDisplayStatusOptions.ShowRetryButton); } } catch (Exception) { rootPage.NotifyUser(string.Format("Projection has failed to '{0}'", selectedDevice.Name), NotifyType.ErrorMessage); // Set status to Failed try { picker.SetDisplayStatus(args.SelectedDevice, "Connection Failed", DevicePickerDisplayStatusOptions.ShowRetryButton); } catch { } } } catch (Exception ex) { UnhandledExceptionPage.ShowUnhandledException(ex); } }); }
private async void Picker_DisconnectButtonClicked(DevicePicker sender, DeviceDisconnectButtonClickedEventArgs args) { //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => { rootPage.NotifyUser("Disconnect Button clicked", NotifyType.StatusMessage); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); bool disconnected = false; if (this.activeCastConnectionHandler is ProjectionViewBroker) disconnected = TryStopProjectionManagerAsync((ProjectionViewBroker)activeCastConnectionHandler); if (this.activeCastConnectionHandler is DialApp) disconnected = await TryStopDialAppAsync((DialApp)activeCastConnectionHandler); if (this.activeCastConnectionHandler is CastingConnection) disconnected = await TryDisconnectCastingSessionAsync((CastingConnection)activeCastConnectionHandler); if (disconnected) { //Update the display status for the selected device. try { sender.SetDisplayStatus(args.Device, "Disconnected", DevicePickerDisplayStatusOptions.None); } catch { } // Set the active device variables to null activeDevice = null; activeCastConnectionHandler = null; //Hide the picker sender.Hide(); } else { //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnect failed", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } }); }
private async void Picker_DisconnectButtonClicked(DevicePicker sender, DeviceDisconnectButtonClickedEventArgs args) { //Casting must occur from the UI thread. This dispatches the casting calls to the UI thread. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { rootPage.NotifyUser("Disconnect Button clicked", NotifyType.StatusMessage); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnecting", DevicePickerDisplayStatusOptions.ShowProgress); if (this.pvb.ProjectedPage != null) this.pvb.ProjectedPage.StopProjecting(); //Update the display status for the selected device. sender.SetDisplayStatus(args.Device, "Disconnected", DevicePickerDisplayStatusOptions.None); rootPage.NotifyUser("Disconnected", NotifyType.StatusMessage); // Set the active device variables to null activeDevice = null; }); }
private async Task ProjectioinViewToScreen(DevicePicker sender, DeviceSelectedEventArgs args) { // 更新 picker 上設備的 status sender.SetDisplayStatus(args.SelectedDevice, "Connecting", DevicePickerDisplayStatusOptions.ShowProgress); // 取得目前選到設備的資訊 activeDevice = args.SelectedDevice; // 現在 view 的 Id 與 CoreDispatcher int currentViewId = ApplicationView.GetForCurrentView().Id; CoreDispatcher currentDispatcher = Window.Current.Dispatcher; // 建立新的 view, if (projectionInstance.ProjectionViewPageControl == null) { await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // 建立新 viewe 的生命管理器 projectionInstance.ProjectionViewPageControl = ViewLifetimeControl.CreateForCurrentView(); projectionInstance.MainViewId = currentViewId; var rootFrame = new Frame(); rootFrame.Navigate(typeof(ProjectionPage), projectionInstance); // 這裏的 Window 代表是新建立這個 view 的 Window // 但是要等到呼叫 ProjectionManager.StartProjectingAsync 才會顯示 Window.Current.Content = rootFrame; Window.Current.Activate(); }); } // 直接切換到指定的 view id //bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(projectionInstance.ProjectionViewPageControl.Id); // 通知要使用新的 view projectionInstance.ProjectionViewPageControl.StartViewInUse(); await ProjectionManager.SwapDisplaysForViewsAsync(projectionInstance.ProjectionViewPageControl.Id, currentViewId); try { await ProjectionManager.StartProjectingAsync(projectionInstance.ProjectionViewPageControl.Id, currentViewId, activeDevice); player.Pause(); sender.SetDisplayStatus(args.SelectedDevice, "connected", DevicePickerDisplayStatusOptions.ShowDisconnectButton); } catch (Exception ex) { sender.SetDisplayStatus(args.SelectedDevice, ex.Message, DevicePickerDisplayStatusOptions.ShowRetryButton); if (ProjectionManager.ProjectionDisplayAvailable == false) { throw; } } }