Android获取内置卡、内置U盘和挂载U盘路径和内存大小

开发一个功能需要使用内置卡、内置U盘和挂载U盘以及分别展示它们内存的大小。

使用的是反射机制,然而在获取外接U盘时发现永远获取导的U盘大小信息是一个固定值,这显示是不正确的,开始是完全使用path路径,后来发现使用internalpath获取U盘大小时是真实的,然而内置卡又没有这个路径,故最后根据不同类型分别选择使用这两个路径。

使用internalPath的大前提获取系统级别的权限:

android:sharedUserId="android.uid.system"

具体代码如下:

public static final String TYPE_INTERNAL_SD_CARD = "SD_Card";//内置卡public static final String TYPE_INTERNAL_T_CARD = "259";//内置T卡public static final String TYPE_U_DISK = "8";//U盘/*** 获取内存大小 (其中path和internalPath为路径,实际看情况使用哪一个)** @param context 上下文* @param uDisks  内置T卡(U盘)或外置U盘* @return String[] U盘信息,[0]U盘总内存大小 [1]U盘可用内存大小*/public static long[] getUsbMemoryMsg(Context context, String uDisks) {String sdcardDir = null;StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);Class<?> volumeInfoClazz = null;Class<?> diskInfoClazz = null;Class<?> storageVolumeClazz = null;long[] memory = new long[2];try {storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");diskInfoClazz = Class.forName("android.os.storage.DiskInfo");Method isUsb = diskInfoClazz.getMethod("isUsb");volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");Method getType = volumeInfoClazz.getMethod("getType");Method getDisk = volumeInfoClazz.getMethod("getDisk");Method getDiskId = volumeInfoClazz.getMethod("getDiskId");Field path = volumeInfoClazz.getDeclaredField("path");//这个路径获取U盘大小时会出现大小固定为某一值的情况;这个路径可以获取内置盘Field internalPath = volumeInfoClazz.getDeclaredField("internalPath");//使用这个路径获取U盘大小就没有上述问题;内置盘没有这个路径Method getVolumes = storageManager.getClass().getMethod("getVolumes");Method getUserLabel = storageVolumeClazz.getMethod("getUserLabel");Method getVolumeList = storageManager.getClass().getMethod("getVolumeList");Object resultVolumeList = getVolumeList.invoke(storageManager);List<Class<?>> result = (List) getVolumes.invoke(storageManager);int resultVolumeListLength = Array.getLength(resultVolumeList);for (int i = 0; i < result.size(); ++i) {Object volumeInfo = result.get(i);Log.w("StorageUtils", "volumeInfo::" + JSON.toJSONString(volumeInfo));String labelInfo = null;Object disk;String diskId = null;if (i < resultVolumeListLength) {disk = Array.get(resultVolumeList, i);labelInfo = (String) getUserLabel.invoke(disk);}disk = getDisk.invoke(volumeInfo);diskId = (String) getDiskId.invoke(volumeInfo);Log.w("StorageUtils", "disk::" + JSON.toJSONString(disk));Log.w("StorageUtils", "diskId::" + diskId + ",,disk-path::" + path.get(volumeInfo) + ",," + (labelInfo == null ? "unknown" : labelInfo));Log.w("StorageUtils", "uDisks::" + uDisks);sdcardDir = (String) path.get(volumeInfo);Log.w("StorageUtils ", "sdcardDir::" + sdcardDir);//内置卡没有disk对象,有两个路径  /data和/storage/emulated只读一个即可if (uDisks.equals(StorageUtils.TYPE_INTERNAL_SD_CARD) && diskId == null && sdcardDir.contains("/storage")) {long total = getTotalExternalStorageSize(sdcardDir);long available = getAvailableExternalStorageSize(sdcardDir);memory[0] = total;memory[1] = available;Log.w("StorageUtils", "sdCard::total::" + total + ",,available::" + available + ",,internalPath::" + internalPath);return memory;}//U盘类型(内置T卡)+U盘if (diskId != null && diskId.contains(uDisks) && disk != null && (Boolean) isUsb.invoke(disk)) {//使用internalPath代替path后没有上述问题sdcardDir = (String) internalPath.get(volumeInfo);long total = getTotalExternalStorageSize(sdcardDir);long available = getAvailableExternalStorageSize(sdcardDir);memory[0] = total;memory[1] = available;Log.w("StorageUtils", "total::" + total + ",,available::" + available + ",,internalPath::" + sdcardDir);return memory;}}return null;} catch (Exception var22) {Log.i("StorageUtils", "usb-path e " + var22.getMessage());var22.printStackTrace();Log.w("StorageUtils", "usb-path null");return null;}}/*** 获取总内存*/public static long getTotalExternalStorageSize(String storagePath) {StatFs statFs = new StatFs(storagePath);long blockSize = statFs.getBlockSizeLong();long totalBlocks = statFs.getBlockCountLong();Log.d(TAG, "blockSize:" + blockSize);Log.d(TAG, "totalBlocks:" + totalBlocks);return totalBlocks * blockSize;}/*** 获取剩余内存*/public static long getAvailableExternalStorageSize(String storagePath) {StatFs statFs = new StatFs(storagePath);long blockSize = statFs.getBlockSizeLong();long availableBlocks = statFs.getAvailableBlocksLong();Log.d(TAG, "blockSize:" + blockSize);Log.d(TAG, "availableBlocks:" + availableBlocks);return availableBlocks * blockSize;}

上述代码中打印的volumeInfo参数信息如下:仅供参考

///内置卡
{"description": "内部共享存储空间","id": "private","mountUserId": -10000,"mountedReadable": true,"mountedWritable": true,"path": "/data","primary": false,"primaryPhysical": false,"state": 2,"type": 1,"visible": false
}
///内置T卡
{"disk": {"adoptable": false,"defaultPrimary": false,"description": "0x144d U 盘","flags": 8,"id": "disk:259,0","label": "0x144d","sd": false,"shortDescription": "U 盘","size": 1000204886016,"stability": 0,"stubVisible": false,"sysPath": "/sys//devices/platform/fe150000.pc/nvme/nvme0/nvme0n1","usb": true,"volumeCount": 1},"diskId": "disk:259,0","fsLabel": "","fsType": "vfat","fsUuid": "1EDB-1816","id": "public:259,1","internalPath": "/mnt/media_rw/1EDB-1816","mountFlags": 2,"mountUserId": 0,"mountedReadable": true,"mountedWritable": true,"normalizedFsUuid": "1edb-1816","partGuid": "","path": "/storage/1EDB-1816","primary": false,"primaryPhysical": false,"stability": 0,"state": 2,"stateDescription": 17040185,"type": 0,"visible": true
}///U盘
{"description": "新加卷  \b","disk": {"adoptable": false,"defaultPrimary": false,"description": "Kingston U 盘","flags": 8,"id": "disk:8,0","label": "Kingston","sd": false,"shortDescription": "U 盘","size": 31029460992,"stability": 0,"stubVisible": false,"sysPath": "/sys//devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.7.auto/usb9/9-1/9-1:1.0/host0/target0:0:0/0:0:0:0/block/sda","usb": true,"volumeCount": 1},"diskId": "disk:8,0","fsLabel": "新加卷  \b","fsType": "vfat","fsUuid": "720F-AFA1","id": "public:8,1","internalPath": "/mnt/media_rw/720F-AFA1","mountFlags": 2,"mountUserId": 0,"mountedReadable": true,"mountedWritable": true,"normalizedFsUuid": "720f-afa1","partGuid": "","path": "/storage/720F-AFA1","primary": false,"primaryPhysical": false,"stability": 0,"state": 2,"stateDescription": 17040185,"type": 0,"visible": true
}

U盘插入拔出状态监听广播:

广播接收U盘插入拔出状态和路径_安卓接收到u盘插入的广播之后,怎么判断已经插入-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/480543.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建文件服务器并使用Qt实现文件上传和下载(带账号和密码)

文章目录 0 背景1 搭建文件服务器2 代码实现文件上传和下载2.1 在pro文件中添加网络支持2.2 创建网络管理类2.3 文件上传2.4 文件下载 3 扩展&#xff08;其他方法实现文件上传和下载&#xff09;3.1 python3.2 npm3.3 ftp服务器 4 完整的代码 0 背景 因为需要使程序具备在远程…

社交新零售模式下“2+1 链动模式 S2B2C 商城小程序”的创新实践与发展策略

摘要&#xff1a;随着实体商业与社交网络深度融合&#xff0c;社交新零售蓬勃兴起&#xff0c;“21 链动模式 S2B2C 商城小程序”作为其中创新典范&#xff0c;融合独特激励机制与数字化运营优势&#xff0c;重塑零售生态。本文剖析该模式架构、运作逻辑&#xff0c;探讨其在私…

【Git】Git 完全指南:从入门到精通

Git 完全指南&#xff1a;从入门到精通 Git 是现代软件开发中最重要的版本控制工具之一&#xff0c;它帮助开发者高效地管理项目&#xff0c;支持分布式协作和版本控制。无论是个人项目还是团队开发&#xff0c;Git 都能提供强大的功能来跟踪、管理代码变更&#xff0c;并保障…

华为E9000刀箱(HWE9000V2)服务器硬件监控指标解读

随着数据中心规模的不断扩大&#xff0c;服务器的稳定性和可靠性变得尤为重要。华为E9000刀箱&#xff08;HWE9000V2&#xff09;作为一款高性能的服务器设备&#xff0c;其硬件状态的实时监控对于保障业务的连续性和系统的稳定运行至关重要。 监控易作为一款专业的IT基础设施监…

Css—实现3D导航栏

一、背景 最近在其他的网页中看到了一个很有趣的3d效果&#xff0c;这个效果就是使用css3中的3D转换实现的&#xff0c;所以今天的内容就是3D的导航栏效果。那么话不多说&#xff0c;直接开始主要内容的讲解。 二、效果展示 三、思路解析 1、首先我们需要将这个导航使用一个大…

gitee:删除仓库

1、点击主页面设置 2、找到左侧导航栏-数据管理->仓库空间信息&#xff1b;找到需要删除的仓库->点击设置 3、点击左侧仓库设置->点击右侧删除仓库 4、输入提示内容->确认删除 5、输入密码验证 6、成功删除提示

探索 Python 任务自动化的新境界:Invoke 库揭秘

文章目录 探索 Python 任务自动化的新境界&#xff1a;Invoke 库揭秘背景&#xff1a;为何选择 Invoke&#xff1f;什么是 Invoke&#xff1f;如何安装 Invoke&#xff1f;5个简单的库函数使用方法1. 定义任务2. 带参数的任务3. 运行 Shell 命令4. 任务参数化5. 列出任务 场景应…

深入理解计算机系统,源码到可执行文件翻译过程:预处理、编译,汇编和链接

1.前言 从一个高级语言到可执行程序&#xff0c;要经过预处理、编译&#xff0c;汇编和链接四个过程。大家可以思考下&#xff0c;为什么要有这样的过程&#xff1f; 我们学习计算机之处&#xff0c;就应该了解到&#xff0c;计算机能够识别的只有二进制语言&#xff08;这是…

六通道串口服务器

型号&#xff1a;SG-TCP232-620 1.1 功能 1.1.1 基本功能 串口服务器是串口 RS232/422/485 和以太网之间的一个转换器&#xff0c;实现串口数 据和以太网数据的双向透明传输&#xff0c;可以让串口设备立即联网&#xff0c;典型应用拓扑如下&#xff1a; 1.1.2 特色功能…

Ubuntu 18.04 中安装 RDKit(针对 Python 2.7)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

websocket前后端长连接之java部分

一共有4个类,第一个WebSocketConfig 配置类 Configuration EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer {Autowiredprivate WebSocketHandler webSocketHandler;Autowiredprivate WebSocketInterceptor webSocketInterceptor;Overridepubli…

PyCharm中Python项目打包并运行到服务器的简明指南

目录 一、准备工作 二、创建并设置Python项目 创建新项目 配置项目依赖 安装PyInstaller 三、打包项目 打包为可执行文件 另一种打包方式&#xff08;使用setup.py&#xff09; 四、配置服务器环境 五、上传可执行文件到服务器 六、在服务器上运行项目 配置SSH解释…

【UE5 C++课程系列笔记】05——组件和碰撞

效果 可以看到我们可以实现的功能是 &#xff08;1&#xff09;可以通过鼠标旋转视角 &#xff08;2&#xff09;通过使用Pawn移动组件来控制Pawn移动 &#xff08;3&#xff09;Pawn碰到物体会被阻挡然后逐渐滑动 &#xff08;4&#xff09;通过空格切换激活/关闭粒子效果…

格网法计算平面点云面积(matlab版本)

1、原理介绍 格网法计算平面点云面积&#xff0c;其思想类似高中油膜法计算面积。其将点云投影到水平面&#xff0c;再将点云划分成尺寸相同的格网。最后&#xff0c;统计格网内包含点的数量number&#xff0c;那么可利用如下公式计算得到点云的面积&#xff1a; Aeranumber*L…

ZooKeeper 基础知识总结

先赞后看&#xff0c;Java进阶一大半 ZooKeeper 官网这样介绍道&#xff1a;ZooKeeper 是一种集中式服务&#xff0c;用于维护配置信息、命名、提供分布式同步和提供组服务。 各位hao&#xff0c;我是南哥&#xff0c;相信对你通关面试、拿下Offer有所帮助。 ⭐⭐⭐一份南哥编写…

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

ATTCK红队评估实战靶场(二)

http://vulnstack.qiyuanxuetang.net/vuln/?page2 描述&#xff1a;红队实战系列&#xff0c;主要以真实企业环境为实例搭建一系列靶场&#xff0c;通过练习、视频教程、博客三位一体学习。本次红队环境主要Access Token利用、WMI利用、域漏洞利用SMB relay&#xff0c;EWS re…

如何启用本机GPU硬件加速猿大师播放器网页同时播放多路RTSP H.265 1080P高清摄像头RTSP视频流?

目前市面上主流播放RTSP视频流的方式是用服务器转码方案&#xff0c;这种方案的好处是兼容性更强&#xff0c;可以用于不同的平台&#xff0c;比如&#xff1a;Windows、Linux或者手机端&#xff0c;但是缺点也很明显&#xff1a;延迟高、播放高清或者同时播放多路视频视频容易…

rocylinux9.4安装prometheus监控

一.上传软件包 具体的软件包如下&#xff0c;其中kubernetes-mixin是下载的监控kubernetes的一些监控规则、dashbaordd等。 二.Prometheus配置 1.promethes软件安装 #解压上传后的软件包 [rootlocalhost ] cd /opt [rootlocalhost opt]# tar xf prometheus-2.35.3.linux-amd…

第五课 Unity资源导入工作流效率优化(AssetGraph工具)

上期我们学习了简单的animation动画的优化&#xff0c;接下来我们继续资源导入效率的优化 工程目录 首先我们来学习一下工程目录结构及用途 Asset文件夹&#xff1a;用来储存和重用的项目资产 Library文件夹&#xff1a;用来储存项目内部资产数据信息的目录 Packages文件夹…