我需要编写一个 Android 应用程序来观察另一个应用程序何时修改文件,然后从中读取数据。该文件由用户选择。所以我想使用 Intent 以及设备上可用的文件选择器供用户选择文件。
使用 Intent.ACTION_OPEN_DOCUMENT 执行此操作会返回 URI。我可以打开一个 InputStream 并将文件读入 File 实例,然后检查上次修改日期。然而,每 5 秒左右将文件内容复制到 File 实例中只是为了检查它是否已被修改,这在资源方面似乎是浪费。显然,我不能使用 File 实例和从流中复制一次的数据来继续检查上次修改时间,我必须每次都继续复制它。
有没有办法使用 URI 获取最后修改时间?或者使用 Intent 获取实际文件/绝对路径?我发现了一些非常复杂的方法来从 URI 获取绝对路径,但它们看起来太复杂了,而且我还没有找到任何我愿意使用并确信它可以在不同版本的 Android 上运行的东西。
还有其他解决办法吗?
请注意,对于 Android 10 及以上版本,您将无法直接使用
file://
。 Android 正在推动 content://
。
要在
lastModified
/intent.ACTION_GET_CONTENT
/等之后从 URI 中提取 OPEN_DOCUMENT
日期,您可以使用 contentProvider.query()
API。
可以提取的可用列列在
DocumentsContract.Document
中
下面是提取最后更新时间的代码:
contentResolver.query( uri, null, null, null, null )?.use { c ->
val dateMod: Long = try {
val colDateModified = c
.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
c.moveToFirst()
c.getLong(colDateModified)
} catch (e: Exception) {
0
}
print("Date modified : $dateMod")
}
您还可以使用
ContentResolver
,而不是手动执行烦人的 DocumentFile.fromSingleUri(context, uri).lastModified()
,它在幕后使用相同的代码。
注意:仅适用于 KitKat 及以上版本,因为 fromSingleUri 在早期 Android 版本上返回 null
。
对此的更新。我最终决定使用这段代码从 URI 获取文件的绝对路径,并从路径获取 File 的实例:https://gist.github.com/asifmujteba/d89ba9074bc941de1eaa
原因是,我绝对需要文件系统上实际文件的最后修改日期。因此通过 InputStream 访问它不是一个选择。
我没有对它进行大量测试,但似乎可以满足我的目的,并且在我测试过的 Android API 级别上。