【问题标题】:How to access (read/write) sd card public directory? Environment.getExternalStoragePublicDirectory return internal storage如何访问(读/写)sd 卡公共目录? Environment.getExternalStoragePublicDirectory 返回内部存储
【发布时间】:2020-08-03 22:40:29
【问题描述】:

如何访问(读/写)sd卡公共目录?

Environment.getExternalStoragePublicDirectory 返回内部存储路径。 getExternalFilesDirs 返回内部存储和 sd 卡。但是应用程序特定的路径。 SD卡上的公共共享目录呢?并附上USB驱动器?如何访问它们?

【问题讨论】:

  • "Environment.getExternalStoragePublicDirectory 返回内部存储路径" -- 不,它返回 Android SDK 引用的路径 external storage。另请注意,此方法已弃用。 “SD卡上的公共共享目录呢?以及附加的USB驱动器?如何访问它们?” -- 使用存储访问框架(例如,ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT)。
  • 这是一个语义学的问题。 “内部存储”或“Android SDK 所指的外部存储”。它完全不是sd卡。或USB连接的驱动器。在哪里可以找到如何使用“存储访问框架”的指南?
  • 没有关于如何访问 sd 卡或 USB 连接驱动器的内容。
  • 这些将作为可用存储位置自动显示在存储访问框架 UI 中。您的代码既不知道也不关心用户是否选择板载闪存、可移动设备、Google Drive 或任何其他 DocumentsProvider 实现。

标签: android android-sdcard


【解决方案1】:

我发现了另一个已弃用的 startActivityForResult 函数,而不是过时的 java File 框架。没有过时的,但仍然是 beta 的 registerForActiviResult。但我找不到要通过什么 Uri 来启动它。因此,我不得不使用 startActivityForResult 让 Uri 进入 Direcroty:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
        flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}
startActivityForResult(intent,10)

然后从已弃用的 onActivityResult 中获取 Uri,制作另一个 Uri,因为第一个 Uri 不适合检查驱动器上的可用空间。

val docUriTree = DocumentsContract.buildDocumentUriUsingTree(u,DocumentsContract.getTreeDocumentId(u))
val fd = app.contentResolver.openFileDescriptor(docUriTree,"r")
val st = Os.fstatvfs(fd?.fileDescriptor)
Log.d(TAG, "sUr: Free ${st.f_bsize * st.f_bavail / 1024 / 1024} MByes  f_bsize: ${st.f_bsize} Bytes  f_bavail: ${st.f_bavail}")

然后是文件列表...

val df = DocumentFile.fromTreeUri(app.applicationContext, u)
val dfl = df?.listFiles()
dfl?.forEach {
       Log.d("MY_TAG",
"\n-------------------\n$it\nname: ${it.name}\nparentFile: ${it.parentFile}\nuri: ${it.uri}\ntype: ${it.type}\nlength: ${it.length()}\nlastModified: ${it.lastModified()}\n-------------------------\n"
       )
       // Do something with it like:
      filelist.add(
                ImageFile(
                    fUri = it.uri,
                    Name = it.name,
                    bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                        DocumentsContract.getDocumentThumbnail(
                            app.contentResolver, it.uri,
                            Point(190, 108), null
                        )
                    else
                        null
                )
            )
}

我不知道如何使用 beta registerForActivityResult 而不是已弃用的 startActivityForResult。

附言

终于找到了要通过什么来启动。它是 DocumentsContract.EXTRA_INITIAL_URI。

registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
          if (it != null) {
                   viewModel.sUr(it)
          }
}.launch(Uri.parse(DocumentsContract.EXTRA_INITIAL_URI))

还有哪些参数可以传递给启动? DocumentsContract.EXTRA_INITIAL_URI 是什么意思?

【讨论】:

猜你喜欢
  • 2013-05-25
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多