Unterstützung der Google Emoji-Schriftartenrichtlinie
Google hat eine Android: Android Emoji Policy eingeführt, die App-Entwickler dazu verpflichtet, die neueste Version von Unicode Emoji zu unterstützen. Die Richtlinie besagt:
Apps mit benutzerdefinierten Emoji-Implementierungen, einschließlich solcher, die von Bibliotheken von Drittanbietern bereitgestellt werden, müssen die neueste Unicode-Version vollständig unterstützen, wenn sie unter Android 12+ innerhalb von 4 Monaten nach der Veröffentlichung neuer Unicode-Emoji laufen.
Dieser Leitfaden zeigt, wie man diese Richtlinie unterstützt, indem man entweder eine Emoji-Schriftart bündelt oder Android verwendet : Google Herunterladbare Schriftarten.
Bündelung einer Emoji-Schriftart VS Google Downloadable Fonts
Beide Methoden zur Unterstützung der neuesten Emojis haben einige Vor- und Nachteile. Die beste Option hängt von der jeweiligen Anwendung ab. Hier sind einige Vor- und Nachteile der beiden Methoden:
Vorteile der gebündelten Schriftart:
- Schnelleres Laden der Schriftart
- Funktioniert, wenn der Nutzer kein Internet hat
- Funktioniert auf allen Betriebssystemen
- Unabhängig (keine anderen Abhängigkeiten als Qt)
- Einfachere Lösung
Nachteile der Bündelung von Schriftarten:
- Erhöht die Größe der Anwendung (NotoColorEmoji ist ~10 MB)
- Erfordert die Aktualisierung der Schriftart auf neueren Versionen
- Ältere Anwendungen aktualisieren Emojis nicht automatisch
Vorteile von Google Downloadable Fonts:
- Verändert nicht die Größe der Anwendung
- Automatische Aktualisierung
- Mehrere Anwendungen, die in keiner Beziehung zueinander stehen, nutzen dieselbe Schriftart
Nachteile von Google Downloadable Fonts:
- Abhängig von den Google Mobile Services
- Nur für Android
- Lädt die Schriftart herunter, wenn sie nicht zuvor zwischengespeichert wurde
- Funktioniert nicht ohne Internet, wenn sie nicht zuvor zwischengespeichert wurde
- Komplexer als das Bündeln der Schriftart
Wie bündelt man eine Schriftart?
Es ist notwendig, die Schriftart zu beschaffen und zu bündeln und sie später entweder mit QML oder C++ zu laden.
Beschaffung einer Schriftart
Für diese Anleitung verwenden wir die Google-Schriftart NotoColorEmoji. NotoColorEmoji ist eine durch SIL OPEN FONT LICENSE lizenzierte Schriftart.
Hinweis: Wenn Sie aus dem Repository herunterladen, laden Sie die Schriftart NotoColorEmoji_WindowsCompatible.ttf anstelle von NotoColorEmoji.ttf herunter. NotoColorEmoji.ttf wird intern mit einem anderen Format erstellt und wird nur von Android/Chrome/Chromium OS unterstützt. Da Qt auf anderen Plattformen läuft, benötigt der Qt-Schriftlader eine standardisierte TrueType/OpenType-Schrift.
Hinzufügen der Schriftart
Der richtige Weg, die Schriftart zu bündeln, ist, sie zu den Qt Resource System Dateien hinzuzufügen. Zum Beispiel können Sie eine separate Ressourcendatei für die Schriftart erstellen - "font.qrc" mit der NotoColorEmoji_WindowsCompatible.ttf. Um die neue Ressourcendatei einzubetten, verwenden Sie den folgenden Code in CMakeLists.txt:
qt_add_big_resources(PROJECT_SOURCES font.qrc)
Laden der gebündelten Schriftart in C++
Um die Schriftart mit C++ zu laden, verwenden Sie QFontDatabase.
// Loading NotoColorEmoji bundled using C++ QFontDatabase QFontDatabase::addApplicationFont(QStringLiteral(":/NotoColorEmoji_WindowsCompatible.ttf"));
Hinweis: Der obige Code sollte verwendet werden, bevor QQmlApplicationEngine die QML lädt, so dass die Schriftart bereits vorhanden und einsatzbereit ist, wenn die QML geladen wird.
Laden der gebündelten Schriftart in QML
Um die Schriftart in QML zu laden, verwenden Sie FontLoader:
// Loading NotoColorEmoji using QML FontLoader FontLoader { source:"NotoColorEmoji_WindowsCompatible.ttf" }
Herunterladbare Google-Schriften verwenden:
Die Verwendung von herunterladbaren Google-Schriften für die Emoji-Schriftart bietet eine automatisch aktualisierte Emoji-Schriftart, ohne die Anwendungsgröße zu erhöhen. Das Verfahren zum Herunterladen einer Schriftart mit der Funktion "Herunterladbare Schriftarten" wird in Android näher erläutert: Prozess für herunterladbare Schriftarten
In diesem Leitfaden wird der Prozess wie folgt aussehen:
- C++-Code startet
- C++ ruft Java-Funktion auf
- Java ruft GDF auf, um die Schriftart zu holen
- Java öffnet die Schrift-URI
- Java gibt den Dateideskriptor an C++ zurück
- C++ lädt die Schriftart mit QFontDatabase
Konfiguration
Google Downloadable Fonts ist für API Level 26 (Android 8.0) verfügbar. Es ist jedoch möglich, frühere APIs bis hinunter zu API 14 zu unterstützen, wenn die Anwendung AndroidX verwendet.
Hinweis: Die Android-Dokumentation bezieht sich auf die Android: Support Library und nicht auf AndroidX. Da die Support-Bibliothek jedoch nicht mehr gepflegt wird und durch AndroidX ersetzt wurde, sind wir der Empfehlung von Google gefolgt, stattdessen AndroidX zu verwenden.
Anpassen der Vorlage für Android-Pakete
Zunächst müssen die Android-Paketvorlagen angepasst werden. Gehen Sie dazu unter Qt Creator auf die Registerkarte Projekte und suchen Sie dann in den Build-Einstellungen nach "Build Android APK". Es sollte sich innerhalb von "Build Steps" befinden. Erweitern Sie die Details und eine Schaltfläche namens "Create Templates" wird erscheinen.
Klicken Sie auf "Create templates", folgen Sie dem Assistenten und am Ende wird ein Ordner mit mehreren Konfigurationsdateien für Android erstellt. Standardmäßig handelt es sich um einen Ordner namens android
im Projektverzeichnis.
Siehe Android-Paketvorlagen für Informationen, wie man die Android-Vorlagen mit qmake anpasst.
Falls Sie CMake und Qt 6 verwenden, wie in dieser Anleitung, müssen Sie die Eigenschaft QT_ANDROID_PACKAGE_SOURCE_DIR setzen. Beispiel:
set_property(TARGET emojiremotefont PROPERTY
QT_ANDROID_PACKAGE_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/android)
Hinzufügen von AndroidX
Um AndroidX hinzuzufügen, öffnen Sie die Datei build.gradle
im Ordner QT_ANDROID_PACKAGE_SOURCE_DIR und fügen Sie dort die Abhängigkeit hinzu:
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation 'androidx.appcompat:appcompat:1.4.1' }
Um Androidx zu verwenden, müssen wir das entsprechende Flag setzen. Dazu erstellen Sie eine Datei namens gradle.properties
im Ordner QT_ANDROID_PACKAGE_SOURCE_DIR und fügen diese Zeile hinzu:
android.useAndroidX=true
Hinzufügen von Font-Provider-Zertifikaten
Da wir AndroidX verwenden, ist eine weitere Konfiguration erforderlich - das Hinzufügen von Android: Font-Provider-Zertifikate. Um den GMS Font Provider zu verwenden, laden Sie die Android: GMS-Schriftartenanbieter-Zertifikate herunter. Wenn Sie andere Schriftartenanbieter verwenden, müssen Sie die Zertifikate vom Anbieter selbst beziehen.
Nachdem Sie die Datei heruntergeladen haben, fügen Sie sie zu den Android-Ressourcen hinzu (nicht zum Qt-Ressourcensystem), indem Sie sie in den Ordner values
im Ordner android templates kopieren. Das folgende Bild zeigt den richtigen Ordner auf (1):
Java Code
Okay, jetzt geht's an den Code!
Wir müssen Java/Kotlin-Code zu unseren Android-Vorlagen hinzufügen. Legen Sie ihn unter dem Ordner src
im Ordner android templates ab. Möglicherweise müssen Sie den Ordner src
und die Ordnerstruktur für Ihre Java-Dateien erstellen. Sie können diese Ordnerstruktur in der Abbildung des Android-Vorlagenordners im vorherigen Abschnitt unter (2) sehen.
Um die Schriftart in C++ zu erhalten, muss der Java-Code Folgendes tun:
- Eine Schriftartanforderung erstellen
- Abrufen der Schriftarten aus FontsContractCompat unter Verwendung der Schriftartanforderung
- Abrufen von Font Info und der Font URI (Content Scheme File)
- den URI zu öffnen und einen Dateideskriptor zu erhalten
- Rückgabe des Dateideskriptors an C++-Code
Um eine Schriftartanforderung zu erstellen, benötigen Sie die Informationen zum Schriftartanbieter (Autorität, Paket und Zertifikate) und eine Suchanfrage für die Schriftart. Für die Zertifikate verwenden Sie die Datei GMS Font Provider Certificates fonts_cert.xml
, die Sie zuvor zu den Android-Ressourcen hinzugefügt haben.
// GMS fonts provider data private static final String PROVIDER_AUTHORITY = "com.google.android.gms.fonts"; private static final String PROVIDER_PACKAGE = "com.google.android.gms"; // Emoji font search query (copied from EmojiCompat source) private static final String EMOJI_QUERY = "emojicompat-emoji-font"; // Font Certificates resources strings (from fonts_certs.xml) private static final String FONT_CERTIFICATE_ID = "com_google_android_gms_fonts_certs"; private static final String FONT_CERTIFICATE_TYPE = "array"; (...) // obtain id for the font_certs.xml int certificateId = context.getResources().getIdentifier( FONT_CERTIFICATE_ID, FONT_CERTIFICATE_TYPE, context.getPackageName()); // creating the request FontRequest request = new FontRequest( PROVIDER_AUTHORITY, PROVIDER_PACKAGE, EMOJI_QUERY, certificateId);
Verwenden Sie nun die soeben erstellte Anfrage, um die Schriftart abzurufen:
// fetch the font FontsContractCompat.FontFamilyResult result = FontsContractCompat.fetchFonts(context, null, request);
Holen Sie sich die FontInfo und URI:
final FontsContractCompat.FontInfo[] fontInfos = result.getFonts(); final Uri emojiFontUri = fontInfos[0].getUri();
Öffnen Sie einen neuen nativen Dateideskriptor von der URI:
final ContentResolver resolver = context.getContentResolver(); // in this case the Font URI is always a content scheme file, made // so the app requesting it has permissions to open final ParcelFileDescriptor fileDescriptor = resolver.openFileDescriptor(fontInfos[0].getUri(), "r"); // the detachFd will return a native file descriptor that we must close // later in C++ code int fd = fileDescriptor.detachFd(); // return fd to C++
Hinweis: Alles, was in Java kodiert wurde, könnte auch in C++ mit JNI gemacht werden. Der in diesem Leitfaden dargestellte Code ist vereinfacht. Produktionsfähiger Code muss geprüft werden, mit Ausnahmefängern usw...
C++-Code
Ok, alles erledigt auf der Java-Seite. Kommen wir nun zur C++-Seite.
C++ ist verantwortlich für den Aufruf des Java-Codes und die Verwendung des Dateideskriptors zum Laden der Schriftart in Qt.
Um ein tieferes Verständnis dafür zu bekommen, wie die Kommunikation zwischen C++ und Java in Qt 6 funktioniert, schauen Sie sich das Beispiel Qt Android Notifier an.
Nachdem Sie den Dateideskriptor aus dem Java-Code erhalten haben, verpacken Sie den Dateideskriptor in eine QFile Klasse und laden Sie die Schriftdatei mit QFontDatabase:
QFile file; file.open(fd, QFile::OpenModeFlag::ReadOnly, QFile::FileHandleFlag::AutoCloseHandle); QFontDatabase::addApplicationFontFromData(file->readAll());
© 2025 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.