Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the ability for users to invoke the soft keyboard anywhere, at any time, even on screens that do not normally allow keyboards. This approach works even on Android 13 (API 33) #497

Closed

Conversation

LostRuins
Copy link

@LostRuins LostRuins commented Nov 30, 2023

I went ahead and did it myself, because I really needed the functionality. I am quite certain no other FOSS keyboard has this ability working in Android 13.

This PR adds the ability for users to invoke the soft keyboard anywhere, at any time, even on screens that do not normally allow keyboards. This approach works even on Android 13 (API 33), and is an essential replacement for the now-defunct Hacker Keyboard's Permanent Notification, which had a similar capability but stopped functioning after API 30 (klausw/hackerskeyboard#897).

Closes #496, Closes #71, Closes #392 and Closes #69

How to use:

  1. Launch Unexpected Keyboard, and click Show Persistent Keyboard
  2. Grant the Draw Over Other Apps permission, allowing overlays to be displayed.
  3. Now, whenever you require a keyboard, launch the app and press Show Persistent Keyboard
  4. A button overlay will appear in the top left corner
  5. Navigate back to the app you want to use that does not support keyboards.
  6. Click the Show button in the top left corner. The overlay will be closed, and at the same time the soft keyboard will be invoked.
  7. Enjoy your ability to use a keyboard anywhere, like Richard Stallman intended.

demo

…y time, even on screens that do not normally allow keyboards. This approach works even on Android 13 (API 33)
@LostRuins
Copy link
Author

Feel free to modify or change anything, I am not an android dev so I might not be following best practices.

Copy link
Owner

@Julow Julow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fantastic, thanks! I'll make a proper review and merge this soon.

Only APKs built by the CI are trustworthy, here's the latest for this PR: https://github.com/Julow/Unexpected-Keyboard/actions/runs/7049282572?pr=497

@LostRuins
Copy link
Author

Worth noting that on android 13, it seems that there must be at least one navigable ui element for the keyboard to remain displayed. Otherwise, it gets dismissed. If you would have been able to plug a real keyboard and navigate that app via arrow keys, then it would probably work.

@Spike-from-NH
Copy link
Contributor

I'm glad you took the initiative!
① Can I drag this button somewhere else if it occludes something important?
② The "X" box is to dismiss the button? Can you jam them together to better show they are parts of the same control? If dismissed, can they be re-enabled in the way they were originally?
③ If Draw Over Other Apps is not granted, do you ask for it?
④ Add the enable button to the Settings menu as well?
⑤ Does it look good in all Themes?

Copy link
Owner

@Julow Julow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work on my device, the keyboard opens then closes immediately on top of any app. Any idea on how to debug this ?

res/layout/overlay_button.xml Outdated Show resolved Hide resolved
@@ -6,4 +6,5 @@
<TextView style="@style/paragraph" android:text="https://github.com/Julow/Unexpected-Keyboard" android:autoLink="web" android:linksClickable="true"/>
<TextView android:id="@+id/launcher_tryhere_text" style="@style/paragraph" android:text="@string/launcher_tryhere"/>
<EditText android:id="@+id/launcher_tryhere_area" style="@style/paragraph" android:inputType="text"/>
<Button style="@style/paragraph" android:text="Show Persistent Keyboard" android:onClick="startOverlayService" android:layout_width="wrap_content"/>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening the app and clicking this button is a lot of work. Any hope of having a permanent notification instead ?

res/layout/overlay_button.xml Outdated Show resolved Hide resolved
srcs/juloo.keyboard2/LauncherActivity.java Outdated Show resolved Hide resolved
srcs/juloo.keyboard2/LauncherActivity.java Show resolved Hide resolved
@LostRuins
Copy link
Author

LostRuins commented Dec 3, 2023

Hi @Julow, I have a bit of bad news. It seems like I was mistaken on the specifics this approach.

If the user's device is below Android 13, it will work in all cases.
If the user's device is at or above Android 13, and the target SDK of the app is below API 33, it will also work.
However, if the APK target SDK exceeds 33, and the device is also android 13 or above, then this approach does not work anymore, as the keyboard will be closed the moment the view loses focus.

You can try by either using any older device, or downloading some random older app from fdroid. I did not notice this at first, as many of the apps installed on my device are older APKs.

With this disappointing news, I am not sure if this warrants closing this PR or not, it's your choice... perhaps it could still be of some use either for older apps or older devices like in my own use case.

Nevertheless, I have tidied up the PR a bit, so do take a look.

  • The button has been changed to an ImageView with the app logo as an icon.
  • The dismiss button has been resized and changed to be more intuitive looking.
  • The overlay is now persistent and does not disappear on a single use. Instead, the keyboard is invoked with this flow:
    1. Overlay view starts as non-focusable (FLAG_NOT_FOCUSABLE), allowing normal interaction with the underlyring screens.
    2. The invoke keyboard button is pressed by the user.
    3. The overlay view layout params is switched to FLAG_NOT_TOUCH_MODAL, allowing it to be focused.
    4. The overlay view requests focus, then the soft keyboard is invoked with inputMethodManager.toggleSoftInput
    5. The overlay view is switched back to non-focusable, allowing normal interaction with the underlyring screens.
  • The overlay button remains on screen and re-usable until manually dismissed, which allows the keyboard to be triggered at will multiple times.
  • Applied all the other changes you have suggested.

Here is another video where I attempt to use this new version on multiple apps on my Android 13 device, you can see it works for any app below target SDK 33 (the bottom group), while failing for those above (the top group). I did also test it on my Android 9 device and it works fine in all cases. I also demonstrate the new interface, switching between apps and invoking the keyboard with touches visible.

only_below_sdk33.mp4

Also replying @Spike-from-NH :

  1. Not at the moment
  2. Adjusted
  3. Yes
  4. See (5)
  5. Let's see if its still worth including first considering the new limitations found.

@LostRuins
Copy link
Author

On a sidenote, I have found another non-free app com.locnet.gamekeyboard2 which does work with SDK 33 on android 13. They achieve this by invoking the keyboard when the Volume Up button is pressed. However, I was unable to replicate this effect in Unexpected Keyboard myself - though it may be worth exploring if someone else figures it out. For now, I am now using both keyboards, switching between them as necessary.

@Spike-from-NH
Copy link
Contributor

They achieve this by invoking the keyboard when the Volume Up button is pressed.

Hacker's Keyboard has, in Settings→Gestures, what to do if Volume up/Volume down is pressed. But these effects are active only when the keyboard is displayed, and "Display the keyboard" is not an option; when not displayed, the Volume keys are controlled by the underlying app (or by default, remain volume keys).

@Julow
Copy link
Owner

Julow commented Dec 3, 2023

The interface looks better :) The target SDK thing is disappointing but if Game Keyboard can do it, it means there's a way.

Could this be related to permission and to the permission change in Android 10 or to background permissions ?

@LostRuins
Copy link
Author

LostRuins commented Dec 4, 2023

I don't think it's permissions related. But yes, Game Keyboard definitely can do this, and it works as a normal keyboard, keys can be sent, and the keyboard behaves the same as it does when invoked for an EditText. If you would like the apk to try let me know of a way to send it to you, I won't upload it here since I think you don't want that.

gk

@diejuse
Copy link

diejuse commented Jan 11, 2024

What about this solution??? https://www.youtube.com/watch?v=OCTiacmVu_Y&ab_channel=ArtTV%3AAGorgeousPlace
This keyboard is permanent and works even on Android 14. I just discovered it and made a comment on the video. I think it's a perfect solution but it needs to have more options.

@RetrogisusDEV
Copy link
Contributor

I think that a good solution would be to use accessibility, to invoke the keyboard without the need for any text field, and it would be more shareable with previous APIs, than how accessibility is implemented? I don't know, but it would be the most viable solution for previous api (estimated up to api 19)

@diejuse
Copy link

diejuse commented Jan 17, 2024

I think that a good solution would be to use accessibility, to invoke the keyboard without the need for any text field, and it would be more shareable with previous APIs, than how accessibility is implemented? I don't know, but it would be the most viable solution for previous api (estimated up to api 19)

@Julow @RetrogisusDEV Yes that's how it is! I don't understand why there isn't any keyboard of this type! (apart from this). It would be perfect to have a floating icon above the rest of the apps and be able to display it whenever you want to send letters.
It would even be usable as a gamepad!

@doak
Copy link

doak commented Jan 31, 2024

I am very much looking forward to this feature.

@diejuse
Copy link

diejuse commented Feb 21, 2024

Anyone knows a always visible keyboard like this for Android? I need it.

@LostRuins
Copy link
Author

I will be closing this PR due to lack of interest.

For future readers, this approach only works for apps with target sdk < 33.
For anyone who wants a fully working solution on Android 13+, use Game Keyboard 2.

@LostRuins LostRuins closed this Feb 22, 2024
@Julow
Copy link
Owner

Julow commented Feb 22, 2024

Sorry for the lack of interest. The target sdk constraint is a big problem as Google Play would not accept upgrades and would lower the rank of the app.

Though, I'd accept to release the app with this on F-Droid and Github, for a bit of time. It'd need to be made optional.

This do not work on my device (running Android 13): the keyboard seems to open and close immediately, no logs.
Do you think there's a way to detect when it wouldn't work and not offer the feature in this case ?

@diejuse
Copy link

diejuse commented Feb 22, 2024

Sorry for the lack of interest. The target sdk constraint is a big problem as Google Play would not accept upgrades and would lower the rank of the app.

Though, I'd accept to release the app with this on F-Droid and Github, for a bit of time. It'd need to be made optional.

This do not work on my device (running Android 13): the keyboard seems to open and close immediately, no logs. Do you think there's a way to detect when it wouldn't work and not offer the feature in this case ?

@Julow Couldn't you try adding the keyboard functionality you mentioned to your keyboard so we could use your wonderful keyboard at any time?
That wat the keyboard could be to invoke without the need for any text field, and it would be more shareable with previous APIs, as said @RetrogisusDEV

@RetrogisusDEV
Copy link
Contributor

RetrogisusDEV commented Feb 22, 2024

Sorry for the lack of interest. The target sdk constraint is a big problem as Google Play would not accept upgrades and would lower the rank of the app.

Though, I'd accept to release the app with this on F-Droid and Github, for a bit of time. It'd need to be made optional.

This do not work on my device (running Android 13): the keyboard seems to open and close immediately, no logs. Do you think there's a way to detect when it wouldn't work and not offer the feature in this case ?

Couldn't you try adding the keyboard functionality you mentioned to your keyboard so we could use your wonderful keyboard at any time?
That wat the keyboard could be to invoke without the need for any text field, and it would be more shareable with previous APIs, as said @RetrogisusDEV

In fact, I've been trying and I'm already giving up xD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants