inway / flutter_ringtone_player

Simple Flutter plugin to play ringtone, alarm & notification sounds
MIT License
92 stars 57 forks source link

Not support the default notification or ringtone sound replacement #5

Closed gonft closed 1 year ago

gonft commented 4 years ago

I am currently creating an alarm app using flutter and want to support the user to select the desired alarm sound. I hope this can be supported via the setActualDefaultRingtoneUri method.

Let's test how it can be configured via Flutter Uri and send a PR.

AxesandGrinds commented 4 years ago

Any news on this? I'm using flutter_ringtone_player but for custom sounds, I have use other audio player library. I would appreciate if flutter_ringtone_player can also play custom sounds, that would be incredibly easy to achieve in less than half a week of coding and testing since plugins that do it such as AudioPlayer already exist in flutter which has android and ios native plugin files in it. "

Last, can you make flutter_ringtone_player usable on the website as well?

gonft commented 4 years ago

@AxesandGrinds Hi I solved this problem using an internal plugin. I haven't sent a PR yet, but the code is below. I haven't done the iOS side yet. But I'll check that the code works well for iOS, and then I'll make a PR.

Dart

await platform.invokeMethod('setDefaultAlarmUri', {
          'path': path,
          'title': title,
          'size': size,
          'useInternal': useInternal ? 'INTERNAL' : 'EXTERNAL',
        });

Kotlin

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, RingtoneChannel)
                .setMethodCallHandler { call: MethodCall?, result: MethodChannel.Result? ->
                    when( call!!.method ) {
                        "setDefaultAlarmUri" -> ifLet(
                                call.argument<String>("path"),
                                call.argument<String>("title"),
                                call.argument<String>("size"),
                                call.argument<String>("useInternal")
                        ) {
                            (path, title, size, useInternal) -> result?.success(setDefaultAlarmUri(path, title, size.toInt(), useInternal.contains("INTERNAL")))
                        }
                        else -> result!!.notImplemented()
                    }
                }
    }

private fun setDefaultAlarmUri(path: String, title: String, size: Int, useInternal: Boolean): Boolean {
        // check if file already exists in MediaStore
        val projection = arrayOf(MediaStore.Audio.Media._ID)
        val selectionClause = MediaStore.Audio.Media.DATA + " = ? "
        val selectionArgs = arrayOf(path)
        val cursor = context.contentResolver.query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, projection, selectionClause, selectionArgs, null)
        val mediaUri = if (useInternal ) { MediaStore.Audio.Media.INTERNAL_CONTENT_URI } else { MediaStore.Audio.Media.EXTERNAL_CONTENT_URI }
        val insertedUri: Uri?
        insertedUri = if (cursor == null || cursor.count < 1) { // not exist, insert into MediaStore
            val cv = ContentValues()
            cv.put(MediaStore.MediaColumns.DATA, path)
            cv.put(MediaStore.MediaColumns.TITLE, title)
            cv.put(MediaStore.MediaColumns.MIME_TYPE, "audio/${path.split('.').last()}")
            cv.put(MediaStore.MediaColumns.SIZE, size)
            cv.put(MediaStore.Audio.Media.ARTIST, "Miracle Alarm")
            cv.put(MediaStore.Audio.Media.IS_RINGTONE, false)
            cv.put(MediaStore.Audio.Media.IS_NOTIFICATION, false)
            cv.put(MediaStore.Audio.Media.IS_ALARM, true)
            cv.put(MediaStore.Audio.Media.IS_MUSIC, false)

            context.contentResolver.insert(mediaUri, cv)
        } else { // already exist
            cursor.moveToNext()
            val id = cursor.getLong(0)
            ContentUris.withAppendedId(mediaUri, id)
        }
        RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_ALARM, insertedUri)
        return true
    }

private inline fun <T: Any> ifLet(vararg elements: T?, closure: (List<T>) -> Unit) {
        if (elements.all { it != null }) {
            closure(elements.filterNotNull())
        }
    }
markosole commented 2 years ago

Hi guys, I am looking for solution and have looked into code example above. I am not really sure how to use any of this two. Can I anyhow pick sounds available in the device? Thanks

github-actions[bot] commented 1 year ago

This issue has stalled.

github-actions[bot] commented 1 year ago

This issue has been closed due to inactivity.

firhanpra commented 1 year ago

Hi guys, I am looking for solution too