ภาพรวม
ตัวอย่างนี้สาธิตการเปิด Ringtone Picker ของระบบเพื่อให้ผู้ใช้เลือกเสียงแจ้งเตือนจากรายการที่มีอยู่ (System Ringtones + Custom Ringtones)
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project
ขั้นตอนที่ 2: 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">
<Button
android:onClick="setRingtone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="set ringtone" />
<Button
android:onClick="createNotification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="16dp"
android:text="Create notification" />
</RelativeLayout>
ขั้นตอนที่ 3: MainActivity - เปิด Ringtone Picker
package app.tutorialspoint.com.notifyme;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private final static String default_notification_channel_id = "default";
private String chosenRingtone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onNewIntent(getIntent());
}
// เปิด System Ringtone Picker
public void setRingtone(View view) {
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
// ประเภทเสียง: TYPE_RINGTONE, TYPE_NOTIFICATION, TYPE_ALARM, TYPE_ALL
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
// หัวข้อ Dialog
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Notification Tone");
// เสียงปัจจุบัน (null = ไม่มีการเลือก)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
// ไม่แสดงตัวเลือก "Default" (optional)
// intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
// ไม่แสดงตัวเลือก "Silent" (optional)
// intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
startActivityForResult(intent, 5); // Request code = 5
}
public void createNotification(View view) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(MainActivity.this, default_notification_channel_id);
mBuilder.setContentTitle("Notify Me");
mBuilder.setContentText("Something important!");
mBuilder.setSmallIcon(R.drawable.ic_launcher_foreground);
mBuilder.setAutoCancel(true);
// ใช้เสียงที่เลือก
if (chosenRingtone != null) {
mBuilder.setSound(Uri.parse(chosenRingtone));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
if (chosenRingtone != null) {
notificationChannel.setSound(Uri.parse(chosenRingtone), null);
}
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
assert mNotificationManager != null;
mNotificationManager.createNotificationChannel(notificationChannel);
}
assert mNotificationManager != null;
mNotificationManager.notify((int) System.currentTimeMillis(), mBuilder.build());
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == 5) {
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (uri != null) {
this.chosenRingtone = uri.toString();
Toast.makeText(this, "Selected: " + uri.getLastPathSegment(), Toast.LENGTH_SHORT).show();
} else {
this.chosenRingtone = null;
Toast.makeText(this, "Default tone selected", Toast.LENGTH_SHORT).show();
}
}
}
}
ขั้นตอนที่ 4: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.tutorialspoint.com.notifyme">
<uses-permission android:name="android.permission.VIBRATE" />
<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>
RingtoneManager EXTRA Parameters
| Extra Key | ประเภท | คำอธิบาย |
|---|---|---|
| EXTRA_RINGTONE_TYPE | int | TYPE_RINGTONE(1), TYPE_NOTIFICATION(2), TYPE_ALARM(4), TYPE_ALL(-1) |
| EXTRA_RINGTONE_TITLE | String | หัวข้อ Dialog Picker |
| EXTRA_RINGTONE_EXISTING_URI | Uri | URI เสียงที่เลือกอยู่ (สำหรับ Pre-select) |
| EXTRA_RINGTONE_SHOW_DEFAULT | boolean | แสดงตัวเลือก "Default" (default: true) |
| EXTRA_RINGTONE_SHOW_SILENT | boolean | แสดงตัวเลือก "Silent" (default: true) |
| EXTRA_RINGTONE_PICKED_URI | Uri (Result) | URI ที่ผู้ใช้เลือก (ใน onActivityResult) |
Ringtone Type Constants
// ใน RingtoneManager public static final int TYPE_RINGTONE = 1; // เสียงโทรเข้า public static final int TYPE_NOTIFICATION = 2; // เสียงแจ้งเตือน (Notification) public static final int TYPE_ALARM = 4; // เสียงนาฬิกาปลุก public static final int TYPE_ALL = -1; // ทั้งหมดรวมกัน // ใช้รวมได้ (Bitwise OR) // TYPE_RINGTONE | TYPE_NOTIFICATION = 3 (โทร + แจ้งเตือน)
การใช้งานขั้นสูง
1. Pre-select เสียงปัจจุบัน
// ดึงเสียงปัจจุบันจาก Settings Uri currentTone = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION); Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentTone); // Pre-select startActivityForResult(intent, REQUEST_CODE);
2. Custom Ringtone Picker (สร้างเอง)
หากต้องการ UI เฉพาะตัว ใช้ RingtoneManager.getRingtone() และสร้าง ListView/RecyclerView เอง
// ดึงรายการ Ringtone ทั้งหมด
RingtoneManager manager = new RingtoneManager(this);
manager.setType(RingtoneManager.TYPE_NOTIFICATION);
Cursor cursor = manager.getCursor();
while (cursor.moveToNext()) {
String title = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX);
Uri uri = manager.getRingtoneUri(cursor.getPosition());
// เพิ่มลงใน Adapter
}
3. ใช้กับ Notification Channel (Android 8.0+)
// บันทึก URI ที่เลือกไว้ใน SharedPreferences
SharedPreferences prefs = getSharedPreferences("notification_prefs", MODE_PRIVATE);
prefs.edit().putString("ringtone_uri", chosenRingtone).apply();
// ตอนสร้าง Channel อ่านค่ามาใช้
String savedUri = prefs.getString("ringtone_uri", null);
if (savedUri != null) {
channel.setSound(Uri.parse(savedUri), new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build());
}
ข้อควรระวัง
- Request Code: ใช้ค่าที่ไม่ซ้ำกันในแอป (ในตัวอย่างใช้ 5)
- onActivityResult Deprecated: Android 13+ (API 33+) ควรใช้
ActivityResultContractsแทน - Emulator: อาจไม่มี Ringtone ให้เลือก ต้องทดสอบบนอุปกรณ์จริง
- OEM Customization: Samsung, Xiaomi, Oppo อาจมี Ringtone Picker UI ต่างจาก Stock Android
- Permission: ไม่ต้องการ Permission เพิ่มเติมสำหรับ Ringtone Picker
Modern API (Android 13+ / API 33+)
// ใช้ ActivityResultLauncher แทน startActivityForResult ActivityResultLauncherringtonePickerLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { Uri uri = result.getData().getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); // Handle URI } } ); // เรียกใช้ Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); // ... putExtras ... ringtonePickerLauncher.launch(intent);