40

I'm writing an app using notification. Google developer guidelines encourages developers to provide settings to customize the notifications (disable vibration, set notification sound...), so I am trying to disable vibration for notifications if the user set it that way.

I am using NotificationCompat.Builder to create the notification, like this:

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(Application.getContext())
            .setDefaults(Notification.DEFAULT_ALL)
            .setPriority(Notification.PRIORITY_MAX)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(largeIconBitmap)
            .setAutoCancel(true)
            .setContentIntent(resultPendingIntent)
            .setContentTitle(title)
            .setContentText(content);

I tried different ways to disable notifications:

notificationBuilder.setVibrate(null);

notificationBuilder.setVibrate(new long[]{0l, 0l});

notificationBuilder.setDefaults(Notification.DEFAULT_ALL | ~Notification.DEFAULT_VIBRATE);

notificationBuilder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND);`

I also tried to build the notification and change values on the resulting object:

Notification notification = notificationBuilder.build();
notification.vibrate = null;

But the phone still vibrates when the notification appears.

How can I disable vibration for notifications?

nstCactus
  • 5,141
  • 2
  • 30
  • 41

11 Answers11

69

After a long trial & error session, I think I finally understood what's wrong.

The problem lies in this instruction notificationBuilder.setDefaults(Notification.DEFAULT_ALL).

No matter what parameter you pass to notificationBuilder.setVibrate() after setting DEFAULT_ALL or DEFAULT_VIBRATE will be silently discarded. Someone at Google must have decided to give a higher precedence to setDefaults than to setVibrate.

This is how I ended up disabling vibration for notifications in my app:

notificationBuilder.setDefaults(Notification.DEFAULT_LIGHT | Notification.DEFAULT_SOUND)
                   .setVibrate(new long[]{0L}); // Passing null here silently fails

This works but doesn't feel right to initialize a new long[] just to disable the vibration.

Mdlc
  • 7,128
  • 12
  • 55
  • 98
nstCactus
  • 5,141
  • 2
  • 30
  • 41
  • 2
    I completely understand the grossness of passing in a variable to tell the device to vibrate once for 0 milliseconds, but it still isn't the worst fix I've ever seen. At least it makes sense when you think about what it's doing. – Gabriel Nov 15 '14 at 01:22
  • 1
    I was just trying to do the same thing and there's a couple other points to make here. The priority level of 3 or greater of the notification channel will also cause vibrate to occur, regardless of your vibrate settings. Furthermore, it seems android is caching the notification channels. If you use NotificationManager.getNotificationChannel(id) you will get your last instance settings – Jesse Nov 13 '18 at 23:03
  • 1
    @Jesse thank you! You were right about the caching. I did `setVibrate(null)` and it had no effect, but when I changed my channel id it worked – Undefined Jan 09 '19 at 04:28
  • 3
    This doesn't work on my device!I'm getting the vibration still – Steve Moretz Feb 11 '19 at 16:48
  • I'd not say the notification channel is being cached, but the settings that were used at the first app install are remembered. Why? Imagine a user customised the notification channel settings. Then an app update with new channel settings should not overwrite those settings. This means you can only change these settings in an app update if you change the channel-ID (or just uninstall the app when testing). Result: the user's customised settings are remembered for the old channel, but you have assigned a new channel for the notification. Of course, don't do this often to prevent annoyed users! – P Kuijpers Mar 30 '20 at 07:47
8

In the year 2020:

Setting the importance of the notification channel to NotificationManager.IMPORTANCE_NONE worked for me.

Jakob Harteg
  • 9,587
  • 15
  • 56
  • 78
  • 2
    this does not work at all ! it just remove all the notifications from the status bar (-1) – Zhar Jul 27 '20 at 14:09
  • 1
    Setting notification channel's importance to NotificationManager.IMPORTANCE_LOW worked for me – Sandaru Jan 10 '22 at 06:50
4

You have 2 solutions with the notification channel.

  1. Set a "fake" pattern to disable the vibration.
  2. Set Importance flag, but less flexible (see https://developer.android.com/training/notify-user/channels#importance). Takes care, it will also impact some other stuff like priority...

As a result, you can use

NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            // no vibration
            channel.setVibrationPattern(new long[]{ 0 });
            channel.enableVibration(true);

Or

 int importance = NotificationManager.IMPORTANCE_LOW;
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        
Zhar
  • 3,330
  • 2
  • 24
  • 25
3

They are not stop because you are use "setDefaults(Notification.DEFAULT_ALL)" so if you need to stop vibration and sound remove this line , or if you need to use the default sound and stop vibration I think you must use setDefaults(Notification.DEFAULT_SOUND) etc ...

Oubaida AlQuraan
  • 1,706
  • 1
  • 18
  • 19
1

.setVibrate(null) works for me - and a better solution than creating a needless long[].

Result: device doesn't vibrate and no grumbling in LogCat either. :)

ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
  • I agree, your solution is way more elegant than mine. Unfortunately it didn't work for me when I tested on a Samsung Galaxy Note. – nstCactus Sep 08 '14 at 01:09
  • Did an exception get thrown and/or did the device vibrate? – ban-geoengineering Sep 08 '14 at 13:54
  • As far as I can remember, it vibrated but didn't throw an exception or any kind of warning. – nstCactus Sep 08 '14 at 14:28
  • That seems a bit strange as I've had a look through the source code for Notification - http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/Notification.java#Notification - and null vibrate seems to be handled correctly. What do you get when you output `notification.toString()` ? (And you're deffo not applying defaults anywhere?) – ban-geoengineering Sep 08 '14 at 18:29
  • Quite frankly I don't have time to do some more testing on this issue at the moment. I'll try again your solution when I start working again on that project but it won't be anytime soon, sorry. – nstCactus Sep 09 '14 at 09:29
  • 1
    OP clearly stated in original post that this solution was tested and did not work. I am also testing it and it does not work. – Kyle Sweet Aug 05 '16 at 15:48
1
notification.vibrate = new long[] { -1 };

this code work for me.

Houssin Boulla
  • 2,687
  • 1
  • 16
  • 22
1

Above solutions didnt work but adding mBuilder.setOnlyAlertOnce(true); to my notification builder solved my problem.

 if (mBuilder == null) {
            String channelId = "channel-id";
            String channelName = "Channel Name";
            int importance = NotificationManager.IMPORTANCE_MAX;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                NotificationChannel mChannel = new NotificationChannel(
                        channelId, channelName, importance);

                mChannel.setSound(null, null);
                mChannel.enableVibration(false);

                notificationManager.createNotificationChannel(mChannel);
            }
            mBuilder = new NotificationCompat.Builder(Application.context, channelId);
            mBuilder.setSmallIcon(R.drawable.ic_ulakbel)
                    .setContentTitle("YOURTITLE")
                    .setAutoCancel(true)
                    .setColor(ContextCompat.getColor(Application.context, R.color.green))
                    .setColorized(true);
            mBuilder.setChannelId(channelId);
            mBuilder.setPriority(1);
            mBuilder.setCustomContentView(notificationLayout);
            mBuilder.setCustomBigContentView(notificationLayout);
            mBuilder.setOnlyAlertOnce(true);
            notificationManager.notify(1452, mBuilder.build());
        }else{
            Notification notification = mBuilder.build();
            notification.flags = Notification.FLAG_ONGOING_EVENT;
            notificationManager.notify(1452,notification);
        }
Bilal Şimşek
  • 5,453
  • 2
  • 19
  • 33
0
private void removeSoundAndVibration(Notification notification) {
        notification.sound = null;
        notification.vibrate = null;
        notification.defaults &= ~DEFAULT_SOUND;
        notification.defaults &= ~DEFAULT_VIBRATE;

This code is from Notification Compat Api Class. This should work, add all these to your builder.

Bipin
  • 334
  • 2
  • 6
0
   private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(
                CHANNEL_ID,
                "Example Service Channel",
                NotificationManager.IMPORTANCE_MIN
        );
        serviceChannel.setVibrationPattern(new long[]{ 0 });
        serviceChannel.enableVibration(true);
        serviceChannel.enableLights(false);
        serviceChannel.setSound(null, null);
        serviceChannel.setShowBadge(false); // 
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }

If you make IMPORTANCE_MIN that you can disabled vibration, if you make IMPORTANCE_DEFAULT it happens vibration so you can try IMPORTANCE_MIN

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 04 '22 at 00:58
0

July 2022: I have tried everything in this thread, and the only thing that worked was Zhar's suggestion to set importance to low:

int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);

I am targeting Android API level 24.

Tumbleweed53
  • 1,491
  • 7
  • 13
0

setVibrate(new long[0]) works if you're targetting API 28. I'm working with chinese smartwatches running smartphone android roms so in the rest of the devices should work fine. Hope it helps!