zoukankan      html  css  js  c++  java
  • Android-IntentFilter

    Android-IntentFilter

    学习自

    《Android开发艺术探索》

    IntentFilter漫谈

    众所周知,在Android中如果要想启动一个Activity,有两种方式,显式启动 隐式启动 ,显式启动不用多说,隐式启动才是我们本章需要学习的重点。

    我们开发的程序,常常需要和其他的APP进行交互,比如说,我们有一个程序,需要快捷拨号,这时候我们就需要启动系统的拨号界面来完成拨号操作了,要是一个程序能够随随便便地就能启动其他程序,那也忒不安全了,如果想要 隐式启动 Activity,必须满足对应的Activity添加的IntentFilter(意图过滤器)。

    IntentFilter主要分为以下几个部分并且均可包含多个且一个Activity可以拥有多个IntentFilter:

    • action
    • category
    • data
    <activity android:name=".Test2Activity">
        <intent-filter>
            <action android:name="com.example.it.studykotlin.Test2Activity_1" />
            <action android:name="com.example.it.studykotlin.Test2Activity_2" />
            <category android:name="com.example.it.studykotlin.Test2Activity_1" />
            <category android:name="com.example.it.studykotlin.Test2Activity_2" />
            <data android:mimeType="text/plain" />
        </intent-filter>  <intent-filter>
            <action android:name="com.example.it.studykotlin.Test2Activity_3" />
            <action android:name="com.example.it.studykotlin.Test2Activity_4" />
            <category android:name="com.example.it.studykotlin.Test2Activity_3" />
            <category android:name="com.example.it.studykotlin.Test2Activity_4" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity>
    

    Action

    一般在建立IntentFilter的时候,我们首先会对Acting进行设置,表示,限定要执行那些操作的人才能跳转我们所创建的Activity。
    Action 是一个普通的字符串,系统已经定义了一些Action,如果系统定义的不能满足我们的需要的话,我们同样可以自定义Action,Action的匹配规则如下: Intent中的Action的只要与IntentFilter中定义的任意一个Action匹配成功即可。

    Demo

    定义Activity并通过IntentFilter的Action来过滤。

    <activity android:name=".TestActivity">
        <intent-filter>
            <action android:name="com.example.it.studyandroid.send" />
        </intent-filter>
    </activity>
    

    Intent设置Action

    val tempIntent = Intent()
    tempIntent.action = "com.example.it.studyandroid.send"
    

    Category

    如果想要建立的Activity能够被隐式启动的话,Category也是必须设置的,有些时候我们可能并不需要Category,但是又有强制的限制必须要设置Category,这时候我们可以将Category设置成为 android.intent.category.DEFAULT ,在使用Intent启动Activity的时候,如果没有设置Category那么系统会为我们设置这个默认的Category。

    Category 同样可以是任意的字符串,Category的匹配规则是,如果在Intent中定义了Category,那么Intent中所有所有的Category必须和IntentFilter中的Category其中之一相匹配。

    Demo

    IntentFilter设置Category

    <activity android:name=".TempActivity">
        <intent-filter>
            <action android:name="com.example.it.studyandroid.send" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

    为Intent添加Activity

    val tempIntent = Intent()
    tempIntent.action = "com.example.it.studyandroid.send"
    //因为IntentFilter中定义的Default Category,所以这句话不写也可以1启动Activity
    tempIntent.addCategory(Intent.CATEGORY_DEFAULT)
    this.startActivity(tempIntent)
    

    Data

    Data 这一筛选条件比较复杂,分为以下几个部分:

    Data是由URI和mimeType两大部分构成的,通过Data我们可以限制,Intent传递过来的数据,更为精确的要求了,启动对应Activity的条件。URI 用力来传递数据,而mineType用来定义数据的类型。 #### URI 一些URI的DEMO ```kotlin content://com.example.project:200/folder/subfolder/etc https://www.baidu.com/ ```
    • __schedule(协议) __URI的协议,常见的有 http file content 等,schedule是必须的,如果没有schedule那么URI无效
    • __host(主机名) __URI中的主机名,例如 www.baidu.com 如果没有host,那么URI无效
    • port(端口号),这个就无需解释了
    • path/pathPattern, 路径信息,其中path 不支持通配符而pathPattern支持通配符
    • pathPrefix: 设置路径的前缀,比如说我的博客https://www.cnblogs.com/slyfox/p/9234790.html 那么只要设置了 pathPrefix为 /slyfox 即可。

    Data的匹配规则

    例子1:

     <activity android:name=".TempActivity">
         <intent-filter>
             <action android:name="com.example.it.studyandroid.send" />
             <category android:name="android.intent.category.DEFAULT" />
             <!--定义的mimeType-->
             <data android:mimeType="image/*" />
         </intent-filter>
     </activity>
    

    上面的代码片段中虽然仅仅是指定了 mimeType 并没有指定URI的信息,但是URI却又默认值 schedule部分必须是 file 或者 content 才能匹配成功。

    val tempIntent = Intent()
    tempIntent.action = "com.example.it.studyandroid.send"
    //如果需要同时设置data和mimiType,那么必须使用此方法才行,
    // 否则使用setData和setType方法的话会相互抵消
    tempIntent.setDataAndType(Uri.parse("content://temp"), "image/*")
    this.startActivity(tempIntent)
    

    例子2:

    <activity android:name=".TempActivity">
        <intent-filter>
            <action android:name="com.example.it.studyandroid.send" />
            <category android:name="android.intent.category.DEFAULT" />
            <data
                android:host="www.baidu.com"
                android:mimeType="video/mpeg"
                android:scheme="http" />
            <data
                android:host="www.baidu.com"
                android:mimeType="audio/mpeg"
                android:scheme="http" />
        </intent-filter>
    </activity>
    

    启动

    tempIntent.setDataAndType(Uri.parse("http://www.baidu.com"), "video/mpeg")
    tempIntent.setDataAndType(Uri.parse("http://www.baidu.com"), "audio/mpeg")
    

    避免隐式启动Activity报错

    当我们使用隐式启动Activity的时候,经常用以报错,所以我们在启动Activity的时候需要事先检查一下是否存在指定的Activity。相关方法如下:

    • packageManager的resolveActivity 方法
    • intent的resolveActivity方法
    • packageManager的queryIntentActivities方法

    其中,intent的resolve不多说了,参数比较简单所以我就不在这里多说,接下来我们来看看其他两个方法的参数

    /**
    @param intent 要检查的Intent对象
    @param flags 标识位,指定匹配哪一类的Activity
    */
    public abstract ResolveInfo resolveActivity(Intent intent, @ResolveInfoFlags int flags);
    //此方法同上,只不过返回的是一个集合
    public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
                @ResolveInfoFlags int flags);
    

    调用方法

    if (packageManager.resolveActivity(tempIntent, PackageManager.MATCH_DEFAULT_ONLY) == null) {
        Toast.makeText(this, "The Activity is not existed!", Toast.LENGTH_SHORT).show()
        return@setOnClickListener
    }
    

    其中flags标志为常用的标志是 MATCH_DEFAULT_ONLY 标识仅仅匹配category中定义了 android.intent.category.DEFAULT 的Activity,这就保证了只要返回值不为空,那么久一定能够成功启动Activity。

  • 相关阅读:
    挺好的程序员面试网址
    [转]浅谈协方差矩阵
    坚持
    matlab中文论坛
    看书
    Opengl绘制点
    说服力
    心情
    vector操作
    我的毕设
  • 原文地址:https://www.cnblogs.com/slyfox/p/9246029.html
Copyright © 2011-2022 走看看