美文网首页
分页查询手机相册地址

分页查询手机相册地址

作者: 人世看客 | 来源:发表于2022-04-26 17:44 被阅读0次

一、背景

公司需要定制相册选择页面ui样式,并且功能不是很多时,这时候要考虑自己去实现相册选择

二、我们需要了解的一些知识

1.获取相册图片地址首先是需要权限的,这里所需要的权限是文件读写权限Manifest.permission.WRITE_EXTERNAL_STORAGE,这个权限需要动态去申请,这里就不讲解了
2.Android Q以后,文件这一块改成了沙盒模式,应用只能访问自己沙盒下的文件和公共媒体文件。不在具有访问其它app文件的权限

三、具体实现代码

    val mPageSize = 100
    val projection = arrayOf(
        MediaStore.Images.Media._ID,
        MediaStore.Files.FileColumns.DATE_MODIFIED
    )
    /**
     *  分页查询媒体库
     *  Android 8.0及以上使用 queryArgs 分页(以用来兼容Android11,android 11 不可用 sortOrder 分页)
     *  Android 8.0以下使用 sortOrder 分页
     *  page从0开始
     */
    fun queryMediaStoreImages(context: Context, page: Int) {
        val uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        var cursor: Cursor ?= null
        // 倒序+分页
        val sortOrder = MediaStore.Images.Media.DATE_ADDED + " DESC limit " + mPageSize + " offset " + page * mPageSize
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val queryArgs = createSqlQueryBundle(null,null,sortOrder, mPageSize,page)

                cursor = context.contentResolver.query(
                    uri,
                    projection,
                    queryArgs,
                    null
                )
            }else{
                val selection: String? = null
                val selectionArgs: Array<String>? = null

                cursor = context.contentResolver.query(
                    uri,
                    projection,
                    selection,
                    selectionArgs,
                    sortOrder,
                )
            }
        }catch (e: Exception){
            LogUtils.d("获取手机相册错误")
        }
        val columnIndexID: Int
        var imageId: Long
        if (cursor != null) {
            columnIndexID = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
            var i = 0
            while (cursor.moveToNext()) {
                imageId = cursor.getLong(columnIndexID)
                val uriImage = Uri.withAppendedPath(uri, "" + imageId)
                Log.d("print","${++i}")
                Log.d("print",uriImage.toString())
            }
            cursor.close()
        }
    }

    /**
     * android o以上处理返回bundler
     */
    @RequiresApi(Build.VERSION_CODES.O)
    fun createSqlQueryBundle(
        selection: String?,
        selectionArgs: Array<String?>?,
        sortOrder: String?,
        limitCount: Int,
        offset: Int
    ): Bundle? {
        if (selection == null && selectionArgs == null && sortOrder == null) {
            return null
        }
        val queryArgs = Bundle()
        if (selection != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
        }
        if (selectionArgs != null) {
            queryArgs.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
        }
        if (sortOrder != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, sortOrder)
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
            // 设置倒序
            queryArgs.putInt(
                ContentResolver.QUERY_ARG_SORT_DIRECTION,
                ContentResolver.QUERY_SORT_DIRECTION_DESCENDING
            )
            // 设置倒序条件--文件添加时间
            queryArgs.putStringArray(
                ContentResolver.QUERY_ARG_SORT_COLUMNS,
                arrayOf(MediaStore.Files.FileColumns.DATE_ADDED)
            )
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_LIMIT, "$limitCount offset $offset")
        }
        return queryArgs
    }

四、代码讲解

1.我们自定义相册,肯定需要分页,这里的mPageSize是每页条数,queryMediaStoreImages()此方法传入页码,需要注意的是page是从0开始的。
2.这里分为了两种查询, 是因为o以后改为Bundle构建查询参数
3.这里返回的是Uri集合,如果想返回的是文件路劲,在循环解析cursor游标中使用如下代码

 if (cursor != null) {
       val columnIndexID = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
       while (cursor.moveToNext()) {
             val path = cursor.getString( columnIndexID)
        }
        cursor.close()
  }

path就是文件地址,MediaStore.Images.Media.DATA会提示过时,大概就是官方现在不推荐使用路基去访问

相关文章

网友评论

      本文标题:分页查询手机相册地址

      本文链接:https://www.haomeiwen.com/subject/zrxwertx.html