Android-通过Intent实现外部应用打开文件

声明

这是第一个有关Android开发的文章,相关代码使用Kotlin而非Java。

使用方法

步骤

假定字符串s指向一个PDF文件,在使用Intent时,遵循以下步骤:

  • 创建Intent对象
  • 给予读取权限
  • 传递URI和MIME Type
  • 开启Activity

关于常用的MIME Type,此后会作总结。

代码

假设当前的this指向了Activity对象:

1
2
3
4
5
6
7
8
9
10
val intent = Intent(Intent.ACTION_VIEW)

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

intent.setDataAndType(
Uri.parse(s)
"application/pdf"
)

this.startActivity(intent)

但是一般情况下,运行后会出现类似以下错误:

1
Cannot display PDF(xxx.pdf cannot be open)

解决方案是使用FileProvider

FileProvider

首先,在AndroidManifest.xml中的<application>下层添加:

1
2
3
4
5
6
7
8
9
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="packageName.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

其中,packageName是包名,对应最外层的package属性。

然后,在res/xml/下新建provider_paths.xml,输入:

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="external_files" path="." />
</paths>

external_files表示APP的外部存储目录(一般为storage/emulated/0/Android/data/packageName)。

最后,在传递URI时使用FileProvider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val intent = Intent(Intent.ACTION_VIEW)

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

val file = File(s)

intent.setDataAndType(
FileProvider.getUriForFile(
this,
"${this.packageName}.fileProvider",
file
)
"application/pdf"
)

this.startActivity(intent)

这样就可以正常打开了!

补充

示例程序参考:

https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/V4FileProvider