LuckSiege / PictureSelector

Picture Selector Library for Android or 图片选择器
Apache License 2.0
13.3k stars 3.01k forks source link

权限问题 #2803

Open xicong opened 11 months ago

xicong commented 11 months ago

Current use version?

当前使用的版本是多少?

3.11.1

Will this problem occur in demo?

Demo能否复现这问题?

可复现

Describe the problem or provide an error log?

描述问题或提供错误log?

当设置选择类型仅为图片的时候,开始选择仍然会申请音视频权限

正常情况下,希望当只需要选择照片的时候,仅仅获取照片权限就可以

RokingYang commented 11 months ago

不怎么维护更新了。只能拉下来自己处理了。

xicong commented 11 months ago

不怎么维护更新了。只能拉下来自己处理了。

这样呀,那就自己改咯😄

RokingYang commented 11 months ago

你准备怎么搞

xicong commented 11 months ago

你准备怎么搞

自己拉代码,下来,改呗

LuckSiege commented 10 months ago

操作步骤是什么? 没有获取音频怎么可能获取权限,没有复现

xicong commented 10 months ago
image image

我只选择了图片,进去还是会请求,图片与视频

xicong commented 10 months ago

难道是因为系统的这个弹窗就算,仅选择图片,也会弹出,照片与视频?

xicong commented 10 months ago
            PictureSelector.create(fragment)
                .openGallery(SelectMimeType.ofImage())  //单独使用相机 媒体类型 PictureMimeType.ofImage()、ofVideo()
                .setSelectionMode(SelectModeConfig.SINGLE)  //单选or多选 PictureConfig.SINGLE PictureConfig.MULTIPLE
                .isPageStrategy(true) //开启分页模式
                .setImageEngine(imageEngine())
                .setSelectorUIStyle(pictureSelectorStyle(context))
                .isDisplayCamera(true) //是否显示相机入口
                .isCameraAroundState(true) //是否开启前置摄像头;系统相机 只支持部分机型
                .setImageSpanCount(imageSpanCount ?: 4) //相册列表每行显示个数
                .isPreviewImage(true)  //支持预览图片
                .isPreviewFullScreenMode(true)  //全屏预览
                .isEmptyResultReturn(true)  //支持未选择返回
                .isAutomaticTitleRecyclerTop(true) //点击相册标题是否快速回到第一项
                .isSyncCover(true)  //isPageModel模式下是否强制同步封面,默认false
                .isMaxSelectEnabledMask(true) //达到最大选择数是否开启禁选蒙层
                .setRecyclerAnimationMode(AnimationType.SLIDE_IN_BOTTOM_ANIMATION)  //相册列表动画效果
                .setRequestedOrientation(requestedOrientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)  //设置相册方向
                .isMaxSelectEnabledMask(true)   // 选择数到了最大阀值列表是否启用蒙层效果
                .isAutomaticTitleRecyclerTop(true)  // 连续点击标题栏RecyclerView是否自动回到顶部,默认true
                .setCropEngine { fragment, currentLocalMedia, dataSource, requestCode ->
                    // 注意* 如果你实现自己的裁剪库,需要在Activity的.setResult(); 
                    // Intent中需要给MediaStore.EXTRA_OUTPUT,塞入裁剪后的路径;如果有额外数据也可以通过CustomIntentKey.EXTRA_CUSTOM_EXTRA_DATA字段存入;
                    // 1、构造可用的裁剪数据源
                    val currentCropPath = currentLocalMedia.availablePath
                    val inputUri: Uri = if (PictureMimeType.isContent(currentCropPath) || PictureMimeType.isHasHttp(currentCropPath)) {
                        Uri.parse(currentCropPath)
                    } else {
                        Uri.fromFile(File(currentCropPath))
                    }
                    val fileName = DateUtils.getCreateFileName("CROP_") + ".jpg"
                    val destinationUri = Uri.fromFile(File(getSandboxPath(context), fileName))
                    val dataCropSource = ArrayList<String>()
                    for (i in 0 until dataSource.size) {
                        val media = dataSource[i]
                        dataCropSource.add(media.availablePath)
                    }
                    val uCrop = UCrop.of(inputUri, destinationUri, dataCropSource)
                    uCrop.setImageEngine(object : UCropImageEngine{
                        override fun loadImage(
                            context: Context?,
                            url: String?,
                            imageView: ImageView?
                        ) {
                            Glide.with(context!!).load(url).into(imageView!!)
                        }
                        override fun loadImage(
                            context: Context?,
                            url: Uri?,
                            maxWidth: Int,
                            maxHeight: Int,
                            call: UCropImageEngine.OnCallbackListener<Bitmap>?
                        ) {
                        }
                    })
                    uCrop.withOptions(buildOptions(context));
                    fragment.activity?.let {
                        uCrop.start(it, fragment, requestCode)
                    };
                }
                .setCompressEngine(object : CompressEngine {
                    override fun onStartCompress(
                        context: Context?,
                        list: ArrayList<LocalMedia>?,
                        listener: OnCallbackListener<ArrayList<LocalMedia>>?
                    ) {

                        list?.let { data ->
                            // 1、构造可用的压缩数据源
                            val compress: MutableList<Uri> = ArrayList<Uri>()
                            for (i in 0 until data.size) {
                                val media = data[i]
                                val availablePath = media.availablePath
                                val uri: Uri =
                                    if (PictureMimeType.isContent(availablePath) || PictureMimeType.isHasHttp(
                                            availablePath
                                        )
                                    ) Uri.parse(availablePath) else Uri.fromFile(
                                        File(availablePath)
                                    )
                                compress.add(uri)
                            }
                            if (compress.size == 0) {
                                listener?.onCall(data)
                                return
                            }

                            // 2、调用Luban压缩
                            Luban.with(context)
                                .load(compress)
                                .ignoreBy(100)
                                .filter { path ->
                                    PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(
                                        path
                                    );
                                }
                                .setRenameListener { filePath ->
                                    val indexOf = filePath.lastIndexOf(".");
                                    val postfix = if (indexOf != -1) {
                                        filePath.substring(indexOf)
                                    } else {
                                        ".jpg"
                                    }
                                    DateUtils.getCreateFileName("CMP_") + postfix;
                                }
                                .setCompressListener(object : OnCompressListener {
                                    override fun onStart() {
                                    }
                                    override fun onSuccess(index: Int, compressFile: File) {
                                        // 压缩完构造LocalMedia对象
                                        val media = list[index];
                                        if (compressFile.exists() && !TextUtils.isEmpty(compressFile.absolutePath)) {
                                            media.isCompressed = true;
                                            media.compressPath = compressFile.absolutePath;
                                            media.sandboxPath = if (SdkVersionUtils.isQ()) {
                                                media.compressPath
                                            } else {
                                                null
                                            }
                                        }
                                        // 因为是多图压缩,所以判断压缩到最后一张时返回结果
                                        if (index == list.size - 1) {
                                            listener?.onCall(list);
                                        }
                                    }
                                    override fun onError(index: Int, e: Throwable?) { //压缩出错
                                        if (index != -1) {
                                            val media = list[index];
                                            media.isCompressed = false;
                                            media.compressPath = null;
                                            media.sandboxPath = null;
                                            if (index == list.size - 1) {
                                                listener?.onCall(list);
                                            }
                                        }
                                    }
                                }).launch();
                        }
                    }
                })
                .forResult(object : OnResultCallbackListener<LocalMedia> {
                    override fun onCancel() {
                        selectorCancel.invoke()
                    }
                    override fun onResult(result: ArrayList<LocalMedia>?) {
                        result?.let {
                            for ((k, v) in it.withIndex()) {
                                if (v.cutPath != null) {
                                    selectedResult.invoke(File(v.cutPath))
                                    return@let
                                }
                            }
                        }
                    }
                })

我再排查下吧?类型都是只选择了img 但是你demo是弹窗是获取照片与视频 我 App这边是照片与音视频

image