{"id":13477796,"url":"https://github.com/DeweyReed/UltimateRingtonePicker","last_synced_at":"2025-03-27T06:30:52.954Z","repository":{"id":45904402,"uuid":"148866812","full_name":"DeweyReed/UltimateRingtonePicker","owner":"DeweyReed","description":"An Android music picker library for picking alarm, notification or ringtones sound using an Activity or a dialog.","archived":false,"fork":false,"pushed_at":"2024-04-13T23:45:10.000Z","size":1024,"stargazers_count":62,"open_issues_count":2,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-30T10:41:25.223Z","etag":null,"topics":["android","android-library","android-pickerdialog","android-pickers","music-library","picker","ringtone-picker"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DeweyReed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-15T03:44:11.000Z","updated_at":"2024-09-21T11:39:24.000Z","dependencies_parsed_at":"2024-04-19T06:18:27.650Z","dependency_job_id":null,"html_url":"https://github.com/DeweyReed/UltimateRingtonePicker","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeweyReed%2FUltimateRingtonePicker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeweyReed%2FUltimateRingtonePicker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeweyReed%2FUltimateRingtonePicker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeweyReed%2FUltimateRingtonePicker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DeweyReed","download_url":"https://codeload.github.com/DeweyReed/UltimateRingtonePicker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245797261,"owners_count":20673818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","android-pickerdialog","android-pickers","music-library","picker","ringtone-picker"],"created_at":"2024-07-31T16:01:47.694Z","updated_at":"2025-03-27T06:30:52.084Z","avatar_url":"https://github.com/DeweyReed.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./art/ic_launcher-web.webp\" height=\"128\" /\u003e\n\u003c/div\u003e\n\n\u003ch1 align=\"center\"\u003eUltimateRingtonePicker\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003ePick ringtone, notification, alarm sound and ringtone files from external storage with an activity or a dialog\u003c/strong\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://android-arsenal.com/details/1/7141\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Android%20Arsenal-UltimateMusicPicker-green.svg?style=flat\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/DeweyReed/UltimateRingtonePicker/actions/workflows/android.yml\"\u003e\n        \u003cimg src=\"https://github.com/DeweyReed/UltimateRingtonePicker/actions/workflows/android.yml/badge.svg\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://jitpack.io/#com.github.DeweyReed/UltimateRingtonePicker\"\u003e\n        \u003cimg src=\"https://jitpack.io/v/com.github.DeweyReed/UltimateRingtonePicker.svg\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://android-arsenal.com/api?level=14\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat\" border=\"0\" alt=\"API\"\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\n## Features\n\n- Respects Scoped Storage(MediaStore is used)\n- Available as an Activity and a Dialog\n- Options to pick alarm sound, notification sound, ringtone sound, and external ringtones.\n- Ringtone preview\n- An interface to set a default entry\n- An interface to add custom ringtone entries\n- Sorted external ringtones with artists, albums and folders\n- Automatically remembers which external ringtones users have picked\n- Multi-select\n- Dark theme support out of box\n- Permissions are handled internally\n- Storage Access Framework support\n\nThe library is inspired by [AOSP DeskClock RingtonePickerActivity](https://android.googlesource.com/platform/packages/apps/DeskClock/+/refs/heads/master/src/com/android/deskclock/ringtone/RingtonePickerActivity.kt).\n\n## Screenshot\n\n||||\n|:-:|:-:|:-:|\n|![Activity](./art/activity.webp)|![Dialog](./art/dialog.webp)|![Dark](./art/dark.webp)|\n\n## Gradle Dependency\n\nStep 1. Add the JitPack repository to your build file\n\nAdd it in your root build.gradle at the end of repositories:\n\n```Groovy\nallprojects {\n    repositories {\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n\nStep 2. Add the dependency\n\n[![The Newest Version](https://jitpack.io/v/com.github.DeweyReed/UltimateRingtonePicker.svg)](https://jitpack.io/#com.github.DeweyReed/UltimateRingtonePicker)\n\n```Groovy\ndependencies {\n    implementation 'com.github.DeweyReed:UltimateRingtonePicker:3.2.0'\n}\n```\n\n## Usage\n\n[Demo APK](https://github.com/deweyreed/ultimateringtonepicker/releases) and [examples in the MainActivity](./app/src/main/java/xyz/aprildown/ultimateringtonepicker/app/MainActivity.kt).\n\n### 0. Add Permission\n\nAdd `\u003cuses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" /\u003e`\nor `\u003cuses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\" /\u003e` when targeting Android\n13 to your Manifest if you are not going to use Storage Access Framework.\n\n### 1. Create an `UltimateRingtonePicker.Settings`\n\n```Kotlin\nval settings = UltimateRingtonePicker.Settings(\n    systemRingtonePicker = UltimateRingtonePicker.SystemRingtonePicker(\n        customSection = UltimateRingtonePicker.SystemRingtonePicker.CustomSection(),\n        defaultSection = UltimateRingtonePicker.SystemRingtonePicker.DefaultSection(),\n        ringtoneTypes = listOf(\n            RingtoneManager.TYPE_RINGTONE,\n            RingtoneManager.TYPE_NOTIFICATION,\n            RingtoneManager.TYPE_ALARM\n        )\n    ),\n    deviceRingtonePicker = UltimateRingtonePicker.DeviceRingtonePicker(\n        deviceRingtoneTypes = listOf(\n            UltimateRingtonePicker.RingtoneCategoryType.All,\n            UltimateRingtonePicker.RingtoneCategoryType.Artist,\n            UltimateRingtonePicker.RingtoneCategoryType.Album,\n            UltimateRingtonePicker.RingtoneCategoryType.Folder\n        )\n    )\n)\n```\n\n### 2. Launch the picker\n\n- Launch the Activity picker\n\n    1. Add the Activity to the manifest.\n\n       `\u003cactivity android:name=\"xyz.aprildown.ultimateringtonepicker.RingtonePickerActivity\" /\u003e`\n\n    1. Register Activity Result callback\n\n        ```Kotlin\n        rivate val ringtoneLauncher =\n            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {\n                if (it.resultCode == Activity.RESULT_OK \u0026\u0026 it.data != null) {\n                    val ringtones = RingtonePickerActivity.getPickerResult(data)\n                }\n            }\n        ```\n\n    1. Start Activity\n\n        ```Kotlin\n        ringtoneLauncher.launch(\n            RingtonePickerActivity.getIntent(\n                context = this,\n                settings = settings,\n                windowTitle = \"Activity Picker\"\n            )\n        )\n        ```\n\n- Launch the dialog picker\n\n    1. Show the dialog\n\n        ```Kotlin\n        RingtonePickerDialog.createInstance(\n            settings = settings,\n            dialogTitle = \"Dialog!\"\n        ).show(supportFragmentManager, null)\n        ```\n\n    1. Get the result\n\n        Implement `UltimateRingtonePicker.RingtonePickerListener` in your activity or fragment.\n\n        ```Kotlin\n        override fun onRingtonePicked(ringtones: List\u003cUltimateRingtonePicker.RingtoneEntry\u003e) {\n\n        }\n        ```\n\n    Alternatively, you can launch the dialog and get the result without implementing the interface, but the dialog will be dismissed in `onPause`:\n\n    ```Kotlin\n    RingtonePickerDialog.createEphemeralInstance(\n        settings = settings,\n        dialogTitle = \"Dialog\",\n        listener = object : UltimateRingtonePicker.RingtonePickerListener {\n            override fun onRingtonePicked(ringtones: List\u003cUltimateRingtonePicker.RingtoneEntry\u003e) {\n\n            }\n        }\n    ).show(supportFragmentManager, null)\n    ```\n\n## BTW\n\n`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!\n\n## License\n\n[MIT License](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeweyReed%2FUltimateRingtonePicker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDeweyReed%2FUltimateRingtonePicker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDeweyReed%2FUltimateRingtonePicker/lists"}