1.android10想要操作tf卡或者内部存储,还是需要先使用SAF获取存储权限.本文需先了解SAF框架和kotlin.
val sm =
getSystemService(Context.STORAGE_SERVICE) as StorageManager
val volume = sm.storageVolumes
val size = volume.size
for (i in 1 until size) {
val storageVolume = volume[i]
val intent = storageVolume.createOpenDocumentTreeIntent()
startActivityForResult(intent, REQUEST_REQUEST_CODE)
}
在onActivityResult中将权限uri保存起来,方便后来使用.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val uri = data!!.getData()
val takeFlags: Int = (data.getFlags()
and (Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION))
contentResolver.takePersistableUriPermission(uri!!, takeFlags)
PreferencesUtil(context!!).saveValue("uri", uri.toString())
super.onActivityResult(requestCode, resultCode, data)
}
我们已经获取到了外部存储的根uri权限
2.想要解压tf卡压缩文件其实很简单,首先通过tf的根uri找到我们需要的zip文件.这里我们的压缩文件是/zipFiles/res.zip
val uri = PreferencesUtil(applicationContext).getString("uri", "asdsa")
val tFPath = DocumentFile.fromTreeUri(this, Uri.parse(uri))
var zipFiles = tFPath!!.findFile("zipFiles")
if (!zipFiles!!.exists()) {
zipFiles = tFPath.createDirectory("zipFiles")
}
val findFile = zipFiles!!.findFile("res.zip")
然后将其转换成zipInputStream,zipInputStream.nextEntry方法可以获取压缩包中每个压缩文件的实体,将其写出到想要的位置就可以了.
val inputStream = contentResolver.openInputStream(findFile!!.uri)
val zipInputStream = ZipInputStream(BufferedInputStream(inputStream!!))
var entry: ZipEntry
val buf = ByteArray(1024)
while (null != zipInputStream.nextEntry.also { entry = it }) {
val createFile = zipFiles.createFile("image/jpg", entry.getName())
val outputStream = contentResolver.openOutputStream(createFile!!.uri)
var readLen = 0
while (-1 != zipInputStream.read(buf, 0, 1024).also({ readLen = it })) {
outputStream!!.write(buf, 0, readLen)
}
outputStream!!.close()
}
inputStream.close()
zipInputStream.close()
3.压缩的方法就是解压的你过程,先通过uri创建压缩文件
val uri = PreferencesUtil(applicationContext).getString("uri", "asdsa")
val tFPath: DocumentFile = DocumentFile.fromTreeUri(this, Uri.parse(uri))!!
var zipFiles: DocumentFile = tFPath.findFile("zipFiles")!!
if (!zipFiles.exists()) {
zipFiles = tFPath.createDirectory("zipFiles")!!
}
val createFile: DocumentFile = tFPath.createFile("application/zip",
"test.zip")!!
zip类型的压缩文件的mini格式为"application/zip",通过压缩文件创建压缩文件里的压缩文件.在将需要压缩的文件数据写入.
val outputStream = contentResolver.openOutputStream(createFile.uri)
val zipOutputStream = ZipOutputStream(BufferedOutputStream(outputStream!!))
zip(zipOutputStream, "", zipFiles)
zipOutputStream.flush()
zipOutputStream.close()
private fun zip(zipOutputStream: ZipOutputStream, zipName: String, zipFiles: DocumentFile) {
if (zipFiles.isDirectory) {
val listFiles = zipFiles.listFiles()
var path = zipFiles.uri.path!!
for (file in listFiles) {
val name = file.name!!
zip(zipOutputStream, name, file)
}
} else {
val entry: ZipEntry = ZipEntry(zipName)
zipOutputStream.putNextEntry(entry)
val input = contentResolver.openInputStream(zipFiles.uri)!!
val buf = ByteArray(1024)
var len = -1
while (input.read(buf).also { len = it } != -1) {
zipOutputStream.write(buf, 0, len)
}
zipOutputStream.flush()
zipOutputStream.closeEntry()
input.close()
}
}
to be continued