Windows カメラのプライバシー設定を処理する

Windows では、ユーザーは Windows 設定アプリの [プライバシーとセキュリティ] -> [カメラ] で、デバイスのカメラへのアクセスを許可または拒否できます。 カメラ アクセスは、デバイス全体、パッケージ化されていないすべてのアプリ、またはパッケージ化された個々のアプリに対して無効にすることができます。 この記事では、アプリがカメラにアクセスできるかどうかを確認し、ユーザーがアクセスを拒否したケースを処理するためのベスト プラクティスについて説明します。

カメラを初期化する前にアクセスを確認する

パッケージ アプリの場合は、カメラを初期化する前に、アプリにカメラ アクセス権があるかどうかを確認する必要があります。 AppCapability クラスを使用して、アプリにアクセスできるかどうかを判断します。

bool cameraCapabilityAccess = false;
private void CheckCameraAccessStatus()
{
    var status = AppCapability.Create("Webcam").CheckAccess();
    
    if (status == AppCapabilityAccessStatus.Allowed)
    {
        cameraCapabilityAccess = true;
        cameraButton.IsEnabled = true;
    }
    else
    {
        cameraCapabilityAccess = false;
        cameraButton.IsEnabled = false;
    }
}

アクセス拒否エラーを処理する

Windows カメラ キャプチャ API は、ユーザーがカメラプライバシー設定ページでカメラを無効にしている場合に、アプリがカメラ キャプチャ デバイスにアクセスしようとしたときに E_ACCESSDENIED エラーを返します。 アプリは、キャプチャ デバイスを初期化するときに、このエラーを確認する必要があります。 このエラーで初期化が失敗した場合は、ユーザーをカメラのプライバシー設定ページに誘導し、アプリへのアクセスを有効にすることをお勧めします。 [カメラのプライバシー設定] ページは、URI ms-settings:privacy-webcamを使用して起動できます。

次の例は、 MediaCapture.InitializeAsync を呼び出すときにE_ACCESSDENIEDを確認する方法を示しています。

try
{
    await mediaCapture.InitializeAsync(mediaCaptureInitializationSettings);
}
catch (System.UnauthorizedAccessException ex)
{
    // E_ACCESSDENIED, 0x80070005 in hexadecimal, -2147024891 in decimal
    if (ex.HResult == -2147024891)
    {
        StatusTextBlock.Text = "Access to the camera has been denied." +
            "Click the Settings button to check the camera privacy settings";               
    }

    return;
}
...
// Launch the camera privacy Settings page
private async void LaunchSettingsButton_Click(object sender, RoutedEventArgs e)
{
    bool result = await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam"));
}

次の例は、キャプチャ デバイスの IMFMediaSource を初期化するときにIMFActivate::ActivateObject から返されるE_ACCESSDENIED エラーの処理を示しています。

IMFMediaSource* pSource = NULL;
IMFAttributes* pAttributes = NULL;
IMFActivate** ppDevices = NULL;

// Create an attribute store to specify the enumeration parameters.
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
if (FAILED(hr))
{
    goto done;
}

// Source type: video capture devices
hr = pAttributes->SetGUID(
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
if (FAILED(hr))
{
    goto done;
}

// Enumerate devices.
UINT32 count;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (FAILED(hr))
{
    goto done;
}

if (count == 0)
{
    hr = E_FAIL;
    goto done;
}

// Create the media source object.
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(&pSource));
if (FAILED(hr))
{
    if (hr == E_ACCESSDENIED)
    {
        int response = MessageBox(hWnd, L"Access to the camera was denied. Open the camera privacy settings?", L"Error", MB_YESNO);
        if (response == IDYES)
        {
            ShellExecute(NULL, L"open", L"ms-settings:privacy-webcam", L"", L".", SW_SHOWDEFAULT);
        }
    } 
    goto done;
}

フォールバック動作を実装する

アプリでは、前の手順を実装して、プライバシー設定のためにカメラのアクセスが制限されていることをユーザーに検出して警告し、ユーザーが設定を更新できるようにカメラのプライバシー設定ページにユーザーを誘導する必要があります。 これらの手順の後、アプリはカメラの初期化を再試行して、アクセスが許可されているかどうかを確認する必要があります。 アプリがカメラにアクセスできるように設定を更新することをユーザーが拒否した場合は、代替機能を提供することを検討してください。 たとえば、カメラ機能を無効にしたり、別のモードに切り替えたり、カメラ プレビューの代わりにプレースホルダー画像を表示したりできます。