Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Discussion Android Build and Bluetooth Keyboard Input - Not Working

Discussion in 'Android' started by keystagefun, Jan 18, 2023.

Thread Status:
Not open for further replies.
  1. keystagefun

    keystagefun

    Joined:
    Feb 19, 2020
    Posts:
    33
    Hi,

    I'm at that point where I have stared at about 8 million forum posts, been through the docs until I'm seeing the Unity manual when I close my eyes and tried everything whilst making zero progress. I'm sure I'm missing something because this surely can't be that difficult...

    I have a bluetooth keyboard working perfectly with the new input system on iOS. No issues.

    I'm now trying to implement the same thing on Android (12) but I can't get it to work.

    I have edited the Android manifest file to include permissions for Bluetooth (and have ensured they're the correct ones for Android 12). Weirdly though, if I install my app on the device and check its permissions in Settings > Apps, I get no mention of bluetooth.

    The bluetooth keyboard is definitely connected to the device - it works perfectly in Chrome, Google Mail etc.

    I have ensured that my code has no references to iOS that are stopping it from running something on Android.

    Is there something else that I need to do to get my app to pick up on input from a bluetooth keyboard? Is there a tutorial somewhere that I've missed?

    My code for checking which devices are connected is as follows:

    Code (CSharp):
    1.  
    2. foreach (InputDevice device in InputSystem.devices) {
    3. Debug.Log("Name: " + device.name + "\nDisplay Name: " + device.displayName + "\nDescription: " + device.description.ToString() + "\nPath: " + device.path.ToString());
    4. }
    5.  
    When I run this on my devices (I have tried on 2 very different Android devices) I am returned 2 devices. One is the Android on-screen software keyboard and the other is a pointer of some kind. But no hardware keyboard despite it being connected

    [EDIT - this was not the case - see below post - I had some additional code after the above that checked if the keyboard name matched what I was expecting in iOS for a hardware keyboard and then broke out of the loop of it found it - this was still running on Android and therefore stopped me from ever getting to the Android hardware keyboard]


    So somewhere along the line, my app is not able to recognise that the keyboard is connected and is a valid input source.

    Any help / ideas / suggestions would be hugely appreciated. It's been one of those days.

    Thanks,

    Ian
     
    Last edited: Jan 19, 2023
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,663
    what about input listening via Keyboard.current.aWasPressedThisFrame, does that get registered if you tap a on your bluetooth keyboard?

    If input from your bluetooth keyboard gets registered on other apps on your Android phone, Unity should pick it up as well.
     
  3. keystagefun

    keystagefun

    Joined:
    Feb 19, 2020
    Posts:
    33
    Thanks for the reply.

    Turns out there were / are several issues. Have fixed 2 of them, but am completely stuck on the third.

    [FIXED] Issue 1 - Finding and setting the Bluetooth keyboard as current
    Firstly I wasn't properly registering the keyboard as the current keyboard (I was looking for the wrong keyboard name when looping through the registered devices and setting the external keyboard as the current device) - that is now working and the keyboard shows up as a connected, current device. If anyone is having the same issue, my Android keyboard was referenced as "qwerty" whereas on iOS it was called "Keyboard" (and worth mentioning that on iOS I was getting 2 different devices returned as keyboards - the bluetooth external keyboard and the on-screen Apple keyboard, whereas on Android there were 4 devices returned that were listed as being keyboards - Virtual, qwerty, gpio_keys and On-Screen). No idea what Virtual or gpio_keys are!!

    [FIXED] Issue 2 - Getting some input from the bluetooth keyboard
    With that sorted, Tomas' suggestion (thank you) gives some results. If I run the following code in the update loop, I see the debug log in Terminal, so that's functioning.
    Code (CSharp):
    1. if (Keyboard.current.aKey.wasPressedThisFrame == true) {
    2.     Debug.Log("A WAS PRESSED!!!!");
    3. }
    The old input system also works.
    Code (CSharp):
    1. if (Input.GetKeyDown(KeyCode.A)) {
    2.     Debug.Log("A WAS PRESSED!!!!");
    3. }
    So clearly the keyboard is connected and my app is able to receive some input from it. However...

    [NOT FIXED] Issue 3 - Using the OnTextInput Method to receive input

    However - the below doesn't work on Android, yet it does work on iOS and in the Unity Editor.
    Code (CSharp):
    1. // Add the OnTextInput method
    2. Keyboard.current.onTextInput += OnTextInput;
    3.  
    4. // And the function that listens for text input
    5. private void OnTextInput(char ch) {
    6.     // Convert the entered character to a string
    7.     string chString = ch.ToString();
    8.     int asciiCode = Convert.ToChar(chString);
    9.  
    10.     // Debug
    11.     Debug.Log("CHAR--"+chString+"-- / LEN: "+chString.Length+" / ASCII: " + asciiCode);
    12. }
    At all times, Keyboard.current.enabled returns true and checking Keyboard.current.displayName returns "qwerty", which is correct.

    I've also checked that the keyboard isn't subsequently being disabled (it isn't), or that the current device isn't being switched to a different input device (it isn't).

    Summary:

    So I'm 50% there, but just can't get OnTextInput to fire on Android. I've stripped back all superfluous code. But still nothing.

    To clarify:
    • I am running both input systems (old and new) concurrently (and have set this in the player settings).
    • Both old and new input systems and all the code above works perfectly on iOS and in the simulator on my Mac
    • The old input system works on Android, as does the new input system if using wasPressedThisFrame, but the new input system does not seem to accept any key presses via OnTextInput on Android, which is the method I would like to use.
    Assume I'm missing something somewhere around how to assign OnTextInput on Android, but I've scoured the docs and can't see anything:

    https://docs.unity3d.com/Packages/c...InputSystem_Keyboard_OnTextInput_System_Char_

    Any ideas?

    Thanks in advance for any assistance anyone can offer!

    Cheers.
     
    Last edited: Jan 19, 2023
  4. keystagefun

    keystagefun

    Joined:
    Feb 19, 2020
    Posts:
    33
    Spent several more hours on this today and still no joy.

    I just can't get any feedback via OnTextInput method on Android, whilst it works perfectly on iOS and in the editor.

    Checking in the update loop that the keyboard is connected and enabled returns the correct keyboard and that it is enabled and current.

    Checking in the update loop for any key's wasPressedThisFrame returns true if I press that key.

    But nothing in OnTextInput.

    Is this a known bug on Android?

    Thanks for any help anyone can offer. I'm completely stumped.
     
  5. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,663
    Not a known bug, you might need to report this issue with repro project if possible.

    OnTextInput is driven by https://developer.android.com/reference/android/view/KeyEvent#getUnicodeChar(int)

    Try adding some debugging code in UnityPlayerActivity.java dispatchKeyEvent method and print KeyEvent getUnicodeChar to logcat. Maybe invalid values are coming from bluetooth keyboard.


    Also, just to be sure, when you do
    Keyboard.current.onTextInput += OnTextInput;
    does current points to your keyboard, because if not you might be subscribing to the wrong keyboard.
     
    Last edited: Jan 20, 2023
  6. keystagefun

    keystagefun

    Joined:
    Feb 19, 2020
    Posts:
    33
    Thanks Tomas. Yes - definitely pointing to the current keyboard and I can get values via wasPressedThisFrame on that keyboard.

    Will try your initial suggestion. Now trying to get it working for WebGL, which is seeming a lot smoother.
     
Thread Status:
Not open for further replies.