如何在Android中访问外部存储(可移动SD卡)?

时间:2017-01-15 11:07:15

标签: android file storage

我一直在尝试访问android中的内部和外部SD卡。我在StackOverFlow中尝试了很多代码,但在大多数或所有Android版本上都不起作用。然后,我找到了两个解决方案。一个适用于Kitkat&上面,另一个工作低于Kitkat。我试图合并他们两个,它的工作原理!

如果有人有比此更好的解决方案,请分享。

1 个答案:

答案 0 :(得分:0)

这两个答案就是我合并后才能让它发挥作用。

  1. How to get SD_Card path in android6.0 programmatically

  2. Find an external SD card location

  3. 这是解决方案,

    AndroidManifest.xml中添加以下代码行,以获取Android对读取外部存储空间的许可。

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    现在,将此类添加到您的项目中。

    public class StoragePath {
    File[] getExternalFilesDirs;
    
    /**
     * Constructor for KitKat & above
     * @param getExternalFilesDirs
     */
    public StoragePath(File[] getExternalFilesDirs) {
        this.getExternalFilesDirs = getExternalFilesDirs;
    }
    
    /**
     * Constructor for lower than Kitkat
     *
     */
    public StoragePath() {
    
    }
    
    public String[] getDeviceStorages() {
        List<String> results = new ArrayList<>();
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
            File[] externalDirs = getExternalFilesDirs;
    
            for (File file : externalDirs) {
                String path = file.getPath().split("/Android")[0];
    
                boolean addPath = false;
    
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    addPath = Environment.isExternalStorageRemovable(file);
                } else {
                    addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
                }
    
                if (addPath) {
                    results.add(path);
                }
            }
        }
    
        if (results.isEmpty()) { //Method 2 for all versions
            final List<String> out = new ArrayList<>();
            String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
            String s = "";
            try {
                final Process process = new ProcessBuilder().command("mount")
                        .redirectErrorStream(true).start();
                process.waitFor();
                final InputStream is = process.getInputStream();
                final byte[] buffer = new byte[1024];
                while (is.read(buffer) != -1) {
                    s = s + new String(buffer);
                }
                is.close();
            } catch (final Exception e) {
                e.printStackTrace();
            }
    
            // parse output
            final String[] lines = s.split("\n");
            for (String line : lines) {
                if (!line.toLowerCase(Locale.US).contains("asec")) {
                    if (line.matches(reg)) {
                        String[] parts = line.split(" ");
                        for (String part : parts) {
                            if (part.startsWith("/"))
                                if (!part.toLowerCase(Locale.US).contains("vold"))
                                    out.add(part);
                        }
                    }
                }
            }
            results.addAll(out);
        }
    
        //Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
                    Log.d("Tag", results.get(i) + " might not be extSDcard");
                    results.remove(i--);
                }
            }
        } else {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
                    Log.d("Tag", results.get(i) + " might not be extSDcard");
                    results.remove(i--);
                }
            }
        }
    
        //Get path to the Internal Storage aka ExternalStorageDirectory
        final String internalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        results.add(0, internalStoragePath);
    
        String[] storageDirectories = new String[results.size()];
        for (int i = 0; i < results.size(); ++i) storageDirectories[i] = results.get(i);
    
        return storageDirectories;
    
    }
    }
    

    现在使用这个类,

    StoragePath storagePath;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            storagePath = new StoragePath(getExternalFilesDirs(null));
    }else {
            storagePath = new StoragePath();
    }
    
    String[] storages;
    storages = storagePath.getDeviceStorages();
    

    字符串数组storages现在包含存储路径。