You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中通过按钮触发GeoJSON文件的生成与外部存储保存?

实现点击按钮保存GeoJSON到手机外部存储

要实现点击按钮将生成的GeoJSON保存到手机可访问的公共存储(比如Downloads文件夹),需要处理权限申请、文件写入等步骤,以下是完整实现方案:

1. 添加必要权限

在AndroidManifest.xml中添加存储权限:

<!-- Android 9及以下需要 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
<!-- Android 10+ 兼容用读取权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ 保存到Downloads需要的权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="33" />

2. 动态申请权限(Android 6+)

在Activity/Fragment中添加权限校验与申请逻辑:

private val REQUEST_STORAGE_PERMISSION = 1001

private fun checkStoragePermission(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
    } else {
        true
    }
}

private fun requestStoragePermission() {
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_STORAGE_PERMISSION)
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_STORAGE_PERMISSION) {
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            saveGeoJsonToExternalStorage()
        } else {
            Toast.makeText(this, "需要存储权限才能保存文件", Toast.LENGTH_SHORT).show()
        }
    }
}

3. 按钮点击事件整合完整逻辑

将GeoJSON生成、序列化、写入外部存储的逻辑整合到按钮点击事件中:

binding.downloadButton.setOnClickListener {
    // 先校验权限
    if (!checkStoragePermission()) {
        requestStoragePermission()
        return@setOnClickListener
    }

    // 生成GeoJSON数据
    val coordinates = listOf(
        Coordinate(4.5165132153, 99.651681683),
        Coordinate(4.5163152153, 99.878981683),
        Coordinate(4.3584532153, 99.021481683),
        Coordinate(4.1578132153, 99.698781683),
        Coordinate(4.3655132153, 99.321481683),
        Coordinate(4.8795132153, 99.874581683)
    )

    val geometry = mapOf(
        "type" to "Polygon",
        "coordinates" to listOf(listOf(coordinates.map { listOf(it.lon, it.lat) }))
    )

    val properties = mapOf(
        "name" to "Your Polygon Name",
        // 可按需添加其他属性
    )

    val feature = mapOf(
        "type" to "Feature",
        "geometry" to geometry,
        "properties" to properties
    )

    val featureCollection = mapOf(
        "type" to "FeatureCollection",
        "features" to listOf(feature)
    )

    // 序列化为JSON字符串
    val gson = Gson()
    val geoJsonString = gson.toJson(featureCollection)

    // 写入外部存储
    saveGeoJsonToExternalStorage(geoJsonString)
}

// 写入外部存储的核心方法
private fun saveGeoJsonToExternalStorage(geoJsonString: String) {
    // 获取公共Downloads目录
    val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
    val file = File(downloadsDir, "my_polygon.geojson")

    try {
        file.writeText(geoJsonString, Charsets.UTF_8)
        Toast.makeText(this, "文件已保存到Downloads文件夹", Toast.LENGTH_SHORT).show()
    } catch (e: IOException) {
        e.printStackTrace()
        Toast.makeText(this, "保存失败:${e.message}", Toast.LENGTH_SHORT).show()
    }
}

关键注意事项

  • Android 10+ 分区存储兼容:使用Environment.getExternalStoragePublicDirectory保存到公共目录,用户可直接在文件管理器中找到文件,无需适配分区存储的复杂逻辑。
  • 编码规范:写入时指定UTF-8编码,避免GeoJSON文件出现乱码。
  • 异常处理:捕获IO异常并给出用户提示,提升交互体验。

内容的提问来源于stack exchange,提问作者Tommy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:37:37