Android中通过反射的方式判断U盘是否真正挂载

2024-09-05 07:58

本文主要是介绍Android中通过反射的方式判断U盘是否真正挂载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       由于StorageManager.java类中的getVolumeList()和getVolumeState(String mountPoint)方法是hide(隐藏)的,所以需要通过反射的方式获取对应的存储信息。源码./frameworks/base/core/java/android/os/storage/StorageManager.java类中的getVolumeList()跟getVolumeState(String mountPoint)方法如下:

/*** Returns list of all mountable volumes.* @hide*/public StorageVolume[] getVolumeList() {if (mMountService == null) return new StorageVolume[0];try {Parcelable[] list = mMountService.getVolumeList();if (list == null) return new StorageVolume[0];int length = list.length;StorageVolume[] result = new StorageVolume[length];for (int i = 0; i < length; i++) {result[i] = (StorageVolume)list[i];}return result;} catch (RemoteException e) {Log.e(TAG, "Failed to get volume list", e);return null;}}/*** Gets the state of a volume via its mountpoint.* @hide*/public String getVolumeState(String mountPoint) {if (mMountService == null) return Environment.MEDIA_REMOVED;try {return mMountService.getVolumeState(mountPoint);} catch (RemoteException e) {Log.e(TAG, "Failed to get volume state", e);return null;}}

可以通过反射的方式获取 getVolumeList()跟getVolumeState(String mountPoint)的方法,实现如下:

    /*** Returns list of all mountable volumes.*/public static StorageVolume[] getVolumeList(StorageManager storageManager){try {Class clz = StorageManager.class;Method getVolumeList = clz.getMethod("getVolumeList", null);StorageVolume[] result = (StorageVolume[]) getVolumeList.invoke(storageManager, null);return result;} catch (Exception e) {e.printStackTrace();}return null;}/*** Gets the state of a volume via its mountpoint.*/public static String getVolumeState(StorageManager storageManager, String path){String result = "";if(null == storageManager || TextUtils.isEmpty(path)){return result;}try {Class clz = StorageManager.class;Method getVolumeList = clz.getMethod("getVolumeState", String.class);result = (String) getVolumeList.invoke(storageManager, path);} catch (Exception e) {e.printStackTrace();}return result;}

 为了方便使用,把这两个方法封装到了USBUtil.java类中,具体实现如下:

package com.example.helloworld.util;import java.lang.reflect.Method;import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;/*** Created by ryan on 01/03/2018.*/public class USBUtil {private static final USBUtil mUtil = new USBUtil();public static USBUtil getInstance() {return mUtil;}/*** Returns list of all mountable volumes.*/public static StorageVolume[] getVolumeList(StorageManager storageManager){try {Class clz = StorageManager.class;Method getVolumeList = clz.getMethod("getVolumeList", null);StorageVolume[] result = (StorageVolume[]) getVolumeList.invoke(storageManager, null);return result;} catch (Exception e) {e.printStackTrace();}return null;}/*** Gets the state of a volume via its mountpoint.*/public static String getVolumeState(StorageManager storageManager, String path){String result = "";if(null == storageManager || TextUtils.isEmpty(path)){return result;}try {Class clz = StorageManager.class;Method getVolumeList = clz.getMethod("getVolumeState", String.class);result = (String) getVolumeList.invoke(storageManager, path);} catch (Exception e) {e.printStackTrace();}return result;}}

接下来是方法的使用,通过UsbTest.java类来进行界面测试,具体实现如下:

package com.example.helloworld;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.view.View;
import android.widget.TextView;import com.example.helloworld.util.Logger;
import com.example.helloworld.util.USBUtil;public class UsbTest extends Activity{private StorageManager storageManager;Context context;TextView mTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.usb);context = UsbTest.this;storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); //存储服务初始化mTextView = (TextView) findViewById(R.id.show_tv);}public void startVoice(View view){Logger.d();if (USBExist(context)){mTextView.setText("USB is exist!");}else {mTextView.setText("USB isn't exist!");}}public void finishVoice(View view){Logger.d();finish();}//判断/storage/udisk是否为挂载的路径private boolean USBExist(Context context){if (null == storageManager){Logger.d("Invalid reference to StorageManager received.");return false;}String usbPath = getUSBPath(context);if (USBUtil.getVolumeState(storageManager, usbPath).equals(android.os.Environment.MEDIA_MOUNTED)){return true;}return false;}//判断USB路径(/storage/udisk)是否存在private String getUSBPath(Context context){Logger.d();String usb = null;StorageVolume[] volumes = USBUtil.getVolumeList(storageManager);for (int i = 0; i < volumes.length; i++){if (volumes[i].isRemovable() && volumes[i].getDescription(context).contains("USB")){usb = volumes[i].getPath();Logger.d("usb = " + usb);if (usb.equals("/storage/udisk")){break;}}}return usb;}}

usb.xml布局如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/show_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="18sp"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="startVoice"android:text="@string/usb_check"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="finishVoice"android:text="@string/version_quit"/></LinearLayout>

 测试结果如下:

a.未插U盘

b.插了U盘

 

 代码参考:https://github.com/gunder1129/android-tool/tree/master/AIDLdemo/SimpleJarClient

注意:由于用到源码中的./frameworks/base/core/java/android/os/storage/StorageManager.java类,所以需要Android的系统平台进行编译。

 

 

 

 

 

 

这篇关于Android中通过反射的方式判断U盘是否真正挂载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138378

相关文章

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局