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
I used the following script in an app published on the Playstore
The versions I tested it with are API 28,29,30 and 31.
Use an if/else to set the property using the supported constructor:
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.