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

相关文章

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio