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.
Checking the stable version of the documentation...
Интегрирование с 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 is a Godot singleton which allows
creating instances of Java / Kotlin classes, implementing Java / Kotlin interfaces, and calling methods on them using only GDScript, C# or 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.
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!")
In the code snippet above, JavaClassWrapper is used to implement the Java android.util.Printer interface from GDScript using a Object as the implementation.
The instantiated proxy can then be passed to Java methods that accept a android.util.Printer parameter.
Check out the JavaClassWrapper documentation to learn more about its API.
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)
Пример: Сохранение изображения в галерею Android
# 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()
# Create the File and Uri.
var Uri = JavaClassWrapper.wrap("android.net.Uri")
var File = JavaClassWrapper.wrap("java.io.File")
var file = File.File(file_path_to_image_here)
var uri = Uri.fromFile(file)
# Set Action and Data of Intent.
intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.setData(uri)
# Broadcast it.
activity.sendBroadcast(intent)