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

相关文章

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

Python如何精准判断某个进程是否在运行

《Python如何精准判断某个进程是否在运行》这篇文章主要为大家详细介绍了Python如何精准判断某个进程是否在运行,本文为大家整理了3种方法并进行了对比,有需要的小伙伴可以跟随小编一起学习一下... 目录一、为什么需要判断进程是否存在二、方法1:用psutil库(推荐)三、方法2:用os.system调用