Search code examples
androidnotificationsandroid-serviceandroid-notificationsforeground-service

Prevent notifications from sounding or vibrating


I use startForeground to make my service persistent. Thus, I must build a notification to pass it to the startForeground function.

I want to start that foreground service without letting the notification make an alert (i.e. with vibration or sound).

For android 8 devices, I create a notification channel before calling the startForeground. I set the importance to NotificationManager.IMPORTANCE_NONE to avoid notification alerts (just to make the icon appear on the status bar).

However, on some devices, I still have a notification alert (for Samsung Galaxy S8 and Honor View 10).

So, I tested this approved answer https://stackoverflow.com/a/24008765/10069542.
This worked fine for the Samsung Galaxy S8. Nonetheless, the Honor View 10 still emits an alert when I start my foreground service.

Here is the code to create my notification channel and to build the notification to be passed to startForeground

Notification channel

@RequiresApi(api = Build.VERSION_CODES.O)
    private String createNotificationChannel() {
        String channelId = NOTIFICATION_CHANNEL_ID;
        String channelName = "My Background Service";
        NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (service != null) {
            service.createNotificationChannel(chan);
        } else {
            Log.e(TAG, "Error creating notification channel");
            return null;
        }

        return channelId;
    }

Notification

private Notification getNotification() {
        Intent startIntent = new Intent(getApplicationContext(), RangoActivity.class);
        startIntent.setAction(Intent.ACTION_MAIN);
        startIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        PendingIntent contentIntent = PendingIntent.getActivity(
                this, REQ_CODE_REQUEST_RANGO_SERVICE, startIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        Notification.Builder builder;
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID);
        } else {
            builder = new Notification.Builder(this);
        }
        builder.setSmallIcon(R.drawable.rango_notification_icon)
                .setContentTitle(getString(R.string.notification_content_title))
                .setContentText(getString(R.string.notification_content_text))
                .setTicker(getString(R.string.notification_ticker))
                .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
                .setVibrate(new long[]{0L})
                .setWhen(System.currentTimeMillis())
                .setOngoing(true)
                .setAutoCancel(true)
                .setContentIntent(contentIntent);

        Notification notification = builder.build();

        return notification;
    }

Solution

  • Here is a NotificationHelper class that supports Android 8+. Use "getNotificationLow" for no sound. For init use this: notificationHelper = new NotificationHelper(context); To show a notification use the methods below:

    public Notification.Builder createNotification( String title, String description, int priority ) {
    
            if (notificationHelper == null) {
                return null;
            } else
            {
                if ( priority == Notification.PRIORITY_HIGH ) {
                    return notificationHelper.getNotificationHigh( title, description );
                } else if ( priority == Notification.PRIORITY_LOW ) {
                    return notificationHelper.getNotificationLow( title, description );
                } else {
                    return notificationHelper.getNotificationDefault( title, description );
                }
            }
        }
    
        public void cancelNotification(int notification_id) {
            if ( notificationHelper != null )
            {
                notificationHelper.cancel( notification_id );
            }
        }
    
        public void showNotification(int notification_id, String title, String description, int priority) {
            if ( notificationHelper != null )
            {
                notificationHelper.notify( notification_id, createNotification(title, description, priority) );
            }
        }
    

    Here is the Helper class

    package com.example.myApp;
    
    import android.annotation.TargetApi;
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.content.Context;
    import android.graphics.BitmapFactory;
    import android.graphics.Color;
    import android.os.Build;
    
    @TargetApi( Build.VERSION_CODES.O )
    public class NotificationHelper
    {
        private NotificationManager notifManager;
        private static final String CHANNEL_HIGH_ID = "com.example.myApp.high";
        private static final String CHANNEL_HIGH_NAME = "myexample (high)";
        private static final String CHANNEL_DEFAULT_ID = "com.example.myApp.default";
        private static final String CHANNEL_DEFAULT_NAME = "myexample (default)";
        private static final String CHANNEL_LOW_NAME = "myexample (low)";
        private static final String CHANNEL_LOW_ID = "com.example.myApp.low";
        private Context mContext;
    
        public NotificationHelper(Context context)
        {
            super();
            mContext = context;
            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
                createChannels();
            }
        }
    
    
        public void createChannels() {
    
            NotificationChannel notificationChannel =
                    new NotificationChannel(CHANNEL_HIGH_ID, CHANNEL_HIGH_NAME, NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.enableLights(true);
            notificationChannel.enableVibration(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.setShowBadge(true);
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            getManager().createNotificationChannel(notificationChannel);
    
            NotificationChannel notificationChannel2 =
                    new NotificationChannel(CHANNEL_DEFAULT_ID, CHANNEL_DEFAULT_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            notificationChannel2.enableLights(true);
            notificationChannel2.enableVibration(true);
            notificationChannel2.setLightColor(Color.RED);
            notificationChannel2.setShowBadge(true);
            notificationChannel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            getManager().createNotificationChannel(notificationChannel2);
    
            NotificationChannel notificationChannel3 =
                    new NotificationChannel(CHANNEL_LOW_ID, CHANNEL_LOW_NAME, NotificationManager.IMPORTANCE_LOW);
            notificationChannel3.enableLights(false);
            notificationChannel3.enableVibration(false);
            notificationChannel3.setLightColor(Color.RED);
            notificationChannel3.setShowBadge(false);
            notificationChannel3.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            getManager().createNotificationChannel(notificationChannel3);
    
        }
    
        public Notification.Builder getNotificationHigh(String title, String body) {
    
            Notification.Builder builder;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
                builder = new Notification.Builder( mContext, CHANNEL_HIGH_ID );
            } else {
                builder = new Notification.Builder( mContext );
                builder.setPriority( Notification.PRIORITY_HIGH );
            }
            builder.setContentTitle(title);
            builder.setContentText(body);
            builder.setAutoCancel( true );
            builder.setSmallIcon(R.mipmap.ic_launcher_bw);
            builder.setLargeIcon( BitmapFactory.decodeResource( mContext.getResources(), R.mipmap.ic_launcher ));
            builder.build();
            return builder;
        }
    
        public Notification.Builder getNotificationDefault(String title, String body) {
            Notification.Builder builder;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
                builder = new Notification.Builder( mContext, CHANNEL_DEFAULT_ID );
            } else {
                builder = new Notification.Builder( mContext );
                builder.setPriority( Notification.PRIORITY_DEFAULT );
            }
            builder.setContentTitle(title);
            builder.setContentText(body);
            builder.setAutoCancel( true );
            builder.setSmallIcon(R.mipmap.ic_launcher_bw);
            builder.setLargeIcon( BitmapFactory.decodeResource( mContext.getResources(), R.mipmap.ic_launcher ));
            builder.build();
            return builder;
        }
    
    
        public Notification.Builder getNotificationLow(String title, String body) {
            Notification.Builder builder;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
                builder = new Notification.Builder( mContext, CHANNEL_LOW_ID );
            } else {
                builder = new Notification.Builder( mContext );
                builder.setPriority( Notification.PRIORITY_LOW );
            }
            builder.setContentTitle(title);
            builder.setContentText(body);
            builder.setAutoCancel( true );
            builder.setSmallIcon(R.mipmap.ic_launcher_bw);
            builder.setLargeIcon( BitmapFactory.decodeResource( mContext.getResources(), R.mipmap.ic_launcher ));
            builder.build();
            return builder;
        }
    
    
        public void notify(int id, Notification.Builder notification) {
            getManager().notify(id, notification.build());
        }
    
        public void cancel(int id) {
            getManager().cancel(id);
        }
    
        private NotificationManager getManager() {
            if (notifManager == null) {
                notifManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            }
            return notifManager;
        }
    }