1、概述

项目中可能会有对android系统文件进行选择查看等操作,比如修改图像,文件浏览器等场景。前不久因为项目需要,需要实现一个文件浏览器,所以在此分享一下项目中的一些经验。

2、权限获取

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//6.0以后ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},100);//10 以后 application标签中添加android:requestLegacyExternalStorage="true"//11(api30) 获取管理文件权限 需要发送一个意图 让用户来授权Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION

3、扫描获取文件

扫描获取文件时,特别是对全盘扫描时,会是一个非常耗时的操作,通常手机中的文件会在几万到几十万个不等,通过 递归逐个获取文件对象(new 一个文件对象),来获取文件信息,异步时间可能在10秒左右扫描完毕,开启多个线程一起 扫描不经不会提速很多,还要控制多线程问题,也不可取,最后选择使用android系统提供的MediaStore来获取文件,MediaStore这类主要就是给你提供获取各种文件所存放的表名也就是内容提供者的URI,我们就可以通过contentresolver来查询数据。但是还需要扫描单独某个文件夹下的文件怎么办了,因为是单独的一个文件夹,文件数量不会太多,我们就可以使用递归的方式扫描,比如微信和qq文件。

3.1mediaStore获取文件列表

 ContentResolver contentResolver = MyApplication.getInstance().getContentResolver();queryVideo(contentResolver);queryImage(contentResolver);queryByMime(contentResolver);queryOther(contentResolver);private void queryOther(ContentResolver contentResolver) {String selection = "(" + MediaStore.Files.FileColumns.DATA + " LIKE '%.xls'" +" or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.docx'" +" or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.apk'" +" or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.xlsx'" +" or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.zip'" +" or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.rar'" + ")";Cursor cursor = contentResolver.query(MediaStore.Files.getContentUri("external"), null, selection, null, MediaStore.Files.FileColumns.DATE_ADDED + " DESC");parseCursor(cursor);}private void queryByMime(ContentResolver contentResolver) {String selection = "mime_type = ? or mime_type = ? or mime_type = ? or mime_type = ? ";String[] selectionArgs = new String[]{"text/html", "application/msword", "application/pdf", "text/plain"};Cursor cursor = contentResolver.query(MediaStore.Files.getContentUri("external"), null, selection, selectionArgs, MediaStore.Files.FileColumns.DATE_ADDED + " DESC");parseCursor(cursor);}private void queryImage(ContentResolver contentResolver) {Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media.MIME_TYPE + "= ? or " +MediaStore.Images.Media.MIME_TYPE + "= ? ", new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED);parseCursor(cursor);}private void queryVideo(ContentResolver contentResolver) {Cursor cursor = contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Video.Media.MIME_TYPE + "= ? or " +MediaStore.Video.Media.MIME_TYPE + "= ?", new String[]{"video/mp4", "video/x-flv"}, MediaStore.Images.Media.DATE_MODIFIED);parseCursor(cursor);}private void parseCursor(Cursor cursor) {if (cursor == null) {return;}while (cursor.moveToNext()) {//String mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE));String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA));long modifyTimed = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_MODIFIED));modifyTimed = modifyTimed * 1000;String displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME));int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE));LogUtil.i("lihui" ,"size " + size + "dispaly " + displayName + "path " + path);}cursor.close();}

上面通过传入一个contentResolver对象就可以获取数据,其实就是sql查询,有些不能通过媒体类型查询的文件就通过指定SQL语句来过滤记录,注意写selection语句的字符串时最后一个?后的空格不能去掉,不然会查询失败,另外获取到cursor后也就是获取到一条记录后,需要先根据字段名获取下标,然后根据下标获取改字段的内容,DATA表示内容也就是该文件的路径、DATE_MODIFIED表示最后被修改时间(单位时秒不是毫秒)、DISPALY_NAME表示文件名、SIZE表示文件大小(单位时字节),

3.2递归获取文件

      private void internalIterator(File rootDirectoryFile) {if (rootDirectoryFile == null) {return;}File[] listFiles = rootDirectoryFile.listFiles();if (listFiles == null || listFiles.length == 0) {return;}for (final File listFile : listFiles) {if (listFile == null) {return;}//TODO somethingif (listFile.isDirectory()) {internalIterator(listFile);}}}

3.3获取人类能理解的大小

public static String getHumanSize(long totalSpace) { //字节double oneG = 1024 * 1024 * 1024; //一g多少字节double oneM = 1024 * 1024;double oneK = 1024;DecimalFormat df = new DecimalFormat("#.00");if (totalSpace >= oneG) {String result = df.format(totalSpace / oneG);return result + "GB";}if (totalSpace >= oneM) {String result = df.format(totalSpace / oneM);return result + "MB";}if (totalSpace >= oneK) {String result = df.format(totalSpace / oneK);return result + "KB";}return totalSpace + "B";}

4、删除和重命名文件

1、删除文件我们直接可以调用delete方法
2、重命名我们可以renameTo方法,传入一个新文件对象
3、更新MediaStore,因为删除或者重命名后需要更新列表,如果不手动触发更新,系统只会在重启后更新,显然不合理,所以需要用到MediaScannerConnection
4、如果只是需要删除文件,也可用用contentresolver的delete,删除字条记录
     //参数一为上下文 参数二为路径数组,经过测试可以是文件夹,参数三是媒体类型,传入null会自动推断,参数四为更新回调,如果路径文件不存在会删除记录。MediaScannerConnection.scanFile(context.getApplicationContext(),path,null,completedListener);//通过contentresolver删除int res = 0;if (filePath.endsWith(".mp4") || filePath.endsWith(".flv")) {res = mContext.getContentResolver().delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,MediaStore.Video.Media.DATA + "= \"" + filePath + "\"",null);} else if (filePath.endsWith(".jpg") || filePath.endsWith(".png") || filePath.endsWith(".bmp") || filePath.endsWith(".jpeg")) {res = mContext.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,MediaStore.Images.Media.DATA + "= \"" + filePath + "\"",null);} else {res = mContext.getContentResolver().delete(MediaStore.Files.getContentUri("external"),MediaStore.Files.FileColumns.DATA + "= \"" + filePath + "\"",null);}

android 文件扫描MediaStore相关推荐

  1. android 扫描手机内存和SD卡,获取手机的视频、音频文件。把获取不到的文件扫描出来

    网上查了下android手机扫描内存或者SD卡里面的音频或者视频文件,进行显示.但是有些视频或者音频扫描不出来.有其中一个原因是当你添加了一个视频或者音频文件后,手机自身没有重新进行扫描.只有手机重启 ...

  2. Android N Android O 默认MTP模式 实时文件扫描

    背景 最近客户那边反馈需求希望我司的设备能像三星的机器一样,usb连接电脑的时候默认是mtp模式,同时可以解决电脑查看手机上的文件有时候不一致的问题(也就是手机上创建的新文件或者目录,电脑上不能及时看 ...

  3. android扫描sd卡图片,Android SD卡 全盘文件扫描

    在开发的过程中,有时候会遇到需要读取多媒体文件的需求,面对这样的需求,通常我们有两种解决方案:自己扫描全盘文件,或者使用ContentResolver读取系统记录. 一般需求不是特别复杂的情况下,直接 ...

  4. android Mp3播放器之音频文件扫描

    文件扫描类.代码很简单将扫描到的文件保存在Vector<file>列表里 [java] view plain copy package com.aws.util; import java. ...

  5. Android存储之MediaStore的使用

    Android系统内容提供者ContentProvider 安卓系统会在每次开机之后扫描所有文件并分类整理存入数据库,这个数据库保存了手机上存储的所有文件的信息.该数据库文件存放在Android设备的 ...

  6. android获取卡号号码,Android银行卡扫描获取银行卡号

    ard.io开源的银行卡扫描的三方库真的是很好用啊. 首先需要在你的module的gradle的依赖文件中添加依赖 compile 'io.card:android-sdk:5.5.1' 2 清单文件 ...

  7. android 上下扫描动画,Android扫描雷达动画

    很简单的一个组合动画,用好基本动画啥子效果都不怕 老规矩先上图 效果图.gif ok 来 既然往下翻那就看看如何实现的吧 首先效果分为两部分 第一部分中间指针(其实这里就是一张图片) 第二部分就是波纹 ...

  8. Android设备扫描机制详解

    Android设备扫描机制详解 本文基于Android pie,对Android的设备扫描机制做一个全面的解析,由于本人掌握的知识有限,如有讲错的地方还请大家指出来. Android提供了一套扫描机制 ...

  9. Android手机扫描mDNS服务

    mDNS即组播DNS(multicast DNS).使用5353端口,在内网没有DNS服务器时,就会出现此组播信息.mDNS 基于 UDP 协议..com/ 在一个局域网内,每个进入局域网的主机,如果 ...

最新文章

  1. JavaScript 写几个简单的知识点
  2. Ubentu编译Android源码(AOSP)
  3. 解决pathForResource返回nil / 无法读取plist文件问题
  4. 【js与jquery】三级联动菜单的制作
  5. 哈罗顺风车送到终点吗_没有了顺风车,滴滴“特惠拼车”来了!比拼车更低价,比顺风车更安全吗?...
  6. SpringBoot获取配置文件常量值
  7. php几个问题的记录
  8. ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”
  9. 最简单的方法实现小程序按钮跳转到指定界面
  10. h5页面自定义字体_H5页面字体设置
  11. 当你的浏览器页面被篡改时,我们该怎么办
  12. 树莓派2代B型性能极限测试
  13. Android车载蓝牙相关开发2:蓝牙总入口BluetoothAdapter
  14. 使用 Metasploit 利用 OpenSSH 用户枚举漏洞 (CVE-2018-15473, CVE-2016-6210, CVE-1999-0502)
  15. 【产品经理】产品经理的日常工作
  16. 抵抗勒索病毒的正确姿势——不要上来就封端口!
  17. android o 结构光流程,【OPPOFindX评测】O-Face 3D结构光:最科幻的交互方式-中关村在线...
  18. hackthebox - inception (考点:dompdf apache配置 webdav 3128 proxy tftp apt update 提权 ssh-key提权)
  19. Vue生命周期详解图
  20. Deep Learning Chapter01:机器学习中高数知识

热门文章

  1. 敏捷下的scrim、xp、3355、TDD、BDD、CI、DI及四个仪式、十二原则汇总
  2. cassandra java cql_Cassandra CQL v3.3中文文档(下)
  3. 程序员用代码求救 同事“秒懂”
  4. python 创建netcdf_如何用python netCDF4创建netCDF文件?
  5. Linux tac命令
  6. 信息收集之通过JS拓展信息面
  7. AWS CLI 安装配置
  8. 网页保存mhtml格式
  9. python牛顿法算立方根_立方根求解(牛顿迭代法)
  10. python给成绩表加上姓名列_Python Pandas 基本操作教学之成绩表