Từ Android 8.0 (Oreo), việc đặt âm thanh cho notification phải thực hiện qua NotificationChannel thay vì trực tiếp trên NotificationCompat.Builder. Bài viết hướng dẫn cấu hình âm thanh tùy chỉnh từ thư mục res/raw/.
Các bước thực hiện
Bước 1: Tạo dự án mới
Tạo dự án Android Studio, package app.tutorialspoint.com.notifyme.
Bước 2: Chuẩn bị file âm thanh
Tạo thư mục res/raw/ (New → Android Resource Directory → raw) và đặt file âm thanh (ví dụ: quite_impressed.mp3) vào đó.
Bước 3: Giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<Button
android:id="@+id/btnCreateNotification"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Tạo thông báo có âm thanh tùy chỉnh"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Bước 4: Cấu hình Channel với âm thanh tùy chỉnh (src/MainActivity.java)
package app.tutorialspoint.com.notifyme;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Bundle;
import androidx.core.app.NotificationCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private static final String DEFAULT_CHANNEL_ID = "default";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnCreateNotification = findViewById(R.id.btnCreateNotification);
btnCreateNotification.setOnClickListener(v -> createNotificationWithCustomSound());
}
private void createNotificationWithCustomSound() {
// URI trỏ đến file trong res/raw/
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ getPackageName() + "/raw/quite_impressed.mp3");
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Thông báo tùy chỉnh âm thanh")
.setContentText("Hello! Đây là notification với âm thanh từ res/raw")
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
// Cấu hình AudioAttributes cho kênh
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION) // Hoặc USAGE_ALARM
.build();
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "Kênh âm thanh tùy chỉnh", importance);
// Cài đặt âm thanh cho CHANNEL (không phải cho builder)
channel.setSound(soundUri, audioAttributes);
// Tùy chọn: đèn LED, rung
channel.enableLights(true);
channel.setLightColor(Color.BLUE);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{0, 200, 100, 200});
manager.createNotificationChannel(channel);
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
} else {
// Pre-Oreo: setSound trực tiếp trên Builder vẫn hoạt động
builder.setSound(soundUri);
}
int notificationId = (int) System.currentTimeMillis();
manager.notify(notificationId, builder.build());
}
}
Bước 5: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.tutorialspoint.com.notifyme">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Lưu ý quan trọng về Android Oreo+
| Trước API 26 | Từ API 26 (Oreo) |
|---|---|
builder.setSound(uri) | channel.setSound(uri, audioAttributes) |
builder.setVibrate(pattern) | channel.setVibrationPattern(pattern) |
builder.setLights(...) | channel.enableLights(true); channel.setLightColor(color) |
| Không cần Channel | Bắt buộc tạo NotificationChannel |
Quan trọng: Sau khi Channel được tạo lần đầu, việc thay đổi sound/vibration/light trên code không có tác dụng trừ khi user tự đổi trong cài đặt hoặc bạn xóa app/cài lại. Để test thay đổi, hãy gỡ app và cài lại.
Các định dạng âm thanh hỗ trợ
- MP3, WAV, OGG, M4A (đặt trong
res/raw/) - Không hỗ trợ streaming từ URL trực tiếp trên Channel (dùng MediaPlayer riêng nếu cần)
- Độ dài khuyến nghị: < 30 giây cho notification sound