本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现。

先贴上效果图:

获取外置存储设备并监听插拔状态

获取文件内容

前言

先说需求,App在引导过程中,通过外置存储设备(U盘或者sd卡)上传指定的配置文件,开始我没打算用系统方法,网上看到 libaums 这个库文件,尝试使用了一下,但是最后发现它并不能友好的支持NTFS格式U盘,能监听到,但是好像没有办法获取到路径,最后看官方也说了不支持NTFS格式,最后索性直接使用系统方法,反正有权限,真的可以为所欲为。

正文

可以看到系统设置里面,是能监听到ntfs格式u盘(Evan_zch)的,并且能获取U盘里面的文件,这样就好办了,挽起袖子直接开干。

1、页面定位

要查看具体某个功能的源码,可以通过界面定位,这样能更快的找到我们想要的代码。

通过执行下面代码,可以直接定位当前展示界面的包名和类名。

linux:

adb shell dumpsys activity | grep "mFocusedActivity"

windows:

adb shell dumpsys activity | findstr "mFocusedActivity"

执行结果:

此时可以定位到系统设置存储界面是StorageSettingsActivity,这个时候可以去 Android OS 这个网站搜索并查看相应的源码。

Snipaste_2018-09-20_11-43-55.png

2、源码分析

直接查看 StorageSettings 这个界面源码,这个比较简单,大致还是能看的清楚,因为项目时间比较紧,没有仔细去研究,只贴一些关键代码,具体能实现我的需求,等完成了这个项目,再好好来琢磨。

private StorageManager mStorageManager;

// 创建 StorageManager

mStorageManager = context.getSystemService(StorageManager.class);

// 注册监听

mStorageManager.registerListener(mStorageListener);

// 监听回调

private final StorageEventListener mStorageListener = new StorageEventListener() {

@Override

public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {

if (isInteresting(vol)) {

refresh();

}

}

@Override

public void onDiskDestroyed(DiskInfo disk) {

refresh();

}

};

private static boolean isInteresting(VolumeInfo vol) {

switch(vol.getType()) {

// 内置存储设备

case VolumeInfo.TYPE_PRIVATE:

// 外置存储设备

case VolumeInfo.TYPE_PUBLIC:

return true;

default:

return false;

}

}

在源码中,直接在 onCreate 方法中创建 StorageManager 然后通过 registerListener 注册存储设备的监听,在监听回调里可以直接判断存储设备的状态,其中说一下 onVolumeStateChanged 回调中的 oldState 和 newState 参数。通过查看源码,能发现在 VolumeInfo 类中设置了存储设备的一些基本状态。

public static final int STATE_UNMOUNTED = 0;

public static final int STATE_CHECKING = 1;

public static final int STATE_MOUNTED = 2;

public static final int STATE_MOUNTED_READ_ONLY = 3;

public static final int STATE_FORMATTING = 4;

public static final int STATE_EJECTING = 5;

public static final int STATE_UNMOUNTABLE = 6;

public static final int STATE_REMOVED = 7;

public static final int STATE_BAD_REMOVAL = 8;

在回调中添加打印日志:

通过后台日志,可以发现在U盘插入过程中,其状态变化为:

STATE_UNMOUNTED ——> STATE_CHECKING ——> STATE_MOUNTED

U盘插入日志

U盘拨出,状态变化:

STATE_EJECTING ——> STATE_UNMOUNTED ——> STATE_BAD_REMOVAL

最后调用监听回调中的 onDiskDestroyed 方法。

U盘拔出日志

为了避免 onVolumeStateChanged 的多次回调,我自己写了个判断方法 isMounted,我们可以在 onVolumeStateChanged 加入 isMounted判断方法,只有当是外置存储设备且挂载成功后才进行ui更新。

public boolean isMounted(VolumeInfo vol, int oldState, int newState) {

return (isInteresting(vol) && oldState != newState && newState == VolumeInfo.STATE_MOUNTED);

}

private static boolean isInteresting(VolumeInfo vol) {

switch (vol.getType()) {

// 这里我们只关心外置存储设备,所以直接注释掉了 TYPE_PRIVATE

// case VolumeInfo.TYPE_PRIVATE:

case VolumeInfo.TYPE_PUBLIC:

return true;

default:

return false;

}

}

在监听回调后,可以通过StorageManager类的 getVolumes方法,获取所有的存储设备。

public List getStorageDeviceList() {

if (mStorageManager == null) {

throw new RuntimeException("StorageManagerUtils not init");

}

List volumes = mStorageManager.getVolumes();

List publicVolumes = new ArrayList<>();

publicVolumes.clear();

for (VolumeInfo info : volumes) {

int type = info.getType();

// 获取当前存储设备的路径

File path = volumeInfo.getPath();

// 同样的,只关心外置存储设备。

if (info.getType() == VolumeInfo.TYPE_PUBLIC) {

publicVolumes.add(info);

}else if(info.getType() == VolumeInfo.TYPE_PRIVATE){

// 获取内置存储设备

}

}

return publicVolumes;

}

当拿到设备后,通过 VolumeInfo 类的 getPath 方法就可以获取到U盘具体路径

后面就可以通过这个路径直接获取U盘的文件了,基本就大功告成,时间有点急,写得有点粗糙,后面有时间再整理一下。

最后贴一下工具类的完整代码:

/**

* @author Evan_zch

* @date 2018/9/17 19:13

*

* 存储设备管理类

*/

public class StorageManagerUtils {

private static final String TAG = "StorageManagerUtils";

private final StorageManager mStorageManager;

private static long totalBytes = 0;

private static long usedBytes = 0;

private static final class StorageManagerHolder {

private static final StorageManagerUtils INSTANCE = new StorageManagerUtils();

}

public static StorageManagerUtils getInstance() {

return StorageManagerHolder.INSTANCE;

}

private StorageManagerUtils() {

mStorageManager = DigiTvApplication.getAppContext().getSystemService(StorageManager.class);

}

public List getStorageDeviceList() {

if (mStorageManager == null) {

throw new RuntimeException("StorageManagerUtils not init");

}

List volumes = mStorageManager.getVolumes();

List publicVolumes = new ArrayList<>();

publicVolumes.clear();

for (VolumeInfo info : volumes) {

int type = info.getType();

if (info.getType() == VolumeInfo.TYPE_PUBLIC) {

Logutils.d(TAG + "--refresh type is public");

String bestVolumeDescription = mStorageManager.getBestVolumeDescription(info);

File path = info.getPath();

Logutils.d(TAG + "--refresh type=" + type + ",bestVolumeDescription=" + bestVolumeDescription + ",path=" + path);

publicVolumes.add(info);

}

}

return publicVolumes;

}

public boolean isMounted(VolumeInfo vol, int oldState, int newState) {

return (isInteresting(vol) && oldState != newState && newState == VolumeInfo.STATE_MOUNTED);

}

private static boolean isInteresting(VolumeInfo vol) {

switch (vol.getType()) {

//case VolumeInfo.TYPE_PRIVATE:

case VolumeInfo.TYPE_PUBLIC:

return true;

default:

return false;

}

}

public String getTotalSize(VolumeInfo vol) {

if (vol.isMountedReadable()) {

final File path = vol.getPath();

if (totalBytes <= 0) {

totalBytes = path.getTotalSpace();

}

}

return Formatter.formatFileSize(DigiTvApplication.getAppContext(), totalBytes);

}

public String getUsedSize(VolumeInfo vol) {

if (vol.isMountedReadable()) {

final File path = vol.getPath();

final long freeBytes = path.getFreeSpace();

usedBytes = totalBytes - freeBytes;

}

return Formatter.formatFileSize(DigiTvApplication.getAppContext(), usedBytes);

}

}

android u盘挂载监听,Android SD卡及U盘插拔状态监听及内容读取相关推荐

  1. Android SD卡及U盘插拔状态监听和内容读取

    本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现. 先贴上效果图: 获取外置存储设备并监听插拔状态 获取 ...

  2. android u盘自动挂载点,Android2.3实现SD卡与U盘自动挂载的方法

    本文实例讲述了Android2.3实现SD卡与U盘自动挂载的方法.分享给大家供大家参考,具体如下: 在 s3c6410平台上移植android2.3 过程中SD卡总是不能自动挂载. 查阅相关资料,知道 ...

  3. Android区分SD卡和U盘

    写过这个功能的童鞋应该很理解我,当初找了大量的资料也只能做到在两者都插入时分辨出哪个是哪个,只插入其中一方,则一脸无奈,当初我甚至在界面上写"检测U盘或SD卡插入,总容量为xx,可用容量为x ...

  4. Android文件系统管理——版本内外存所指差异,获得外接SD/U盘路径,在SD卡与U盘间传送文件,两天辛酸泪,收藏不迷路

    在开发一个文件管理系统的路上,总有坑在等着你. 前情提示:因为该系统的使用方需要严格保密文件,导致它失去了无线传输功能,只能通过外设传输文件. 在没接触这个功能之前,我想大家应该都觉得手机自带的存储空 ...

  5. android加密设备,用于Android手机的加密设备和加密外部SD卡

    电话被盗或丢失后,隐私将被泄露. Android手机具有"加密设备"和"加密外部SD卡"功能. 那么这两个功能有什么区别? 加密设备 加密设备后,内置SD卡上的 ...

  6. wince 快速挂载SD卡及U盘

    作者:Apollo5520 转自:http://blog.chinaunix.net/uid-8087110-id-1989039.html 1.起初我的wince bsp 在插入8G u盘时需要等待 ...

  7. 2019 SD卡、U盘无法格式化怎么办的解决方法

    有天 闲的没事, 格式化一下U盘 ,结果突然断电了,我的天.我还在格式化的U盘 ,果然 ,我在此启动电脑后,的U盘直接 就不能用了.于是 我格式化. 然后,我的U盘就怎么也格式化不好了 ,找到了几种解 ...

  8. ZYNQ裸机实现 USB MASS STORAGE (usb+sd卡 实现U盘功能)

    ZYNQ裸机实现 USB MASS STORAGE (usb+sd卡 实现U盘功能) 之所以写裸机,也就是没有操作系统的实现方法是因为linux系统下的实现方法网上已经有很多了,之前使用的STM32实 ...

  9. windows无法格式化u盘_2019 SD卡、U盘无法格式化怎么办的解决方法

    有天 闲的没事, 格式化一下U盘 ,结果突然断电了,我的天.我还在格式化的U盘 ,果然 ,我在此启动电脑后,的U盘直接 就不能用了.于是 我格式化. 然后,我的U盘就怎么也格式化不好了 ,找到了几种解 ...

最新文章

  1. Java垃圾回收之老年代垃圾收集器
  2. 集成支付宝钱包支付iOS SDK的方法与经验
  3. tkinter回调异常_使用matplotlib保存动画时Tkinter回调出现异常
  4. TCP连接之未连接队列的理解[转]
  5. servlet session持久化
  6. 微软的创新还是败笔?Windows 8为苹果创造天赐良机
  7. .net模式子窗口传值给父窗口
  8. ASP.NETSpring.NETNHibernate最佳实践(七)——第3章人事子系统(4)人事子系统小结...
  9. java版的mrp模拟器_mrp模拟器(simulator)
  10. VTN:视频Transformer网络
  11. matlab画基尼系数,matlab 拟合洛伦兹曲线求基尼系数
  12. 采集用python还是火车头_火车采集器V9插件开发手册
  13. 利用Python爬取拉勾网招聘信息
  14. python 霍夫直线变换_霍夫线变换
  15. NVIDIA Jetson之PWM风扇自定义控制
  16. micropython 进阶小实验 如何用单片机制作鞋码匹配仪
  17. 均方误差——MSE 和标准差 的区别
  18. Vijos P1794 文化之旅
  19. Angular文件创建命令
  20. 苏州技师学院计算机专业怎么样,苏州技师学院口碑怎么样

热门文章

  1. Web端CAD图形找不同?一键在Web端找出CAD图不同并对比分析
  2. Python语法解析器PLY( lex and yacc in Python)
  3. 面包板入门制作之光敏电阻,
  4. EM算法推断混合高斯模型参数
  5. Eclipse 字体、字号的设置、最佳字体推荐
  6. AutoCAD2007下载AutoCAD2007安装教程
  7. 使用三目运算求三个数的最大值、最小值和中间值
  8. C语言求1到20的阶乘之和
  9. 前端开发 IE 中的常用调试工具 _ PlanABC - 怿飞’s Blog
  10. Redis的下载安装运行