Android:选择其他应用打开文件
问题
Android 应用需要提供浏览文件内容的功能时,我们一般不会自己创建一个页面来实现展示文件内容的功能,而是将用户引导到一个具有此功能的应用,例如 WPS。要实现这一目的,我们需要做哪些工作呢?
选择其他应用打开文件示例.png回答
这一功能可以借助隐式 Intent 来实现。
隐式 intent 不会声明要启动的组件的类名称,而是声明要执行的动作。该动作指定您要做的事情,例如查看、编辑、发送或获取某项内容。
没有应用可以接收 Intent 的情况
如果用户没有安装的应用中没有可以处理我们的 Intent 的 Activity ,会引发 ActivityNotFoundException。
方案一:捕获异常
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Define what your app should do if no activity can handle the intent.
}
方案二:确认有可以处理 Intent 的 Activity 后再 startActivity()
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
Intent#resolveActivity(android.content.pm.PackageManager)
如果用户确实没有可以处理 Intent 的应用 ,可以为用户提供下载应用的链接。
只有一个应用可以接收 Intent 的情况
如果只有一个应用能够处理 Intent ,系统会直接启动它,将 Intent 交给它处理。
有多个应用可以接收 Intent 的情况
场景一:其他应用打开,支持选择默认应用
打开并选择默认应用.png如果系统识别出多个可以处理 Intent 的 Activity,则会向用户显示一个对话框(有时称为“消除歧义对话框”),以供其选择要使用的应用,用户可以选择默认使用哪个应用。
public void openWithAnotherAppChooseDefault() {
...
Intent intent = buildViewFileIntent();
try {
startActivity(intent);
} catch (ActivityNotFoundException exception) {
Toast.makeText(this, "未找到可以打开此类文件的应用", Toast.LENGTH_SHORT).show();
exception.printStackTrace();
}
}
场景二:其他应用打开
打开.png用户可能希望每次都使用不同的应用,我们应该显示应用选择器对话框,供用户进行选择,此时,用户无法选择默认应用。
public void openWithAnotherApp() {
...
Intent intent = buildViewFileIntent();
Intent chooser = Intent.createChooser(intent, "选择打开文件的应用");
try {
startActivity(chooser);
} catch (ActivityNotFoundException exception) {
Toast.makeText(this, "未找到可以打开此类文件的应用", Toast.LENGTH_SHORT).show();
exception.printStackTrace();
}
}
构建 Intent 实例
private Intent buildViewFileIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
String fileProviderAuthority = getString(R.string.file_provider_authorities);
Uri contentUri = FileProvider.getUriForFile(this, fileProviderAuthority, file);
intent.setDataAndType(contentUri, "text/plain");
return intent;
}
在创建 Intent 时,需要使用 Uri 来表示文件的路径。针对 API 24(Android 7.0 N)及以上版本构建的应用,传递 File:// Uri
会抛出 FileUriExposedException , 替代方案是 content:// Uri
。
为文件生成 content:// Uri
需要借助 FileProvider 类的静态方法 getUriForFile()。
附
测试设备参数
- 测试设备1:
- 型号:Mi 10 Lite Zoom
- 操作系统:MIUI 12.0.6 稳定版 (Android 10)
- 测试设备2:
- 型号:vivo Y66L
- 操作系统:Funtouch OS 3.0(Android 6.0.1)