WebUSB: как вызвать navigator.usb.requestDevice () в случае сбоя navigator.usb.getDevices () - PullRequest
0 голосов
/ 15 марта 2019

Я пишу расширение на основе WebUSB для Scratch3. В конструкторе расширений мне нужно установить соединение с WebUSB. В идеале я хотел бы использовать navigator.usb.getDevices () для проверки доступных / сопряженных устройств, и в случае сбоя я хотел бы попросить пользователя выбрать устройство с помощью navigator.usb.requestDevice ().

Проблема в том, что navigator.usb.requestDevice () должен вызываться из жеста пользователя. В большинстве случаев конструктор расширения scratch3 вызывается из пользовательского действия, и поэтому я могу прекрасно использовать navigator.usb.requestDevice ().

Но navigator.usb.getDevices () возвращает Promise и вызывает navigator.usb.requestDevice () оттуда с ошибкой «Должен обрабатывать пользовательский жест для отображения запроса на разрешение.»

Итак, работает следующее (но каждый раз открывает диалог запроса):

navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
        .then(selectedDevice => {
            // ...
        })

Но из-за отсутствия "пользовательского жеста" происходит следующее:

navigator.usb.getDevices().then(devices => {
    if(devices.length == 0) {
        navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
            .then(selectedDevice => {
                // ...
        })
    }
})

Я бы хотел не связываться с ядром Scratch 3 и поэтому не хотел бы добавлять еще один элемент пользовательского интерфейса.

Использование только navigator.usb.requestDevice (), как в первом фрагменте, имеет два основных недостатка:

  1. Он все время открывает диалог запроса, хотя это необходимо только один раз
  2. Иногда позже конструктор может быть вызван из неинтерактивной ситуации, и navigator.usb.requestDevice () полностью потерпит неудачу, в то время как navigator.usb.getDevices () завершится успешно

Есть ли способ заставить подход из второго фрагмента кода работать?

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

Это исправлено в Chrome 72 с помощью функции User Activation v2 .

0 голосов
/ 16 марта 2019

Я не знаком с Scratch 3, но можно ли вызвать getDevices(), когда ваше расширение инициализировано, и отложить предоставление кнопки, которую пользователь может нажать, чтобы вызвать requestDevice(), пока код не узнает, имеет ли он уже разрешение на доступустройство?

Предоставляются метод getDevices() и обработчики событий onconnect и ondisconnect, чтобы страница могла поддерживать свой интерфейс в актуальном состоянии с любыми доступными устройствами.

...