android u盘挂载监听,Android SD卡及U盘插拔状态监听及内容读取
本篇是通过系统方法来对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盘插拔状态监听及内容读取相关推荐
- Android SD卡及U盘插拔状态监听和内容读取
本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现. 先贴上效果图: 获取外置存储设备并监听插拔状态 获取 ...
- android u盘自动挂载点,Android2.3实现SD卡与U盘自动挂载的方法
本文实例讲述了Android2.3实现SD卡与U盘自动挂载的方法.分享给大家供大家参考,具体如下: 在 s3c6410平台上移植android2.3 过程中SD卡总是不能自动挂载. 查阅相关资料,知道 ...
- Android区分SD卡和U盘
写过这个功能的童鞋应该很理解我,当初找了大量的资料也只能做到在两者都插入时分辨出哪个是哪个,只插入其中一方,则一脸无奈,当初我甚至在界面上写"检测U盘或SD卡插入,总容量为xx,可用容量为x ...
- Android文件系统管理——版本内外存所指差异,获得外接SD/U盘路径,在SD卡与U盘间传送文件,两天辛酸泪,收藏不迷路
在开发一个文件管理系统的路上,总有坑在等着你. 前情提示:因为该系统的使用方需要严格保密文件,导致它失去了无线传输功能,只能通过外设传输文件. 在没接触这个功能之前,我想大家应该都觉得手机自带的存储空 ...
- android加密设备,用于Android手机的加密设备和加密外部SD卡
电话被盗或丢失后,隐私将被泄露. Android手机具有"加密设备"和"加密外部SD卡"功能. 那么这两个功能有什么区别? 加密设备 加密设备后,内置SD卡上的 ...
- wince 快速挂载SD卡及U盘
作者:Apollo5520 转自:http://blog.chinaunix.net/uid-8087110-id-1989039.html 1.起初我的wince bsp 在插入8G u盘时需要等待 ...
- 2019 SD卡、U盘无法格式化怎么办的解决方法
有天 闲的没事, 格式化一下U盘 ,结果突然断电了,我的天.我还在格式化的U盘 ,果然 ,我在此启动电脑后,的U盘直接 就不能用了.于是 我格式化. 然后,我的U盘就怎么也格式化不好了 ,找到了几种解 ...
- ZYNQ裸机实现 USB MASS STORAGE (usb+sd卡 实现U盘功能)
ZYNQ裸机实现 USB MASS STORAGE (usb+sd卡 实现U盘功能) 之所以写裸机,也就是没有操作系统的实现方法是因为linux系统下的实现方法网上已经有很多了,之前使用的STM32实 ...
- windows无法格式化u盘_2019 SD卡、U盘无法格式化怎么办的解决方法
有天 闲的没事, 格式化一下U盘 ,结果突然断电了,我的天.我还在格式化的U盘 ,果然 ,我在此启动电脑后,的U盘直接 就不能用了.于是 我格式化. 然后,我的U盘就怎么也格式化不好了 ,找到了几种解 ...
最新文章
- Java垃圾回收之老年代垃圾收集器
- 集成支付宝钱包支付iOS SDK的方法与经验
- tkinter回调异常_使用matplotlib保存动画时Tkinter回调出现异常
- TCP连接之未连接队列的理解[转]
- servlet session持久化
- 微软的创新还是败笔?Windows 8为苹果创造天赐良机
- .net模式子窗口传值给父窗口
- ASP.NETSpring.NETNHibernate最佳实践(七)——第3章人事子系统(4)人事子系统小结...
- java版的mrp模拟器_mrp模拟器(simulator)
- VTN:视频Transformer网络
- matlab画基尼系数,matlab 拟合洛伦兹曲线求基尼系数
- 采集用python还是火车头_火车采集器V9插件开发手册
- 利用Python爬取拉勾网招聘信息
- python 霍夫直线变换_霍夫线变换
- NVIDIA Jetson之PWM风扇自定义控制
- micropython 进阶小实验 如何用单片机制作鞋码匹配仪
- 均方误差——MSE 和标准差 的区别
- Vijos P1794 文化之旅
- Angular文件创建命令
- 苏州技师学院计算机专业怎么样,苏州技师学院口碑怎么样