- Respects Scoped Storage(MediaStore is used)
- Available as an Activity and a Dialog
- Options to pick alarm sound, notification sound, ringtone sound, and external ringtones.
- Ringtone preview
- An interface to set a default entry
- An interface to add custom ringtone entries
- Sorted external ringtones with artists, albums and folders
- Automatically remembers which external ringtones users have picked
- Multi-select
- Dark theme support out of box
- Permissions are handled internally
- Storage Access Framework support
The library is inspired by AOSP DeskClock RingtonePickerActivity.
Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.DeweyReed:UltimateRingtonePicker:3.2.0'
}
Demo APK and examples in the MainActivity.
Add <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
or <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
when targeting Android
13 to your Manifest if you are not going to use Storage Access Framework.
val settings = UltimateRingtonePicker.Settings(
systemRingtonePicker = UltimateRingtonePicker.SystemRingtonePicker(
customSection = UltimateRingtonePicker.SystemRingtonePicker.CustomSection(),
defaultSection = UltimateRingtonePicker.SystemRingtonePicker.DefaultSection(),
ringtoneTypes = listOf(
RingtoneManager.TYPE_RINGTONE,
RingtoneManager.TYPE_NOTIFICATION,
RingtoneManager.TYPE_ALARM
)
),
deviceRingtonePicker = UltimateRingtonePicker.DeviceRingtonePicker(
deviceRingtoneTypes = listOf(
UltimateRingtonePicker.RingtoneCategoryType.All,
UltimateRingtonePicker.RingtoneCategoryType.Artist,
UltimateRingtonePicker.RingtoneCategoryType.Album,
UltimateRingtonePicker.RingtoneCategoryType.Folder
)
)
)
-
Launch the Activity picker
-
Add the Activity to the manifest.
<activity android:name="xyz.aprildown.ultimateringtonepicker.RingtonePickerActivity" />
-
Register Activity Result callback
rivate val ringtoneLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK && it.data != null) { val ringtones = RingtonePickerActivity.getPickerResult(data) } }
-
Start Activity
ringtoneLauncher.launch( RingtonePickerActivity.getIntent( context = this, settings = settings, windowTitle = "Activity Picker" ) )
-
-
Launch the dialog picker
-
Show the dialog
RingtonePickerDialog.createInstance( settings = settings, dialogTitle = "Dialog!" ).show(supportFragmentManager, null)
-
Get the result
Implement
UltimateRingtonePicker.RingtonePickerListener
in your activity or fragment.override fun onRingtonePicked(ringtones: List<UltimateRingtonePicker.RingtoneEntry>) { }
Alternatively, you can launch the dialog and get the result without implementing the interface, but the dialog will be dismissed in
onPause
:RingtonePickerDialog.createEphemeralInstance( settings = settings, dialogTitle = "Dialog", listener = object : UltimateRingtonePicker.RingtonePickerListener { override fun onRingtonePicked(ringtones: List<UltimateRingtonePicker.RingtoneEntry>) { } } ).show(supportFragmentManager, null)
-
UltimateRingtonePicker
supports activity pick RingtonePickerActivity
and dialog pick RingtonePickerDialog
out of the box. Both of them are just wrappers of RingtonePickerFragment
. Therefore, you can directly wrap RingtonePickerFragment
into your activity/fragment to provide more customization!