diff --git a/node_modules/react-native-audio-recorder-player/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties b/node_modules/react-native-audio-recorder-player/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties
new file mode 100644
index 0000000..1211b1e
--- /dev/null
+++ b/node_modules/react-native-audio-recorder-player/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties
@@ -0,0 +1,6 @@
+aarFormatVersion=1.0
+aarMetadataVersion=1.0
+minCompileSdk=1
+minCompileSdkExtension=0
+minAndroidGradlePluginVersion=1.0.0
+coreLibraryDesugaringEnabled=false
diff --git a/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt b/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
index 5cb9bbf..25090aa 100644
--- a/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
+++ b/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
@@ -18,7 +18,12 @@ import java.io.IOException
 import java.util.*
 import kotlin.math.log10
 
-class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), PermissionListener {
+class RNAudioRecorderPlayerModule(
+    private val reactApplicationContext: ReactApplicationContext
+) : ReactContextBaseJavaModule(reactApplicationContext),
+    PermissionListener,
+    LifecycleEventListener {
+
     private var audioFileURL = ""
     private var subsDurationMillis = 500
     private var _meteringEnabled = false
@@ -29,345 +34,206 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
     private var mTimer: Timer? = null
     private var pausedRecordTime = 0L
     private var totalPausedRecordTime = 0L
-    var recordHandler: Handler? = Handler(Looper.getMainLooper())
-    override fun getName(): String {
-        return tag
-    }
+    private var recordHandler: Handler? = Handler(Looper.getMainLooper())
+
+    private val activity
+        get() = reactApplicationContext.currentActivity
+
+    private val appContext
+        get() = reactApplicationContext.applicationContext
+
+    override fun getName(): String = tag
 
     @ReactMethod
-    fun startRecorder(path: String, audioSet: ReadableMap?, meteringEnabled: Boolean, promise: Promise) {
+    fun startRecorder(
+        path: String,
+        audioSet: ReadableMap?,
+        meteringEnabled: Boolean,
+        promise: Promise
+    ) {
+        if (activity == null) {
+            promise.reject("NO_ACTIVITY", "Activity not attached")
+            return
+        }
+
         try {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                // TIRAMISU (33)
-                // https://github.com/hyochan/react-native-audio-recorder-player/issues/503
-                if (Build.VERSION.SDK_INT < 33 &&
-                        (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
-                        ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))  {
-                    ActivityCompat.requestPermissions((currentActivity)!!, arrayOf(
-                            Manifest.permission.RECORD_AUDIO,
-                            Manifest.permission.WRITE_EXTERNAL_STORAGE), 0)
-                    promise.reject("No permission granted.", "Try again after adding permission.")
-                    return
-                } else if (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
-                    ActivityCompat.requestPermissions((currentActivity)!!, arrayOf(Manifest.permission.RECORD_AUDIO), 0)
-                    promise.reject("No permission granted.", "Try again after adding permission.")
+                if (ActivityCompat.checkSelfPermission(
+                        appContext,
+                        Manifest.permission.RECORD_AUDIO
+                    ) != PackageManager.PERMISSION_GRANTED
+                ) {
+                    ActivityCompat.requestPermissions(
+                        activity!!,
+                        arrayOf(Manifest.permission.RECORD_AUDIO),
+                        0
+                    )
+                    promise.reject("PERMISSION_DENIED", "RECORD_AUDIO permission not granted")
                     return
                 }
             }
-        } catch (ne: NullPointerException) {
-            Log.w(tag, ne.toString())
-            promise.reject("No permission granted.", "Try again after adding permission.")
+        } catch (e: Exception) {
+            promise.reject("PERMISSION_ERROR", e.message)
             return
         }
-        audioFileURL = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/$defaultFileName" else path
+
+        val outputFormat =
+            if (audioSet?.hasKey("OutputFormatAndroid") == true)
+                audioSet.getInt("OutputFormatAndroid")
+            else
+                MediaRecorder.OutputFormat.MPEG_4
+
+        audioFileURL =
+            if (path == "DEFAULT")
+                "${reactApplicationContext.cacheDir}/sound.${defaultFileExtensions[outputFormat]}"
+            else path
+
         _meteringEnabled = meteringEnabled
 
-        if (mediaRecorder == null) {
-            mediaRecorder = MediaRecorder()
+        if (mediaRecorder != null) {
+            promise.reject("InvalidState", "Recorder already running")
+            return
         }
 
-        if (audioSet != null) {
-            mediaRecorder!!.setAudioSource(if (audioSet.hasKey("AudioSourceAndroid")) audioSet.getInt("AudioSourceAndroid") else MediaRecorder.AudioSource.MIC)
-            mediaRecorder!!.setOutputFormat(if (audioSet.hasKey("OutputFormatAndroid")) audioSet.getInt("OutputFormatAndroid") else MediaRecorder.OutputFormat.MPEG_4)
-            mediaRecorder!!.setAudioEncoder(if (audioSet.hasKey("AudioEncoderAndroid")) audioSet.getInt("AudioEncoderAndroid") else MediaRecorder.AudioEncoder.AAC)
-            mediaRecorder!!.setAudioSamplingRate(if (audioSet.hasKey("AudioSamplingRateAndroid")) audioSet.getInt("AudioSamplingRateAndroid") else 48000)
-            mediaRecorder!!.setAudioEncodingBitRate(if (audioSet.hasKey("AudioEncodingBitRateAndroid")) audioSet.getInt("AudioEncodingBitRateAndroid") else 128000)
-        } else {
-            mediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
-            mediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
-            mediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
-            mediaRecorder!!.setAudioEncodingBitRate(128000)
-            mediaRecorder!!.setAudioSamplingRate(48000)
-        }
-        mediaRecorder!!.setOutputFile(audioFileURL)
+        val recorder =
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
+                MediaRecorder(appContext)
+            else MediaRecorder()
 
         try {
-            mediaRecorder!!.prepare()
+            recorder.setAudioSource(MediaRecorder.AudioSource.MIC)
+            recorder.setOutputFormat(outputFormat)
+            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
+            recorder.setOutputFile(audioFileURL)
+
+            recorder.prepare()
+            recorder.start()
+
+            mediaRecorder = recorder
             totalPausedRecordTime = 0L
-            mediaRecorder!!.start()
-            val systemTime = SystemClock.elapsedRealtime()
+
+            val startTime = SystemClock.elapsedRealtime()
             recorderRunnable = object : Runnable {
                 override fun run() {
-                    val time = SystemClock.elapsedRealtime() - systemTime - totalPausedRecordTime
-                    val obj = Arguments.createMap()
-                    obj.putDouble("currentPosition", time.toDouble())
+                    val time =
+                        SystemClock.elapsedRealtime() - startTime - totalPausedRecordTime
+                    val map = Arguments.createMap()
+                    map.putDouble("currentPosition", time.toDouble())
+
                     if (_meteringEnabled) {
-                        var maxAmplitude = 0
-                        if (mediaRecorder != null) {
-                            maxAmplitude = mediaRecorder!!.maxAmplitude
-                        }
-                        var dB = -160.0
-                        val maxAudioSize = 32767.0
-                        if (maxAmplitude > 0) {
-                            dB = 20 * log10(maxAmplitude / maxAudioSize)
-                        }
-                        obj.putInt("currentMetering", dB.toInt())
+                        val amp = mediaRecorder?.maxAmplitude ?: 0
+                        val dB =
+                            if (amp > 0) (20 * log10(amp / 32767.0)).toInt() else -160
+                        map.putInt("currentMetering", dB)
                     }
-                    sendEvent(reactContext, "rn-recordback", obj)
-                    recordHandler!!.postDelayed(this, subsDurationMillis.toLong())
+
+                    sendEvent("rn-recordback", map)
+                    recordHandler?.postDelayed(this, subsDurationMillis.toLong())
                 }
             }
-            (recorderRunnable as Runnable).run()
-            promise.resolve("file:///$audioFileURL")
-        } catch (e: Exception) {
-            Log.e(tag, "Exception: ", e)
-            promise.reject("startRecord", e.message)
-        }
-    }
 
-    @ReactMethod
-    fun resumeRecorder(promise: Promise) {
-        if (mediaRecorder == null) {
-            promise.reject("resumeReocrder", "Recorder is null.")
-            return
-        }
-
-        try {
-            mediaRecorder!!.resume()
-            totalPausedRecordTime += SystemClock.elapsedRealtime() - pausedRecordTime;
-            recorderRunnable?.let { recordHandler!!.postDelayed(it, subsDurationMillis.toLong()) }
-            promise.resolve("Recorder resumed.")
-        } catch (e: Exception) {
-            Log.e(tag, "Recorder resume: " + e.message)
-            promise.reject("resumeRecorder", e.message)
-        }
-    }
-
-    @ReactMethod
-    fun pauseRecorder(promise: Promise) {
-        if (mediaRecorder == null) {
-            promise.reject("pauseRecorder", "Recorder is null.")
-            return
-        }
+            recorderRunnable?.run()
+            promise.resolve("file:///$audioFileURL")
 
-        try {
-            mediaRecorder!!.pause()
-            pausedRecordTime = SystemClock.elapsedRealtime();
-            recorderRunnable?.let { recordHandler!!.removeCallbacks(it) };
-            promise.resolve("Recorder paused.")
         } catch (e: Exception) {
-            Log.e(tag, "pauseRecorder exception: " + e.message)
-            promise.reject("pauseRecorder", e.message)
+            recorder.release()
+            mediaRecorder = null
+            promise.reject("startRecorder", e.message)
         }
     }
 
     @ReactMethod
     fun stopRecorder(promise: Promise) {
-        if (recordHandler != null) {
-            recorderRunnable?.let { recordHandler!!.removeCallbacks(it) }
-        }
-
-        if (mediaRecorder == null) {
-            promise.reject("stopRecord", "recorder is null.")
-            return
-        }
-
         try {
-            mediaRecorder!!.stop()
-        } catch (stopException: RuntimeException) {
-            stopException.message?.let { Log.d(tag,"" + it) }
-            promise.reject("stopRecord", stopException.message)
-        }
-
-        mediaRecorder!!.release()
-        mediaRecorder = null
-        promise.resolve("file:///$audioFileURL")
-    }
-
-    @ReactMethod
-    fun setVolume(volume: Double, promise: Promise) {
-        if (mediaPlayer == null) {
-            promise.reject("setVolume", "player is null.")
-            return
+            recordHandler?.removeCallbacks(recorderRunnable!!)
+            mediaRecorder?.stop()
+            mediaRecorder?.release()
+            mediaRecorder = null
+            promise.resolve("file:///$audioFileURL")
+        } catch (e: Exception) {
+            promise.reject("stopRecorder", e.message)
         }
-
-        val mVolume = volume.toFloat()
-        mediaPlayer!!.setVolume(mVolume, mVolume)
-        promise.resolve("set volume")
     }
 
     @ReactMethod
-    fun startPlayer(path: String, httpHeaders: ReadableMap?, promise: Promise) {
+    fun startPlayer(path: String, headers: ReadableMap?, promise: Promise) {
         if (mediaPlayer != null) {
-            val isPaused = !mediaPlayer!!.isPlaying && mediaPlayer!!.currentPosition > 1
-
-            if (isPaused) {
-                mediaPlayer!!.start()
-                promise.resolve("player resumed.")
-                return
-            }
-
-            Log.e(tag, "Player is already running. Stop it first.")
-            promise.reject("startPlay", "Player is already running. Stop it first.")
+            promise.reject("PLAYER_RUNNING", "Player already running")
             return
-        } else {
-            mediaPlayer = MediaPlayer()
         }
 
+        mediaPlayer = MediaPlayer()
+
         try {
-            if ((path == "DEFAULT")) {
-                mediaPlayer!!.setDataSource("${reactContext.cacheDir}/$defaultFileName")
-            } else {
-                if (httpHeaders != null) {
-                    val headers: MutableMap<String, String?> = HashMap<String, String?>()
-                    val iterator = httpHeaders.keySetIterator()
-                    while (iterator.hasNextKey()) {
-                        val key = iterator.nextKey()
-                        headers.put(key, httpHeaders.getString(key))
-                    }
-                    mediaPlayer!!.setDataSource(currentActivity!!.applicationContext, Uri.parse(path), headers)
-                } else {
-                    mediaPlayer!!.setDataSource(path)
+            if (headers != null) {
+                val map = HashMap<String, String?>()
+                val it = headers.keySetIterator()
+                while (it.hasNextKey()) {
+                    val k = it.nextKey()
+                    map[k] = headers.getString(k)
                 }
+                mediaPlayer!!.setDataSource(appContext, Uri.parse(path), map)
+            } else {
+                mediaPlayer!!.setDataSource(path)
             }
 
-            mediaPlayer!!.setOnPreparedListener { mp ->
-                Log.d(tag, "mediaplayer prepared and start")
-                mp.start()
-                /**
-                 * Set timer task to send event to RN.
-                 */
-                mTask = object : TimerTask() {
-                    override fun run() {
-                        val obj = Arguments.createMap()
-                        obj.putInt("duration", mp.duration)
-                        obj.putInt("currentPosition", mp.currentPosition)
-                        sendEvent(reactContext, "rn-playback", obj)
-                    }
-                }
-
-                mTimer = Timer()
-                mTimer!!.schedule(mTask, 0, subsDurationMillis.toLong())
-                val resolvedPath = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/$defaultFileName" else path
-                promise.resolve(resolvedPath)
+            mediaPlayer!!.setOnPreparedListener {
+                it.start()
+                promise.resolve(path)
             }
 
-            /**
-             * Detect when finish playing.
-             */
-            mediaPlayer!!.setOnCompletionListener { mp ->
-                /**
-                 * Send last event
-                 */
-                val obj = Arguments.createMap()
-                obj.putInt("duration", mp.duration)
-                obj.putInt("currentPosition", mp.duration)
-                sendEvent(reactContext, "rn-playback", obj)
-                /**
-                 * Reset player.
-                 */
-                Log.d(tag, "Plays completed.")
-                mTimer!!.cancel()
-                mp.stop()
-                mp.release()
+            mediaPlayer!!.setOnCompletionListener {
+                sendEvent("rn-playback", Arguments.createMap().apply {
+                    putBoolean("isFinished", true)
+                })
+                it.release()
                 mediaPlayer = null
             }
 
-            mediaPlayer!!.prepare()
+            mediaPlayer!!.prepareAsync()
         } catch (e: IOException) {
-            Log.e(tag, "startPlay() io exception")
-            promise.reject("startPlay", e.message)
-        } catch (e: NullPointerException) {
-            Log.e(tag, "startPlay() null exception")
+            promise.reject("startPlayer", e.message)
         }
     }
 
-    @ReactMethod
-    fun resumePlayer(promise: Promise) {
-        if (mediaPlayer == null) {
-            promise.reject("resume", "mediaPlayer is null on resume.")
-            return
-        }
-
-        if (mediaPlayer!!.isPlaying) {
-            promise.reject("resume", "mediaPlayer is already running.")
-            return
-        }
-
-        try {
-            mediaPlayer!!.seekTo(mediaPlayer!!.currentPosition)
-            mediaPlayer!!.start()
-            promise.resolve("resume player")
-        } catch (e: Exception) {
-            Log.e(tag, "mediaPlayer resume: " + e.message)
-            promise.reject("resume", e.message)
-        }
+    private fun sendEvent(event: String, params: WritableMap?) {
+        reactApplicationContext
+            .getJSModule(RCTDeviceEventEmitter::class.java)
+            .emit(event, params)
     }
 
-    @ReactMethod
-    fun pausePlayer(promise: Promise) {
-        if (mediaPlayer == null) {
-            promise.reject("pausePlay", "mediaPlayer is null on pause.")
-            return
-        }
-
+    override fun onHostDestroy() {
         try {
-            mediaPlayer!!.pause()
-            promise.resolve("pause player")
-        } catch (e: Exception) {
-            Log.e(tag, "pausePlay exception: " + e.message)
-            promise.reject("pausePlay", e.message)
+            mediaRecorder?.release()
+            mediaPlayer?.release()
+        } catch (_: Exception) {
         }
     }
 
-    @ReactMethod
-    fun seekToPlayer(time: Double, promise: Promise) {
-        if (mediaPlayer == null) {
-            promise.reject("seekTo", "mediaPlayer is null on seek.")
-            return
-        }
-
-        mediaPlayer!!.seekTo(time.toInt())
-        promise.resolve("pause player")
-    }
-
-    private fun sendEvent(reactContext: ReactContext,
-                          eventName: String,
-                          params: WritableMap?) {
-        reactContext
-                .getJSModule<RCTDeviceEventEmitter>(RCTDeviceEventEmitter::class.java)
-                .emit(eventName, params)
-    }
-
-    @ReactMethod
-    fun stopPlayer(promise: Promise) {
-        if (mTimer != null) {
-            mTimer!!.cancel()
-        }
-
-        if (mediaPlayer == null) {
-            promise.resolve("Already stopped player")
-            return
-        }
+    override fun onHostPause() {}
+    override fun onHostResume() {}
 
-        try {
-            mediaPlayer!!.release()
-            mediaPlayer = null
-            promise.resolve("stopped player")
-        } catch (e: Exception) {
-            Log.e(tag, "stopPlay exception: " + e.message)
-            promise.reject("stopPlay", e.message)
-        }
-    }
-
-    @ReactMethod
-    fun setSubscriptionDuration(sec: Double, promise: Promise) {
-        subsDurationMillis = (sec * 1000).toInt()
-        promise.resolve("setSubscriptionDuration: $subsDurationMillis")
-    }
-
-    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray): Boolean {
-        var requestRecordAudioPermission: Int = 200
-
-        when (requestCode) {
-            requestRecordAudioPermission -> if (grantResults[0] == PackageManager.PERMISSION_GRANTED) return true
-        }
-
-        return false
-    }
+    override fun onRequestPermissionsResult(
+        requestCode: Int,
+        permissions: Array<String>,
+        grantResults: IntArray
+    ): Boolean = true
 
     companion object {
-        private var tag = "RNAudioRecorderPlayer"
-        private var defaultFileName = "sound.mp4"
+        private const val tag = "RNAudioRecorderPlayer"
+        private val defaultFileExtensions = listOf(
+            "mp4",
+            "3gp",
+            "mp4",
+            "amr",
+            "amr",
+            "aac",
+            "aac",
+            "rtp",
+            "ts",
+            "webm",
+            "xxx",
+            "ogg"
+        )
     }
 }
