Android搜索本地文件

作者: 奔跑吧李博 | 来源:发表于2022-12-18 00:03 被阅读0次

    最近做了一个搜索本地文件功能,搜索文件范围包括日志,apk,pdf,txt,jpg,zip,mp3,mp4等各种文件。使用了contentResolver访问本地文件数据,效果如下:

    文件实体类FileBean:

    data class FileBean(val fileName: String, val path: String)
    

    文件搜索管理类SearchFileProvider:
    查询的uri为MediaStore.Files.getContentUri("external"),查询条件为各位类型文件。

    object SearchFileProvider {
        private const val MAX_FILE_COUNT = 30
    
        /**
         * 模糊查询本地文件
         */
        fun searchLocalFile(context: Context, key: String): ArrayList<FileBean> {
            var list = ArrayList<FileBean>()
            val volumeName = "external"
            val columns = arrayOf(MediaStore.Files.FileColumns.DATA)
            val selection = MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.mp3' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.json' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.log' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.apk' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.mp4' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.pdf' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.txt' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.jpg' OR " +
                    MediaStore.Files.FileColumns.DATA + " LIKE '%$key%.zip'"
            var cursor: Cursor? = null
            try {
                cursor = context.contentResolver.query(
                    MediaStore.Files.getContentUri(volumeName),
                    columns,
                    selection,
                    null,
                    null
                )
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        if (list.size < MAX_FILE_COUNT) {
                            val absolutePath = cursor.getString(0)
                            File(absolutePath).apply {
                                if (exists() && !TextUtils.isEmpty(name) && name.contains(".")) {
                                    if (!TextUtils.isEmpty(name)) {
                                        var bean = FileBean(name, path)
                                        list.add(bean)
                                    }
                                }
                            }
                        } else {
                            return list
                        }
                    }
                }
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            } finally {
                try {
                    if (cursor != null) {
                        cursor.close()
                        cursor = null
                    }
                } catch (e: java.lang.Exception) {
                }
            }
            return list
        }
    }
    

    这里是列表adapter:

    class FileAdapter(val context: Context): RecyclerView.Adapter<FileAdapter.FileViewHolder>() {
        private var datas = ArrayList<FileBean>()
    
        fun setDatas(datas: ArrayList<FileBean>) {
            this.datas = datas
            notifyDataSetChanged()
        }
    
        class FileViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
            var ivIcon: ImageView?= null
            var tvName: TextView?= null
    
            init {
                ivIcon = itemView.findViewById(R.id.iv_icon)
                tvName = itemView.findViewById(R.id.tv_file_name)
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileViewHolder {
            return FileViewHolder(LayoutInflater.from(context).inflate(R.layout.item_file, parent, false))
        }
    
        override fun onBindViewHolder(holder: FileViewHolder, position: Int) {
            holder.tvName?.text = datas[position].fileName
            setFileIcon(holder.ivIcon!!, datas[position].fileName)
    
            holder.itemView.setOnClickListener {
    
            }
        }
    
        override fun getItemCount(): Int {
            return datas.size
        }
    
        /**
         * 根据文件后缀类型设置对应类型图标
         */
        private fun setFileIcon(imageView: ImageView, fileName: String) {
            if (fileName.endsWith(".jpg") || fileName.endsWith(".mp4")) {
                imageView.background = context.resources.getDrawable(R.drawable.category_file_icon_pic_phone)
            } else {
                var drawableId = 0
                if (fileName.endsWith(".txt") || fileName.endsWith(".pdf")) {
                    drawableId = R.drawable.category_file_icon_doc_phone
                } else if (fileName.endsWith(".zip")) {
                    drawableId = R.drawable.category_file_icon_zip_phone
                } else if (fileName.endsWith(".mp3")) {
                    drawableId = R.drawable.category_file_icon_music_phone
                } else if (fileName.endsWith(".apk")) {
                    drawableId = R.drawable.category_file_icon_apk_phone
                } else {
                    drawableId = R.drawable.ic_local_file
                }
                imageView.background = context.resources.getDrawable(drawableId)
            }
        }
    }
    

    然后,需要能够访问文件,别忘了加上6.0访问权限里的WRITE_EXTERNAL_STORAGE权限,获取本地文件访问的权限。并且注意,在targetsdk 29及以下,可以访问所有问题,高于29,则只能够访问到图片,视频,音乐这样的多媒体文件。

    相关文章

      网友评论

        本文标题:Android搜索本地文件

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