Android - Turn off vibration for 'Sign in to WiFi network' notification

There is a workaround involving Do not disturb's Priority only mode.

To put it simply, you must use Priority only (from Quick Settings - Do not disturb) since it has per-app setting for notification alert that can overwrite system's default setting. Priority only mode will still show all notifications. However, only priority notifications will be alerted (sound, vibration and LED light).

The idea is to treat all notifications as priority (from Settings - Sound & notification - App notifications - [app name] - Treat as priority) except for captive portal notification, which is under Android System app (by default, system apps are not listed. You need to tick Show system from overflow menu. Leave this app as non-priority, but don't forget for the rest of system apps).

However, there are some disadvantages that you might consider first before using this workaround:

  1. You sacrifice the intended usage of Priority only mode, only leave Total silence as the only option (however, if you never intend to use this feature, then you're fortunate since you can utilize it).
  2. If you have many apps installed, it's quite tedious to set all apps to treat their notifications as priority (perhaps a script might help...). Also, every time you install a new app, you must not forget to treat its notification as priority (unless you don't care about its alert).
  3. You won't get any alerts for all notifications from Android System (you need to experiment with this, since I don't know what notifications are considered by Android System).

TL;DR

If you still want to have vibration on all notifications except for captive portal (this particular issue), I'm afraid you can't.

It's as dbasch mentioned in the comment, that the vibration (actually, the notification alert itself) was added in Marshmallow.


Technical Details

When Android detects that the WiFi needs to login to captive portal, as you already noticed, it will create a notification. It's done by setProvNotificationVisibleIntent() function in ConnectivityService.

Show or hide network provisioning notifications.

We use notifications for two purposes: to notify that a network requires sign in (NotificationType.SIGN_IN), or to notify that a network does not have Internet access (NotificationType.NO_INTERNET). We display at most one notification per ID, so on a particular network we can display the notification type that was most recently requested. So for example if a captive portal fails to reply within a few seconds of connecting, we might first display NO_INTERNET, and then when the captive portal check completes, display SIGN_IN.

The relevant code to the notification alert that is used in Android 6.0 Marshmallow:

Notification notification = new Notification.Builder(mContext)
    ...
    .setDefaults(Notification.DEFAULT_ALL)
    ...

Note that Notification.DEFAULT_ALL will "use all default values (where applicable)", which means that it depends on your system's notification setting (sound, vibration, and LED light).

Compared to the one in Android 5.x Lollipop, the code is:

Notification notification = new Notification();
...

No more, no less. That's the relevant code. new Notification() will "construct a Notification object with default values". While it seems that there's no change in the meaning, note that defaults is not set/initialized to Notification.DEFAULT_ALL (value: -1). Instead, since there's no initialization, it will be defaulted to 0, which is no alert.

Whether it's a bug overlooked by Google which has been fixed in Marshmallow or not, I don't know. Also, that's the reason why there's no alert in Android Lollipop, but now there is in Android Marshmallow.