[英]How to record audio with android 11
我正在制作一個應用程序來在 Android 11 設備上錄制音頻。 但是折騰了好幾天,權限設置還是有問題。 我不斷收到這樣的錯誤
I/System.out: java.io.FileNotFoundException: /storage/emulated/0/Recordings/2022-12-14T10:11:37.089test.3gp: open failed: EPERM (Operation not permitted)
然后APP會在調用recorder.start()后關閉。 看起來它需要更多權限才能執行此操作。 現在這是我的代碼:
package com.example.eslab_final_impromptu
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.media.SoundPool
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.eslab_final_impromptu.databinding.FragmentDetailBinding
import java.io.IOException
import java.time.LocalDateTime
class DetailFragment : Fragment() {
private var _binding: FragmentDetailBinding? = null
private val binding get() = _binding!!
private var recorder: MediaRecorder? = null
private var recording=false
private var isRecordable=true
private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission())
{ isGranted: Boolean ->
if (isGranted) {
// Permission is granted. Continue the action or workflow in your
// app.
} else {
isRecordable=false
Log.d("ddddd","permission")
// Explain to the user that the feature is unavailable because the
// feature requires a permission that the user has denied. At the
// same time, respect the user's decision. Don't link to system
// settings in an effort to convince the user to change their
// decision.
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentDetailBinding.inflate(inflater, container, false)
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.RECORD_AUDIO )!= PackageManager.PERMISSION_GRANTED
) {
Log.d("ddddd","audio")
requestPermission.launch(Manifest.permission.RECORD_AUDIO)
}
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE )!= PackageManager.PERMISSION_GRANTED
) {
Log.d("ddddd","write")
requestPermission.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.sheet.setOnClickListener {
val action =
DetailFragmentDirections.actionDetailFragmentToSheetFragment()
this.findNavController().navigate(action)
}
binding.settings.setOnClickListener {
}
binding.disconnect.setOnClickListener {
val action =
DetailFragmentDirections.actionDetailFragmentToHomeFragment()
this.findNavController().navigate(action)
}
binding.record.setOnClickListener{
if(!recording)
record()
else
stopRecord()
}
}
override fun onDestroyView() {
super.onDestroyView()
}
fun record(){
Log.d("ddddd",LocalDateTime.now().toString())
if(!isRecordable)
return
var mFileName:String = Environment.getExternalStorageDirectory().absolutePath+"/Recordings/"+ LocalDateTime.now().toString()+"test.3gp"
println(Environment.getExternalStorageState())
recorder = MediaRecorder().apply {
setAudioSource( MediaRecorder.AudioSource.DEFAULT)
setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
setOutputFile(mFileName)
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
try {
prepare()
} catch (e: IOException) {
println(e)
}
start()
}
recording=true
}
fun stopRecord(){
recorder?.apply {
stop()
release()
}
recorder = null
recording=false
}
}
我現在請求 RECORD_AUDIO 和 WRITE_EXTERNAL_STORAGE。 我還需要要求什么嗎? 我的設備是帶有 SDK30 的 Android 11。
Google 發布了有關將文件寫入應用特定存儲的新存儲更新。 SDK 30 及以上版本不能訪問 WRITE_EXTERNAL_STORAGE 權限。 閱讀此內容:https ://developer.android.com/about/versions/11/privacy/storage
刪除 WRITE_EXTERNAL_STORAGE 權限請求。
嘗試以下解決方案:
var mFileName:String = getContext().externalMediaDirs[0].absolutePath+"/" + System.currentTimeMillis()+"test.3gp"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.