簡體   English   中英

如何用安卓11錄音

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM