intent-filter | 内容 | 对应intent关系 (intent-fileter包含的某参数的数用A表示 intetn用B代表) |
---|---|---|
action | 用来表示意图的动作, 如:查看,发邮件,打电话 常用action: ACTION_MAIN:Android程序入口。 | A>0 B=0 ,1 A contains B? (要求intent-fileter的action属性数目一定大于0,如果为空,无法匹配任何action) (要求intent的action属性为0或者1,不设置即为0,多次设置只保留最后设置的) (匹配要求:intent-fileter的action包含inten的action,如果intent的action为空,则显然包含) |
category | 用来表示动作的类别,通常为 CATEGORY_DEFAULT
| A>0 B>0 A contains B? (要求intent-fileter的category属性数目一定大于0,如果为空,无法匹配任何category) (要求intent的category属性大于0,不设置则自动添加android.intent.category.DEFAULT) (匹配要求:intent-fileter的category包含inten的category) |
data | 表示与动作要操作的数据, 比如一个电话号码或者uri 首先包含一个uri,包含scheme://host:port/path,其次包含一个minitype,代表文件类型
含义: scheme:类型(例如, content 或 http,比如http代表网络请 求 ) host:指定一个有效的主机名(例如, com.google ) port:特定主机上的有效端口。(比如,80) | 先定义一个动词吧 匹配其中之一 match 并且uri包括scheme://host:port/path,我们这里用uri统一表示 A.uri>=0 and A.minitype>0 B.uri>=0 and B.minitype>0 if(A.uri==0&&A.minitype=0){ B.uri==0 && B.minitype==0 ? else if(A.uri==0&&A.minitype>0){ B.minitype match A ? else if(A.uri>0&&A.minitype==0){ B.uri match A && B.minitype==0 ? else if(A.uri>0&&A.minitype>0){ B.uri match A && B.minitype match A ? (要求intent-fileter的data属性minitype和uri数目任意) (要求intent的data属性minitype和uri数目任意) (匹配要求: (1) 一个既不包含URI也不包含数据类型的意图对象,仅在过滤器也同样没有指定任何URI和数据类型的情况下才能通过测试。 (2)一个包含URI但没有数据类型的意图对象,仅在它的URI和一个同样没有指定数据类型的,过滤器里的URI匹配时才能通过测试。这通常发生在类似于mailto:和tel:这样的URIs上:它们并不引用实际数据。 (3)一个包含数据类型但不包含URI的意图对象,仅在这个过滤器列举了同样的数据类型,而且也没有指定一个URI的情况下才能通过测试。 (4)一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象可以通过测试,如果它的类型和过滤器中列举的类型相匹配的话。如果它的URI和这个过滤器中的一个URI相匹配或者它有一个内容 content:或者文件file: URI,而且这个过滤器没有指定一个URI,那么它也能通过测试。换句话说,一个组件被假定为支持 ”content: 数据“ 和 “file: 数据”,如果它的过滤器仅列举了一个数据类型。 ) 然后我们讲解一下uri的匹配,这里的match和上面的不一样,对于uri的某一项,如果A此项为空,则B此项无论是否有值,此项都匹配,即如果A,scheme没有设定要求,那么无论B的scheme是什么,都匹配,match都返回true if(B.scheme match A.scheme &&B.host match A.host && B.port match A.port && B.uri match Auri ) B.url match A.url =true (即scheme,host,port,path分别匹配: 如果过滤器仅指定了一个scheme,所有该scheme的URIs都能够和这个过滤器相匹配; 如果过滤器指定了一个scheme、主机名但没有路经部分,所有具有相同scheme和主机名的URIs都可以和这个过滤器相匹配,而不管它们的路经; 如果过滤器指定了一个scheme、主机名和路经,只有具有相同scheme、主机名和路经的URIs才可以和这个过滤器相匹配。 当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。) |
下面再详细介绍一下data的一些设置
记住,这里的设置data要符合上面的匹配要求
如果你想让你的文件被其他文件打开:
方式:
public void open(File file) {
Intent intent;
Uri uri1;
try {
intent = new Intent();
//这里是想查看文件
intent.setAction(Intent.ACTION_VIEW);
// intent.setAction(Intent.ACTION_EDIT); 如果想编辑可以用这个,其他的同理
intent.addCategory("android.intent.category.DEFAULT");
//这个必须要加,意思是用一个新的task打开
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//对于安卓7.0获取文件路径需要使用FileProvider
if (Build.VERSION.SDK_INT >= 24) {
//判断安卓版本 高于7.0
uri1 = FileProvider.getUriForFile((Activity) view.getContext(), "这里换成你自己的fileprovider", file);
// 第一个是content ,第二个人可以是唯一的字符,第三个是File对象
} else {
//低于7.0
uri1 = Uri.fromFile(file);
//获取图片路径
}
//增加读写问的权限,即如果这个文件在你的私有目录,增加这句可以让其他的app也可以读写
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//这里的getMiMEType是用来获取文件类型,是指MIMETyoe
intent.setDataAndType(/*uri*/uri1, getMIMEType(file));
startActivity(intent);
}catch (Exception e){
Log.e("打开文件",e.getMessage());
//如果没有找到能够打开的app,会报错
Toast.makeText(view.getContext(),"没有打开此文件的app",Toast.LENGTH_LONG).show();
}
}
public String getMIMEType(File file){
//这里的s是指获取文件名的后缀,如a.txt就是.txt, GetFilesUtils是我的一个工具类,你处理
//一下file的name就可以
String s = GetFilesUtils.getInstance().getFileType(file.getName());
for(int i=0 ;i<63;i++){
if(MIME_MapTable[i][0].equals(s)){
return MIME_MapTable[i][1];
}
}
return "";
}
//建立一个MIME类型与文件后缀名的匹配表
private static final String[][] MIME_MapTable={
//{后缀名, MIME类型}
{".3gp", "video/3gpp"},
{".apk", "application/vnd.android.package-archive"},
{".asf", "video/x-ms-asf"},
{".avi", "video/x-msvideo"},
{".bin", "application/octet-stream"},
{".bmp", "image/bmp"},
{".c", "text/plain"},
{".class", "application/octet-stream"},
{".conf", "text/plain"},
{".cpp", "text/plain"},
{".doc", "application/msword"},
{".exe", "application/octet-stream"},
{".gif", "image/gif"},
{".gtar", "application/x-gtar"},
{".gz", "application/x-gzip"},
{".h", "text/plain"},
{".htm", "text/html"},
{".html", "text/html"},
{".jar", "application/java-archive"},
{".java", "text/plain"},
{".jpeg", "image/jpeg"},
{".jpg", "image/jpeg"},
{".js", "application/x-javascript"},
{".log", "text/plain"},
{".m3u", "audio/x-mpegurl"},
{".m4a", "audio/mp4a-latm"},
{".m4b", "audio/mp4a-latm"},
{".m4p", "audio/mp4a-latm"},
{".m4u", "video/vnd.mpegurl"},
{".m4v", "video/x-m4v"},
{".mov", "video/quicktime"},
{".mp2", "audio/x-mpeg"},
{".mp3", "audio/x-mpeg"},
{".mp4", "video/mp4"},
{".mpc", "application/vnd.mpohun.certificate"},
{".mpe", "video/mpeg"},
{".mpeg", "video/mpeg"},
{".mpg", "video/mpeg"},
{".mpg4", "video/mp4"},
{".mpga", "audio/mpeg"},
{".msg", "application/vnd.ms-outlook"},
{".ogg", "audio/ogg"},
{".pdf", "application/pdf"},
{".png", "image/png"},
{".pps", "application/vnd.ms-powerpoint"},
{".ppt", "application/vnd.ms-powerpoint"},
{".prop", "text/plain"},
{".rar", "application/x-rar-compressed"},
{".rc", "text/plain"},
{".rmvb", "audio/x-pn-realaudio"},
{".rtf", "application/rtf"},
{".sh", "text/plain"},
{".tar", "application/x-tar"},
{".tgz", "application/x-compressed"},
{".txt", "text/plain"},
{".wav", "audio/x-wav"},
{".wma", "audio/x-ms-wma"},
{".wmv", "audio/x-ms-wmv"},
{".wps", "application/vnd.ms-works"},
//{".xml", "text/xml"},
{".xml", "text/plain"},
{".z", "application/x-compress"},
{".zip", "application/zip"},
{"", "*/*"}
};
然后比如你想让你的app可以接受任何的文件,你的intent-filter可以这样设置
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*"/>
</intent-filter>
mimeType设置为可以匹配任意值,再根据上面的表的匹配规则,可以匹配任何data
参考了下面的博客,感谢:
https://www.cnblogs.com/ywtk/p/4158103.html
https://blog.youkuaiyun.com/wenzhi20102321/article/details/52876648
https://blog.youkuaiyun.com/elevendgq/article/details/51436608