Browse Source

优化Android 5/6 获取磁盘崩溃问题

zk 1 year ago
parent
commit
3dfb09ba96

+ 38 - 6
app/src/main/java/com/datarecovery/master/utils/xfile/StorageVolumeUtil.java

@@ -36,13 +36,27 @@ public class StorageVolumeUtil {
      * 获取存储卷的根目录Uri
      */
     public static Uri getRootUri(StorageVolume storageVolume) {
-        Uri rootUri;
+        Uri rootUri = null;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
             rootUri = storageVolume.createOpenDocumentTreeIntent().getParcelableExtra(
                     DocumentsContract.EXTRA_INITIAL_URI);
         } else {
-            rootUri = DocumentsContract.buildRootUri("com.android.externalstorage.documents",
-                    (storageVolume.isPrimary() ? "primary" : storageVolume.getUuid()));
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                rootUri = DocumentsContract.buildRootUri("com.android.externalstorage.documents",
+                        (storageVolume.isPrimary() ? "primary" : storageVolume.getUuid()));
+            } else {
+                try {
+                    Method isPrimary = StorageVolume.class.getMethod("isPrimary");
+                    boolean primary = (boolean) isPrimary.invoke(storageVolume);
+                    //反射获取getUuid
+                    Method getUuid = StorageVolume.class.getMethod("getUuid");
+                    String uuid = (String) getUuid.invoke(storageVolume);
+                    rootUri = DocumentsContract.buildRootUri("com.android.externalstorage.documents",
+                            (primary ? "primary" : uuid));
+                } catch (NoSuchMethodException | IllegalAccessException |
+                         InvocationTargetException e) {
+                }
+            }
         }
         return rootUri;
     }
@@ -52,19 +66,37 @@ public class StorageVolumeUtil {
     }
 
     public static String getMediaStoreVolumeName(StorageVolume storageVolume) {
-        String volumeName;
+        String volumeName = null;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
             volumeName = storageVolume.getMediaStoreVolumeName();
         } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
             volumeName = storageVolume.isPrimary() ? MediaStore.VOLUME_EXTERNAL_PRIMARY : getNormalizedUuid(storageVolume);
-        } else {
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
             volumeName = storageVolume.isPrimary() ? "external" : getNormalizedUuid(storageVolume);
+        } else {
+            //反射获取isPrimary
+            try {
+                Method isPrimary = StorageVolume.class.getMethod("isPrimary");
+                boolean primary = (boolean) isPrimary.invoke(storageVolume);
+                volumeName = primary ? "external" : getNormalizedUuid(storageVolume);
+            } catch (Exception e) {
+            }
+
         }
         return volumeName;
     }
 
     public static String getNormalizedUuid(StorageVolume storageVolume) {
-        String uuid = storageVolume.getUuid();
+        String uuid = null;
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+            uuid = storageVolume.getUuid();
+        } else {
+            try {
+                Method getUuid = StorageVolume.class.getMethod("getUuid");
+                uuid = (String) getUuid.invoke(storageVolume);
+            } catch (Exception e) {
+            }
+        }
         return uuid == null ? null : uuid.toLowerCase(Locale.US);
     }
 }

+ 36 - 5
app/src/main/java/com/datarecovery/master/utils/xfile/XStorageManager.java

@@ -1,11 +1,14 @@
 package com.datarecovery.master.utils.xfile;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Environment;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
@@ -16,21 +19,49 @@ public class XStorageManager {
      */
     public static List<StorageVolume> getReadableStorageVolumes(Context context) {
         StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
-        List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
+        List<StorageVolume> storageVolumes = null;
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+            storageVolumes = storageManager.getStorageVolumes();
+        } else {
+            try {
+                Method getVolumeList = StorageManager.class.getMethod("getVolumeList");
+                StorageVolume[] storageVolumes21 = (StorageVolume[]) getVolumeList.invoke(storageManager);
+                storageVolumes = Arrays.asList(storageVolumes21);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (storageVolumes == null) {
+            storageVolumes = new ArrayList<>();
+        }
         ArrayList<StorageVolume> result = new ArrayList<>(storageVolumes.size());
         for (StorageVolume storageVolume : storageVolumes) {
-            if (isReadable(storageVolume)) {
+            if (isReadable(storageManager, storageVolume)) {
                 result.add(storageVolume);
             }
         }
         return result;
     }
 
-    private static boolean isReadable(StorageVolume storageVolume) {
+    private static boolean isReadable(StorageManager storageManager, StorageVolume storageVolume) {
         if (storageVolume == null) {
             return false;
         }
-        return Objects.equals(storageVolume.getState(), Environment.MEDIA_MOUNTED)
-                || Objects.equals(storageVolume.getState(), Environment.MEDIA_MOUNTED_READ_ONLY);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            return Objects.equals(storageVolume.getState(), Environment.MEDIA_MOUNTED)
+                    || Objects.equals(storageVolume.getState(), Environment.MEDIA_MOUNTED_READ_ONLY);
+        } else {
+            try {
+                Method getPath = StorageVolume.class.getMethod("getPath");
+                String path = (String) getPath.invoke(storageVolume);
+                Method getVolumeState = StorageManager.class.getMethod("getVolumeState", String.class);
+                String state = (String) getVolumeState.invoke(storageManager, path);
+                return Objects.equals(state, Environment.MEDIA_MOUNTED)
+                        || Objects.equals(state, Environment.MEDIA_MOUNTED_READ_ONLY);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return false;
+        }
     }
 }