Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Integrazione con le API di Android

La piattaforma Android ha numerose API e di un ricco ecosistema di librerie di terze parti con funzionalità ampie e diversificate, come notifiche push, analisi, autenticazione, annunci, ecc.

Queste funzionalità non hanno senso nel core di Godot, pertanto Godot fornisce da tempo un sistema di plugin Android. Il sistema di plugin Android consente agli sviluppatori di creare plugin Android per Godot attraverso codice Java o Kotlin, che fornisce un'interfaccia per accedere e utilizzare le API di Android o librerie di terze parti nei progetti Godot da GDScript, C# o GDExtension.

class MyAndroidSingleton(godot: Godot?) : GodotPlugin(godot) {
        @UsedByGodot
        fun doSomething(value: String) {
                // ...
        }
}

Tuttavia, scrivere un plugin per Android richiede la conoscenza del codice Java o Kotlin, che la maggior parte degli sviluppatori di Godot non possiede. Pertanto, molte API di Android e librerie di terze parti non hanno un plugin di Godot con cui gli sviluppatori possano interagire. In effetti, questo è uno dei motivi principali per cui gli sviluppatori non riescono a passare a Godot da altri motori di gioco.

Per risolvere ciò, abbiamo introdotto un paio di strumenti in Godot 4.4 per semplificare il processo di accesso degli sviluppatori alle API di Android e alle librerie di terze parti.

JavaClassWrapper (singleton di Godot)

JavaClassWrapper è un singleton di Godot che consente di creare istanze di classi Java/Kotlin, implementare interfacce Java/Kotlin, e di chiamare metodi su di esse utilizzando solo GDScript, C# o GDExtension.

var LocalDateTime = JavaClassWrapper.wrap("java.time.LocalDateTime")
var DateTimeFormatter = JavaClassWrapper.wrap("java.time.format.DateTimeFormatter")

var datetime = LocalDateTime.now()
var formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")

print(datetime.format(formatter))

Nel frammento di codice sopra, JavaClassWrapper è utilizzato da GDScript per accedere alle classi Java LocalDateTime e DateTimeFormatter. Tramite JavaClassWrapper, possiamo chiamare i metodi delle classi Java direttamente da GDScript come se fossero metodi in GDScript.

class PrintProxy:
    func println(content: String) -> void:
        print(content)

var print_proxy = PrintProxy.new()
var printer_object = JavaClassWrapper.create_proxy(print_proxy, ["android.util.Printer"])
printer_object.println("Hello Godot World!")

Nel frammento di codice sopra, JavaClassWrapper è utilizzato per implementare l'interfaccia Java android.util.Printer di GDScript utilizzando un Object come implementazione. Il proxy istanziato si può quindi passare ai metodi Java che accettano un parametro android.util.Printer.

Consultare la documentazione di JavaClassWrapper per saperne di più sulla sua API.

Plugin AndroidRuntime

JavaClassWrapper è fantastico, ma per fare molte cose su Android, è necessario accedere a vari oggetti del ciclo di vita/esecuzione di Android. Il plugin AndroidRuntime è un plugin Android Godot integrato che consente di fare questo.

Combinare i plugin JavaClassWrapper e AndroidRuntime consente agli sviluppatori di accedere e utilizzare le API di Android senza dover abbandonare GDScript o utilizzare altri strumenti oltre a Godot. Questo è enorme per l'adozione di Godot nello sviluppo per Android:

  • Se c'è bisogno di fare qualcosa di semplice o di utilizzare solo una piccola parte di una libreria di terze parti, non è necessario creare un plugin

  • Permette agli sviluppatori di integrare rapidamente le funzionalità di Android

  • Permette agli sviluppatori di creare componenti aggiuntivi di Godot tramite solo GDScript e JavaClassWrapper (non è necessario Java o Kotlin)

Nota

Per le esportazioni tramite gradle, Godot includerà automaticamente i file .jar o .aar che trova nella cartella addons del progetto. Quindi, per utilizzare una libreria di terze parti, è sufficiente trascinare il file .jar o .aar nella cartella addons e chiamare il suo metodo direttamente da GDScript attraverso JavaClassWrapper.

Esempio: mostra un toast di Android

# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
    # Retrieve the Android Activity instance.
    var activity = android_runtime.getActivity()

    # Create a Godot Callable to wrap the toast display logic.
    var toast_callable = func():
        # Use JavaClassWrapper to retrieve the android.widget.Toast class, then make and show a toast using the class APIs.
        var ToastClass = JavaClassWrapper.wrap("android.widget.Toast")
        ToastClass.makeText(activity, "This is a test", ToastClass.LENGTH_LONG).show()

    # Wrap the Callable in a Java Runnable and run it on the Android UI thread to show the toast.
    activity.runOnUiThread(android_runtime.createRunnableFromGodotCallable(toast_callable))

Esempio: vibra il dispositivo

# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
    # Retrieve the Android Vibrator system service and check if the device supports it.
    var vibrator_service = android_runtime.getApplicationContext().getSystemService("vibrator")
    if vibrator_service and vibrator_service.hasVibrator():
        # Configure and run a VibrationEffect.
        var VibrationEffect = JavaClassWrapper.wrap("android.os.VibrationEffect")
        var effect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)
        vibrator_service.vibrate(effect)

Esempio: accedi alle classi interne

È possibile accedere alle classi interne Java utilizzando il segno $:

# Accessing 'VERSION' class, which is an inner class from the 'android.os.Build' class.
var version = JavaClassWrapper.wrap("android.os.Build$VERSION")
var sdk_int = version.SDK_INT
if sdk_int == 30:
    # Do something specific on android 11 devices.
else:
    # All other devices

Esempio: chiamare un costruttore

Un costruttore è invocato chiamando un metodo con lo stesso nome della classe.

Questo esempio crea un intento di inviare un testo:

# Retrieve the AndroidRuntime singleton.
var android_runtime = Engine.get_singleton("AndroidRuntime")
if android_runtime:
    var Intent = JavaClassWrapper.wrap("android.content.Intent")
    var activity = android_runtime.getActivity()
    var intent = Intent.Intent() # Call the constructor.
    intent.setAction(Intent.ACTION_SEND)
    intent.putExtra(Intent.EXTRA_TEXT, "This is a test message.")
    intent.setType("text/plain")
    activity.startActivity(intent)