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...
Integrando com APIs do Android
A plataforma Android possui inúmeras APIs, bem como um rico ecossistema de bibliotecas de terceiros com funcionalidade ampla e diversificada, como notificações push, análise, autenticação, anúncios, etc...
Essas ferramentas não fazem sentido no próprio núcleo do Godot, por isso o Godot há muito tempo fornece um sistema de plugins do Android. O sistema de plugins do Android permite que os desenvolvedores criem plugins Android do Godot usando códigos Java ou Kotlin, o que fornece uma interface para acessar e usar APIs do Android ou bibliotecas de terceiros em projetos do Godot a partir do GDScript, C# ou GDExtension.
class MyAndroidSingleton(godot: Godot?) : GodotPlugin(godot) {
@UsedByGodot
fun doSomething(value: String) {
// ...
}
}
No entanto, escrever um plugin do Android exige conhecimento de código Java ou Kotlin, o que a maioria dos desenvolvedores do Godot não possui. Como tal, existem muitas APIs do Android e bibliotecas de terceiros que não têm um plugin do Godot com o qual os desenvolvedores possam fazer a interface. Na verdade, essa é uma das principais razões que os desenvolvedores citam para não conseguirem migrar para o Godot a partir de outros motores de jogos.
Para resolver isso, introduzimos algumas ferramentas no Godot 4.4 para simplificar o processo de acesso dos desenvolvedores às APIs do Android e bibliotecas de terceiros.
JavaClassWrapper (singleton do Godot)
O JavaClassWrapper é um singleton do Godot que permite criar instâncias de classes Java / Kotlin, implementar interfaces Java / Kotlin e chamar métodos nelas usando apenas GDScript, C# ou 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))
No trecho de código acima, o JavaClassWrapper é usado a partir do GDScript para acessar as classes Java LocalDateTime e DateTimeFormatter. Através do JavaClassWrapper, podemos chamar os métodos das classes Java diretamente do GDScript como se fossem métodos do 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!")
No trecho de código acima, o JavaClassWrapper é usado para implementar a interface Java android.util.Printer a partir do GDScript usando um Object como implementação. O proxy instanciado pode então ser passado para métodos Java que aceitam um parâmetro do tipo android.util.Printer.
Confira a documentação do JavaClassWrapper para saber mais sobre sua API.
Plugin AndroidRuntime
O JavaClassWrapper é ótimo, mas para fazer muitas coisas no Android, você precisa de acesso a vários objetos de tempo de execução / ciclo de vida do Android. O plugin AndroidRuntime é um plugin Android nativo do Godot que permite fazer isso.
A combinação do JavaClassWrapper com o plugin AndroidRuntime permite que os desenvolvedores acessem e usem as APIs do Android sem precisar sair do GDScript ou usar quaisquer outras ferramentas além do próprio Godot. Isso é gigante para a adoção do Godot no desenvolvimento para Android:
Se você precisa fazer algo simples ou usar apenas uma pequena parte de uma biblioteca de terceiros, não precisa criar um plugin
Permite que os desenvolvedores integrem funcionalidades do Android rapidamente
Ele permite que desenvolvedores criem add-ons para o Godot usando apenas GDScript e
JavaClassWrapper(sem necessidade de Java ou Kotlin)
Nota
Para exportações usando o gradle, o Godot incluirá automaticamente os arquivos .jar ou .aar que encontrar no diretório addons do projeto. Portanto, para usar uma biblioteca de terceiros, você pode simplesmente colocar seu arquivo .jar ou .aar no diretório addons e chamar seus métodos diretamente do GDScript usando o JavaClassWrapper.
Exemplo: Exibir um toast do 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))
Exemplo: Vibrar o 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)
Exemplo: Acessando classes internas
As classes internas do Java podem ser acessadas usando o símbolo $:
# 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
Exemplo: Chamando um construtor
Um construtor é invocado chamando um método com o mesmo nome da classe.
Este exemplo cria uma intent para enviar um texto:
# 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)
Exemplo: Salvando uma imagem na galeria do 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)