intent-filter超清晰总结 让别人打开你的app

本文深入探讨了Android中Intent与IntentFilter的工作原理,包括action、category和data的匹配规则,以及如何设置IntentFilter来实现组件间通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

intent-filter对应intent
intent-filter
内容

对应intent关系

(intent-fileter包含的某参数的数用A表示  intetn用B代表)

action

用来表示意图的动作,

如:查看,发邮件,打电话

常用action:

  ACTION_MAIN:Android程序入口。
  ACTION_VIEW: 显示指定数据。
  ACTION_EDIT:  编辑指定数据。
  ACTION_DIAL:  显示拨号面板。
  ACTION_CALL: 直接呼叫Data中所带的号码。
  ACTION_ANSWER: 接听来电。
  ACTION_SEND: 向其他人发送数据(例如:彩信/email)。
  ACTION_SENDTO:  向其他人发送短信。
  ACTION_SEARCH:  执行搜索。
 

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)
path:有效地 URI 路径值(例如, /transport/boats/ )
mimetype:允许你设定组件能处理的数据类型。例如,<type                          android:value=”vnd.android.cursor.dir/*”/>能匹配任何                   Android 游标。获取minetype的方法下面的代码有

先定义一个动词吧 匹配其中之一 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值