Haptic Feedback / Vibrations in .NET MAUI

A very simple UX improvement in your mobile app is to add a subtle vibration on taps, clicks, scrolls with snapped values etc. We will explore here the remarkably simple way to do this within your MAUI app.

Haptic Feedback / Vibrations in .NET MAUI

The basics

By default, the goal of MAUI is to simplify the developer's work by providing an ultra-simple API. It can't get simpler than this:

// Simple click
HapticFeedback.Default.Perform(HapticFeedbackType.Click);

// Longer click
HapticFeedback.Default.Perform(HapticFeedbackType.LongPress);

// Vibrate
Vibration.Default.Vibrate(TimeSpan.FromMilliseconds(DurationInMs))

// Cancel vibration
Vibration.Default.Cancel()

Platform considerations

Most of the time, platforms allow the user to disable Haptic Feedback, here are where to find these settings:

🤖 Android

In Android, there is a setting often found under Settings > Sound & vibration > Vibration & haptics.

In addition, you'll need to add the permission for VIBRATE in your AndroidManifest.xml :

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

🍏 iOS

In iOS you'll need to navigate to Settings > Sounds & Haptics, and enable "System Haptics"

⚠️
Unfortunately, there is no API to detect or override this setting programmatically.

More articles to come, covering the platforms (Android, iOS and Windows) in-depth.

Code sample

Here is a simple HapticFeedback_Service:

public class HapticFeedback_Service : BaseBindableAppCapability_Service
{
    public HapticFeedback_Service()
    {
        VibrateClickCommand = new Command(VibrateClick);
        VibrateLongPressCommand = new Command(VibrateLongPress);
    }

    protected override bool IsSupported() => HapticFeedback.Default.IsSupported;
    
    public void VibrateClick() => HapticFeedback.Default.Perform(HapticFeedbackType.Click);

    public void VibrateLongPress() => HapticFeedback.Default.Perform(HapticFeedbackType.LongPress);

    public Command VibrateClickCommand { get; }

    public Command VibrateLongPressCommand { get; }
}

And a Vibration_Service:

public class Vibration_Service : BaseBindableAppCapability_Service
{
    protected override bool IsSupported() => Vibration.Default.IsSupported;

    public Vibration_Service()
    {
        VibrateCommand = new Command(Vibrate);
        CancelCommand = new Command(Cancel);
    }

    private void Vibrate() => Vibration.Default.Vibrate(TimeSpan.FromMilliseconds(DurationInMs));

    private void Cancel() => Vibration.Default.Cancel();

    public double DurationInMs
    {
        get => GetValue(500d);
        set => SetValue(value);
    }

    public Command VibrateCommand { get; }

    public Command CancelCommand { get; }
}

Check out my MAUI playground for a full sample:

GitHub - framinosona/Maui-Developer-Sample: This is my playground, I try to make things as clean as possible so that I can reuse them.
This is my playground, I try to make things as clean as possible so that I can reuse them. - framinosona/Maui-Developer-Sample

Results

You should feel a very faint vibration, even the "LongPress" is not strong. It's normal. These are meant to add a little extra to your User Experience, not to be used as a massage gun ...

For advanced patterns like waveform control, intensity, or cross-platform abstraction, native implementations will be necessary. I’ll cover that in a future post.

Stay tuned 🙂