Cómo interactuar con dispositivos NFC en Chrome para Android

Ahora es posible leer etiquetas NFC y escribir en ellas.

François Beaufort
François Beaufort

¿Qué es NFC web?

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

La NFC web proporciona a los sitios la capacidad de leer y escribir en etiquetas NFC cuando se encuentran cerca del dispositivo del usuario (por lo general, de 5 a 10 cm o 2 a 4 pulgadas). El alcance actual se limita al formato de intercambio de datos NFC (NDEF), un formato de mensaje binario liviano que funciona en diferentes formatos de etiquetas.

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

Casos de uso sugeridos

NFC se limita a NDEF porque las propiedades de seguridad de lectura y escritura de datos NDEF son más fácilmente cuantificables. No se admiten operaciones de E/S de bajo nivel (p.ej., ISO-DEP, NFC-A/B, NFC-F), el modo de comunicación entre pares y 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 pantalla cuando el usuario toca una tarjeta NFC cerca de la exhibición en su dispositivo.
  • Los sitios de administración de inventario 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 bloqueados para evitar nuevos cambios en la información escrita en ellos.
  • Los sitios pueden usarlo con el fin de 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.
El teléfono escanea varias etiquetas NFC
Ilustración de la administración de inventario de NFC

Estado actual

Step Estado
1. Crear explicación Completo
2. Crea el borrador inicial de la especificación Completo
3. Recopila comentarios e itera en el diseño Completo
4. Prueba de origen Completo
5. Lanzamiento Completo

Usar NFC web

Detección de funciones

La detección de funciones para hardware es diferente de lo que probablemente estés acostumbrado. La presencia de NDEFReader indica que el navegador admite NFC web, pero no si se encuentra presente el hardware requerido. En particular, si falta el hardware, se rechazará la promesa que devuelvan ciertas llamadas. Proporcionaré detalles cuando describo 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 un dispositivo NFC activo (como un teléfono) se encuentra cerca. Las etiquetas NFC vienen en muchas formas y estilos, como calcomanías, tarjetas de crédito, muñecas para brazos y mucho más.

Foto de una etiqueta NFC transparente
Una etiqueta NFC transparente

El objeto NDEFReader es el punto de entrada en la NFC en la Web que expone la funcionalidad para preparar acciones de lectura o escritura que se completan cuando una etiqueta NDEF se acerca. NDEF en NDEFReader significa Formato de intercambio de datos NFC, un formato de mensaje binario liviano estandarizado por el Foro NFC.

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

Una etiqueta NFC que admite NDEF es como una nota adhesiva. Cualquier persona puede leerlos y, a menos que sea de solo lectura, cualquiera puede escribir en ellos. 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, además de información de tipo asociada. La NFC web admite los siguientes tipos de registros estandarizados del foro NFC: vacío, texto, URL, póster inteligente, tipo de 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. La llamada a scan() muestra una promesa. Si no se le otorgó acceso con anterioridad, es posible que se le solicite al usuario. La promesa se resolverá si se cumplen las siguientes condiciones:

  • Solo se llamaba 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 admite NFC.
  • El usuario habilitó NFC en su teléfono.

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

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 una etiqueta NFC se encuentra 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, recorre message.records y procesa sus miembros de data de forma 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. Llamar a write() muestra una promesa. Si el acceso no se otorgó con anterioridad, es posible que se le solicite al usuario. En este punto, un mensaje NDEF está “preparado” y la promesa se resolverá si se cumplen todas las siguientes condiciones:

  • Solo se llamaba 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 admite 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 hay un mensaje NDEF almacenado 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}.`);
});

Haz que las etiquetas NFC sean de solo lectura

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

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

  • Solo se llamaba 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 admite NFC.
  • El usuario habilitó NFC en su teléfono.
  • El usuario presionó una etiqueta NFC y esta se configuró correctamente como 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, te mostramos 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 para Chrome 100 o versiones posteriores, verifica si esta función es compatible con lo siguiente:

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

Seguridad y permisos

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

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

Captura de pantalla de un mensaje de NFC en la Web en un sitio web
Mensaje del usuario de NFC web

La NFC web solo está disponible para los marcos de nivel superior y los contextos de navegación segura (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 del usuario si no se otorgó acceso con anterioridad.

  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 de selección que se encuentra en las otras APIs de acceso al dispositivo y archivos.

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

Gracias a la API de visibilidad de páginas, es posible hacer un seguimiento de los cambios en la visibilidad de los documentos.

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

Guía de soluciones

A continuación, se incluyen 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ó el acceso anteriormente, o bien se muestra un botón en caso contrario. Ten en cuenta que el mismo mecanismo funciona para escribir etiquetas NFC, ya que usa el mismo permiso de forma interna.

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 NFC

Usar el primitivo AbortController facilita la anulació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 cómo anular 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();
};

Lectura después de escritura

Si usas write() y luego scan() con la primitiva AbortController, podrás 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 cómo leer el mensaje nuevo en esa etiqueta. Detiene la búsqueda 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.

Cómo leer y escribir un registro de texto

Se puede decodificar el registro de texto data con una instancia de TextDecoder 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 suponen 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] });

Lee y escribe 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] });

Leer y escribir un registro de tipo MIME

La propiedad mediaType de un registro de tipo de 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 de imagen a fin de 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 de MIME, pasa un diccionario de mensajes NDEF al método write() de NDEFReader. El registro de tipo de MIME que se incluye 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 ArrayBuffer o proporcionar una vista en 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] });

Lee y escribe un registro de URL absoluto

El registro de URL absoluto 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 URL absoluto que se incluye 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] });

Lee y escribe un registro de póster inteligente

Un registro de póster inteligente (usado en anuncios de revistas, volantes, vallas publicitarias, etc.) describe contenido web como un registro NDEF que contiene un mensaje NDEF como su carga útil. Llama a record.toRecords() para transformar data en una lista de registros contenidos en el registro del póster inteligente. Debe tener un registro de URL, un registro de texto para el título, un registro de tipo de MIME de 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 sea importante fuera del contexto local del registro que los contiene y cuando el uso de almacenamiento sea una restricción estricta. Los nombres de registros de tipo local siempre comienzan con : en NFC web (p.ej., ":t", ":s", ":act"). Esto sirve 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 que se incluye 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 del 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] });

Lee y escribe un registro de tipo externo

Para crear registros definidos por la aplicación, usa registros de tipos externos. Estos pueden contener un mensaje NDEF como carga útil accesible con toRecords(). Su nombre contiene el nombre de dominio de la organización emisora, 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 que se incluye 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 un ArrayBuffer o proporcionar una vista en 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

La función NFC web está disponible en Android en Chrome 89.

Sugerencias para desarrolladores

Esta es una lista de lo que hubiera sabido cuando empecé a jugar con Web NFC:

  • Android controla las etiquetas NFC a nivel del SO antes de que la función NFC web esté operativa.
  • Puedes encontrar un ícono de NFC en material.io.
  • Usa el registro id de NDEF para identificar con facilidad un registro cuando sea necesario.
  • Una etiqueta NFC sin formato que admite NDEF contiene un único registro del tipo vacío.
  • Escribir un registro de aplicación para Android es sencillo, 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 descubre algunas demostraciones web geniales de NFC:

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

Comentarios

Al grupo comunitario web de NFC y al equipo de Chrome les encantaría conocer tus opiniones y experiencias con la función NFC web.

Cuéntanos sobre el diseño de la API

¿Hay algo acerca de la API que no funciona como se espera? ¿O faltan métodos o propiedades que necesitas para implementar tu idea?

Informa sobre un problema de especificaciones en el repositorio de GitHub de Web NFC o comenta un problema existente.

Informar un problema con la implementación

¿Encontraste un error en la implementación de Chrome? ¿La implementación es diferente de las especificaciones?

Informa un error en https://new.crbug.com. Asegúrate de incluir todos los detalles que puedas, proporciona instrucciones simples para reproducir el error y configura los componentes como Blink>NFC. Glitch funciona muy bien para compartir repros rápidos y fáciles.

Muestra tu apoyo

¿Planeas usar NFC web? Tu asistencia pública ayuda al equipo de Chrome a priorizar funciones y le muestra a otros proveedores de navegadores la importancia de brindar compatibilidad.

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

Vínculos útiles

Agradecimientos

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