前言
项目中需要在内网使用高德地图,由于很多功能需要鉴权才能使用,一般的解决方案是在内网中做代理,或者内网添加白名单访问外网。而我们项目目前只需要显示地图及在地图上添加一些标记,所以只需要将离线数据打包进APK,第一次启动时放到指定缓存目录即可。
一、获取离线数据
接入高德地图后,通过SDK里的 OfflineMapActivity 先下载需要的离线地图资源,这些资源放在 外部存储/amap 目录下,或者我们代码中通过 MapsInitializer.sdcardDir 设置的目录。
二、使用步骤
1.将资源放在assets目录下
2.app启动时将资源放到缓存目录
注意要在子线程去操作,缓存目录使用app内部目录,可不用检查读写权限。
object AssetZipUtils {
@Throws(IOException::class)
fun unzipFromAssets(context: Context, assetName: String, outputDirPath: String) {
val assetManager = context.assets
assetManager.open(assetName).use { inputStream ->
unzip(inputStream, outputDirPath)
}
}
@Throws(IOException::class)
fun unzip(inputStream: InputStream, outputDirPath: String) {
val buffer = ByteArray(1024)
val outputDir = File(outputDirPath)
if (!outputDir.exists()) {
outputDir.mkdirs()
}
ZipInputStream(inputStream).use { zis ->
var zipEntry: ZipEntry? = zis.nextEntry
while (zipEntry != null) {
val newFile = File(outputDir, zipEntry.name)
if (zipEntry.isDirectory) {
if (!newFile.isDirectory && !newFile.mkdirs()) {
throw IOException("Failed to create directory ${newFile.path}")
}
} else {
// Ensure parent directories exist
val parent = newFile.parentFile
if (!parent.isDirectory && !parent.mkdirs()) {
throw IOException("Failed to create directory ${parent.path}")
}
FileOutputStream(newFile).use { fos ->
var len: Int
while (zis.read(buffer).also { len = it } > 0) {
fos.write(buffer, 0, len)
}
}
}
zipEntry = zis.nextEntry
}
zis.closeEntry()
}
}
}
注意
当前使用的高德地图版本是 V10.0.700 2024-05-13,后续更新不确定能不能使用这种方法。