隐式Intent

相比于显示Intent,隐式Intent则含蓄了很多,它并不明确指出要启动哪一个活动,而是指定了一系列更为抽象的 action 和 category 等信息,然后交由系统去分析这个Intent,并帮我们找出合适的 组件 去启动。

通过<activity>标签下配置<intent-filter>的内容,可以指定activity能够响应的action和category。

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.shijiusui.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

在<action>标签中我们指明了当前activity可以响应com.shijiusui.ACTION_START这个açtion,而<category>标签则包含了一些附加信息,更精确地指明了当前的activity能够响应的Intent中还可能带有的category。

只有<action>和<category>中的内容同时匹配上的Intent,才能启动这个activity。

btn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
        Intent intent = new Intent("com.shijiusui.ACTION_START");
        startActivity(intent);
    }
});

可以看到,我们使用了Intent的构造函数,直接将action的字符串传了进去,表明我们想要启动能够响应 com.shijiusui.ACTION_START 这个action的activity。

但前面不是说要<action>和<category>同时匹配上才能响应吗?怎么没看到category呢?

这是因为android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。


每个Intent中只能指定一个action,却能指定多个category。目前我们的Intent中只有一个默认的category,那么现在再来增加一个吧。

btn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
        Intent intent = new Intent("com.shijiusui.ACTION_START");
        intent.addCategory("com.shijiusui.MY_CATEGORY");
        startActivity(intent);
    }
});

可以调用Intent中的addCategory()方法来添加一个category,对应的AndroidMenifest.xml中Activity的<intent-filter>需要添加一个category的声明。

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.shijiusui.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="com.shijiusui.MY_CATEGORY" />
    </intent-filter>
</activity>

:经测试,必须加上android.intent.category.DEFAULT。

使用隐式Intent,我们不仅可以启动自己的程序内的组件,还可以启动其他程序的组件,这使得Android多个应用程序之间的可以共享功能。

事实上,Intent还可以传递Uri对象,通过setData()方法。通过Uri.parse()方法将一个字符串解析为一个Uri对象。

与此对应,我们还可以再<intent-filter>标签中再配置一个<data>标签,用于更精确地指定当前活动能够响应什么类型的数据。<data>标签中主要可以配置以下内容。

  • android:scheme。用于指定数据的协议部分。如http。
  • android:host。用于指定数据的主机名部分。如www.baidu.com。
  • android:port。用于知道你个数据的端口部分,一般紧随主机名之后。
  • android:path。
  • android.mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有<data>标签中指定的内容和Intent中携带的Data完全一致时,当前组件才能够响应该Intent。
不过一般在<data>标签中都不会指定过多的内容,一般其实只需要指定android:scheme。如指定http,就可以响应所有的http协议的Intent了。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com");
startActivity(intent);
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" />
</intent-filter>

除了http协议外,我们还可以指定很多其他协议,比如geo表示显示地理位置、tel表示拨打电话。

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086");
startActivity(intent);
打赏