Skip to main content
Preskoči na vsebino

Nastavitev za Android

Priprava vaše C++ aplikacije za Android

Uvod

Qt ima odlično podporo za Android, vendar aplikacije zahtevajo precejšnje spremembe, da na Androidu pravilno delujejo.

Potrebnih je nekaj stvari:

Načrt Craft je potreben za združevanje vseh odvisnosti z aplikacijo, da se ustvari paket Android APK.

Slog qqc2-breeze je alternativa slogu qqc2-desktop-style za namizne računalnike, ki je posebej prilagojen mobilnim platformam, kot sta Android in Plasma Mobile.

Craft-načrt aplikacije zahteva pogojno kodo, da se slogi za namizne in mobilne naprave ne mešajo, medtem ko bo pri kodi v jeziku C++ potrebna posebna previdnost, da se za namizne in mobilne naprave ne uporabi napačna konfiguracija. Tudi koda CMake bo morda zahtevala pogojne elemente, čeprav se jim je mogoče izogniti.

Vključevanje ikon, potrebnih za delovanje aplikacije, poteka s pomočjo KDE-jevih modulov »extra-cmake-modules«, orodij za vključevanje virov v ogrodju Qt ter funkcij CMake iz knjižnic Kirigami in Kirigami Addons.

Datoteka Android manifest določa metapodatke in dodatne datoteke, ki morajo biti vključene v aplikacijo za Android.

Datoteka za gradnjo Gradle je potrebna, če uporabljate integracijo »extra-cmake-modules« za prenos obstoječih metapodatkov vaše aplikacije v postopek gradnje za Android – na primer različice aplikacije – ali če potrebujete posebne možnosti gradnje.

Datoteka XML za uvodni zaslon je potrebna, če želite dodati uvodni zaslon s prilagojeno ikono, ozadjem in postavitvijo.

Craft blueprint

Nastavitev sloga qqc2-breeze-style

Za začetek uporabe qqc2-breeze-style ga morate dodati v Craft. Ker se uporablja izključno za Android, je potreben pogojni stavek – še zlasti, če je aplikacija že nastavljena za gradnjo na sistemih Windows in/ali Linux z uporabo qqc2-desktop style. To zahteva uvoz modula CraftCore:

from CraftCore import CraftCore

# ...
def setDependencies(self):
  # ...
  if not CraftCore.compiler.isAndroid:
      self.runtimeDependencies["kde/frameworks/tier1/breeze-icons"] = None
      self.runtimeDependencies["kde/frameworks/tier3/qqc2-desktop-style"] = None
  else:
      self.runtimeDependencies["kde/plasma/qqc2-breeze-style"] = None

Podobno logiko – »ČE ni Android, uporabi qqc2-desktop-style, SICER pa qqc2-breeze-style« – je treba uporabiti tudi v sistemu CMake, in sicer za primer, ko se uporabi kateri koli od načinov za iskanje sloga qqc2-desktop-style:

if (NOT ANDROID)
    find_package(KF6QQC2DesktopStyle REQUIRED)
    ecm_find_qmlmodule(org.kde.desktop REQUIRED)
endif()

Pogojna koda je potrebna tudi v jeziku C++.

V sistemu Android aplikacije KDE ne uporabljajo razreda QApplication, temveč QGuiApplication. Poleg nastavitve sloga qqc2-breeze-style, ki velja izključno za Android, je treba poskrbeti tudi za vrstni red inicializacije – še posebej zato, ker je zelo verjetno, da je vaša aplikacija že združljiva z namiznim okoljem. To lahko uredite na naslednji način:

int main(int argc, char* argv[])
{
    KIconTheme::initTheme();
#ifdef Q_OS_ANDROID
    QGuiApplication app(argc, argv);
    QQuickStyle::setStyle("org.kde.breeze");
#else
    QIcon::setFallbackThemeName("breeze");
    if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE"))
    {
        QQuickStyle::setStyle("org.kde.desktop");
    }
    QApplication app(argc, argv);
    // ...
#endif
}

Dobavljanje ikon

Prva stvar, ki je potrebna, da aplikacija uporablja ikone Breeze, je vključitev knjižnice KIconThemes v vaš projekt.

Za vključitev ikone vaše aplikacije v samo aplikacijo je potrebnih nekaj ukazov CMake.

Nazadnje lahko uporabite dodaten ukaz CMake, ki ga ponuja Kirigami, za vključitev ikon Kirigami (in po želji tudi ikon iz paketa Kirigami Addons) v svojo aplikacijo.

KIconThemes

To je mogoče storiti takole:

  • Dodajanje kot odvisnosti v Craft:
def setDependencies(self):
    self.runtimeDependencies["kde/frameworks/tier3/kiconthemes"] = None
  • Dodajanje kot odvisnosti v CMake:
find_package(KF6 REQUIRED COMPONENTS IconThemes)

# ...

target_link_libraries(kirigami-hello
    PRIVATE
    # ...
    KF6::IconThemes
)
  • Uporaba v kodi C++, v datoteki main.cpp:
#include <KIconTheme>

// ...
int main(int argc, char* argv[])
{
    KIconTheme::initTheme();
    QApplication app(argc, argv);
    // ...
}

Upoštevajte, da čeprav ime projekta in klic CMake uporablja množino (KIconThemes, KF6IconThemes), klic C++ uporablja ednino (KIconTheme).

KIconThemes je treba inicializirati pred uporabo aplikacije.

Ikona aplikacije

Če ima vaša aplikacija ikono, jo je treba v projekt dodati tako kot vir QML kot tudi v sklopu namestitve ikon.

Običajno je v Linuxu ikono aplikacije mogoče preprosto namestiti v pravilen imenik, aplikacija pa jo bo po potrebi pridobila. Ikona aplikacije je običajno sestavljena iz primarne ikone SVG, povezane z ikonami več velikosti PNG.

Namestitev ikone SVG se v CMake izvede takole:

install(FILES ${CMAKE_SOURCE_DIR}/icons/org.kde.myapp.svg
    DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps)

Namestitev ikon PNG pa se izvede takole:

ecm_install_icons(ICONS
    16-apps-myapp.png
    24-apps-myapp.png
    32-apps-myapp.png
    48-apps-myapp.png
    64-apps-myapp.png
    128-apps-myapp.png
    256-apps-myapp.png
    512-apps-myapp.png    
    DESTINATION share/icons)

Ko je ikona aplikacije nameščena v Linuxu, se ikona PNG, kot je 48-apps-myapp.png, premakne v ${INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/myapp.png, ikona SVG pa v ${INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/org.kde.myapp.svg, kjer ${INSTALL_PREFIX} običajno pomeni /usr, /usr/local ali ~/.local. Upoštevajte, kako se v primeru PNG-jev ime ikone prevede v pot, ki jo bo imela v datotečnem sistemu.

Ko je ikona na ta način nameščena, jo je v kodi QML mogoče priklicati preprosto z myapp ali org.kde.myapp, podobno kot bi jo priklicali s funkcijo QIcon::fromTheme(). To je mogoče uporabiti pri katerem koli gradniku QML, ki ima lastnost icon.name.

Android nima takšnega standardnega imenika, zato namestitev ikone nima nobenega učinka; ikona mora biti vključena v paket aplikacije. To lahko storite tako, da datoteko PNG namestite v njen lastni namestitveni imenik s pomočjo ecm_add_app_icon(), datoteko PNG ali SVG pa v aplikacijo vključite kot vir Qt (Qt resource file) z uporabo ecm_add_qml_module() ali ecm_target_qml_sources().

Ikona aplikacije PNG je nameščena z:

ecm_add_app_icon(myapp ICONS ${PROJECT_SOURCE_DIR}/icons/256-apps-myapp.png)

Glavna ikona aplikacije je združena kot vir Qt z:

ecm_add_qml_module(myapp URI org.kde.myapp)
ecm_target_qml_sources(myapp SOURCES Main.qml RESOURCES ../icons/org.kde.myapp.svg)

S tem bo ikona aplikacije na voljo kot vir Qt na naslovu qrc:/qt/qml/org/kde/myapp/org.kde.myapp.svg. Uporabiti jo je mogoče s katerim koli gradnikom QML, ki ima lastnost icon.source.

Pot RESOURCES je odvisna od tega, kje so ikone nameščene. Običajno se v korenskem imeniku projekta ustvari mapa icons/ za shranjevanje vseh ikon, saj te dejansko ne štejejo med izvorne datoteke.

Ko so ikone nameščene (za Linux) oziroma vključene v paket (za Windows in Android), jih lahko določite v kodi. V kodi QML je zaradi združljivosti s sistemoma Windows in Android priporočljivo uporabiti ikono, ki je del paketa; v kodi C++ – zlasti pri nastavljanju ikone okna – lahko privzeto uporabite ikono iz teme, kot nadomestno možnost (če prva ni na voljo) pa ikono iz paketa, in sicer v okviru funkcije QGuiApplication::setWindowIcon():

QGuiApplication::setWindowIcon(QIcon::fromTheme("org.kde.myapp", QIcon(":/qt/qml/org/kde/myapp/org.kde.myapp.svg")));

Ikone Kirigami

Čeprav Android nima standardnega imenika za namestitev ikon iz teme ikon, je mogoče potrebne ikone Kirigami vključiti v paket skupaj z vašo aplikacijo za Android.

Za to sta potrebni dve stvari:

  • Pripravite projekt s KIconThemes
  • Vključite ikone Breeze v svojo predlogo Craft
  • kirigami_package_breeze_icons()

Za nastavitev KIconThemes glejte zgornji razdelek KIconThemes.

Če želite dodati breeze-icons kot odvisnost za svoj projekt, v svoj načrt Craft blueprint dodajte naslednje:

def setDependencies(self):
    # ...
    self.runtimeDependencies["kde/frameworks/tier1/breeze-icons"] = None

Zaradi načina, kako poteka gradnja za Android, Craft ne more samodejno vključiti ikon v paket. Zato Kirigami ponuja funkcijo CMake kirigami_package_breeze_icons(), ki med postopkom gradnje kopira in pripravi ikone za vključitev v paket. Ta ukaz mora biti izveden pred korakom, opisanim v razdelku Funkcija CMake za pakiranje za Android.

Ukaza CMake kirigami_package_breeze_icons() ni treba vključiti v pogojni stavek, saj se izvede le v okolju Android.

Poleg tega lahko, če v svoji aplikaciji uporabljate Kirigami Addons, posredujete spremenljivko ${KIRIGAMI_ADDONS_ICONS} in s tem vključite tudi potrebne ikone za komponente, kot sta FormCard.AboutPage in podobne.

kirigami_package_breeze_icons(ICONS
        org.kde.myapp insert-image-symbolic kde application-exit-symbolic
        edit-clear-all-symbolic edit-undo-symbolic document-save-symbolic
        applications-development-symbolic system-user-list donate-symbolic
        ${KIRIGAMI_ADDONS_ICONS}
)

Android manifest

Android manifest je datoteka XML, ki orodjem za gradnjo, operacijskemu sistemu in trgovinam z aplikacijami podaja opis aplikacije. Datoteka se mora imenovati AndroidManifest.xml.

Qt uporablja manifest za Android in podpira dodatne nastavitve za priklic orodij, potrebnih za izdelavo datoteke APK, ki jo je mogoče namestiti v sistem Android.

Aplikacije KDE hranijo datoteko manifesta v imeniku android/ v korenu projekta.

Manifest za Android je bi lahko bil videti takole:

<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="org.kde.myapp"
          android:installLocation="auto">
    <application android:name="org.qtproject.qt.android.bindings.QtApplication" android:label="MyApp" android:usesCleartextTraffic="true" android:icon="@drawable/myapp">
        <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
                  android:name="org.qtproject.qt.android.bindings.QtActivity"
                  android:label="MyApp"
                  android:windowSoftInputMode="adjustResize"
                  android:launchMode="singleTop"
                  android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

            <meta-data android:name="android.app.lib_name" android:value="myapp"/>
        </activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    
    <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
</manifest>

Gre večinoma za standardno predlogo, ki jo je mogoče kopirati in prilagoditi obstoječemu projektu, vendar se splača spoznati, katere dele je treba upoštevati.

V oznaki <manifest> atribut package ustreza imenu, s katerim sistem Android interno prepozna aplikacijo. Uporabiti je treba obratni zapis domenskega imena. Ime se mora ujemati z identifikatorjem aplikacije, določenim v kodi.

V oznakah <application> in <activity> mora android:label predstavljati ime aplikacije, ki je vidno uporabniku. V oznaki <meta-data> se mora android:value ujemati s ciljnim imenom, kot je določeno v sistemu CMake.

V oznaki <application> mora android:icon="@drawable/myapp" predstavljati ikono, shranjeno v mapi android/res/drawable/, pri čemer se končnica datoteke ne navede. V tem primeru bi bila datoteka android/res/drawable/myapp.png. Mapa res je okrajšava za »resources« (viri). Če ikona ni določena, se v meniju aplikacij in ob pozivu za namestitev namesto nje prikaže privzeta nadomestna ikona sistema Android.

Activity pomeni, kaj bo aplikacija počela v različnih stanjih. Na primer, lahko izvaja določena dejanja v ospredju in druga dejanja v ozadju. Običajno ima aplikacija Qt/KDE samo eno dejavnost.

Vsaka dejavnost ima lahko enega ali več filtrov namenov. Namen predstavlja nekaj, kar dejavnost lahko izvede; v primeru aplikacij KDE gre običajno za dejanje (action), lahko pa tudi za storitev (service). Če se na primer aplikacija namerava zagnati, mora sistemu Android sporočiti, da je ta dejavnost vstopna točka aplikacije (android.intent.action.MAIN) in da je namen vrste LAUNCHER – s tem se aplikacija prikaže v meniju aplikacij in jo je mogoče zagnati. To bi moralo praviloma zadostovati za večino aplikacij KDE.

Oznaka <meta-data> se lahko večkrat ponovi in ​​ima različne namene; uporabiti je mogoče tudi posebne konfiguracije, značilne za Qt. Metapodatki android.app.lib_name so obvezni.

Oznaka <uses-permission> je preprosta in aplikaciji omogoča, da zahteva dovoljenje za izvedbo določenega dejanja. Dovoljenje se od namena (angl. Intent) razlikuje po tem, da namen od druge komponente zahteva izvedbo dejanja, povezanega z aktivnostjo, medtem ko je dovoljenje zahteva za dostop do funkcionalnosti, ki privzeto ni na voljo.

Oznaka <supports-screens> določa, katere oblike naprav (velikosti zaslonov in gostote slikovnih pik, telefoni ali tablice) aplikacija podpira. Ker so aplikacije QML konvergentne, je "any size" smiselna privzeta nastavitev.

Edina dela zgornjega primera, ki niso obvezna, so android:icon="@drawable/myapp" (uporabi se le, če ima vaša aplikacija že ikono) in <uses-permissions> (ki ga dodajate le takrat, ko je dejansko potreben).

Zaslon dobrodošlice

Zaslon dobrodošlice je neobvezen zaslon s statično sliko ali animacijo, ki se prikaže ob zagonu aplikacije in omogoči nekaj sekund za njeno inicializacijo. Če ta uvodni zaslon ni določen, se aplikacija prikaže takoj, ko jo odprete, tudi če še ni pripravljena na uporabo.

Če ga želite dodati v svojo aplikacijo, ga morate navesti v metapodatkih datoteke AndroidManifest.xml:

<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>

Poleg tega mora obstajati datoteka android/res/drawable/splash.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:width="128dp" android:height="128dp" android:gravity="center">
        <bitmap
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="fitXY"
            android:src="@drawable/myapp"/>
    </item>
</layer-list>

Ta preprost primer, ki se pogosto uporablja v aplikacijah KDE, postavi ikono aplikacije na sredino praznega ozadja, zato je potrebna ikona aplikacije, ki se nahaja v mapi android/res/drawable/.

Priprava datoteke APK

Zadnji korak, potreben za dejansko omogočanje izdelave datoteke APK za Android, je preprosta funkcija CMake, ki uporablja datoteke v imeniku android/:

ecm_add_android_apk(myapp
    ANDROID_DIR ${PROJECT_SOURCE_DIR}/android
)

Izgradnja

Za izdelavo aplikacije za Android sledite navodilom v razdelku Izdelava aplikacij za Android.

Izgradnje CI

Če je projekt ustrezno konfiguriran za gradnjo v okolju Windows in za gostovanje kode uporablja infrastrukturo KDE (KDE Invent), je mogoče konfigurirati opravila CI/CD za Android.

Če želite to narediti, boste morali dodati ustrezne predloge CI za Windows z datoteko .gitlab-ci.yaml in navesti svoje odvisnosti v datoteki .kde-ci.yaml, kot je omenjeno v Continuous Integration System.