Giới thiệu
Hướng dẫn này minh họa cách mở trình chọn chuông báo (Ringtone Picker) của hệ thống và đặt chuông báo mặc định từ Activity Android sử dụng RingtoneManager và Kotlin.
Các bước thực hiện
Bước 1: Tạo dự án mới
Tạo project: File → New Project.
Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Tutorials Point"
android:textAlignment="center"
android:textColor="@android:color/holo_green_dark"
android:textSize="32sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnSelRingtone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Select Ringtone" />
<TextView
android:id="@+id/tvRingtone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btnSelRingtone"
android:layout_centerInParent="true"
android:text="Ringtone Path"
android:textStyle="bold|italic" />
</RelativeLayout>
Bước 3: Xử lý logic (src/MainActivity.kt)
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var btn: Button
private lateinit var txtView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
btn = findViewById(R.id.btnSelRingtone)
txtView = findViewById(R.id.tvRingtone)
btn.setOnClickListener {
// Lấy chuông báo mặc định hiện tại (TYPE_ALARM làm ví dụ)
val currentRingtone: Uri = RingtoneManager.getActualDefaultRingtoneUri(
this,
RingtoneManager.TYPE_ALARM
)
// Tạo intent mở Ringtone Picker
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE)
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone")
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentRingtone)
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
}
startActivityForResult(intent, 999)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 999 && resultCode == RESULT_OK) {
val uri = data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
uri?.let {
txtView.text = "Selected: ${it.path}"
// Để đặt làm chuông báo mặc định thực sự:
// RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, it)
}
}
}
}
Bước 4: Cấu hình Manifest (androidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.q1">
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<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>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Nhấn nút "Select Ringtone" sẽ mở hệ thống chọn chuông. Sau khi chọn, đường dẫn file sẽ hiển thị trên TextView.
Các loại Ringtone (TYPE_*)
TYPE_RINGTONE: Chuông gọi đếnTYPE_NOTIFICATION: Thông báoTYPE_ALARM: Báo thứcTYPE_ALL: Tất cả
Lưu ý quan trọng (Android 10+)
- Quyền
WRITE_SETTINGSlà special permission, cần user cấp qua Settings → Special app access → Modify system settings. - Từ Android 10, app không thể tự đặt ringtone mặc định toàn cục mà chỉ có thể gợi ý. User phải xác nhận trong system picker.
- Để đặt ringtone cho contact cụ thể, dùng
ContactsContract.Contacts.CUSTOM_RINGTONE.
Đặt ringtone mặc định thực sự (cần WRITE_SETTINGS)
fun setDefaultRingtone(uri: Uri, type: Int = RingtoneManager.TYPE_RINGTONE) {
RingtoneManager.setActualDefaultRingtoneUri(this, type, uri)
}