Custom Notification Sound not working in Android Oreo

前端 未结 6 1669
闹比i
闹比i 2020-12-14 16:44
Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + \"://\" + context.getPackageName() + \"/\" + R.raw.notification_mp3);
            mBuilder.setSound(s         


        
相关标签:
6条回答
  • 2020-12-14 17:26

    This might help the new comers.

    Here is a code for a working notification sample on all android versions with all kinds of possible setups.

    1 -> sound and vibration
    2 -> sound but no vibration
    3 -> no sound but vibration
    4 -> no sound no vibration
    

    OUTPUT

    Github Repo -> https://github.com/usman14/Notification

    CODE

    MainActivity

    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.NotificationCompat;
    import android.annotation.TargetApi;
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.CompoundButton;
    import android.widget.Switch;
    
    public class MainActivity extends AppCompatActivity {
    
        public boolean shouldSound;
        public boolean shouldVibrate;
        NotificationManager notificationManager;
    
        Button button;
        Switch soundSwitch;
        Switch vibrationSwitch;
    
        @TargetApi(Build.VERSION_CODES.O)
        public void registerNormalNotificationChannel(android.app.NotificationManager notificationManager) {
    
            NotificationChannel channel_all = new NotificationChannel("CHANNEL_ID_ALL", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
            channel_all.enableVibration(true);
            notificationManager.createNotificationChannel(channel_all);
    
            NotificationChannel channel_sound = new NotificationChannel("CHANNEL_ID_SOUND", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
            channel_sound.enableVibration(false);
            notificationManager.createNotificationChannel(channel_sound);
    
            NotificationChannel channel_vibrate = new NotificationChannel("CHANNEL_ID_VIBRATE", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
            channel_vibrate.setSound(null, null);
            channel_vibrate.enableVibration(true);
            notificationManager.createNotificationChannel(channel_vibrate);
    
    
            NotificationChannel channel_none = new NotificationChannel("CHANNEL_ID_NONE", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
            channel_none.setSound(null, null);
            channel_none.enableVibration(false);
            notificationManager.createNotificationChannel(channel_none);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            button = findViewById(R.id.btn);
            soundSwitch = findViewById(R.id.switch_sound);
            vibrationSwitch = findViewById(R.id.switch_vibration);
            notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            if (isOreoOrAbove()) {
                setupNotificationChannels();
            }
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    makeNotification();
                }
            });
    
            soundSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                    if (b) {
                        shouldSound = true;
                    } else {
                        shouldSound = false;
                    }
                }
            });
    
            vibrationSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                    if (b) {
                        shouldVibrate = true;
                    } else {
                        shouldVibrate = false;
                    }
                }
            });
        }
    
        private void setupNotificationChannels() {
            registerNormalNotificationChannel(notificationManager);
        }
    
        public void makeNotification() {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this, getChannelId())
                    .setContentTitle("Hi")
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentText("Welcome to Android");
    
            Intent intent = new Intent(MainActivity.this, MainActivity.class);
    
            PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    
            builder.setContentIntent(pendingIntent);
            if (shouldSound && !shouldVibrate) {
                builder.setDefaults(Notification.DEFAULT_SOUND)
                        .setVibrate(new long[]{0L});
            }
            if (shouldVibrate && !shouldSound) {
                builder.setDefaults(Notification.DEFAULT_VIBRATE)
                        .setSound(null);
            }
            if (shouldSound && shouldVibrate) {
                builder.setDefaults(Notification.DEFAULT_ALL);
            }
    
    
            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(0, builder.build());
        }
    
        private String getChannelId() {
            if (shouldSound && shouldVibrate) {
                return "CHANNEL_ID_ALL";
            } else if (shouldSound && !shouldVibrate) {
                return "CHANNEL_ID_SOUND";
            } else if (!shouldSound && shouldVibrate) {
                return "CHANNEL_ID_VIBRATE";
            } else {
                return "CHANNEL_ID_NONE";
            }
        }
    
        private boolean isOreoOrAbove() {
            return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O;
        }
    }
    

    activity_main (xml)

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/sound_layout"
            android:orientation="horizontal"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="SOUND SWITCH"></TextView>
    
    
            <Switch
                android:layout_marginLeft="50dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:id="@+id/switch_sound">
    
            </Switch>
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/vibration_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="horizontal"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/sound_layout">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="VIBRATION SWITCH"></TextView>
    
    
            <Switch
                android:layout_marginLeft="50dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:id="@+id/switch_vibration">
    
            </Switch>
    
        </LinearLayout>
    
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Send Notification"
            android:id="@+id/btn"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/vibration_layout"></Button>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    0 讨论(0)
  • 2020-12-14 17:29

    Android O comes with NotificationChannel use that instead

     int importance = NotificationManager.IMPORTANCE_HIGH;
                NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.RED);
                notificationChannel.enableVibration(true);
                notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                assert mNotificationManager != null;
                mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
                mNotificationManager.createNotificationChannel(notificationChannel);
    
    0 讨论(0)
  • 2020-12-14 17:29
    mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
    

    This line of code is worked for me. But you have to delete old channel and create new one.

    0 讨论(0)
  • 2020-12-14 17:30

    Create a channel (I use this method in Application.clss to create the channel )

      public void initChannels(Context context) {
        if (Build.VERSION.SDK_INT < 26) {
            return;
        }
        NotificationManager notificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel("default"/*CHANNEL ID*/,
                "CHANNEL_NAME",
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("Channel description");
        assert notificationManager != null;
        notificationManager.createNotificationChannel(channel);
    }
    

    And use this channel default while creating instance of NotificationCompat

     .... notificationBuilder = new NotificationCompat.Builder(this,"default") ....
    
    0 讨论(0)
  • 2020-12-14 17:30

    try this:

    /**
     * show notification
     *
     * @param message
     */
    private static void showNotification(RemoteMessage message, Context baseContext) {
        Context context = baseContext.getApplicationContext();
        NotificationManagerCompat managerCompat = NotificationManagerCompat.from(context.getApplicationContext());
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null)
                .setSmallIcon(R.drawable.ic_logo_xxxdpi)
                .setContentTitle(message.getData().get(TITLE))
                .setContentText(message.getData().get(BODY))
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setAutoCancel(true)
                .setVibrate(new long[]{500, 500})
                .setLights(Color.RED, 3000, 3000)
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setContentIntent(getPendingIntent(context, message));
        managerCompat.notify(getRandom(), builder.build());
    }
    
    0 讨论(0)
  • 2020-12-14 17:50

    To set a sound to notifications in Oreo, you must set sound on NotificationChannel and not on Notification Builder itself. You can do this as follows

    Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.notification_mp3);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
            NotificationChannel mChannel = new NotificationChannel("YOUR_CHANNEL_ID",
                "YOUR CHANNEL NAME",
                NotificationManager.IMPORTANCE_DEFAULT)
    
            AudioAttributes attributes = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build();
    
            NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, 
                    context.getString(R.string.app_name),
                    NotificationManager.IMPORTANCE_HIGH);
    
            // Configure the notification channel.
            mChannel.setDescription(msg);
            mChannel.enableLights(true);
            mChannel.enableVibration(true);
            mChannel.setSound(sound, attributes); // This is IMPORTANT
    
    
            if (mNotificationManager != null)
                mNotificationManager.createNotificationChannel(mChannel);
        }
    

    This will set a custom sound to your notifications. But if the app is being updated and the notification channel is used before, it won't be updated. i.e. you need to create a different channel and set sound to it to make it work. But this will show multiple channels in the notifications section of app info of your app. If you are setting sound to an entirely new channel that is fine, but if you want the channel being used before, you have to delete the existing channel and recreate the channel. To do that you can do something like that before creating channel

    if (mNotificationManager != null) {
                List<NotificationChannel> channelList = mNotificationManager.getNotificationChannels();
    
                for (int i = 0; channelList != null && i < channelList.size(); i++) {
                    mNotificationManager.deleteNotificationChannel(channelList.get(i).getId());
                }
            }
    
    0 讨论(0)
提交回复
热议问题