Confused about haptic feedback in Android
Asked Answered
B

3

6

I have an Android app with 9 buttons. This app runs on 2.36 and is the only app on the device (or at least the only app we let the user use - we ship the device with our code preinstalled as part of a suite of industrial products we sell.)

All the buttons go to the same handler and get sorted out there by their tag. The handler is specified in the XML:

   <Button android:id="@+id/IdleButton"
     android:layout_marginLeft="5dp"
     android:background="@drawable/idle18pt_he_normal"
     android:hapticFeedbackEnabled="true"
     android:layout_width="92dp"
     android:layout_height="92dp"
     android:tag="0"
     android:onClick="theButtonHandler">
   </Button> 

I want to enable haptic feedback, i.e., a vibration, when the user presses the button. Is there a way to do this just in the XML, or if not, is there a way to do it in my onClick() handler?

The web examples I've seen (e.g., http://androidcookbook.com/Recipe.seam?recipeId=1242 ) for haptic feedback on Android mostly seem to involve changes to the manifest, changes to the XML (you can see I've already enabled it in my XML, above) and then declaring, initializing and implementing a separate Touch handler for the button. This seems like a lot of work, especially since I have 9 buttons.

Since I already have just one onClick handler for all my buttons is there a way I can implement the haptic feedback there?

All I had to do to get a "click" sound when I tap one of my buttons was to checkmark "Audible selection" in the "Sounds" part of the phone's settings - no coding at all. Why is haptic feedback so much more complicated?

Bannerman answered 9/9, 2014 at 15:16 Comment(0)
S
8

Create a custom VibrateButton class that inherits from Button, and add this vibration onClick. You'll still need to ask for permissions in the Manifest, so there's nothing much you can do without inheriting. This example code is taken from here, and does the vibration.

import android.os.Vibrator;
...
Vibrator v = (Vibrator) this.context.getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(500);

Note:

Don't forget to include permission in AndroidManifest.xml file:

<uses-permission android:name="android.permission.VIBRATE"/>

The reason sound can be automatically set for buttons, but vibration can't, is the same it asks for permissions to allow vibration. Vibration consumes battery (way more than a simple sound), and so it affects battery duration, which needs to be, somehow, approved by the end user. If you see, in most some there's an option to "vibrate on click" for some specific buttons (keyboard apps, mainly), but that's dependant on each app.

PS: Make sure the device can vibrate. I had some hours stupidily lost when adding vibration to a Nexus 7 2012; it hasn't got a vibration module. Also, make sure you can disable that, to keep battery up longer.

Squirrel answered 9/9, 2014 at 15:28 Comment(0)
F
11

Without using the VIBRATE permission.

You can use performHapticFeedback() function of any View including Button.

For example programmatically in Kotlin:

view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)

This vibrates the device.

You can vibrate the device from anywhere in your Fragment or Activity, even when you don't have a View available.

In Fragment you can do:

requireView().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)

In Activity you do:

window.decorView.rootView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
Ferraro answered 16/10, 2019 at 14:31 Comment(8)
Could please mention your device name and Os version? because this solution does not work on any of my devices.Bombard
@LibinThomas, I have successfully tested from Lollipop onwards. I'm sure this will work on older versions too, because the support for performHapticFeedback() goes way back to Android API 3.Ferraro
Checked in OnePlus devices, none of them worked. Could you please guide me if am missing something? even I have added vibrator permission also -ThanksBombard
@LibinThomas, the vibrator permission is not required for this to work. Check if your code works on the older versions of Android using emulator, if you don't have devices. You can also try a more specific View other than Fragment. In the end if this solution doesn't work for you, you can always go with permissions way of vibrating. You can find the code for that in this question.Ferraro
@LibinThomas, For first solution, try adding the flag, so instead of the above code, use it like this: requireView().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)Ferraro
@ Yogesh Umesh Vaity Thank you so much for the updates The problem was FLAG_IGNORE_GLOBAL_SETTING is not working for me. In my device touch vibration was disabled in settings, After enabling it manually am able to run haptic successfully. Seems like FLAG_IGNORE_GLOBAL_SETTING have something wrong. Please correct me if anything is wrong with what I understood.Bombard
@LibinThomas, that's right. But if with FLAG_IGNORE_GLOBAL_SETTING your code works, then you should keep that flag, because it give better results for supporting the new devices.Ferraro
Thanks for the update.Sure I will keep thatBombard
S
8

Create a custom VibrateButton class that inherits from Button, and add this vibration onClick. You'll still need to ask for permissions in the Manifest, so there's nothing much you can do without inheriting. This example code is taken from here, and does the vibration.

import android.os.Vibrator;
...
Vibrator v = (Vibrator) this.context.getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(500);

Note:

Don't forget to include permission in AndroidManifest.xml file:

<uses-permission android:name="android.permission.VIBRATE"/>

The reason sound can be automatically set for buttons, but vibration can't, is the same it asks for permissions to allow vibration. Vibration consumes battery (way more than a simple sound), and so it affects battery duration, which needs to be, somehow, approved by the end user. If you see, in most some there's an option to "vibrate on click" for some specific buttons (keyboard apps, mainly), but that's dependant on each app.

PS: Make sure the device can vibrate. I had some hours stupidily lost when adding vibration to a Nexus 7 2012; it hasn't got a vibration module. Also, make sure you can disable that, to keep battery up longer.

Squirrel answered 9/9, 2014 at 15:28 Comment(0)
D
0

on Some Devices like samsung v.vibrate(500) or pattern vibration isn't working so i tried the following solution and it worked.

view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
Dday answered 15/10 at 9:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.