Android搜索本地文件
2022-12-18 本文已影响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,则只能够访问到图片,视频,音乐这样的多媒体文件。