Android Studio 如何在Android 13中获取存储权限?

ddrv8njm  于 8个月前  发布在  Android
关注(0)|答案(2)|浏览(320)

BroadcastReceiver文件

class CallReceiver : BroadcastReceiver() {
private var mediaRecorder : MediaRecorder? = null

override fun onReceive(context: Context?, intent: Intent?) {
    val state : String
  if(intent?.action.equals("android.intent.action.PHONE_STATE")){
      if(intent?.extras != null){
          state = intent.getStringExtra(TelephonyManager.EXTRA_STATE).toString()
          when(state){
              TelephonyManager.EXTRA_STATE_RINGING -> {
                  Log.d("CallRec", "Ringing......")
              }

              TelephonyManager.EXTRA_STATE_OFFHOOK -> {
                  startRecording(context)
              }

              TelephonyManager.EXTRA_STATE_IDLE ->{
                  stopRecording()
              }
          }
      }
  }
}

private fun startRecording(context: Context?) {
    if(context != null){
        mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) MediaRecorder(context) else MediaRecorder()
    }

    mediaRecorder?.apply {
        setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
        setOutputFormat(MediaRecorder.OutputFormat.AMR_NB)
        setOutputFile(getRecordingFilePath())
        setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
    }

    try {
        mediaRecorder?.prepare()
        mediaRecorder?.start()
    }
    catch (e : IOException){
        Log.d("CallError", e.toString())
    }

    Log.d("CallRec", "Call Recording Start......")
}

private fun stopRecording(){
    try {
        mediaRecorder?.stop()
        mediaRecorder?.release()
    }
    catch (e : Exception){
        Log.d("CallError", e.toString())
    }
    mediaRecorder = null
    Log.d("CallRec", "Call Recording Stopped......")
}

private fun getRecordingFilePath(): String {
    val directory = File(Environment.getExternalStorageDirectory(), "TestRecording")
    if(!directory.exists()){
        directory.mkdir()
    }
    val filePath = File(directory, "testing_${System.currentTimeMillis()}" + ".amr")
    return filePath.path
}

}主活动类

class MainActivity : AppCompatActivity() {

private var callReceiver = CallReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
  
  allowPermission()

    val makeCall: Button = findViewById(R.id.makeCall)
    makeCall.setOnClickListener {
        val intent = Intent(Intent.ACTION_DIAL)
        startActivity(intent)
    }

    if(hasPermission()) {
        val intentFilter = IntentFilter()
        intentFilter.addAction("android.intent.action.PHONE_STATE")
        this.registerReceiver(callReceiver, intentFilter)
    }
    else{
        allowPermission()
    }
}

override fun onDestroy() {
    super.onDestroy()
    this.unregisterReceiver(callReceiver)
}

private fun allowPermission() {
    ActivityCompat.requestPermissions(
        this, arrayOf(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.RECORD_AUDIO
        ), 2
    )
}

private fun hasPermission() : Boolean{
    val phoneStatePermission = Manifest.permission.READ_PHONE_STATE
    val writeFilePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE
    val recordAudioPermission = Manifest.permission.RECORD_AUDIO
    return ContextCompat.checkSelfPermission(this, phoneStatePermission) == PackageManager.PERMISSION_GRANTED
            &&   ContextCompat.checkSelfPermission(this, writeFilePermission) == PackageManager.PERMISSION_GRANTED
            &&   ContextCompat.checkSelfPermission(this, recordAudioPermission) == PackageManager.PERMISSION_GRANTED

}

}

清单文件

<uses-feature
    android:name="android.hardware.telephony"
    android:required="false" />

<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28"
    />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />



<application
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.CallRecording"
    tools:targetApi="31">
    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

LogCat

java.io.FileNotFoundException: /storage/emulated/0/TestRecording/testing_1694590203887.amr: open failed: ENOENT (No such file or directory)

我正在构建一个通话录音应用程序,我想在自定义目录中存储录制的音频文件。当我在android 8上运行这个应用程序时,它工作得很好。但是对于Android 13,它给出了EPERM(不允许操作)例外。我认为这个问题与许可有关。

vx6bjr1n

vx6bjr1n1#

谷歌限制通话录音功能,只有系统应用程序。在Android 8以上无法使用。[https://support.google.com/googleplay/android-developer/answer/9888170]

ghhkc1vu

ghhkc1vu2#

在Android 13设备上,您不应该请求通常的WRITE权限,因为默认情况下您拥有该权限。
但您不能在外部存储的根目录中创建文件夹“TestRecording”。
相反,在已经存在的公共目录之一中创建文件夹,如下载,文档,DCIM,图片,视频。

相关问题