Cómo interactuar con dispositivos NFC en Chrome para Android

Ahora es posible leer y escribir en etiquetas NFC.

François Beaufort
François Beaufort

¿Qué es NFC web?

NFC significa comunicación de campo cercano, una tecnología inalámbrica de corto alcance que funciona a 13.56 MHz y permite la comunicación entre dispositivos a una distancia inferior a 10 cm y una tasa de transmisión de hasta 424 Kbit/s.

El NFC web permite que los sitios lean y escriban en etiquetas NFC cuando están cerca del dispositivo del usuario (por lo general, de 5 a 10 cm, o de 2 a 4 pulgadas). El alcance actual se limita al formato de intercambio de datos NFC (NDEF), un formato de mensaje binario ligero que funciona en diferentes formatos de etiqueta.

Teléfono que enciende una etiqueta NFC para intercambiar datos
Diagrama de una operación de NFC

Casos de uso sugeridos

El NFC web se limita a NDEF porque las propiedades de seguridad de la lectura y escritura de datos NDEF se pueden cuantificar con mayor facilidad. No se admiten las operaciones de E/S de bajo nivel (p.ej., ISO-DEP, NFC-A/B, NFC-F), el modo de comunicación punto a punto ni la emulación de tarjetas basada en host (HCE).

Estos son algunos ejemplos de sitios que pueden usar NFC web:

  • Los museos y las galerías de arte pueden mostrar información adicional sobre una exhibición cuando el usuario acerca su dispositivo a una tarjeta NFC cerca de la exposición.
  • Los sitios de administración de inventarios pueden leer o escribir datos en la etiqueta NFC de un contenedor para actualizar la información de su contenido.
  • Los sitios de conferencias pueden usarlo para escanear insignias NFC durante el evento y asegurarse de que estén bloqueadas para evitar más cambios en la información que se escribe en ellas.
  • Los sitios pueden usarlo para compartir los secretos iniciales necesarios para situaciones de aprovisionamiento de dispositivos o servicios, y también para implementar datos de configuración en modo operativo.
Escaneo de varias etiquetas NFC en el teléfono
Administración de inventario de NFC ilustrada

Estado actual

Paso Estado
1. Crea una explicación Completar
2. Crea el borrador inicial de la especificación Completar
3. Recopila comentarios y itera en el diseño Completar
4. Prueba de origen Completar
5. Lanzamiento Completar

Usar NFC web

Detección de funciones

La detección de funciones para el hardware es diferente de lo que probablemente estés acostumbrado. La presencia de NDEFReader indica que el navegador admite NFC web, pero no si está presente el hardware necesario. En particular, si falta el hardware, se rechazará la promesa que devuelvan ciertas llamadas. Proporcionaré detalles cuando describa NDEFReader.

if ('NDEFReader' in window) { /* Scan and write NFC tags */ }

Terminología

Una etiqueta NFC es un dispositivo NFC pasivo, lo que significa que se alimenta por inducción magnética cuando hay un dispositivo NFC activo (como un teléfono) cerca. Las etiquetas NFC se presentan en muchas formas y diseños, como calcomanías, tarjetas de crédito, pulseras y mucho más.

Foto de una etiqueta NFC transparente
Una etiqueta NFC transparente

El objeto NDEFReader es el punto de entrada en NFC web que expone la funcionalidad para preparar acciones de lectura o escritura que se cumplen cuando una etiqueta NDEF está cerca. El NDEF en NDEFReader significa Formato de intercambio de datos NFC, un formato de mensaje binario ligero estandarizado por el Foro NFC.

El objeto NDEFReader sirve para actuar sobre mensajes NDEF entrantes de etiquetas NFC y para escribir mensajes NDEF en etiquetas NFC dentro del rango.

Una etiqueta NFC que admite NDEF es como una nota adhesiva. Cualquier persona puede leerlo y, a menos que sea de solo lectura, cualquiera puede escribir en él. Contiene un solo mensaje NDEF que encapsula uno o más registros NDEF. Cada registro NDEF es una estructura binaria que contiene una carga útil de datos y la información del tipo asociada. El NFC web admite los siguientes tipos de registros estandarizados del NFC Forum: vacío, texto, URL, póster inteligente, tipo MIME, URL absoluta, tipo externo, desconocido y tipo local.

Diagrama de un mensaje NDEF
Diagrama de un mensaje NDEF

Escanear etiquetas NFC

Para escanear etiquetas NFC, primero crea una instancia de un nuevo objeto NDEFReader. Si se llama a scan(), se muestra una promesa. Es posible que se le solicite al usuario que otorgue acceso si no se le otorgó anteriormente. La promesa se resolverá si se cumplen todas las siguientes condiciones:

  • Solo se llamó en respuesta a un gesto del usuario, como un gesto táctil o un clic con el mouse.
  • El usuario permitió que el sitio web interactúe con dispositivos NFC.
  • El teléfono del usuario es compatible con NFC.
  • El usuario habilitó NFC en su teléfono.

Una vez que se resuelve la promesa, los mensajes NDEF entrantes están disponibles si te suscribes a los eventos reading a través de un objeto de escucha de eventos. También debes suscribirte a eventos readingerror para recibir notificaciones cuando haya etiquetas NFC incompatibles cerca.

const ndef = new NDEFReader();
ndef.scan().then(() => {
  console.log("Scan started successfully.");
  ndef.onreadingerror = () => {
    console.log("Cannot read data from the NFC tag. Try another one?");
  };
  ndef.onreading = event => {
    console.log("NDEF message read.");
  };
}).catch(error => {
  console.log(`Error! Scan failed to start: ${error}.`);
});

Cuando hay una etiqueta NFC cerca, se activa un evento NDEFReadingEvent. Contiene dos propiedades únicas:

  • serialNumber representa el número de serie del dispositivo (p. ej., 00-11-22-33-44-55-66) o una cadena vacía si no hay ninguna disponible.
  • message representa el mensaje NDEF almacenado en la etiqueta NFC.

Para leer el contenido del mensaje NDEF, realiza un bucle en message.records y procesa sus miembros data de manera adecuada según su recordType. El miembro data se expone como DataView, ya que permite controlar casos en los que los datos están codificados en UTF-16.

ndef.onreading = event => {
  const message = event.message;
  for (const record of message.records) {
    console.log("Record type:  " + record.recordType);
    console.log("MIME type:    " + record.mediaType);
    console.log("Record id:    " + record.id);
    switch (record.recordType) {
      case "text":
        // TODO: Read text record with record data, lang, and encoding.
        break;
      case "url":
        // TODO: Read URL record with record data.
        break;
      default:
        // TODO: Handle other records with record data.
    }
  }
};

Escribir etiquetas NFC

Para escribir etiquetas NFC, primero crea una instancia de un nuevo objeto NDEFReader. Si llamas a write(), se muestra una promesa. Es posible que se le solicite al usuario si no se otorgó acceso con anterioridad. En este punto, se “prepara” un mensaje NDEF y se resolverá la promesa si se cumplen todas las siguientes condiciones:

  • Solo se llamó en respuesta a un gesto del usuario, como un gesto táctil o un clic con el mouse.
  • El usuario permitió que el sitio web interactúe con dispositivos NFC.
  • El teléfono del usuario es compatible con NFC.
  • El usuario habilitó NFC en su teléfono.
  • El usuario presionó una etiqueta NFC y se escribió correctamente un mensaje NDEF.

Para escribir texto en una etiqueta NFC, pasa una cadena al método write().

const ndef = new NDEFReader();
ndef.write(
  "Hello World"
).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Para escribir un registro de URL en una etiqueta NFC, pasa un diccionario que represente un mensaje NDEF a write(). En el siguiente ejemplo, el mensaje NDEF es un diccionario con una clave records. Su valor es un array de registros; en este caso, un registro de URL definido como un objeto con una clave recordType establecida en "url" y una clave data establecida en la cadena de URL.

const ndef = new NDEFReader();
ndef.write({
  records: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }]
}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

También es posible escribir varios registros en una etiqueta NFC.

const ndef = new NDEFReader();
ndef.write({ records: [
    { recordType: "url", data: "https://w3c.github.io/web-nfc/" },
    { recordType: "url", data: "https://web.dev/nfc/" }
]}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Si la etiqueta NFC contiene un mensaje NDEF que no se debe reemplazar, establece la propiedad overwrite en false en las opciones que se pasan al método write(). En ese caso, la promesa que se muestra se rechazará si ya se almacenó un mensaje NDEF en la etiqueta NFC.

const ndef = new NDEFReader();
ndef.write("Writing data on an empty NFC tag is fun!", { overwrite: false })
.then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Cómo hacer que las etiquetas NFC sean de solo lectura

Para evitar que usuarios malintencionados reemplacen el contenido de una etiqueta NFC, es posible hacerlas de solo lectura de forma permanente. Esta operación es un proceso unidireccional y no se puede revertir. Una vez que se establece una etiqueta NFC como de solo lectura, ya no se puede escribir en ella.

Para que las etiquetas NFC sean de solo lectura, primero crea una instancia de un nuevo objeto NDEFReader. Si llamas a makeReadOnly(), se muestra una promesa. Es posible que se le solicite al usuario que otorgue acceso si no se le otorgó anteriormente. La promesa se resolverá si se cumplen todas las siguientes condiciones:

  • Solo se llamó en respuesta a un gesto del usuario, como un gesto táctil o un clic con el mouse.
  • El usuario permitió que el sitio web interactúe con dispositivos NFC.
  • El teléfono del usuario es compatible con NFC.
  • El usuario habilitó NFC en su teléfono.
  • El usuario tocó una etiqueta NFC y esta se convirtió correctamente en de solo lectura.
const ndef = new NDEFReader();
ndef.makeReadOnly()
.then(() => {
  console.log("NFC tag has been made permanently read-only.");
}).catch(error => {
  console.log(`Operation failed: ${error}`);
});

A continuación, se explica cómo hacer que una etiqueta NFC sea de solo lectura de forma permanente después de escribir en ella.

const ndef = new NDEFReader();
try {
  await ndef.write("Hello world");
  console.log("Message written.");
  await ndef.makeReadOnly();
  console.log("NFC tag has been made permanently read-only after writing to it.");
} catch (error) {
  console.log(`Operation failed: ${error}`);
}

Dado que makeReadOnly() está disponible en Android en Chrome 100 o versiones posteriores, comprueba si esta función es compatible con los siguientes elementos:

if ("NDEFReader" in window && "makeReadOnly" in NDEFReader.prototype) {
  // makeReadOnly() is supported.
}

Seguridad y permisos

El equipo de Chrome diseñó e implementó NFC web con los principios básicos definidos en Control de acceso a funciones potentes de la plataforma web, incluidos el control del usuario, la transparencia y la ergonomía.

Debido a que NFC expande el dominio de información potencialmente disponible para sitios web maliciosos, la disponibilidad de NFC se restringe para maximizar el conocimiento y el control de los usuarios sobre el uso de NFC.

Captura de pantalla de un mensaje de NFC web en un sitio web
Mensaje para el usuario de NFC web

El NFC web solo está disponible para marcos de nivel superior y contextos de navegación seguros (solo HTTPS). Los orígenes primero deben solicitar el permiso "nfc" mientras controlan un gesto del usuario (p. ej., un clic en un botón). Los métodos NDEFReader, scan(), write() y makeReadOnly() activan un mensaje para el usuario si no se otorgó acceso anteriormente.

  document.querySelector("#scanButton").onclick = async () => {
    const ndef = new NDEFReader();
    // Prompt user to allow website to interact with NFC devices.
    await ndef.scan();
    ndef.onreading = event => {
      // TODO: Handle incoming NDEF messages.
    };
  };

La combinación de una solicitud de permiso iniciada por el usuario y el movimiento físico real de colocar el dispositivo sobre una etiqueta NFC de destino refleja el patrón del selector que se encuentra en las otras APIs de acceso al dispositivo y archivos.

Para realizar una lectura o escritura, la página web debe ser visible cuando el usuario toca una etiqueta NFC con su dispositivo. El navegador usa la respuesta táctil para indicar un toque. El acceso a la radio NFC se bloquea si la pantalla está apagada o el dispositivo está bloqueado. En el caso de las páginas web no visibles, se suspenden el envío y la recepción de contenido NFC, y se reanudan cuando una página web vuelve a ser visible.

Gracias a la API de Page Visibility, es posible realizar un seguimiento de los cambios en la visibilidad del documento.

document.onvisibilitychange = event => {
  if (document.hidden) {
    // All NFC operations are automatically suspended when document is hidden.
  } else {
    // All NFC operations are resumed, if needed.
  }
};

Libro de recetas

Aquí tienes algunas muestras de código para comenzar.

Verifica el permiso

La API de Permissions permite verificar si se otorgó el permiso "nfc". En este ejemplo, se muestra cómo escanear etiquetas NFC sin interacción del usuario si se otorgó acceso anteriormente, o bien mostrar un botón en caso contrario. Ten en cuenta que el mismo mecanismo funciona para escribir etiquetas NFC, ya que usa el mismo permiso en niveles más profundos.

const ndef = new NDEFReader();

async function startScanning() {
  await ndef.scan();
  ndef.onreading = event => {
    /* handle NDEF messages */
  };
}

const nfcPermissionStatus = await navigator.permissions.query({ name: "nfc" });
if (nfcPermissionStatus.state === "granted") {
  // NFC access was previously granted, so we can start NFC scanning now.
  startScanning();
} else {
  // Show a "scan" button.
  document.querySelector("#scanButton").style.display = "block";
  document.querySelector("#scanButton").onclick = event => {
    // Prompt user to allow UA to send and receive info when they tap NFC devices.
    startScanning();
  };
}

Anular operaciones de NFC

El uso de la primitiva AbortController facilita la interrupción de las operaciones de NFC. En el siguiente ejemplo, se muestra cómo pasar el signal de un AbortController a través de las opciones de los métodos scan(), makeReadOnly() y write() de NDEFReader, y abortar ambas operaciones de NFC al mismo tiempo.

const abortController = new AbortController();
abortController.signal.onabort = event => {
  // All NFC operations have been aborted.
};

const ndef = new NDEFReader();
await ndef.scan({ signal: abortController.signal });

await ndef.write("Hello world", { signal: abortController.signal });
await ndef.makeReadOnly({ signal: abortController.signal });

document.querySelector("#abortButton").onclick = event => {
  abortController.abort();
};

Leer luego de escribir

El uso de write() y, luego, scan() con la primitiva AbortController permite leer una etiqueta NFC después de escribirle un mensaje. En el siguiente ejemplo, se muestra cómo escribir un mensaje de texto en una etiqueta NFC y leer el mensaje nuevo en la etiqueta NFC. Deja de escanear después de tres segundos.

// Waiting for user to tap NFC tag to write to it...
const ndef = new NDEFReader();
await ndef.write("Hello world");
// Success! Message has been written.

// Now scanning for 3 seconds...
const abortController = new AbortController();
await ndef.scan({ signal: abortController.signal });
const message = await new Promise((resolve) => {
  ndef.onreading = (event) => resolve(event.message);
});
// Success! Message has been read.

await new Promise((r) => setTimeout(r, 3000));
abortController.abort();
// Scanning is now stopped.

Lee y escribe un registro de texto

El registro de texto data se puede decodificar con un TextDecoder creado con la propiedad encoding del registro. Ten en cuenta que el idioma del registro de texto está disponible a través de su propiedad lang.

function readTextRecord(record) {
  console.assert(record.recordType === "text");
  const textDecoder = new TextDecoder(record.encoding);
  console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
}

Para escribir un registro de texto simple, pasa una cadena al método write() de NDEFReader.

const ndef = new NDEFReader();
await ndef.write("Hello World");

Los registros de texto son UTF-8 de forma predeterminada y asumen el idioma del documento actual, pero ambas propiedades (encoding y lang) se pueden especificar con la sintaxis completa para crear un registro NDEF personalizado.

function a2utf16(string) {
  let result = new Uint16Array(string.length);
  for (let i = 0; i < string.length; i++) {
    result[i] = string.codePointAt(i);
  }
  return result;
}

const textRecord = {
  recordType: "text",
  lang: "fr",
  encoding: "utf-16",
  data: a2utf16("Bonjour, François !")
};

const ndef = new NDEFReader();
await ndef.write({ records: [textRecord] });

Leer y escribir un registro de URL

Usa TextDecoder para decodificar el data del registro.

function readUrlRecord(record) {
  console.assert(record.recordType === "url");
  const textDecoder = new TextDecoder();
  console.log(`URL: ${textDecoder.decode(record.data)}`);
}

Para escribir un registro de URL, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro de URL contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en "url" y una clave data establecida en la cadena de URL.

const urlRecord = {
  recordType: "url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [urlRecord] });

Cómo leer y escribir un registro de tipo MIME

La propiedad mediaType de un registro de tipo MIME representa el tipo de MIME de la carga útil del registro NDEF para que data se pueda decodificar correctamente. Por ejemplo, usa JSON.parse para decodificar texto JSON y un elemento Image para decodificar datos de imagen.

function readMimeRecord(record) {
  console.assert(record.recordType === "mime");
  if (record.mediaType === "application/json") {
    const textDecoder = new TextDecoder();
    console.log(`JSON: ${JSON.parse(decoder.decode(record.data))}`);
  }
  else if (record.mediaType.startsWith('image/')) {
    const blob = new Blob([record.data], { type: record.mediaType });
    const img = new Image();
    img.src = URL.createObjectURL(blob);
    document.body.appendChild(img);
  }
  else {
    // TODO: Handle other MIME types.
  }
}

Para escribir un registro de tipo MIME, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro de tipo MIME contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en "mime", una clave mediaType establecida en el tipo de MIME real del contenido y una clave data establecida en un objeto que puede ser un ArrayBuffer o proporcionar una vista de un ArrayBuffer (p.ej., Uint8Array, DataView).

const encoder = new TextEncoder();
const data = {
  firstname: "François",
  lastname: "Beaufort"
};
const jsonRecord = {
  recordType: "mime",
  mediaType: "application/json",
  data: encoder.encode(JSON.stringify(data))
};

const imageRecord = {
  recordType: "mime",
  mediaType: "image/png",
  data: await (await fetch("icon1.png")).arrayBuffer()
};

const ndef = new NDEFReader();
await ndef.write({ records: [jsonRecord, imageRecord] });

Cómo leer y escribir un registro de URL absoluta

El registro de URL absoluta data se puede decodificar con un TextDecoder simple.

function readAbsoluteUrlRecord(record) {
  console.assert(record.recordType === "absolute-url");
  const textDecoder = new TextDecoder();
  console.log(`Absolute URL: ${textDecoder.decode(record.data)}`);
}

Para escribir un registro de URL absoluto, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro de URL absoluta contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en "absolute-url" y una clave data establecida en la cadena de URL.

const absoluteUrlRecord = {
  recordType: "absolute-url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [absoluteUrlRecord] });

Cómo leer y escribir un registro de póster inteligente

Un registro de póster inteligente (que se usa en anuncios de revistas, folletos, vallas publicitarias, etc.) describe parte del contenido web como un registro NDEF que contiene un mensaje NDEF como carga útil. Llama a record.toRecords() para transformar data en una lista de registros contenidos en el registro de póster inteligente. Debe tener un registro de URL, un registro de texto para el título, un registro de tipo MIME para la imagen y algunos registros de tipo local personalizados, como ":t", ":act" y ":s", respectivamente, para el tipo, la acción y el tamaño del registro de póster inteligente.

Los registros de tipo local son únicos solo dentro del contexto local del registro NDEF que los contiene. Úsalos cuando el significado de los tipos no importe fuera del contexto local del registro contenedor y cuando el uso de almacenamiento sea una restricción estricta. Los nombres de los registros de tipo local siempre comienzan con : en NFC web (p.ej., ":t", ":s", ":act"). Esto se hace para diferenciar un registro de texto de un registro de texto de tipo local, por ejemplo.

function readSmartPosterRecord(smartPosterRecord) {
  console.assert(record.recordType === "smart-poster");
  let action, text, url;

  for (const record of smartPosterRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      text = decoder.decode(record.data);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      url = decoder.decode(record.data);
    } else if (record.recordType == ":act") {
      action = record.data.getUint8(0);
    } else {
      // TODO: Handle other type of records such as `:t`, `:s`.
    }
  }

  switch (action) {
    case 0:
      // Do the action
      break;
    case 1:
      // Save for later
      break;
    case 2:
      // Open for editing
      break;
  }
}

Para escribir un registro de póster inteligente, pasa un mensaje NDEF al método write() de NDEFReader. El registro de póster inteligente contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en "smart-poster" y una clave data establecida en un objeto que representa (una vez más) un mensaje NDEF contenido en el registro de póster inteligente.

const encoder = new TextEncoder();
const smartPosterRecord = {
  recordType: "smart-poster",
  data: {
    records: [
      {
        recordType: "url", // URL record for smart poster content
        data: "https://my.org/content/19911"
      },
      {
        recordType: "text", // title record for smart poster content
        data: "Funny dance"
      },
      {
        recordType: ":t", // type record, a local type to smart poster
        data: encoder.encode("image/gif") // MIME type of smart poster content
      },
      {
        recordType: ":s", // size record, a local type to smart poster
        data: new Uint32Array([4096]) // byte size of smart poster content
      },
      {
        recordType: ":act", // action record, a local type to smart poster
        // do the action, in this case open in the browser
        data: new Uint8Array([0])
      },
      {
        recordType: "mime", // icon record, a MIME type record
        mediaType: "image/png",
        data: await (await fetch("icon1.png")).arrayBuffer()
      },
      {
        recordType: "mime", // another icon record
        mediaType: "image/jpg",
        data: await (await fetch("icon2.jpg")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
await ndef.write({ records: [smartPosterRecord] });

Cómo leer y escribir un registro de tipo externo

Para crear registros definidos por la aplicación, usa registros de tipo externos. Pueden contener un mensaje NDEF como carga útil a la que se puede acceder con toRecords(). Su nombre contiene el nombre de dominio de la organización emisora, un dos puntos y un nombre de tipo que tiene al menos un carácter, por ejemplo, "example.com:foo".

function readExternalTypeRecord(externalTypeRecord) {
  for (const record of externalTypeRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      console.log(`URL: ${decoder.decode(record.data)}`);
    } else {
      // TODO: Handle other type of records.
    }
  }
}

Para escribir un registro de tipo externo, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro de tipo externo contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en el nombre del tipo externo y una clave data establecida en un objeto que representa un mensaje NDEF contenido en el registro de tipo externo. Ten en cuenta que la clave data también puede ser ArrayBuffer o proporciona una vista de un ArrayBuffer (p.ej., Uint8Array o DataView).

const externalTypeRecord = {
  recordType: "example.game:a",
  data: {
    records: [
      {
        recordType: "url",
        data: "https://example.game/42"
      },
      {
        recordType: "text",
        data: "Game context given here"
      },
      {
        recordType: "mime",
        mediaType: "image/png",
        data: await (await fetch("image.png")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
ndef.write({ records: [externalTypeRecord] });

Cómo leer y escribir un registro vacío

Un registro vacío no tiene carga útil.

Para escribir un registro vacío, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro vacío contenido en el mensaje NDEF se define como un objeto con una clave recordType establecida en "empty".

const emptyRecord = {
  recordType: "empty"
};

const ndef = new NDEFReader();
await ndef.write({ records: [emptyRecord] });

Navegadores compatibles

El NFC web está disponible en Android a partir de Chrome 89.

Sugerencias para desarrolladores

Esta es una lista de lo que me hubiera gustado saber cuando comencé a usar NFC web:

  • Android controla las etiquetas NFC a nivel del SO antes de que el NFC web esté en funcionamiento.
  • Puedes encontrar un ícono de NFC en material.io.
  • Usa el registro NDEF id para identificar fácilmente un registro cuando sea necesario.
  • Una etiqueta NFC sin formato que admite NDEF contiene un único registro de tipo vacío.
  • Escribir un registro de aplicación para Android es fácil, como se muestra a continuación.
const encoder = new TextEncoder();
const aarRecord = {
  recordType: "android.com:pkg",
  data: encoder.encode("com.example.myapp")
};

const ndef = new NDEFReader();
await ndef.write({ records: [aarRecord] });

Demostraciones

Prueba el ejemplo oficial y mira algunas demostraciones geniales de NFC web:

Demostración de tarjetas NFC web en Chrome Dev Summit 2019

Comentarios

Al grupo comunitario de Web NFC y al equipo de Chrome les encantaría conocer tus opiniones y experiencias con Web NFC.

Cuéntanos sobre el diseño de la API

¿Existe algún aspecto de la API que no funcione según lo esperado? ¿O faltan métodos o propiedades que necesitas para implementar tu idea?

Informa un problema de especificaciones en el repositorio de GitHub Web NFC o agrega tus ideas sobre un problema existente.

Denuncia un problema con la implementación

¿Encontraste un error en la implementación de Chrome? ¿O la implementación es diferente de la especificación?

Informa un error en https://new.crbug.com. Asegúrate de incluir la mayor cantidad de detalles posible, proporciona instrucciones simples para reproducir el error y establece Componentes en Blink>NFC. Glitch es excelente para compartir reproducciones rápidas y fáciles.

Demostrar apoyo

¿Planeas usar NFC web? Tu apoyo público ayuda al equipo de Chrome a priorizar las funciones y les muestra a otros proveedores de navegadores lo importante que es admitirlas.

Envía un tuit a @ChromiumDev con el hashtag #WebNFC y cuéntanos dónde y cómo lo usas.

Vínculos útiles

Agradecimientos

Muchas gracias al equipo de Intel por implementar el NFC web. Google Chrome depende de una comunidad de colaboradores que trabajan juntos para hacer avanzar el proyecto Chromium. No todos los colaboradores de Chromium son Googlers, y estos colaboradores merecen un reconocimiento especial.