Интегрирование с Android API-ами

Платформа Android имеет множество API, а также богатую экосистему сторонних библиотек с широкими и разнообразными функциональными возможностями, такими как push-уведомления (push notifications), аналитика, аутентификация, реклама (ads) и т. д.

В самом ядре Godot они не имеют смысла, поэтому Godot уже давно предоставляет Android plugin system. Android plugin system позволяет разработчикам создавать плагины Godot для Android с использованием кода Java или Kotlin, предоставляя интерфейс для доступа и использования API Android или сторонних библиотек в проектах Godot из GDScript, C# или GDExtension.

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

Однако написание плагина для Android требует знания кода Java или Kotlin, чего большинство разработчиков Godot не знают. Поэтому существует множество API Android и сторонних библиотек, не имеющих плагина Godot, с которым разработчики могли бы взаимодействовать. Фактически, это одна из главных причин, по которой разработчики не могут перейти на Godot с других игровых движков.

Чтобы решить эту проблему, мы представили несколько инструментов в Godot 4.4, которые упрощают для разработчиков процесс доступа к API Android и сторонним библиотекам.

JavaClassWrapper (Godot синглтон)

JavaClassWrapper - это Godot singleton, который позволяет создавать экземпляры классов Java / Kotlin и вызывать их методы, используя только GDScript, C# или 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))

В приведённом выше фрагменте кода JavaClassWrapper используется из GDScript для доступа к классам Java LocalDateTime и DateTimeFormatter. С помощью JavaClassWrapper мы можем вызывать методы классов Java непосредственно из GDScript, как если бы они были методами GDScript.

AndroidRuntime плагин

JavaClassWrapper — это здорово, но для выполнения многих задач на Android вам понадобится доступ к различным объектам Android жизненного цикла/среды выполнения. Плагин AndroidRuntime — это встроенный плагин Godot для Android, который позволяет вам это сделать.

Объединение JavaClassWrapper и плагина AndroidRuntime позволяет разработчикам получать доступ ко множеству API Android и использовать их, не отказываясь от GDScript и не используя какие-либо инструменты, кроме самого Godot. Это огромное преимущество для внедрения Godot в разработку под Android:

  • Если вам нужно сделать что-то простое или использовать только небольшую часть сторонней библиотеки, вам не обязательно создавать плагин

  • Это дает разработчикам быстро интегрировать функциональность Android

  • Позволяет разработчикам создавать дополнения Godot, используя только GDScript и JavaClassWrapper (Java или Kotlin не требуются)

Примечание

При экспорте с помощью gradle Godot автоматически включает файлы .jar или .aar, найденные в каталоге addons проекта. Поэтому, чтобы использовать стороннюю библиотеку, просто поместите её файл .jar или .aar в каталог addons и вызовите её метод напрямую из GDScript с помощью JavaClassWrapper.

Пример: показ уведомление 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))

Пример: Вибрация устройства

# 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)

Пример: Доступ к внутренним классам

Доступ к внутренним классам Java можно получить с помощью знака $:

# 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

Пример: Вызов конструктора

Конструктор вызывается путем вызова метода с тем же именем, что и у класса.

В этом примере создается намерение отправить текст:

# 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)