You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt在Android上获取更清晰存储卷信息的技术问询

这个问题在Android上用Qt的QStorageInfo时很常见——因为它会列出所有系统挂载的文件系统,包括大量普通应用根本不需要访问的内部系统分区,同时对Android特有的虚拟/emulated存储处理不够直观。我来拆解下问题并给出解决办法:

为什么会出现混乱的挂载列表?

Android系统本身会挂载很多用于系统运行的分区(比如/system、/cache、/efs这些),这些分区对普通应用要么完全没有访问权限,要么是系统内部使用的,QStorageInfo不会自动过滤它们,所以会一起列出来。那些“无名称”的卷通常是临时挂载或者系统内部的虚拟分区,同样没有实际使用价值。

如何过滤出真正可用的存储卷?

你需要通过QStorageInfo的属性和路径特征来手动筛选,同时单独处理Android的/emulated内部存储:

1. 基础过滤:排除无效/未就绪的卷

先通过isValid()和isReady()排除那些根本不可用的卷,这能先去掉大部分标记为N的条目。

2. 排除系统内部分区

根据路径前缀过滤掉系统专属的分区,比如/system、/cache、/efs、/firmware、/persist这些,普通应用完全不需要访问它们。

3. 手动添加/storage/emulated/0

QStorageInfo通常只会列出父挂载点/storage/emulated,而实际用户可访问的内部存储是/storage/emulated/0(多用户环境下会有对应编号),所以需要手动检查并添加这个路径。

4. 处理部分可用的卷(YN标记)

这类卷通常是/storage或/mnt,它们是挂载点的根目录,本身不能直接访问,但子目录是有效存储。可以检查它们的子目录,或者直接跳过根目录,只保留实际的存储子路径。

完整代码示例

#include <QStorageInfo>
#include <QDebug>

QList<QStorageInfo> getValidStorageVolumes() {
    QList<QStorageInfo> validVolumes;
    const auto allVolumes = QStorageInfo::mountedVolumes();

    for (const QStorageInfo &volume : allVolumes) {
        // 跳过无效或未就绪的卷
        if (!volume.isValid() || !volume.isReady()) {
            continue;
        }

        const QString rootPath = volume.rootPath();
        // 跳过系统核心分区
        if (rootPath.startsWith("/system") || rootPath.startsWith("/cache") ||
            rootPath.startsWith("/efs") || rootPath.startsWith("/firmware") ||
            rootPath.startsWith("/persist")) {
            continue;
        }

        // 处理emulated存储的特殊情况
        if (rootPath == "/storage/emulated") {
            QStorageInfo userStorage("/storage/emulated/0");
            if (userStorage.isValid() && userStorage.isReady()) {
                validVolumes.append(userStorage);
            }
            continue;
        }

        // 对于/storage或/mnt这类父挂载点,直接跳过根目录
        if (rootPath == "/storage" || rootPath == "/mnt") {
            continue;
        }

        // 剩下的就是可用的存储卷(比如SD卡的挂载点)
        validVolumes.append(volume);
    }

    return validVolumes;
}

// 使用示例
int main() {
    const auto volumes = getValidStorageVolumes();
    for (const auto &v : volumes) {
        qDebug() << "可用存储:" << v.rootPath() << "名称:" << v.displayName();
    }
    return 0;
}

额外注意事项

  • 权限问题:Android 10及以上版本,访问外部存储需要申请MANAGE_EXTERNAL_STORAGE权限(或者针对特定目录的分区存储权限),否则即使路径正确,也可能无法访问文件。
  • 多用户环境:如果设备支持多用户,/storage/emulated下会有多个编号目录(比如/storage/emulated/1),你可能需要根据当前用户ID来获取对应的路径。

内容的提问来源于stack exchange,提问作者dtech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:01:05