Reputation: 121
Hiyas.
Does anyone know how to achieve this?
I'm creating a "context" (a draw surface) with something like the following code:
Initially:
FApp:= Pandroid_app(PANativeActivity(DelphiActivity)^.instance);
FApp.userData:= Self;
FApp.onAppCmd:= OnAppCmd;
After receiving APP_CMD_INIT_WINDOW in OnAppCmd:
FDisplay := eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(FDisplay, nil, nil);
eglChooseConfig(FDisplay, @attribs[0], @config, 1, @numConfigs);
eglGetConfigAttrib(FDisplay, config, EGL_NATIVE_VISUAL_ID, @format);
ANativeWindow_setBuffersGeometry(FApp.window, 0, 0, format);
FSurface := eglCreateWindowSurface(FDisplay, config, FApp.window, nil);
FContext := eglCreateContext(FDisplay, config, nil, nil);
if (eglMakeCurrent(FDisplay, FSurface, FSurface, FContext) = EGL_FALSE) then
begin
Abort;
end;
However, I seem to need a "view" in order to make it focused such that I can then tell the Android system to enable and show the keyboard for it. The following code does not work (because I don't have focus, I believe):
ANativeActivity_showSoftInput(PANativeActivity(DelphiActivity), 0);
Does anyone know how to get a view without any FireMonkey code?
I found a reference that seemed to suggest that FApp^.window is a SurfaceHolder (because that's what you pass to eglCreateWindowSurface in their example code) but that didn't seem to work or take me very far.
Do I need to do something like in Java and create a GLSurfaceView descendant? But how do I do that?
Any help very much appreciated.
Daniel.
Edit:
I'm still trying to get this to work. All of the examples I can find are in Java so I've attempted to replicate them.
After APP_CMD_GAINED_FOCUS in OnAppCmd I'm using the following code:
CallInUIThread(procedure
var
wnd: JWindow;
ctx: JContext;
ctxcls: JContextClass;
imm: JInputMethodManager;
immcls: JInputMethodManagerClass;
begin
wnd:= TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz).getWindow;
wnd.getDecorView.setFocusable(True);
wnd.getDecorView.setFocusableInTouchMode(True);
ctx:= wnd.getContext;
ctxcls:= JContextClass(ctx.getClass);
imm:= JInputMethodManager(TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz).getSystemService(ctxcls.INPUT_METHOD_SERVICE));
if Assigned(imm) then
begin
immcls:= JInputMethodManagerClass(imm.getClass);
imm.showSoftInput(wnd.getDecorView, immcls.SHOW_FORCED);
end;
end);
It uses some of the FireMonkey framework (for executing in the "UI" thread because trying to access the window otherwise gives a system error that views can't be touched by any other thread) but I should be able to replace that by implementing a JRunnable. I also still don't have a "logical" view...
However, the real problem with this code is that imm is not assigned a value when I try to get it from the context. All of the Java examples assume that it will be.
Further edit:
I think as a last-ditch effort, I have modified the AndroidManifest.template.xml file with the following lines:
android:configChanges="orientation|keyboard"
android:windowSoftInputMode="stateAlwaysVisible">
It still doesn't appear.
Upvotes: 4
Views: 803
Reputation: 1
after googled 2 days, I stitch up a solution that works with Delphi XE11.1
.
here is the code, make use of it:
CallInUIThread(
procedure
var
wnd: JWindow;
ctx: JContext;
ctxcls: JContextClass;
imm: JInputMethodManager;
immcls: JInputMethodManagerClass;
view: JView;
ret: Boolean;
begin
wnd := MainActivity.getWindow;
view := wnd.getDecorView;
view.setFocusable(True);
view.setFocusableInTouchMode(True);
ret := MainActivity.getVirtualKeyboard.showFor(View);
end);
Upvotes: 0
Reputation: 121
Eureka! I have it!
I should have gotten it sooner because I'm copying what FMX does but I thought at the time that I could do it more simply, i.e. do what they do in Java.
It seems that instead of using the InputMethodManager, I need to access the "TextEditorProxy" of the native activity instance that Delphi creates for Android apps.
I'm still using a part of the FireMonkey framework here in order to call CallInUIThread but I will replace it in time with my own JRunnable and call to the Activity's runOnUiThread.
Without further ado, here is the code:
CallInUIThread(procedure
var
fmx: JFMXNativeActivity;
TextView: JFMXTextEditorProxy;
begin
fmx:= TJFMXNativeActivity.Wrap(FApp^.activity.clazz);
TextView:= fmx.getTextEditorProxy;
TextView.setFocusable(true);
TextView.setFocusableInTouchMode(true);
TextView.requestFocus;
TextView.showSoftInput(true);
end);
I still don't know for sure where the input goes to but I shall find out, I hope.
Daniel.
Upvotes: 1