organicmaps / organicmaps

🍃 Organic Maps is a free Android & iOS offline maps app for travelers, tourists, hikers, and cyclists. It uses crowd-sourced OpenStreetMap data and is developed with love by MapsWithMe (MapsMe) founders and our community. No ads, no tracking, no data collection, no crapware. Please donate to support the development!
https://organicmaps.app
Apache License 2.0
9.98k stars 957 forks source link

[Android] trigger 'tap & click' sounds/vibration when interacting with map #8765

Open RedAuburn opened 3 months ago

RedAuburn commented 3 months ago

if tap & click sounds are enabled in android settings (it's enabled by default), tapping or long-pressing on the map should trigger the sounds/vibration like it does with the other buttons in the app, and across the system. this will make the map feel more integrated & tactile.

see https://m2.material.io/design/sound/applying-sound-to-ui.html#system-sounds

RedAuburn commented 3 months ago

i think iOS has similar sounds, not sure if it's properly handled there either

varad64 commented 1 month ago

Hello @RedAuburn,

I tried out adding both sound and haptic feedback, but there's an issue for the tap sounds. When the user touches the map interface, the onTouch() method is invoked at least twice. And the calls to onTouch() only grow when the user drags the map interface.

As a result, if view.performClick() is invoked from within onTouch(), it leads to a barrage of tap sounds and quickly becomes annoying.

We could add the sound and haptic feedback for long press with no issues, however.

Could you please let me know what you think of this and how we can proceed?

Thanks in advance!

RedAuburn commented 1 month ago

Hiya @varad64!

I tried out adding both sound and haptic feedback, but there's an issue for the tap sounds. When the user touches the map interface, the onTouch() method is invoked at least twice. And the calls to onTouch() only grow when the user drags the map interface.

As a result, if view.performClick() is invoked from within onTouch(), it leads to a barrage of tap sounds and quickly becomes annoying.

Unfortunately, a simple fix of adding onTouch() to the view won't suffice, a proper implementation that only has tap sounds when actually tapping something on the map will require passing the touch from the C++ core to native via JNI, then triggering a performClick().

varad64 commented 1 month ago

Thanks for responding, @RedAuburn. Okay, I understand. Is there any documentation on how to to get the C++ core to talk to the Java code?

Thank you!

RedAuburn commented 1 month ago

Is there any documentation on how to to get the C++ core to talk to the Java code?

there's JNI docs, but not anything Organic Maps specific as far as i know.

it's probably easiest to understand via example; have a look at https://github.com/search?q=repo%3Aorganicmaps%2Forganicmaps+nativeontouch&type=code

varad64 commented 1 month ago

Okay, great. Let me try implementing this and get back to you!

Thanks for the useful example

varad64 commented 1 month ago

Hello @RedAuburn,

I spent some time analysing the concerned native code execution and its interaction with the Java code. I now have a better understanding. But there are 2 challenges:

  1. All of the concerned events and callbacks are in the file user_event_stream.cpp. How do I figure out what is the native equivalent of performClick() or alternatively playSoundEffect() and performHapticFeedback()?
  2. If we solve for 1, the issue described in #9195 still isn't solved, because, if the performClick method is called in MapFragment.java, the tap sound and haptic feedback will be duplicated. If not called, the original problem remains unsolved.

The long tap behavior can be solved for by means of the onLongClick method without any issues.

Thanks in advance!