skip to Main Content

i make program for record audio for android but i find MediaRecorder() Deprecated
kotlin code

package noteapp.notesnotesnotescairo.mynoteapp

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.icu.text.SimpleDateFormat
import android.media.MediaRecorder
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.os.Looper.prepare

import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.NonCancellable.start

import java.io.IOException
import java.util.*

const val REQUEST_CODE=200

private  var permission = arrayOf(Manifest.permission.RECORD_AUDIO)
private  var permissionGranted=false

private lateinit var recorder : MediaRecorder
private  var dirPath=""
private   var filename=""
private  var isRecording=false
private  var isPaused=false

class MainActivity : AppCompatActivity(){


    @RequiresApi(Build.VERSION_CODES.S)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        permissionGranted=ActivityCompat.checkSelfPermission(this, permission[0])==PackageManager.PERMISSION_GRANTED

        if(!permissionGranted)
            ActivityCompat.requestPermissions(this, permission, REQUEST_CODE)
        btnRecord.setOnClickListener{
            when{
                isPaused->resumeRecorder()
            isRecording->pauseRecorder()
            else->startRecording()
            }

        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if(requestCode== REQUEST_CODE)
            permissionGranted=grantResults[0]==PackageManager.PERMISSION_GRANTED
    }
private  fun pauseRecorder(){
    recorder.pause()
    isPaused=true
    btnRecord.setImageResource(R.drawable.ic_record)
}

    private  fun resumeRecorder(){
        recorder.resume()
        isPaused=false
        btnRecord.setImageResource(R.drawable.ic_pause)
    }



    @RequiresApi(Build.VERSION_CODES.S)
    private  fun startRecording(){
        if(!permissionGranted){
            ActivityCompat.requestPermissions(this, permission, REQUEST_CODE)
            return
        }
        recorder =  MediaRecorder( this)

        dirPath="${externalCacheDir?.absolutePath}/"
        var simpleDateFormat= SimpleDateFormat("yyyy.mm.dd.hh.mm.ss")
        var date :String=simpleDateFormat.format(Date())
        filename="audio_record_$date"

        recorder.apply {

            setAudioSource(MediaRecorder.AudioSource.MIC)
            setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
            setOutputFile("$dirPath$filename.mp3")
            try{
              prepare()
            }catch (e:IOException){}
            start()

        }
        btnRecord.setImageResource(R.drawable.ic_pause)
        isRecording=true
        isPaused=false
    }

}

xml code

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvTimer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="00:00:00"
        android:textSize="56sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:layout_marginBottom="80dp"
    app:layout_constraintBottom_toBottomOf="parent"
    >
    <ImageButton
        android:id="@+id/btnDelete"
        android:layout_width="@dimen/btn_size"
        android:src="@drawable/ic_delete_disable"
        android:layout_height="@dimen/btn_size"
        android:background="@drawable/ic_ripple"/>
    <ImageButton
        android:id="@+id/btnRecord"
        android:layout_width="66dp"
        android:layout_marginStart="30dp"
        android:layout_marginEnd="30dp"
        android:layout_height="66dp"
        android:background="@drawable/ic_record"/>
    <ImageButton
        android:id="@+id/btnList"
        android:layout_width="@dimen/btn_size"
        android:src="@drawable/ic_list"
        android:layout_height="@dimen/btn_size"
        android:background="@drawable/ic_ripple"/>

    <ImageButton
        android:id="@+id/btnDone"
        android:layout_width="@dimen/btn_size"
        android:src="@drawable/ic_done"
        android:visibility="gone"
        android:layout_height="@dimen/btn_size"
        android:background="@drawable/ic_ripple"/>

</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


what is new defind for MediaRecorder() not Deprecated ?

give me error

java.lang.NoSuchMethodError: No direct method (Landroid/content/Context;)V in class Landroid/media/MediaRecorder; or its super classes (declaration of ‘android.media.MediaRecorder’ appears in /system/framework/framework.jar!classes2.dex)

2

Answers


  1. I used the following script in an app published on the Playstore

     fun prepare_audio_and_directories(v : View) {
        var tempDir : File
       // current_filename = (v.findViewById(R.id.audio_filename_xml) as TextView).text.toString()
    
        current_dir = main?.dir!!
        tempDir = current_dir
        main?.filenameCompletePath = tempDir?.toPath().toString() + "/" +current_filename + "."+ main?.ext
        main?.filename_text = current_filename
    
        Log.d("$TAG:prepare_audio_and_directories:main?.filenameCompletePath=", main?.filenameCompletePath!!
        )
        Log.d("$TAG:prepare_audio_and_directories:main?.filename_text=", main?.filename_text!!)
        Log.d("NoiseSuppressor.isAvailable()=", NoiseSuppressor.isAvailable().toString() )
        mediaRecorder = MediaRecorder()
        mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
        mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        mediaRecorder?.setAudioEncodingBitRate(128000)
        mediaRecorder?.setAudioSamplingRate(96000);
        mediaRecorder?.setOutputFile(main?.filenameCompletePath)
    
    }
    

    The versions I tested it with are API 28,29,30 and 31.

    Login or Signup to reply.
  2. Use an if/else to set the property using the supported constructor:

    recorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) MediaRecorder(this) else MediaRecorder()
    

    Down the road it is possible Jetpack will add a helper function that would do this for you, something like MediaRecorderCompat.newInstance(this). However, it has been so long I think we can assume they will probably not be adding it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search