问题
I am trying to show error message "Cannot setup camera; currently being using" when there is already a process running the camera. I have the code that starts the preview using the MediaCapture and it works fine when running without another application using camera. I do get the exception
0x40080201: WinRT originate error (parameters: 0xC00D3704, 0x00000049, 0x10EFF1CC)
in my logs but my try catch block doesn't catch the error.
create_task(_mediaCapture->StartPreviewToCustomSinkAsync(encoding_profile, media_sink)).then([this, &hr](task<void>& info) {
try {
info.get();
} catch (Exception^ e) {
hr = e->HResult;
}
}).wait();
回答1:
StartPreviewAsync method will throw a FileLoadException if another app has exclusive control of the capture device. We can catch this error to alert the user that the camera is currently being used by another application. A simple sample can be found at Use MediaCapture to start the preview stream.
However, this is a C# sample and FileLoadException
is what used in .Net. For C++/CX, we can check the HRESULT value which should be 0x80070020
. Following is the simple sample in C++/CX version.
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<CaptureElement Name="PreviewControl" Stretch="Uniform"/>
<Button Click="Button_Click">Click</Button>
</Grid>
MainPage.xaml.h
public ref class MainPage sealed
{
public:
MainPage();
private:
// Prevent the screen from sleeping while the camera is running
Windows::System::Display::DisplayRequest^ _displayRequest;
// MediaCapture
Platform::Agile<Windows::Media::Capture::MediaCapture^> _mediaCapture;
void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};
MainPage.xaml.cpp
MainPage::MainPage()
: _mediaCapture(nullptr)
, _displayRequest(ref new Windows::System::Display::DisplayRequest())
{
InitializeComponent();
}
void MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
_mediaCapture = ref new Windows::Media::Capture::MediaCapture();
create_task(_mediaCapture->InitializeAsync())
.then([this](task<void> previousTask) {
try
{
previousTask.get();
_displayRequest->RequestActive();
Windows::Graphics::Display::DisplayInformation::AutoRotationPreferences = Windows::Graphics::Display::DisplayOrientations::Landscape;
PreviewControl->Source = _mediaCapture.Get();
create_task(_mediaCapture->StartPreviewAsync())
.then([this](task<void>& previousTask)
{
try
{
previousTask.get();
}
catch (Exception^ exception)
{
if (exception->HResult == 0x80070020)
{
auto messageDialog = ref new Windows::UI::Popups::MessageDialog("Cannot setup camera; currently being using.");
create_task(messageDialog->ShowAsync());
}
}
});
}
catch (AccessDeniedException^)
{
auto messageDialog = ref new Windows::UI::Popups::MessageDialog("The app was denied access to the camera.");
create_task(messageDialog->ShowAsync());
}
});
}
StartPreviewToCustomSinkAsync method is similar to StartPreviewAsync method and can also throw a FileLoadException. You should be able to handle it using the same way. For more info, please also see Handle changes in exclusive control.
来源:https://stackoverflow.com/questions/44468297/how-to-know-that-camera-is-currently-being-used-by-another-application-with-uwp