All Collections
Push Notifications
Android
How can I use a custom notification sound on Android?
How can I use a custom notification sound on Android?
Arnaud avatar
Written by Arnaud
Updated over a week ago

On Android 8.0 and higher, notification sounds are managed using Notification Channels. Users can reconfigure those channels: while you are in control of the default settings (sound played if any, importance, ...), users can change them at any time and the system will honour those settings.

Batch automatically registers a default channel when displaying the first notification if no channel override has been set. This channel's sound cannot be changed: developers will need to implement their own channel to do so.

You must tell the system about your notification channels before sending notifications by registering them: your Application's startup phase is a good place to do it. Then, tell Batch about it either by overriding the default channel or by using a NotificationChannelIdInterceptor.

Note: Once a channel has been created, it cannot be updated by the application. If you want to change your notification sound with another resource, you will have to create another channel. During development, try uninstalling and reinstalling your app if you don't notice a change after you've updated your code.

Changing the default sound

In order to change the default sound, you will need to:

Implementing multiple sounds depending on the notification payload

To do so, you will have to:

Backwards compatibility

As Notification Channels did not exist on versions earlier than Android 8.0, you will have to implement a Notification Interceptor to change the notification sound.


Code example

This code implements multiple possible sounds controlled by a custom payload:

  • A custom payload of {“channel": "win"} plays "sound_win" from raw resources

  • {“channel": "defeat"} plays "sound_defeat" from raw resources

  • Anything else falls back on Batch's default channel

This snippet works on Android 4.1 and higher by implementing a notification interceptor for devices that don't support channels.

public class MyApplication extends Application {
public static final String CHANNEL_WIN = "win";
public static final String CHANNEL_DEFEAT = "defeat";

public static final String SOUND_RESOURCE_WIN = "sound_win";
public static final String SOUND_RESOURCE_DEFEAT = "sound_defeat";

@Override
public void onCreate() {
super.onCreate();
// This code should be in your Application subclass' onCreate, not in your Activity's! It is required so that Batch can call your interceptor while your app is in the background
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setupNotificationChannels(this);
setupBatchChannelInterceptor();
} else {
setupLegacyBatchSoundInterceptor();
}
}

@RequiresApi(api = Build.VERSION_CODES.O)
private void setupNotificationChannels(@NonNull Context context) {
// This sample assumes that your sounds are named "sound_win"/"sound_defeat"
// and placed in the "raw" resource folder.

AudioAttributes soundAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();

@SuppressLint("WrongConstant")
NotificationChannel winChannel = new NotificationChannel(
CHANNEL_WIN,
"Win notifications",
NotificationManager.IMPORTANCE_DEFAULT);
winChannel.setSound(getUriForSoundName(context, SOUND_RESOURCE_WIN), soundAttributes);

@SuppressLint("WrongConstant")
NotificationChannel defeatChannel = new NotificationChannel(
CHANNEL_DEFEAT,
"Defeat notifications",
NotificationManager.IMPORTANCE_DEFAULT);
defeatChannel.setSound(getUriForSoundName(context, SOUND_RESOURCE_DEFEAT), soundAttributes);

NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(winChannel);
notificationManager.createNotificationChannel(defeatChannel);
}

@NonNull
private Uri getUriForSoundName(@NonNull Context context, @NonNull String soundName) {
return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName()
+ "/raw/" + soundName);
}

private void setupBatchChannelInterceptor() {
Batch.Push.getChannelsManager().setChannelIdInterceptor((payload, deductedChannelId) -> {
// custom payload: {"channel":"win"}/{"channel":"defeat"}
String channel = payload.getPushBundle().getString("channel");
switch (channel) {
case "win":
return CHANNEL_WIN;
case "defeat":
return CHANNEL_DEFEAT;
}
return deductedChannelId;
});
}

private void setupLegacyBatchSoundInterceptor() {
Batch.Push.setNotificationInterceptor(new BatchNotificationInterceptor() {
@Override
public NotificationCompat.Builder getPushNotificationCompatBuilder(@NonNull Context context,
@NonNull NotificationCompat.Builder defaultBuilder,
@NonNull Bundle pushIntentExtras,
int notificationId) {
String sound = pushIntentExtras.getString("channel", null);
Uri soundUri = null;

switch (sound) {
case "win":
soundUri = getUriForSoundName(context, SOUND_RESOURCE_WIN);
break;
case "defeat":
soundUri = getUriForSoundName(context, SOUND_RESOURCE_DEFEAT);
break;
}

if (soundUri != null) {
defaultBuilder.setSound(soundUri);
}
return defaultBuilder;
}
});
}
}


This article belongs to Batch's FAQ. Need more help? Find insightful articles, documentation, case & market studies, guides, and even more in our website's Resources section on batch.com and our blog.

Did this answer your question?