javaandroidkotlinandroid-vibrationhaptic-feedback

Confused about haptic feedback in Android


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?


Solution

  • 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.