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

如何配置CWAC-Provider以实现跨应用访问?

嘿,我来帮你捋清楚怎么用StreamProvider实现AppA和AppB之间的图片资源共享~ 你已经开始配置AppA的Provider了,我把完整的实现步骤和细节给你拆解清楚:

实现AppA与AppB的图片资源共享(基于StreamProvider)

先补全AppA里StreamProvider的完整Manifest配置

你给出的配置还没写完,先把Manifest里的Provider配置补完整,尤其是用来指定共享路径的meta-data部分:

<provider
    android:authorities="org.example.AssetProvider"
    android:name="com.commonsware.cwac.provider.StreamProvider"
    android:exported="true"
    android:grantUriPermissions="true">
    <!-- 关联路径配置文件,告诉Provider哪些资源可以共享 -->
    <meta-data
        android:name="com.commonsware.cwac.provider.STREAM_PROVIDER_PATHS"
        android:resource="@xml/stream_provider_paths" />
</provider>

然后创建路径配置文件

在AppA的res/xml目录下新建一个stream_provider_paths.xml文件,用来定义你要开放的资源目录。比如你想共享assets文件夹下的images子目录,内容可以这么写:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- assets/images下的所有资源都允许被访问,"shared_images"是路径别名,隐藏真实路径更安全 -->
    <asset path="images/" name="shared_images" />
    
    <!-- 如果是共享内部存储的图片,就用<files-path>,比如:
    <files-path path="images/" name="local_images" />
    -->
</paths>

给你解释下关键配置的作用

  • android:authorities:这是你的Provider唯一标识,AppB访问时必须用这个值构建Uri,一定要用唯一的名字,比如加自己的包名前缀,避免和其他应用冲突。
  • android:exported="true":允许其他应用访问这个Provider,必须设为true才能让AppB拿到资源。
  • android:grantUriPermissions="true":支持临时授权,你可以只给AppB访问某一张图片的权限,而不是开放整个目录,安全性更高。

接下来是AppB如何访问AppA的资源

我给你两种方式,推荐用第一种更安全的:

方式1:通过Intent临时授权访问(推荐)

AppA可以在启动AppB的页面时,把授权后的图片Uri传过去。比如在AppA的某个按钮点击事件里:

// 构建要共享的图片Uri,格式是content://[authorities]/[别名]/[文件名]
val targetImageUri = Uri.parse("content://org.example.AssetProvider/shared_images/photo1.jpg")

// 启动AppB的图片查看页面
val intent = Intent().apply {
    // 指定AppB的目标Activity组件
    component = ComponentName("com.example.appb", "com.example.appb.ImageViewerActivity")
    action = Intent.ACTION_VIEW
    setDataAndType(targetImageUri, "image/jpeg")
    // 给AppB临时授权,让它能读取这个Uri对应的资源
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}

startActivity(intent)

然后在AppB的ImageViewerActivity里,就可以拿到Uri并读取图片了:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_image_viewer)

    val imageUri = intent.data ?: return
    // 用ContentResolver打开输入流,读取图片
    contentResolver.openInputStream(imageUri)?.use { inputStream ->
        val bitmap = BitmapFactory.decodeStream(inputStream)
        imageView.setImageBitmap(bitmap)
    }
}

方式2:直接构建Uri访问(不推荐,风险高)

如果不需要临时授权,也可以直接在AppB里构建Uri访问,但这种方式相当于把整个共享目录开放给所有知道authorities和路径的应用,安全性差:

val imageUri = Uri.parse("content://org.example.AssetProvider/shared_images/photo1.jpg")
contentResolver.openInputStream(imageUri)?.use { inputStream ->
    // 这里处理图片流,比如显示到ImageView
}

最后提几个注意事项

  • 别忘了在AppA的Module级build.gradle里添加StreamProvider的依赖:
    implementation 'com.commonsware.cwac:provider:0.6.3'
    
    版本号可以根据最新的稳定版调整哈。
  • 如果共享的是外部存储的图片,Android 10以下需要动态申请READ_EXTERNAL_STORAGE权限,Android 10及以上用Scoped Storage,StreamProvider会帮你处理大部分兼容问题。
  • 测试的时候要确保AppA和AppB都装在同一设备上,而且AppA的assets/images目录下确实有你要共享的图片哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:14:16