【问题标题】:Qt - Getting cleaner storage volumes info on AndroidQt - 在 Android 上获取更清晰的存储卷信息
【发布时间】:2018-04-01 14:56:20
【问题描述】:

我使用QStorageInfo::mountedVolumes() 获取卷列表,然后使用rootPath() 获取每个卷列表,但我得到的结果很混乱:

/storage/613C-16DF Y
/storage/emulated N 
/storage YN
/persist N
/efs N
/firmware-modem N
/firmware N
/cache N
/data N
/system Y
N
N
N
N
N
N
/mnt YN

Y 表示它按预期工作,N 表示它根本不工作,YN - 一些子目录工作,其他人不工作。还有 6 卷“无名”卷,都不起作用。

还有/storage/emulated/0 未列出,但我知道它可以工作并为我提供集成存储。

从普通用户的角度来看,设备应该只列出两个卷:

/storage/emulated/0 - integrated memory
/storage/613C-16DF - external sd card

奇怪的是,我可以从/storage/613C-16DF,但我不能去/emulated,即使我可以直接去/storage/emulated/0

问题是如何获得更清晰的结果。我可以硬编码/storage/emulated/0,但我不能硬编码外部 sd 卡容量,因为它会发生变化,而且设备可能有更多的用户容量。

过滤掉所有不是isValid()的,去掉空白的,其余的都一样。

这可能与我正在使用(实验性?)QML Qt.labs.folderlistmodel 2.1 API 有关。

【问题讨论】:

  • dtech,困惑:QStorageInfo::mountedVolumes() 是 qt 类?虽然搜索 Qt.labs.folderlistmodel 2.1 不包括类型 mountedVolumes?
  • QStorageInfo 是一个 C++ 类,与 folderlistmodel 无关。
  • 但是你的最后一行是什么意思?
  • 这意味着在 GUI 端我使用 QML 和 folderlistmodel 而不是基于 QtWidget 的文件模型/对话框。
  • 我认为您可以使用 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) 获取内部存储位置 (/storage/emulated/0)。 AFAIK 您无法通过QStandardPaths 获取外部 SD 卡位置。

标签: android c++ qt qml storage


【解决方案1】:

好的,一些基本的正则表达式似乎可以隔离可用的可移动卷:

  • /\/storage\/[0-9A-F]{4}-[0-9A-F]{4}/ 用于 SD 卡
  • /\/mnt\/media_rw\/[0-9A-F]{4}-[0-9A-F]{4}/ 用于 USB 驱动器

所以在 C++ 中,我们将系统卷作为 JS 对象数组:

QVariantList volumes() {
  QVariantList l;
  for (const auto & i : QStorageInfo::mountedVolumes()) {
    QVariantMap m;
    m.insert("name", i.name());
    m.insert("dname", i.displayName());
    m.insert("valid", i.isValid());
    m.insert("readonly", i.isReadOnly());
    m.insert("ready", i.isReady());
    m.insert("rootPath", i.rootPath());
    m.insert("bsize", i.blockSize());
    m.insert("available", i.bytesAvailable() / (1024 * 1024));
    m.insert("free", i.bytesFree() / (1024 * 1024));
    m.insert("total", i.bytesTotal() / (1024 * 1024));
    l.append(m);
  }
  return l;
}

在 QML 中,我们会在 android 的情况下进行一些“模型过滤”:

  function getVolumes() {
    var v = SY.volumes()
    switch (Qt.platform.os) {
    case "android":
      var l = []
      var sd = /\/storage\/[0-9A-F]{4}-[0-9A-F]{4}/, sdc = 1
      var usb = /\/mnt\/media_rw\/[0-9A-F]{4}-[0-9A-F]{4}/, usbc = 1
      l.push({"name" : "Internal Storage", "rootPath": "/storage/emulated/0", "valid" : true})
      for (var c = 0; c < v.length; ++c) { // for-in doesn't work?!?
        if (sd.test(v[c].rootPath)) {
          v[c].name = "SD Card " + sdc++ // name is blank on android
          l.push(v[c])
        } else if (usb.test(v[c].rootPath)) {
          v[c].name = "USB drive " + usbc++
          l.push(v[c])
        }
      }
      return l
    default: return v
    }
  }

请注意,由于目前缺少工作的 M micro usb 到 F usb 适配器,我没有测试 USB 部分,它基于this answer。另请注意,/storage/emulated/0 并没有实现所有额外的属性,在我的情况下它们不是必需的,如果它们应该显式填充。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 2018-05-11
    相关资源
    最近更新 更多