En esta página

URL anotada

Lee mensajes con formato de intercambio de datos NFC (NDEF).

El ejemplo de URL anotada utiliza Qt NFC para mostrar el contenido de mensajes NFC Data Exchange Format (NDEF) específicamente formateados y leídos desde una etiqueta NFC. El mensaje NDEF debe contener un registro URI, un registro MIME opcional image/* y uno o más registros de texto localizados.

Este es el estado inicial del ejemplo:

URL anotada Pantalla principal de NFC

Si se toca una etiqueta, se mostrará su contenido NDEF. Esta es la interfaz de usuario para una etiqueta que contiene un registro de texto y un registro URI:

URL anotada Detalles de la etiqueta NFC

Si se toca la pantalla, se abrirá la URL en el navegador.

Definición de la clase AnnotatedUrl

La clase AnnotatedUrl envuelve a QNearFieldManager, la clase que proporciona la funcionalidad de detección de etiquetas NFC. Los mensajes NDEF son leídos por QNearFieldManager y reenviados a un manejador contenido en la clase AnnotatedUrl. Tras analizar el mensaje NDEF, la clase emite la señal annotatedUrl(). La interfaz de usuario reacciona a la señal mostrando el contenido del mensaje NDEF.

class AnnotatedUrl : public QObject
{
    Q_OBJECT

public:
    explicit AnnotatedUrl(QObject *parent = 0);
    ~AnnotatedUrl();

    void startDetection();

signals:
    void annotatedUrl(const QUrl &url, const QString &title, const QPixmap &pixmap);
    void nfcStateChanged(bool enabled);
    void tagError(const QString &error);

public slots:
    void targetDetected(QNearFieldTarget *target);
    void targetLost(QNearFieldTarget *target);
    void handleMessage(const QNdefMessage &message, QNearFieldTarget *target);
    void handlePolledNdefMessage(QNdefMessage message);
    void handleAdapterStateChange(QNearFieldManager::AdapterState state);

private:
    QNearFieldManager *manager;
    QNdefFilter messageFilter;
};

Nota: El método startDetection() se utiliza para aplazar la detección real de la etiqueta hasta que se hayan establecido todas las conexiones entre la interfaz de usuario y la lógica relacionada con NFC. Esto es importante cuando la aplicación se inicia automáticamente una vez que se toca una etiqueta NFC. Este caso de uso está soportado actualmente en Android.

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow mainWindow;
    AnnotatedUrl annotatedUrl;

    QObject::connect(&annotatedUrl, &AnnotatedUrl::annotatedUrl,
                     &mainWindow, &MainWindow::displayAnnotatedUrl);
    QObject::connect(&annotatedUrl, &AnnotatedUrl::nfcStateChanged,
                     &mainWindow, &MainWindow::nfcStateChanged);
    QObject::connect(&annotatedUrl, &AnnotatedUrl::tagError,
                     &mainWindow, &MainWindow::showTagError);

    annotatedUrl.startDetection();
    mainWindow.show();

    return a.exec();
}

Filtrado de mensajes

Como se ha mencionado anteriormente, la aplicación soporta los mensajes NDEF de un formato específico. Un mensaje correcto debe contener los siguientes campos

  • Al menos un registro NDEF Text, que se utilizará como cabecera.
  • Exactamente un registro NDEF URI.
  • Un registro MIMEopcional con un icono.

El orden de los registros no está estrictamente especificado.

Para validar el mensaje NDEF se utiliza una instancia de QNdefFilter. El filtro se rellena del siguiente modo:

    messageFilter.setOrderMatch(false);
    messageFilter.appendRecord<QNdefNfcTextRecord>(1, 100);
    messageFilter.appendRecord<QNdefNfcUriRecord>(1, 1);
    messageFilter.appendRecord(QNdefRecord::Mime, "", 0, 1);

Si el mensaje entrante no coincide con el filtro, se muestra un mensaje de error:

URL anotada Vista de datos de etiquetas NFC

Nota: La aplicación de ejemplo NDEF Editor se puede utilizar para crear las etiquetas con estructura de mensaje correcta o incorrecta.

Implementación del manejador AnnotatedUrl

Los mensajes NFC leídos por QNearFieldManager se reenvían a AnnotatedUrl::handleMessage.

void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target)
{

Al principio, los mensajes se validan mediante el método QNdefFilter::match():

    if (!messageFilter.match(message)) {
        emit tagError("Invalid message format");
        return;
    }

Si los mensajes tienen el formato correcto, continúa el análisis sintáctico.

Dado que los mensajes NFC se componen de varios registros NDEF, el bucle a través de todos los registros permite la extracción de los 3 parámetros que se mostrarán en la interfaz de usuario: el Uri, el Título y el Pixmap:

    for (const QNdefRecord &record : message) {
        if (record.isRecordType<QNdefNfcTextRecord>()) {
            QNdefNfcTextRecord textRecord(record);

            title = textRecord.text();
            QLocale locale(textRecord.locale());
        } else if (record.isRecordType<QNdefNfcUriRecord>()) {
            QNdefNfcUriRecord uriRecord(record);

            url = uriRecord.uri();
        } else if (record.typeNameFormat() == QNdefRecord::Mime &&
                   record.type().startsWith("image/")) {
            pixmap = QPixmap::fromImage(QImage::fromData(record.payload()));
        }

Finalmente tras haber extraído los parámetros del mensaje NFC se emite la señal correspondiente para que la UI pueda manejarlo.

    }

    emit annotatedUrl(url, title, pixmap);
}

Manejo del estado del adaptador

En Android los cambios de estado del adaptador pueden ser detectados conectándose a la señal QNearFieldManager::adapterStateChanged(). Esto permite detener la detección cuando el adaptador NFC se desactiva, y reiniciarla cuando el adaptador se activa de nuevo. Este enfoque se implementa en la ranura AnnotatedUrl::handleAdapterStateChange.

void AnnotatedUrl::handleAdapterStateChange(QNearFieldManager::AdapterState state)
{
    if (state == QNearFieldManager::AdapterState::Online) {
        startDetection();
    } else if (state == QNearFieldManager::AdapterState::Offline) {
        manager->stopTargetDetection();
        emit nfcStateChanged(false);
    }
}

Inicio automático de aplicaciones

Android admite el inicio automático de la aplicación cuando se toca la etiqueta NDEF. Consulte Qt NFC en Android para conocer los cambios necesarios en el archivo de manifiesto de Android.

La introducción de un AndroidManifest.xml personalizado requiere pasos especiales en el lado del sistema de compilación.

Compilación con qmake

Cuando se utiliza qmake, es necesario añadir lo siguiente al archivo .pro:

android {
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

    DISTFILES += \
        android/AndroidManifest.xml
}
Compilación con CMake

Cuando se utiliza CMake, lo siguiente debe ser añadido a la CMakeLists.txt:

if(ANDROID)
    set_property(TARGET annotatedurl
        APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
        ${CMAKE_CURRENT_SOURCE_DIR}/android
    )
endif()

Ejecutar el ejemplo

Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para obtener más información, consulte Qt Creator: Tutorial: Construir y ejecutar.

Proyecto de ejemplo @ code.qt.io

Véase también Qt NFC.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.