v154 · webhid on android
Asking for one
A filter, a gesture, and a chooser only the user can answer. Everything up to the chooser is code you write, and it is where the mistakes are — so this page builds the call, makes it for real, and records what came back.
Build a filter
What happened
The second button is the interesting one. It makes the identical call from a timer rather than from your click, which removes the transient user activation — and the rejection you get names the reason, which is more than most gesture-gated APIs manage.
What a filter can say
| field | example | what it matches |
|---|
An empty filters array does not mean "no devices" — it means no constraint, so the chooser offers everything the browser is willing to show. That is rarely what you want: a chooser full of every HID device on the machine asks the user to make a decision they cannot make well.
And then
const [device] = await navigator.hid.requestDevice({ filters });
if (!device) return; // the user closed the chooser — not an error
await device.open();
device.addEventListener("inputreport", ({ data, reportId }) => {
// data is a DataView over the report body, without the report id byte
});
// Give the permission back when you are finished with it.
await device.forget();
The empty result is the case worth handling first: a user who closes the chooser has said no, and it arrives as an empty array rather than a rejection. Code that destructures without checking treats a considered refusal as a crash.