Android8.0中获取U盘的各种信息

原文链接: https://blog.csdn.net/w71451000/article/details/80539738

转自:https://blog.csdn.net/w71451000/article/details/80539738


权限

首先获取U盘信息,我们需要在androidmanifest.xml中添加以下权限 
 



    package="com.changhong.usbbroadcast">

   
   

            android:allowBackup="true"
        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 getVolumes() {
        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如下:


    android:sharedUserId="android.uid.system"
    package="com.changhong.usbbroadcast">

   
   

            android:allowBackup="true"
        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;
        }

    }

}
 

你可能感兴趣的:(Android,android,studio,eclipse)