如何保存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
相关产品推荐
相关产品推荐

