Search code examples
javaandroidkotlinmediarecorder

MediaRecorder.stop() throwing illegalException


I'm using MediaRecorder to record audio files, I have set up the necessary code to do, the code works fine until I press stop recording right after an exception is thrown crashing the application don't know exactly what is the issue! I'd be happy to get some help from you guys and thank you


override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       binding = ActivityMainBinding.inflate(layoutInflater)
       setContentView(binding.root)
   
       binding.sendIcon.setOnClickListener {
           startRecording()
       }
       binding.recordingIcon.setOnClickListener {
           stopRecording()
       }
     


   }

private fun startRecording() {
       if (mediaRecorder == null){
           mediaRecorder = MediaRecorder()
           mediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
           mediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
           mediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
           mediaRecorder!!.setAudioSamplingRate(16000)
           mediaRecorder!!.setOutputFile(getOutputFilePath())
           try {
               mediaRecorder!!.prepare()
               mediaRecorder!!.start()
           } catch (e: Exception) {
               Log.d("TAG","Recording Exception " + e.localizedMessage)
           }
       }
   }

   private fun stopRecording() {
       if (mediaRecorder != null){
           mediaRecorder?.stop()
           mediaRecorder?.release()
       }
   }


     private fun getOutputFilePath(): String {
       val recordingID = "Recording_" + System.currentTimeMillis()
       val directory = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
           applicationContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC)
       } else {
           Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
       }
       return directory?.absolutePath + "/AudioRecording/" +  recordingID + ".3gp"
   }


Solution

  • The reason why it doesn't work is because it throws an exception when calling the prepare/start methods therefore the initialization of the MediaRecorder fails. In particular, the issue is related to opening the output file (open failed: ENOENT). After a failed initialization it is normal that the call to stop will fail as well.

    As suggested by the documentation, you can provide the directory to store the output file in this way:

    val fileName = "${externalCacheDir?.absolutePath}/audiorecordtest.3gp"
    mediaRecorder!!.setOutputFile(fileName)
    

    Of course you have to adjust this suggestion according to your needs.

    Hope this helps.