Android 10的AudioRecord和MediaRecorder启动延迟

问题描述

我正在使用Cotlin进行开发,该代码自动停止记录然后每小时重新启动的代码的一部分,并且可以在Android 9上正常运行。

但是,在Android 10上,用MediaRecorder编写时,prepare函数有时会延迟10到20分钟,并且当我使用AudioRecord切换到库时,也会出现相同的问题。

为什么会这样?我该如何解决

开始录制方法

class RecorderService() : Service() {

// Voice recorder
private var recorder: Recorder? = null
private val binder:Binder = RecorderServiceBinder()
// Destination file
private var destFile: File? = null
private lateinit var path:String
// Voice record status
private var isRecording: Boolean = false
// Record pause status
var isPauseRecording:Boolean = false
// M4a conversion status
var isConverting:Boolean = false

inner class RecorderServiceBinder:Binder() {
    val service:RecorderService
        get() = this@RecorderService
}

override fun onBind(intent: Intent?): IBinder? {
    return binder
}

override fun onCreate() {
    super.onCreate()

    path = "${getExternalFilesDir("/")?.absolutePath}/output"

    Log.d("TAG","onCreate")
}

override fun onStartCommand(intent: Intent?,flags: Int,startId: Int): Int {
    Log.d("TAG","onStartCommand")
    val intent:Intent = intent ?: return START_NOT_STICKY

    when(intent.action) {
        Constants.RECORD_SERVICE_ACTION_PLAY -> { startRecording() }
        Constants.RECORD_SERVICE_ACTION_PAUSE -> { pauseRecording() }
        Constants.RECORD_SERVICE_ACTION_STOP -> { stopRecording(false) }
        Constants.RECORD_SERVICE_ACTION_CANCEL -> { stopRecording(true) }
        Constants.RECORD_SERVICE_ACTION_RESUME -> { resumeRecording() }
        Constants.RECORD_SERVICE_ACTION_START -> { showNotification() }
    }

    return START_NOT_STICKY
}

override fun onDestroy() {
    stopRecording(false)

    super.onDestroy()
}

private fun showNotification() {
    val notificationIntent:Intent = Intent(this,MainActivity::class.java)
    val pendingIntent:PendingIntent = PendingIntent.getActivity(this,notificationIntent,0)
    var builder:NotificationCompat.Builder

    if(Build.VERSION.SDK_INT >=  Build.VERSION_CODES.O) {
        val channelId:String = "Voice Recorder Channel"
        val channel:NotificationChannel = NotificationChannel(channelId,"Voice Recorder Channel",notificationmanager.IMPORTANCE_DEFAULT)
        val nm:notificationmanager = getSystemService(Context.NOTIFICATION_SERVICE) as? notificationmanager ?: return
        nm.createNotificationChannel(channel)

        builder = NotificationCompat.Builder(this,channelId)
    } else {
        builder = NotificationCompat.Builder(this)
    }

    builder.setContentTitle("Foreground Service Kotlin Example")
    builder.setContentText("This is demo voice recorder")
    builder.setContentIntent(pendingIntent)

    startForeground(1,builder.build())

    startRecording()
}

// Start recording
fun startRecording() {
    if(!isRecording) {
        createFolder()

        isRecording = true

        destFile = File(saveFilePath())
            recorder = omrecorder.wav(
                PullTransport.Default(mic(),PullTransport.OnAudioChunkPulledListener { }),destFile
            )

        recorder?.startRecording()
        Log.d("TAG","startRecording")
    }
}

// Pause recording
fun pauseRecording() {
    if(isRecording && !isPauseRecording) {
        Log.d("TAG","pauseRecording")
        recorder?.pauseRecording()
        isPauseRecording = true
    }
}

// Resume recording
fun resumeRecording() {
    if(isRecording && isPauseRecording) {
        Log.d("TAG","resumeRecording")

        recorder?.resumeRecording()
        isPauseRecording = false
    }
}

// Stop recording
fun stopRecording(isCancelled: Boolean) {
    if (isRecording) {
        recorder?.stopRecording()
        isRecording = false
        isPauseRecording = false
        isConverting = true
        Log.d("TAG","stopRecording")

        if(isCancelled) {
            removeFile()
        }
    }
}

private fun mic(): PullableSource? {
    return PullableSource.Default(
        AudioRecordConfig.Default(
            MediaRecorder.AudioSource.MIC,AudioFormat.ENCODING_PCM_16BIT,AudioFormat.CHANNEL_IN_MONO,44100
        )
    )
}

// Create save folder
private fun createFolder() {
    val file = File(path)

    if(!file.exists())
        file.mkdir()
}

private fun saveFilePath(): String {
    val NowDate:LocalDate = LocalDate.Now()
    val dateFormatter:DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd")
    val formatDate:String = NowDate.format(dateFormatter)
    val fileLists = File(path).walk().filter { it.isFile }.sortedBy { it.lastModified() }.filter { it.nameWithoutExtension != "temp" && it.nameWithoutExtension != "convert" }

    if(fileLists.count() > 0) {
        val lastFile:File = fileLists.last()
        val lastFileName:String = lastFile.nameWithoutExtension

        val split = lastFileName.split("-")
        val lastNum = split.last().toInt() ?: 0

        return "$path/$formatDate-${lastNum+1}.m4a"
    }

    return "$path/$formatDate-0.m4a"
}

// Delete voice file
private fun removeFile() {
    val file:File = destFile ?: return

    if(file.exists()) {
        file.delete()
    }
}

}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)