11

My app's main functionality is push-notification messages sent from remote server. I am using FCM as a message delivery service. My problem is that notifications come without any sound on Xiaomi Mi 9 Lite (Android 9/MIUI 11). However, on Xiaomi Redmi Note 5 (Android 9/MIUI 10) sound works fine and on Samsung Galaxy S7 Edge (Android 8) as well. I created MessagingService which extends FirebaseMessagingService and notification channel as written in documentation.

Here is my code:

public class MessagingService extends FirebaseMessagingService {

    private static String channelId;
    private NotificationManager notificationManager;
    private NotificationChannel notificationChannel;
    private NotificationCompat.Builder notificationBuilder;

    private MessagesViewModel viewModel;

    public MessagingService() { }

    @Override
    public void onCreate() {
        super.onCreate();
        channelId = getResources().getString(R.string.default_notification_channel_id);
        notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

        final Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        notificationBuilder = new NotificationCompat.Builder(this, channelId);
        notificationBuilder.setSmallIcon(R.raw.metrial_message_icon);
        notificationBuilder.setAutoCancel(false);
        notificationBuilder.setSound(soundUri);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            final AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build();

            String name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_HIGH;
            notificationChannel = new NotificationChannel(channelId, name, importance);
            notificationChannel.setDescription(description);
            notificationChannel.enableLights(true);
            notificationChannel.setShowBadge(true);
            notificationChannel.setSound(soundUri, audioAttributes);
            notificationManager.createNotificationChannel(notificationChannel);
            notificationBuilder.setChannelId(channelId);
        }
        else {
            notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
            notificationBuilder.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL);
            notificationBuilder.setLights(Color.WHITE, 500, 5000);
        }

        viewModel = new MessagesViewModel(getApplication());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onNewToken(@NonNull String s) {
        super.onNewToken(s);
        logger.info("onNewToken()");
        ConnectionParameters.getInstance().setToken(s);
        MyPrefs.getInstance(getApplicationContext()).putString(Constants.TOKEN, s);
    }

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        final String messageId = remoteMessage.getData().get("message_id");
        final String title = remoteMessage.getData().get("title");
        final String body = remoteMessage.getData().get("body");

        if (messageId != null && title != null && body != null) {

            final Message message = new Message();
            message.setMessageId(messageId);
            message.setTitle(title);
            message.setContent(body);
            message.setTimestamp(new Date());

            try {
                message.setNotificationId((int)viewModel.insert(message));
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }

            logger.info("onMessageReceived(): notificationId=" + message);

            if (MyPrefs.getInstance(getApplicationContext()).getBoolean(Constants.ENABLE_PUSH)) {
                notificationBuilder.setContentTitle(title);
                notificationBuilder.setContentText(body);

                final Intent notifyIntent = new Intent(this, MessageInfoActivity.class);
                notifyIntent.putExtra(Constants.ARG_MESSAGE_OBJECT, message);
                TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
                stackBuilder.addNextIntentWithParentStack(notifyIntent);
                PendingIntent pendingActivityIntent =
                        stackBuilder.getPendingIntent(message.getNotificationId(), PendingIntent.FLAG_UPDATE_CURRENT);
                notificationBuilder.setContentIntent(pendingActivityIntent);

                final Notification notification = notificationBuilder.build();
                notification.defaults = Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS;
                notificationManager.notify(message.getNotificationId(), notification);
            }
        }
    }

    private final Logger logger = LoggerFactory.getLogger(getClass());
}

And in Settings->Notifications I got the following parameters: enter image description here

And inside my push-notifications-channel sound is enabled but whenever a message comes, it seems like app notification settings override parameters in notification channel. enter image description here

There should be some solution because in popular apps such WhatsApp, Telegram, etc., these switches are enabled after installation (by default). Hope, someone helps!

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Sergey Kim
  • 377
  • 1
  • 3
  • 12

1 Answers1

11

As nobody provided better solution, I guess there is no way to allow sound/badge counter/floating notifications programmatically on MIUI (and mostly on other Chinese OEMs). It is a user's privilege to turn these settings on manually. Therefore, to enhance UX, it is important to decrease the quantity of "clicks" as much as possible. So, we could provide a dialog describing how to enable the features above with button leading to App's settings. Namely, to open a notification settings page through Intent, do the following:

final Intent notificationSettingsIntent = new Intent();
notificationSettingsIntent
        .setAction("android.settings.APP_NOTIFICATION_SETTINGS");
notificationSettingsIntent
        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    notificationSettingsIntent.putExtra(
            "android.provider.extra.APP_PACKAGE",
            activity.getPackageName());
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        notificationSettingsIntent.putExtra(
                "app_package",
                activity.getPackageName());
        notificationSettingsIntent.putExtra(
                "app_uid", 
                activity.getApplicationInfo().uid);
}
activity.startActivityForResult(
        notificationSettingsIntent, 
        NOTIFICATIONS_SETTINGS_REQUEST_CODE);

and you could open a dialog with button "Open notification settings" clicking on which triggers the code snippet above.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Sergey Kim
  • 377
  • 1
  • 3
  • 12
  • Thanks for your diligence! I could not find other solutions on this issue. – konstantin_doncov Jan 09 '20 at 00:19
  • 3
    @wai Ha Lee is there any way to check permission is on or off because if sound is on then i don't want to open dialog again – Raj Gohel Jun 25 '20 at 06:26
  • Unfortunately, you cannot check whether sound was enabled or not. It is possible to check are notifications enabled for the app, however, as far as I know, no way to get result from sound availability. – Sergey Kim Feb 03 '21 at 10:13