结合着Android的历史问题,我们需要这样写才行:
首先 manifest 部分
<manifest>
<!-- Devices running Android 12L (API level 32) or lower -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- To handle the reselection within the app on Android 14 (API level 34) -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
...
</manifest>
这是能够完美适配Android各个系统版本的本地读写权限的写法。
Android 12及以下系统,我们只需要声明READ_EXTERNAL_STORAGE权限即可。并且由于从Android 13开始这个权限就被废弃了,因此还要加上maxSdkVersion="32"才行。
Android 13新增了3个运行时权限,分别用于控制App对照片、视频、音频的访问。
为了让大家不用每次都绞尽脑汁地思考这个地方应该如何处理才能考虑得最为周全,这里我直接贴出一份模板代码,可以放在BaseActivity当中,大家在实现的时候复制粘贴即可:
代码部分
import android.Manifest
import android.app.Activity
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.PermissionChecker
private val permissionLauncher =
this.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { _ ->
// 处理权限请求结果
checkPermissionResult()
}
fun permission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
permissionLauncher.launch(
arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
)
)
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) {
permissionLauncher.launch(
arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO
)
)
} else {
permissionLauncher.launch(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE))
}
}
private fun checkPermissionResult() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
&& (ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_MEDIA_IMAGES
) == PermissionChecker.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_MEDIA_VIDEO
) == PermissionChecker.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_MEDIA_AUDIO
) == PermissionChecker.PERMISSION_GRANTED)
) {
// Android 13及以上完整照片和视频访问权限
doAction()
} else if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
) == PermissionChecker.PERMISSION_GRANTED
) {
// Android 14及以上部分照片和视频访问权限
doAction()
} else if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PermissionChecker.PERMISSION_GRANTED
) {
// Android 12及以下完整本地读写访问权限
doAction()
} else {
// 无本地读写访问权限
doElse()
}
}
open fun doAction() {
}
open fun doElse() {
ToastUtils.showLong("您拒绝了文件访问权限")
}
可以看到,现在判断权限的请求结果需要分4种情况,分别是:
Android 13及以上完整照片和视频访问权限
Android 14及以上部分照片和视频访问权限
Android 12及以下完整本地读写访问权限
无本地读写访问权限
支付宝这一次力度够大的啊,后台看到有人居然领了 20 元,你也来试试
如果帮助到你,打赏就不必了,领个现金红包再走吧~
参考文献:郭神: https://blog.csdn.net/guolin_blog/article/details/137410229