转自:https://blog.csdn.net/w71451000/article/details/80539738
权限
首先获取U盘信息,我们需要在androidmanifest.xml中添加以下权限
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
1
详细步骤
要获取U盘的详细信息主要用到3个类:
android.os.storage.StorageManager
android.os.storage.StorageVolume
android.os.storage.VolumeInfo
其中第3个类VolumeInfo默认不可见 ,因此只能通过反射调用,VolumeInfo中主要的成员变量如下:
/** vold state */
public final String id;
public final int type;
public final DiskInfo disk;
public final String partGuid;
public int mountFlags = 0;
public int mountUserId = -1;
public int state = STATE_UNMOUNTED;
public String fsType; //U盘类型,vfat ntfs
public String fsUuid; //UUID
public String fsLabel; //U盘名称,必须更改U盘名字后才能够正确显示,否则显示""
public String path; //U盘挂载路径
public String internalPath; //U盘挂载路径
1
首先获取StorageManager的实例
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
1
我们通过StorageManager的getVolumes方法获取全部的Volumes,由于此方法在SDK中是hide,所以也需要通过反射来调用.
/** {@hide} */
public @NonNull List
try {
return Arrays.asList(mStorageManager.getVolumes(0));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
Class storeManagerClazz = Class.forName("android.os.storage.StorageManager");
Method getVolumesMethod = storeManagerClazz.getMethod("getVolumes");
List> volumeInfos = (List>)getVolumesMethod.invoke(storageManager);//获取到了VolumeInfo的列表
在获取到VolumeInfo的list后,我们通过反射依次获得每一个Volumes的各种信息,
如果某些Volumes的uuid如果为null,那么我们需要忽略,也就是说UUID不为0的VolumeInfo则代表了我们 已经插入的U盘
Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
Field fsTypeField = volumeInfoClazz.getDeclaredField("fsType");
Field fsLabelField = volumeInfoClazz.getDeclaredField("fsLabel");
Field pathField = volumeInfoClazz.getDeclaredField("path");
Field internalPath = volumeInfoClazz.getDeclaredField("internalPath");
if(volumeInfos != null){
for(Object volumeInfo:volumeInfos){
String uuid = (String)getFsUuidMethod.invoke(volumeInfo);
if(uuid != null){
String fsTypeString = (String)fsTypeField.get(volumeInfo);//U盘类型
String fsLabelString = (String)fsLabelField.get(volumeInfo);//U盘名称
String pathString = (String)pathField.get(volumeInfo);//U盘路径
String internalPathString = (String)internalPath.get(volumeInfo);//U盘路径
}
}
}
要获取U盘的总空间以及剩余空间等,我们需要知道U盘挂载路径,同时使用android.os.StatFs这个类
//StatFs statFs = new StatFs(internalPathString);
StatFs statFs = new StatFs(pathString);
long avaibleSize = statFs.getAvailableBytes();//获取U盘可用空间
long totalSize = statFs.getTotalBytes();//获取U盘总空间
在获取U盘空间时,如果Statfs直接使用VolumeInfo的path时,我发现多次插拔U盘时获取的空间大小不准确,获取的大小老是1008091136字节,于是我通过internalPath去获取U盘空间,发现结果是OK的,但是如果我们使用internalPath,我们的App必需要获取system权限,否则会报权限错误,要获取system权限,则在androidmanifest中加入
android:sharedUserId="android.uid.system"
完整manifest如下:
package="com.changhong.usbbroadcast">
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
完整代码如下:
public class UsbBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case Intent.ACTION_MEDIA_MOUNTED: {
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
Class storeManagerClazz = Class.forName("android.os.storage.StorageManager");
Method getVolumesMethod = storeManagerClazz.getMethod("getVolumes");
List> volumeInfos = (List>)getVolumesMethod.invoke(storageManager);
Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
Method getTypeMethod = volumeInfoClazz.getMethod("getType");
Method getFsUuidMethod = volumeInfoClazz.getMethod("getFsUuid");
Field fsTypeField = volumeInfoClazz.getDeclaredField("fsType");
Field fsLabelField = volumeInfoClazz.getDeclaredField("fsLabel");
Field pathField = volumeInfoClazz.getDeclaredField("path");
Field internalPath = volumeInfoClazz.getDeclaredField("internalPath");
if(volumeInfos != null){
for(Object volumeInfo:volumeInfos){
String uuid = (String)getFsUuidMethod.invoke(volumeInfo);
if(uuid != null){
String fsTypeString = (String)fsTypeField.get(volumeInfo);
String fsLabelString = (String)fsLabelField.get(volumeInfo);
String pathString = (String)pathField.get(volumeInfo);
String internalPathString = (String)internalPath.get(volumeInfo);
StatFs statFs = new StatFs(internalPathString);
long avaibleSize = statFs.getAvailableBytes();
long totalSize = statFs.getTotalBytes();
}
}
}
}catch(Exception e){
e.printStackTrace();
}
break;
}
case Intent.ACTION_MEDIA_UNMOUNTED: {
break;
}
default:
break;
}
}
}