Skip to content

Latest commit

 

History

History
180 lines (138 loc) · 5.97 KB

README.md

File metadata and controls

180 lines (138 loc) · 5.97 KB

UltimateRingtonePicker

Pick ringtone, notification, alarm sound and ringtone files from external storage with an activity or a dialog


Features

  • 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.

Screenshot

Activity Dialog Dark

Gradle Dependency

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

The Newest Version

dependencies {
    implementation 'com.github.DeweyReed:UltimateRingtonePicker:3.2.0'
}

Usage

Demo APK and examples in the MainActivity.

0. Add Permission

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.

1. Create an UltimateRingtonePicker.Settings

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
        )
    )
)

2. Launch the picker

  • Launch the Activity picker

    1. Add the Activity to the manifest.

      <activity android:name="xyz.aprildown.ultimateringtonepicker.RingtonePickerActivity" />

    2. Register Activity Result callback

      rivate val ringtoneLauncher =
          registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
              if (it.resultCode == Activity.RESULT_OK && it.data != null) {
                  val ringtones = RingtonePickerActivity.getPickerResult(data)
              }
          }
    3. Start Activity

      ringtoneLauncher.launch(
          RingtonePickerActivity.getIntent(
              context = this,
              settings = settings,
              windowTitle = "Activity Picker"
          )
      )
  • Launch the dialog picker

    1. Show the dialog

      RingtonePickerDialog.createInstance(
          settings = settings,
          dialogTitle = "Dialog!"
      ).show(supportFragmentManager, null)
    2. 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)

BTW

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!

License

MIT License