getActivity / XXPermissions

Android 权限请求框架,已适配 Android 14
Apache License 2.0
5.44k stars 735 forks source link

[疑惑]:对于一个兼容问题,不知道算bug还是算正常,所以提出一点疑问 #275

Closed mobilewhj closed 3 weeks ago

mobilewhj commented 1 month ago

问题描述【必填】

今天做系统相机录像功能demo的时候,做了如下操作:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        XXPermissions.with(this)
            .permission(Permission.READ_MEDIA_VIDEO)
            .request { _, allGranted ->
                if (allGranted){
                    // 创建录制视频的Intent
                    val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                    // 指定视频最大录制时长,单位为秒
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5)
                    mVideoCameraLauncher.launch(intent)
                }
            }
    }else{
        XXPermissions.with(this)
            .unchecked()
            .permission(Permission.WRITE_EXTERNAL_STORAGE)
            .permission(Permission.READ_EXTERNAL_STORAGE)
            .request { _, allGranted ->
                if (allGranted){
                    // 创建录制视频的Intent
                    val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                    // 指定视频最大录制时长,单位为秒
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5)
                    mVideoCameraLauncher.launch(intent)
                }
            }
    }

我只能使用uncheked()绕过框架限制才能不会崩溃。我尝试了几种写法:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        XXPermissions.with(this)
            .permission(Permission.READ_MEDIA_VIDEO)
            .request { _, allGranted ->
                if (allGranted){
                    // 创建录制视频的Intent
                    val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                    // 指定视频最大录制时长,单位为秒
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5)
                    mVideoCameraLauncher.launch(intent)
                }
            }
    }else{
        XXPermissions.with(this)
            .permission(Permission.MANAGE_EXTERNAL_STORAGE)
            .request { _, allGranted ->
                if (allGranted){
                    // 创建录制视频的Intent
                    val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                    // 指定视频最大录制时长,单位为秒
                    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5)
                    mVideoCameraLauncher.launch(intent)
                }
            }
    }

这种会提示我 java.lang.IllegalStateException: Please register the android:requestLegacyExternalStorage="true" attribute in the AndroidManifest.xml file, otherwise it will cause incompatibility with the old version。

XXPermissions.with(this) .permission(Permission.WRITE_EXTERNAL_STORAGE) .permission(Permission.READ_EXTERNALSTORAGE) .request { , allGranted -> if (allGranted){ // 创建录制视频的Intent val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE) // 指定视频最大录制时长,单位为秒 intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5) mVideoCameraLauncher.launch(intent) } }

这种会提示我 java.lang.IllegalArgumentException: When targetSdkVersion >= 33 should use android.permission.READ_MEDIA_IMAGES, android.permission.READ_MEDIA_VIDEO, android.permission.READ_MEDIA_AUDIO instead of android.permission.READ_EXTERNAL_STORAGE。 如果不做版本判断,

XXPermissions.with(this) .permission(Permission.READ_MEDIAVIDEO) .request { , allGranted -> if (allGranted){ // 创建录制视频的Intent val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE) // 指定视频最大录制时长,单位为秒 intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5) mVideoCameraLauncher.launch(intent) } }

只这么处理的话,会出现 java.io.FileNotFoundException: /storage/emulated/0/Movies/MyMovies/19866.mp4 (No such file or directory)没有权限的错误。我不知道怎么写是正确的,所以想咨询一下,对于读写的兼容应该如何处理呢。 下面是我xml中权限部分的声明:

<!-- 提供积分商城位置权限 -->
<!-- 后台定位权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
    android:name="android.permission.ACCESS_FINE_LOCATION"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />

<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />

我的版本: compileSdk = 33, minSdk = 24, targetSdk = 33 androidstudio版本: Android Studio Hedgehog | 2023.1.1 Patch 2 手机型号: vivo Y93 V1818T android版本为8.1.0

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

getActivity commented 1 month ago

XXPermissions-18.63.aar.zip

getActivity commented 1 month ago
image
getActivity commented 1 month ago

@mobilewhj 小伙子,我优化了这个问题,你可以下载上面的 aar 包,然后直接申请 READ_MEDIA_VIDEOWRITE_EXTERNAL_STORAGE 试试看。

mobilewhj commented 1 month ago

fun XXPermissions.videoRequest(manager: FragmentManager, callback: () -> Unit) { this .permission(Permission.CAMERA) .permission(Permission.READ_MEDIA_VIDEO) .permission(Permission.WRITE_EXTERNAL_STORAGE) .interceptor( PermissionInterceptor( BaseApplication.instance.getString(R.string.permissionvideo), manager = manager ) ) .request { , allGranted -> if (allGranted) { callback() } else { Toaster.show(R.string.permission_deny) } } }

使用上面的aar经过测试在我出问题的手机上没问题了。

getActivity commented 1 month ago

@mobilewhj 小伙子,远程依赖已经更新,你可以换成远程依赖再试一下。

mobilewhj commented 1 month ago

顺便问一下RECORD_AUDIO这个权限要做类似的WRITE_EXTERNAL_STORAGE操作吗?当前加上是报错的。

getActivity commented 1 month ago

@mobilewhj 申请RECORD_AUDIO 权限为什么要带上 WRITE_EXTERNAL_STORAGE 权限?这两者没有关系吧?

getActivity commented 1 month ago

你说的类似是什么意思?麦克风本身只有读取权限,没有提供写入权限。

image
mobilewhj commented 1 month ago

我想的是录制音频文件写入磁盘,对于低版本手机需要好WRITE_EXTERNAL_STORAGE,可能我想的多了。