Qt - 在Android上获取更清晰的存储卷信息

时间:2018-04-01 14:56:20

标签: android c++ qt qml storage

我正在使用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。< / p>

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

过滤掉所有非isValid()的文件,除去空白文件,但其余部分是相同的。

我正在使用(实验?)QML Qt.labs.folderlistmodel 2.1 API。

1 个答案:

答案 0 :(得分:0)

好的,一些基本的regexing似乎可以解决隔离可用的可移动卷的问题:

  • /\/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中我们做了一些&#34;模型过滤&#34;在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
    }
  }

请注意,我目前还没有测试USB部件,因为目前缺少一个工作的M micro usb到F usb适配器,它基于this answer。另请注意,/storage/emulated/0并未实现所有额外属性,在我的情况下,它们并非必要,如果它们应该明确填充它们。