下面是打开文件的Intent的代码片段:
public static Intent makeOpenFileIntent(Context context, String mime, File path) {
Intent intent = new Intent(Intent.ACTION_VIEW);
LogUtils.v(TAG, "Open file with mime: " + mime);
if (StringUtils.isNullOrEmpty(mime)) {
intent.setDataAndType(Uri.fromFile(path), "*/*");
} else {
intent.setDataAndType(Uri.fromFile(path), mime);
}
return intent;
}
通过Intent请求系统筛选出能打开目标文件的Activity,基本都是通过上面这段代码来实现的,没毛病。
使用魅族手机debug后发现,出问题的都是那些 mime 为null的文件。mime这个参数,即文件的 MimeType。通过下面的代码来获取:
MimeTypeMap.getSingleton().getMimeTypeFromExtension(String extension);
由此基本可以得出结论,魅族手机发现你传递过来的文件的 MimeType
为 */*
时,并不会弹出所有支持 Intent.ACTION_VIEW
的Activity供你选择,而是直接跳转到某个系统自带的应用了。
Context#start...(Intent) 系列方法的工作原理:如果使用的是显式Intent,就直接去启动具体的组件;如果使用的是隐式Intent,那么系统先经过筛选找到所有符合Intent描述信息的组件,然后显示符合条件的组件列表供你选择。其实,隐式Intent最终还是被转换成了显示Intent。
实现Activity选择器
经过上面分析,我们就可以开始实现自定义Activity选择器了,这个项目的名称就叫做AppChooser。
先来看一下效果:
引入项目
compile 'io.julian:appchooser:1.0.4'
使用方法,在Activity或Fragment中:
@NonNull
private AppChooser mAppChooser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_infos);
// 初始化 AppChooser
mAppChooser = AppChooser.with(this);
}
@Override
public void onStart() {
super.onStart();
// 绑定 AppChooser
mAppChooser.bind();
}
@Override
public void onStop() {
super.onStop();
// 解绑 AppChooser
mAppChooser.unbind();
}
/**
* 打开文件
*/
private void showFile(FileInfo file) {
// 传入File对象
mAppChooser.file(new File(file.getAbsolutePath())).load();
}
网友评论