更新记录

1.0.2(2024-05-30)

更新依赖库,新增对其他UTS、其他App提供图片选择的能力

1.0.1(2024-05-26)

Api错误消息请看interface.uts中的MediaSelectorErrorCode

1.0.0(2024-05-24)

citycoder-mediaselector,一个出色的媒体(图片、视频)选择器框架,1.0.0版本正式发布!

查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.99,Android:5.0,iOS:不支持,HarmonyNext:不确定 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

插件使用

注意事项

  • 1.HBuilderX设置->插件配置->uts开发扩展ndroid中gradle版本(若配置过)不能高于7.6.1
  • 2.项目根目录manifest.json-App常用其他配置-targetSdkVerson需配置为大于等于33(由于官方目前不支持配置compileSdkVersion,这里升高targetSdkVersion后,App需要适配高版本Sdk)
  • 3.导入插件后,需自定义基座后再使用
  • 4.视频播放,需勾选videoplayer模块
  • 5.HBuilderX版本4.02及以上时,需删除插件app-android目录AndroidManifest.xml文件中的package字段
  • 6.若需对其他UTS插件(如扫一扫插件)、或是其他App提供图片选择服务时,可放开AndroidManifest.xml中的注释
  • 7.插件仅适配android uniapp项目,不支持iOS,还未在uniappx中测试

    AndroidManifest.xml文件

    <!--app-android AndroidManifest.xml文件 -->
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    package="com.ccxxcoder.uniapp.mediaselector">
    <!--若需对其他UTS插件、或是其他App提供图片选择服务时,可放开如下配置-->
    <application>
        <activity android:name="com.city.code.android.mediaselector.view.ImageSelectorActivity" android:exported="true"
            android:screenOrientation="portrait">
    
            <intent-filter>
                <!--若用户手机有其他App也用了我的插件,因名称相同时,会触发多个选择,因此尽量保证name唯一,一般使用公司名称作为包名。 -->
                <action android:name="需要用英文填写name,格式如:com.你的公司名英文.uts.ImageSelectorActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
    </manifest>

亮点

  • 1.自动处理Android Camera、Storage权限(符合应用市场对隐私弹窗的样式要求),使用者无需处理权限
  • 2.图片选择器
  • 3.图片预览
  • 4.拍摄照片
  • 5.系统相册
  • 6.保存图片到相册
  • 7.视频选择器
  • 8.视频预览
  • 9.录制视频
  • 10.系统视频
  • 11.可对其他UTS插件、其他App提供图片选择器能力

使用

示例

<template>
    <view class="content">
        <image class="logo" :src="iconPath"></image>
        <video class="video" :src="videoPath"></video>
        <view class="text-area">
            <text class="title">{{title}}</text>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToImageSelectorPage">
                图片选择
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToImagePreviewPage">
                图片预览
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToImageCapturePage">
                拍摄照片
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToImageOfficialPage">
                系统照片
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToVideoSelectorPage">
                视频选择
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToVideoPreviewPage">
                视频预览
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToVideoCapturePage">
                录制视频
            </button>
        </view>
        <view class="buttonWrap">
            <button class="buttonItem buttonItemTopMargin" type="primary" @click="jumpToVideoOfficialPage">
                系统视频
            </button>
        </view>
    </view>
</template>

<script>
    import {
        imageAlbumApi,
        imagePreviewApi,
        captureImageApi,
        imageOfficialApi,
        saveImageToGalleryApi,
        videoAlbumApi,
        videoPreviewApi,
        captureVideoApi,
        videoOfficialApi
    } from "@/uni_modules/citycoder-mediaselector";
    export default {
        onLoad() {

        },
        data() {
            return {
                title: 'Hello',
                iconPath: '/static/logo.png',
                videoPath: '',
                imageSelectorPageStyle: {
                    // 公共样式配置
                    "commonPageStyle": {
                        // 页面主色
                        "pagePrimaryColor": "#1D1D20",
                        // 页面次色
                        "pageSecondaryColor": "#000000",
                        // 左方向箭头路径
                        "leftArrowPath": "",
                        // 对左方向箭头着色(颜色会覆盖图片)
                        "leftArrowTintColor": "#FFFFFF",
                        // 右方向箭头路径
                        "rightArrowPath": "",
                        // 对右方向箭头着色(颜色会覆盖图片)
                        "rightArrowTintColor": "#D8D8D8",
                        // 占位组件的颜色
                        "placeholderColor": "#EFEFEF",
                        // 按钮组件主色
                        "buttonPrimaryColor": "#FF4700",
                        // 按钮组件次色
                        "buttonSecondaryColor": "#47474D",
                        // 按钮组件圆角大小
                        "buttonRadius": 8,
                        // 选择组件主色
                        "checkedPrimaryColor": "#FF4700",
                        // 选择组件次色
                        "checkedSecondaryColor": "#FFFFFF",
                        // 文本组件主色
                        "textPrimaryColor": "#FFFFFF",
                        // 文本组件次色
                        "textSecondaryColor": "#60FFFFFF",
                        // 文本组件第三色
                        "textTertiaryColor": "#30FFFFFF"
                    },
                    // 对话框样式配置
                    "dialogStyle": {
                        // 警告对话框位置,位置,0:顶部,1:中间,2:底部,默认值:2
                        "alertDlgPosition": 2,
                        // 警告对话框背景颜色
                        "alertDlgBackgroundColor": "#FF2A2A2E",
                        // 警告对话框标题颜色
                        "alertDlgTitleColor": "#FFFFFF",
                        // 警告对话框分割线颜色
                        "alertDlgDividerColor": "#10FFFFFF",
                        // 警告对话框消息颜色
                        "alertDlgMessageColor": "#80FFFFFF",
                        // 警告对话框确定按钮文本颜色
                        "alertDlgSureTextColor": "#FF4700",
                        // 列表对话框背景颜色
                        "listDlgBackgroundColor": "#FF2A2A2E",
                        // 列表对话框分割线颜色
                        "listDlgDividerColor": "#10FFFFFF",
                        // 列表对话框每行item的文本颜色
                        "listDlgItemTitleColor": "#FFFFFF"
                    },
                    // 权限申请对话框样式
                    "permissionAdaptStyle": {
                        // 对话框,位置,0:顶部,1:中间,2:底部,默认值 2
                        "dialogPosition": 2,
                        // 进入App设置页面对话框标题
                        "settingsTitle": "权限设置提示",
                        // 进入App设置页面对话框取消按钮
                        "settingsCancelText": "取消",
                        // 进入App设置页面对话框确认按钮
                        "settingsSureText": "进入设置",
                        // 初次申请相机权限对话框标题
                        "cameraRequestTitle": "开启相机权限",
                        // 初次申请相机权限对话框消息
                        "cameraRequestMessage": "为了支持拍照上传图片,我们将征求你的同意来获取相机权限",
                        // 初次申请相机权限对话框确认按钮
                        "cameraRequestSureText": "我知道了",
                        // 相机权限拒绝时,给出解释对话框标题
                        "cameraExplainTitle": "App需要获取相机权限才能拍摄照片,否则部分功能无法正常使用",
                        // 相机权限拒绝时,给出解释对话框取消按钮
                        "cameraExplainCancelText": "取消",
                        // 相机权限拒绝时,给出解释对话框确认按钮
                        "cameraExplainSureText": "授权",
                        // 进入App设置页面对话框确消息 
                        "cameraSettingsMessage": "相机权限被拒绝,为了不影响您的正常使用,请在权限设置中开启对应权限",
                        // 初次申请存储权限对话框标题
                        "storageRequestTitle": "开启存储空间权限",
                        // 初次申请存储权限对话框消息
                        "storageRequestMessage": "为了您能下载文件、上传头像或图片、保存图片,我们将征求你的同意来获取存储空间权限",
                        // 初次申请存储权限对话框确认按钮
                        "storageRequestSureText": "我知道了",
                        // 存储权限拒绝时,给出解释对话框标题
                        "storageExplainTitle": "App需要获取存储权限才能显示图片,否则部分功能无法正常使用",
                        // 存储权限拒绝时,给出解释对话框取消按钮
                        "storageExplainCancelText": "取消",
                        // 存储权限拒绝时,给出解释对话框确认按钮
                        "storageExplainSureText": "授权",
                        // 进入App设置页面对话框确消息 
                        "storageSettingsMessage": "存储权限被拒绝,为了不影响您的正常使用,请在权限设置中开启对应权限"
                    },
                    // 相册页面样式配置
                    "albumPageStyle": {
                        // 标题栏左侧文字
                        "leadingTitle": "取消",
                        // 标题
                        "title": "手机相册"
                    },
                    // 图片选择器页面样式配置
                    "imageSelectorPageStyle": {
                        // 标题
                        "title": "所有图片",
                        // 标题栏右侧文字
                        "trailingTitle": "相册",
                        // loading组件,对loading组件中的loading、empty、failure图片着色(颜色会覆盖图片)
                        "loadingTintColor": "#FFFFFF",
                        // loading组件,loading图片地址
                        "loadingIconPath": "",
                        // loading组件,loading提示文本
                        "loadingText": "加载中...",
                        // loading组件,加载结果为空时图片地址
                        "loadingEmptyIconPath": "",
                        // loading组件,加载结果为空时文本
                        "loadingEmptyText": "暂无图片",
                        // loading组件,加载结果失败时图片地址
                        "loadingFailureIconPath": "",
                        // loading组件,加载结果失败时文本
                        "loadingFailureText": "图片加载失败",
                        // 多选模式时,最多选多少张图片对话框标题
                        "maxSelectedCountDlgTitle": "你最多只能选择%d张图片",
                        // 多选模式时,最多选多少张图片对话框确认按钮文本
                        "maxSelectedCountDlgSureText": "知道了",
                        // 底部操作栏,预览按钮文本
                        "previewActionText": "预览",
                        // 底部操作栏,完成按钮文本
                        "completeActionText": "完成"
                    },
                    // 图片预览页面样式配置
                    "imagePreviewPageStyle": {
                        // 是否显示标题
                        "showTitle": true,
                        // 预览组件背景色
                        "previewBackgroundColor": "#FF000000",
                        // 预览列表背景色
                        "previewListMaskColor": "#801D1D20",
                        // 底部操作栏,完成按钮文本
                        "completeActionText": "完成",
                    }
                },
                mediaSelectorAllPageStyle: {
                    "commonPageStyle": {
                        "buttonPrimaryColor": "#FF4700",
                        "buttonRadius": 8,
                        "buttonSecondaryColor": "#47474D",
                        "checkedPrimaryColor": "#FF4700",
                        "checkedSecondaryColor": "#FFFFFF",
                        "leftArrowPath": "",
                        "leftArrowTintColor": "#FFFFFF",
                        "pagePrimaryColor": "#1D1D20",
                        "pageSecondaryColor": "#000000",
                        "placeholderColor": "#EFEFEF",
                        "rightArrowPath": "",
                        "rightArrowTintColor": "#D8D8D8",
                        "textPrimaryColor": "#FFFFFF",
                        "textSecondaryColor": "#60FFFFFF",
                        "textTertiaryColor": "#30FFFFFF"
                    },
                    "dialogStyle": {
                        "alertDlgBackgroundColor": "#FF2A2A2E",
                        "alertDlgDividerColor": "#10FFFFFF",
                        "alertDlgMessageColor": "#80FFFFFF",
                        "alertDlgPosition": 2,
                        "alertDlgSureTextColor": "#FF4700",
                        "alertDlgTitleColor": "#FFFFFF",
                        "listDlgBackgroundColor": "#FF2A2A2E",
                        "listDlgDividerColor": "#10FFFFFF",
                        "listDlgItemTitleColor": "#FFFFFF"
                    },
                    "permissionAdaptStyle": {
                        "cameraExplainCancelText": "取消",
                        "cameraExplainSureText": "授权",
                        "cameraExplainTitle": "App需要获取相机权限才能拍摄照片,否则部分功能无法正常使用",
                        "cameraRequestMessage": "为了支持拍照上传图片,我们将征求你的同意来获取相机权限",
                        "cameraRequestSureText": "我知道了",
                        "cameraRequestTitle": "开启相机权限",
                        "cameraSettingsMessage": "相机权限被拒绝,为了不影响您的正常使用,请在权限设置中开启对应权限",
                        "dialogPosition": 2,
                        "settingsCancelText": "取消",
                        "settingsSureText": "进入设置",
                        "settingsTitle": "权限设置提示",
                        "storageExplainCancelText": "取消",
                        "storageExplainSureText": "授权",
                        "storageExplainTitle": "App需要获取存储权限才能显示图片,否则部分功能无法正常使用",
                        "storageRequestMessage": "为了您能下载文件、上传头像或图片、保存图片,我们将征求你的同意来获取存储空间权限",
                        "storageRequestSureText": "我知道了",
                        "storageRequestTitle": "开启存储空间权限",
                        "storageSettingsMessage": "存储权限被拒绝,为了不影响您的正常使用,请在权限设置中开启对应权限"
                    },
                    "albumPageStyle": {
                        "leadingTitle": "取消",
                        "title": "手机相册"
                    },
                    "imagePreviewPageStyle": {
                        "completeActionText": "完成",
                        "previewBackgroundColor": "#FF000000",
                        "previewListMaskColor": "#801D1D20",
                        "showTitle": true
                    },
                    "imageSelectorPageStyle": {
                        "completeActionText": "完成",
                        "loadingEmptyIconPath": "",
                        "loadingEmptyText": "暂无图片",
                        "loadingFailureIconPath": "",
                        "loadingFailureText": "图片加载失败",
                        "loadingIconPath": "",
                        "loadingText": "加载中...",
                        "loadingTintColor": "#FFFFFF",
                        "maxSelectedCountDlgSureText": "知道了",
                        "maxSelectedCountDlgTitle": "你最多只能选择%d张图片",
                        "previewActionText": "预览",
                        "title": "所有图片",
                        "trailingTitle": "相册"
                    },
                    "videoPreviewPageStyle": {
                        "completeActionText": "完成",
                        "playerIconPath": "",
                        "previewBackgroundColor": "#FF000000",
                        "previewListMaskColor": "#801D1D20",
                        "showTitle": true
                    },
                    "videoSelectorPageStyle": {
                        "completeActionText": "完成",
                        "loadingEmptyIconPath": "",
                        "loadingEmptyText": "暂无视频",
                        "loadingFailureIconPath": "",
                        "loadingFailureText": "视频加载失败",
                        "loadingIconPath": "",
                        "loadingText": "加载中...",
                        "loadingTintColor": "#FFFFFF",
                        "maxSelectedCountDlgSureText": "知道了",
                        "maxSelectedCountDlgTitle": "你最多只能选择%d个视频",
                        "previewActionText": "预览",
                        "title": "所有视频",
                        "trailingTitle": "相册"
                    }
                }
            }
        },
        methods: {
            jumpToImageSelectorPage() {
                let _that = this
                imageAlbumApi({
                    pageStyle: _that.imageSelectorPageStyle,
                    selectMode: 2,
                    maxSelectedCount: 3,
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.iconPath = result[0]
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToImagePreviewPage() {
                let _that = this
                imagePreviewApi({
                    imagePaths: [
                        "https://smart-network.oss-cn-hangzhou.aliyuncs.com/app/feedback/F00100149/1711626309474.jpg",
                        "/static/logo.png"
                    ],
                    pageStyle: _that.mediaSelectorAllPageStyle,
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.iconPath = result[0]
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToImageCapturePage() {
                let _that = this
                captureImageApi({
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.iconPath = result
                        saveImageToGalleryApi({
                            imagePath: result,
                            success: () => {
                                console.log("Page. 图片保存成功")
                            },
                            failure: (res) => {
                                console.log("Page failure. 图片保存失败" + res.errCode + ",错误消息:" + res
                                    .errMsg)
                            }
                        })
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToImageOfficialPage() {
                let _that = this
                imageOfficialApi({
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.iconPath = result
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToVideoSelectorPage() {
                let _that = this
                videoAlbumApi({
                    pageStyle: _that.mediaSelectorAllPageStyle,
                    selectMode: 2,
                    maxSelectedCount: 3,
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.videoPath = result[0]
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToVideoPreviewPage() {
                let _that = this
                videoPreviewApi({
                    videoPaths: [
                        "https://minigame.vip/Uploads/images/2021/09/18/1631951892_page_img.mp4",
                        "https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4"
                    ],
                    pageStyle: _that.mediaSelectorAllPageStyle,
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.videoPath = result[0]
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToVideoCapturePage() {
                let _that = this
                captureVideoApi({
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.videoPath = result
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            },
            jumpToVideoOfficialPage() {
                let _that = this
                videoOfficialApi({
                    success: (result) => {
                        console.log("Page. " + result)
                        _that.videoPath = result
                    },
                    failure: (res) => {
                        console.log("Page failure. " + res.errCode + ",错误消息:" + res.errMsg)
                    }
                })
            }
        }
    }
</script>

<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .logo {
        height: 200rpx;
        width: 200rpx;
        margin-top: 16rpx;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 50rpx;
    }

    .video {
        height: 108rpx;
        width: 192rpx;
        margin-top: 16rpx;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 50rpx;
    }

    .text-area {
        display: flex;
        justify-content: center;
    }

    .title {
        font-size: 36rpx;
        color: #8f8f94;
    }

    .buttonWrap {
        display: flexbox;
        width: 100%;
        padding: 0 16px;
    }

    .buttonItem {
        position: relative;
        display: block;
        margin-left: 16px;
        margin-right: 16px;
        padding-left: 14px;
        padding-right: 14px;
        box-sizing: border-box;
        font-size: 18px;
        text-align: center;
        text-decoration: none;
        line-height: 2.55555556;
        border-radius: 5px;
        -webkit-tap-highlight-color: transparent;
        overflow: hidden;
        color: #000;
        background-color: #f8f8f8;
        cursor: pointer;
    }

    .buttonItemTopMargin {
        margin-top: 16px;
    }
</style>

Api介绍

  • 1.imageAlbumApi 图片选择器Api
  • 2.imagePreviewApi 图片预览Api
  • 3.captureImageApi 拍摄照片Api
  • 4.imageOfficialApi 系统相册Api
  • 5.saveImageToGalleryApi 保存图片到相册Api
  • 6.videoAlbumApi 视频选择器Api
  • 7.videoPreviewApi 视频预览Api
  • 8.captureVideoApi 录制视频Api
  • 9.videoOfficialApi 系统视频Api

Error Api介绍

错误码、错误消息详见插件的unierror.uts、interface.uts中的MediaSelectorErrorCode

样式定制

样式Api可看插件的interface.uts中的注释

  • 1.pageStyle配置媒体选择器页面样式

图片

部分样式支持传图片,支持本地static目录中的图片、网络图片(http开头) 例:

commonPageStyle: {
  leftArrowPath:"/static/logo.png",
  // leftArrowPath:"http://www.......",
  // leftArrowPath:"https://www.......",
}

个人博客

CSDN

DCloud个人中心

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问