From 5bf09e435027df64aed9e5cd95491e04f5fadabf Mon Sep 17 00:00:00 2001 From: ardocrat Date: Fri, 30 Jun 2023 21:25:06 +0300 Subject: [PATCH] android: copy/paste from clipboard --- .../java/mw/gri/android/MainActivity.java | 26 ++++++++++++++ src/gui/platform/android/mod.rs | 35 +++++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/mw/gri/android/MainActivity.java b/app/src/main/java/mw/gri/android/MainActivity.java index 5091c04..bdba327 100644 --- a/app/src/main/java/mw/gri/android/MainActivity.java +++ b/app/src/main/java/mw/gri/android/MainActivity.java @@ -7,12 +7,16 @@ import android.os.Bundle; import android.os.Process; import android.system.ErrnoException; import android.system.Os; +import android.util.Log; import android.view.KeyEvent; import android.view.OrientationEventListener; import com.google.androidgamesdk.GameActivity; import java.util.concurrent.atomic.AtomicBoolean; +import static android.content.ClipDescription.MIMETYPE_TEXT_HTML; +import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; + public class MainActivity extends GameActivity { public static String FINISH_ACTIVITY_ACTION = "MainActivity.finish"; @@ -130,5 +134,27 @@ public class MainActivity extends GameActivity { Process.killProcess(Process.myPid()); } + // Notify native code to stop activity (e.g. node) on app destroy. public native void onTermination(); + + public void copyText(String data) { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText(data, data); + clipboard.setPrimaryClip(clip); + } + + public String pasteText() { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + String text; + if (!(clipboard.hasPrimaryClip())) { + text = ""; + } else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) + && !(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_HTML))) { + text = ""; + } else { + ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); + text = item.getText().toString(); + } + return text; + } } \ No newline at end of file diff --git a/src/gui/platform/android/mod.rs b/src/gui/platform/android/mod.rs index fdb5a97..6bb7aca 100644 --- a/src/gui/platform/android/mod.rs +++ b/src/gui/platform/android/mod.rs @@ -42,12 +42,41 @@ impl PlatformCallbacks for Android { } fn copy_string_to_buffer(&self, data: String) { - //TODO + use jni::objects::{JObject, JValue}; + + let vm = unsafe { jni::JavaVM::from_raw(self.android_app.vm_as_ptr() as _) }.unwrap(); + let mut env = vm.attach_current_thread().unwrap(); + let activity = unsafe { + JObject::from_raw(self.android_app.activity_as_ptr() as jni::sys::jobject) + }; + let arg_value = env.new_string(data).unwrap(); + let _ = env.call_method( + activity, + "copyText", + "(Ljava/lang/String;)V", + &[JValue::Object(&JObject::from(arg_value))] + ).unwrap(); } fn get_string_from_buffer(&self) -> String { - //TODO - "".to_string() + use jni::objects::{JObject, JValue, JString}; + + let vm = unsafe { jni::JavaVM::from_raw(self.android_app.vm_as_ptr() as _) }.unwrap(); + let mut env = vm.attach_current_thread().unwrap(); + let activity = unsafe { + JObject::from_raw(self.android_app.activity_as_ptr() as jni::sys::jobject) + }; + let result = env.call_method( + activity, + "pasteText", + "()Ljava/lang/String;", + &[] + ).unwrap(); + let j_object: jni::sys::jobject = unsafe { result.as_jni().l }; + let paste_data: String = unsafe { + env.get_string(JString::from(JObject::from_raw(j_object)).as_ref()).unwrap().into() + }; + paste_data } fn exit(&self) {