0

您好,我已经制作了自定义呼叫拨号器,其中呼叫拨到预定义的号码。接通电话后,我开始录制语音并将其保存到外部存储中。

一切都很好,直到我在通话期间不杀死应用程序。一旦我杀了 app mediarecorder 停止录制语音但仍在写入字节。

它看起来像 mediaRecorder 与活动有一些联系。但不知道我在哪里做错了。这是我的呼叫服务代码。

class ServiceToMakeCall : InCallService() {
private lateinit var setTimer: CountDownTimer
private lateinit var inProgressCall: Call
private var mediaRecorder: MediaRecorder? = null

override fun onCreate() {
    super.onCreate()
    LocalBroadcastManager.getInstance(this)
        .registerReceiver(timerBroadcastReceiver, IntentFilter().apply {
            addAction(getString(R.string.should_start_timer))
        })
    InCallServiceUtil.setServiceContext(this)
}

@RequiresApi(Build.VERSION_CODES.O)
override fun onCallAdded(call: Call?) {
    super.onCallAdded(call)
    Log.e("Calling", "Call Added")
    call?.let {
        inProgressCall = it
        CallingActivity.call = it
        moveToCallingScreen()
        showNotification(0)
    }
}

override fun onCallRemoved(call: Call?) {
    super.onCallRemoved(call)
    Log.e("Calling", "Call Removed")
    LocalBroadcastManager.getInstance(this)
        .sendBroadcast(
            Intent(getString(R.string.package_name))
                .putExtra(IsFinished, true)
        )
    AppPreferences.apply {
        putString(DISCONNECT_TIME, System.currentTimeMillis().toString())
        if (getString(DIAL_TIME, "").isEmpty() || getString(
                CONNECT_SETUP,
                ""
            ).isEmpty() || getString(DISCONNECT_TIME, "").isEmpty()
        ) {
            moveToNextActivity(ConductTestsActivity::class.java)
        } else {
            putInt(TEST_STATE, 6)
            moveToNextActivity(FeedBackActivity::class.java)
        }
    }
    stopTimer()
    stopRecording()
    stopForeground(true)
}

private fun moveToCallingScreen() {
    Intent(applicationContext, CallingActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK
        startActivity(this)
    }
}

private fun <T> moveToNextActivity(movingClass: Class<T>) {
    Intent(applicationContext, movingClass).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        startActivity(this)
    }
}

@RequiresApi(Build.VERSION_CODES.O)
private fun showNotification(miliTime: Long) {
    val channelId = "CallService"
    val pendingIntent = PendingIntent.getActivity(
        this,
        101,
        Intent(this, CallingActivity::class.java),
        PendingIntent.FLAG_UPDATE_CURRENT
    )
    val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        notificationManager.createNotificationChannel(
            NotificationChannel(
                channelId,
                channelId,
                NotificationManager.IMPORTANCE_DEFAULT
            )
        )
    }
    val notification = NotificationCompat.Builder(this, channelId).apply {
        setContentTitle("Call In Progress")
        setContentText("Remaining Time : ${getCallDuration(miliTime / 1000)}s")
        setOnlyAlertOnce(true)
        setSmallIcon(R.drawable.logo_small)
        setContentIntent(pendingIntent)
    }.build()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        startForeground(100, notification, FOREGROUND_SERVICE_TYPE_MICROPHONE)
    } else startForeground(100, notification)
}

override fun onDestroy() {
    super.onDestroy()
    LocalBroadcastManager.getInstance(this).unregisterReceiver(timerBroadcastReceiver)
    with(inProgressCall) {
        if (state == Call.STATE_RINGING)
            reject(false, "")
        else {
            disconnect()
        }
    }
}

private var timerBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.extras?.getBoolean(StartTimer) == true && !::setTimer.isInitialized) {
            startTimer()
            startRecording()
        }
    }
}

private fun startTimer() {
    setTimer = object : CountDownTimer(90000, 1000) {
        @RequiresApi(Build.VERSION_CODES.O)
        override fun onTick(miliTime: Long) {
            showNotification(miliTime)
            LocalBroadcastManager.getInstance(this@ServiceToMakeCall)
                .sendBroadcast(
                    Intent(getString(R.string.package_name))
                        .putExtra(MiliTime, miliTime)
                )
        }

        override fun onFinish() {
            inProgressCall.disconnect()
        }
    }.start()
}

private fun stopTimer() {
    if (::setTimer.isInitialized) setTimer.cancel()
}

private fun startRecording() {
    mediaRecorder = MediaRecorder().apply {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION)
        } else {
            setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
        }
        setOutputFormat(MediaRecorder.OutputFormat.AMR_NB)
        setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
        val currentMilliseconds = System.currentTimeMillis().toString()
        AppPreferences.putString(CONNECT_SETUP, currentMilliseconds)
        setOutputFile(saveCallRecording(applicationContext, currentMilliseconds).absolutePath)
    }
    try {
        mediaRecorder?.prepare()
    } catch (e: IllegalStateException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }
    mediaRecorder?.start()
}

private fun stopRecording() {
    try {
        mediaRecorder?.apply {
            stop()
            reset() // clear recorder configuration
            release() // release the recorder object
        }
    } catch (ex: Exception) {
        ex.printStackTrace()
    }
}

}

请帮我解决这个问题,我不知道出了什么问题。

4

0 回答 0