Detecting Long Key Press on Samsung Galaxy Watch 4 (Android Wear OS) - android

I have written a sailing app for watches running Wear OS. Sailing watches often get wet so I disabled the screen and navigate the menu using physical key presses (single and multiple presses). So far so good
I am now trying to detect a Long Press of the physical key (for an emergency Man-Over-Board function) but so far I have been unable to find any event which is triggered when a physical key is held down on the Samsung Galaxy Watch 4.
Can anyone suggest how to detect a long key press on the Samsung Galaxy Watch 4?
Most of the key press detection can be done by overriding onKeyDown()
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
return if (keyCode == bottomKeyCode) {
// process bottomKeyPress
writeToLog("onKeyDown()")
event.startTracking() // required to enable LongPress (works on TicWatch NOT Samsung)
true
} else
super.onKeyDown(keyCode, event)
}
On the Samsung Galaxy Watch 4 a short press will trigger the onKeyDown() event
The problem is no events are triggered when the key is held down. Holding down the key does not trigger onKeyDown or onKeyLongPress. It does not even trigger onKeyUp when the key is released!
Further testing
I have also looked at dispatchKeyEvent()
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
writeToLog("dispatchKeyEvent() keyCode ${event.keyCode} keyAction ${event.action}")
return super.dispatchKeyEvent(event)
}
This was also unsuccessful
I have run the code on a Ticwatch Pro 3 GPS (Wear OS 2) and the behaviour is 'closer' to what is described in the Android documentation. When the key is first pressed onKeyDown() is triggered. Continuing to hold the key down results in a second onKeyDown() 350msec later. This is followed by more onKeyDown() events sent every 50msec after that (along with an onLongKeyPress()). Hence the easiest way to implement Long Key Press detection on the TicWatch is to simply count the number of onKeyDown() events (to avoid the unneeded onLongKeyPress() event simply remove event.startTracking()).
Note the Samsung Galaxy Watch 4 uses keyCode == KeyEvent.KEYCODE_BACK for the bottom physical key rather than the Ticwatch which uses KeyEvent.KEYCODE_STEM_1. For completeness I investigated onBackPressed() but this is also not being triggered
override fun onBackPressed() {
writeToLog("onBackPressed()")
super.onBackPressed()
}

Samsung finally responded and the formal answer is Long Press is not supported
Unfortunately, it is not possible to get dispatched long-press keyEvent from the Samsung Galaxy watch 4.
Both Hardware buttons (named Home key and Back key) of watch 4 are system keys.
According to Samsung's policy, in the case of system keys, 3rd party can not get the KeyEvent of the watch 4 devices.
Factually it is possible for 3rd party apps to get access to the onKeyDown() event (as shown in the original question) PROVIDED it is only a short press
If the back key is held down then the watch does not trigger the onKeyDown() event (meaning any attempt to use a timer to simulate an onLongKeyPress() event will also be unsuccessful)

Related

Detect/override controller "Home" button press android

I have an android application that is meant to be used with a game controller connected to the android device.
Most game controllers have a center 'home' button that I would like to use to pause the game (for example, an Xbox controller center nexus button should pause).
However, when you press the center nexus button on the controller it causes the entire app to close as though the actual home button on the phone was pressed. Why is the center button on some controllers causing the app to return to the home screen? Note, this doesn't happen with all controllers or all devices. For example, using a pixel 6 and an xbox controller it doesn't send the app home. But using a galaxy a32 the center nexus button does triggers the home action.
I understand its not possible to intercept the actual home action from within an app. But is it possible to do so from a physical controller? Or is it possible to remap the controller buttons?
I tried this in an attempt to intercept the home action:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.e("KeyPress", "Code: " + keyCode);
switch (event.getKeyCode()){
case KeyEvent.KEYCODE_HOME:
return false;
default:
return super.onKeyDown(keyCode, event);
}
}
but this isn't working. Pressing the center button on the controller doesn't trigger the log but it still goes to the home screen.
Any ideas how to make certain button on physical controllers not trigger the home action?
Thanks
This happens with gamepads that send the same input code used for the "Homepage" key on some keyboards. By default, HID input devices are handled by the hid-input driver which always translates the "Consumer Application Control Home" usage (000C:0223) to the KEY_HOMEPAGE Linux input event code.
https://github.com/torvalds/linux/blob/4e23eeebb2e57f5a28b36221aa776b5a1122dde5/drivers/hid/hid-input.c#L1151
The Android OS converts KEY_HOMEPAGE to KeyEvent.KEYCODE_HOME which is handled by the framework and never delivered to applications. Probably it should convert it to BTN_MODE as suggested by the Linux gamepad specification.
If you have root access you can fix this by adding a Key Layout file to correct the button mapping for a specific device. See Vendor_045e_Product_02fd.kl for an example of a key layout file that maps KEY_HOMEPAGE (Linux input event code 172) to Android's KeyEvent.KEYCODE_BUTTON_MODE.

how to response click event when screen off

i have a app,if my app screen off some times,i want to click the screen to awake the screen on.i know i can press the power to deal with using flag_user_present to receive the broadcast or
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
//do nothing but show a warning message
Toast.makeText(this, "you pressed the power button",Toast.LENGTH_SHORT).show();
return true;
}
return super.dispatchKeyEvent(event);
}
but i want to click the screen to do the same thing ,so i overload the ontouch event,but when screen off,the ontouch not receive focus and deal with the click event.
so my question how to deal with click event when screen off(my screen not lock and stay the same activity,only screen off)
You won't be able to do this when the device shuts off the screen. If the screen is off, then the touchscreen usually get's shut down immediately by the kernel (if it's not modified otherwise). This happens for obvious reasons.
You could use what tsp said in his answer, and emulate the screen off by turning it black, turn the brightness as far low as possible and then still listen for touch events. Keep in mind though, that this behavior is unexpected by the user and he might think the screen is off, where it isn't. I don't recommend doing this! Also, not all devices allow a zero brightness.
u can use
android:keepScreenOn="true"

hook power key and detect volume key is press when screen is turn off

As the title, I have two problems:
1. Hook power key- I need detect and prevent power key.
2. When screen is off, i need to handle event foe volume,menu,back key press.
KeyEvents stackoverflow This link lets you know how to handle onKeyUp/Down event.
For Back key detection use KEYCODE_BACK
For Volume Keys use KEYCODE_VOLUME_DOWN and KEYCODE_VOLUME_UP
list of Key events
Detecting menu button
OnStop() lifecycle method of a activity is called when power button is pressed.

Is there a way to catch the Search key so that the Google Voice Search dialog doesn't appear?

I'm aware that the home key cannot be caught, and I'm worried that a long-press on the Search key is another "Android-OS protected" key press. Just for testing, I tried to catch all keys with this code within my Activity, but it does not stop the Google Voice Search dialog from being triggered.
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
return true;
}
Edit: I tested this code on the Nexus One, and it successfully blocks the key event on that phone, but I still have this problem on the Droid 2. Both are running Froyo 2.2
Im not at my pc, so im just gonna paste a search result.
I think you'r looking for this:
Activity | Android Developers
boolean, onSearchRequested(). This hook is called when the user signals the desire to start a search.
http://developer.android.com/reference/android/app/Activity.html

can we restrict backbutton functionality to given levels?

i am fighting with android hardware backbutton
now my question to you is can i restrict its functionality upto 3 or 4 levels?
right now for example, i have 1,2,3,4,5,6,7,8,9,10 activities
i go to 1 then 2 then 3 .... upto 10 and start pressing backbutton
it takes me to 9 then 8 then 7 upto end
i want to keep track of only last three levels is this possible or not?
any help would be appreciated.
i want to keep track of only last three levels is this possible or not?
You are welcome to keep count, perhaps using an integer. Use onBackPressed() (Android 2.x) and onKeyDown() (Android 1.x) to detect BACK button presses. If you chain to the superclass, normal BACK processing will occur. If you do not chain to the superclass, normal BACK processing will not occur.
Now, bear in mind that the user can press other keys, like HOME, or the user might respond to a notification (e.g., incoming text message). In those cases, it is possible that your counts may get out of sync with the actual user navigation. Hence, I encourage you to find some other UI pattern that does not involve artificially restricting the BACK button between activities in the fashion that you have outlined here.
This is the example code to CommonsWare's answer "onKeyDown() (Android 1.x)"
public boolean onKeyDown( int keyCode, KeyEvent event ) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
//do some stuff
return false;
}
return super.onKeyDown(keyCode, event);
}

Categories

Resources