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

如何保存ACTION_CREATE_DOCUMENT返回的URI并在不同Activity/Fragment中使用

保存ACTION_CREATE_DOCUMENT返回的URI并跨组件使用(替代废弃的startActivityForResult)

首先,官方已废弃startActivityForResult,推荐使用Activity Result API来处理页面间的结果回调。下面是完整的实现方案,包含URI持久化保存和跨组件调用的步骤:

步骤1:注册Activity Result回调

在你的Activity或Fragment中,先注册用于接收创建文档结果的Launcher,处理返回的URI并完成持久化:

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import android.view.View

class MainActivity : AppCompatActivity() {
    // 注册创建文档的结果回调
    private val createDocumentLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
            result.data?.data?.let { uri ->
                // 关键:申请持久化访问权限,避免APP重启后URI失效
                val persistFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                contentResolver.takePersistableUriPermission(uri, persistFlags)
                
                // 将URI字符串保存到SharedPreferences(也可改用Room数据库存储多个URI)
                val sharedPref = getSharedPreferences("AppStoragePrefs", MODE_PRIVATE)
                sharedPref.edit().putString("target_pdf_uri", uri.toString()).apply()
            }
        }
    }

    // 启动创建文档的方法
    private fun startCreateDocument() {
        val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
            type = "application/pdf"
            putExtra(Intent.EXTRA_TITLE, "新文档.pdf") // 设置默认文件名
        }
        createDocumentLauncher.launch(intent)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 示例:点击按钮触发创建文档流程
        findViewById<View>(R.id.btn_create_pdf).setOnClickListener {
            startCreateDocument()
        }
    }
}

步骤2:在其他组件中读取并使用URI

在需要使用该URI的Activity或Fragment中,读取保存的URI字符串并转换为Uri对象,即可直接进行读写操作:

import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class AnotherActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_another)
        
        // 从SharedPreferences读取保存的URI字符串
        val sharedPref = getSharedPreferences("AppStoragePrefs", MODE_PRIVATE)
        val savedUriString = sharedPref.getString("target_pdf_uri", null)
        
        savedUriString?.let { uriString ->
            val uri = Uri.parse(uriString)
            // 示例:打开输出流写入PDF内容
            contentResolver.openOutputStream(uri)?.use { outputStream ->
                // 写入逻辑,比如从字节数组或本地文件写入数据
                // outputStream.write(pdfByteArray)
            }
            
            // 示例:打开输入流读取文档内容
            contentResolver.openInputStream(uri)?.use { inputStream ->
                // 读取逻辑
            }
        }
    }
}

关键注意事项

  • 持久化权限:必须调用takePersistableUriPermission,否则APP重启后系统会收回对该URI的访问权限,导致无法正常使用。
  • 存储选择:如果需要管理多个URI,建议使用Room数据库替代SharedPreferences,更适合存储结构化的URI列表。
  • 权限验证:使用URI前可通过contentResolver.checkUriPermission(uri, android.os.Process.myPid(), android.os.Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION)验证是否仍有权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:22:22