Intent filter 关于Action、Category属性详解

说几句俗话:

对应Activity,Service等四大组件在AndroidManifest.xml中设置Action的值,相当于对外,包括对其他app暴露自己是可以被外面调用,为其他组件(或者app)服务的,其他组件(或app)使用:

Intent intent=new Intent();

intent.setAction(Action字符窜[intent.name]);

startActivity(intent);

其中Category约束条件为DEFAULT,只要其他匹配IntentFilter中的action相符,即通过检查,被暴露的组件或者APP机会启动并进行为启动者提供服务.

如果加了Category约束条件:那么启动者还要在启动intent之前提供Category相同的证明条件,可以是多个,只要其中一个相符,被暴露的组件或者APP将会启动并进行为启动者提供服务.

最后给出了自己的例子.

如果一个 Intent 请求在一片数据上执行一个动作, Android 如何知道哪个应用程序(和组件)能用来响应这个请求呢? Intent Filter就是 用来注册 Activity 、 Service 和 Broadcast Receiver 具有能在某种数据上执行一个动作的能力。使用 Intent Filter  ,应用程序组件告诉 Android ,它们能为其它程序的组件的动作请求提供服务,包括同一个程序的组件、本地的或第三方的应用程序。

为了注册一个应用程序组件为 Intent 处理者,在组件的 manifest 节点添加一个 intent-filter  标签。在 Intent Filter 节点里使用下面的标签(关联属性),你能指定组件支持的动作、种类和数据。

1、动作测试:

 

        <activity android:name="com.x210.intentfilters.OneActivity" android:label="oneActivity">   
            <intent-filter>
                <action android:name="myapp.action.test1" />
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

 

规则a.一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配

        <activity android:name="com.x210.intentfilters.OtherActivity" android:label="otherActivity">   
            <intent-filter>  
                <category android:name="cate1"/>
                <category android:name="cate2"/>
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity> 

以上<intent-filter>元素没有包含<action>标签,任何Intent请求都无法与该<intent-filter>匹配。

规则b.如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。

 

 

        <activity android:name="com.x210.intentfilters.OneActivity" android:label="oneActivity">   
            <intent-filter>
                 <action android:name="myapp.action.test1" />
                 <action android:name="myapp.action.test2" />
                 <action android:name="myapp.action.test3" />
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

 

以下几种Intent请求都可以通过上述<intent-filter>的动作测试。

请求1:

 

Intent intent = new Intent("myapp.action.test1");
startActivity(intent);

 

请求2:

Intent intent = new Intent("myapp.action.test2");
startActivity(intent);

如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

 

(1)  如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent-filter>匹配;
(2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

2、类别测试

 

  <activity android:name="com.x210.intentfilters.OtherActivity" android:label="otherActivity">   
            <intent-filter>  
                <action android:name="myapp.action.test1" />
                <category android:name="cate1"/>
                <category android:name="cate2"/>
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

 

只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该 Intent请求通过测试,IntentFilter中多余的<category>声明并不会导致匹配失败。一个没有指定任何类别测试的  IntentFilter仅仅只会匹配没有设置类别的Intent请求。

以下三种Intent请求都可以通过上述<intent-filter>的类别测试。

请求1:

 

    Intent intent = new Intent("myapp.action.test1");
    intent.addCategory("cate1");
    startActivity(intent);

 

请求2:

    Intent intent = new Intent("myapp.action.test1");
    intent.addCategory("cate2");
    startActivity(intent);

请求3:

        Intent intent = new Intent("myapp.action.test1");
        intent.addCategory("cate1");
        intent.addCategory("cate2");
        startActivity(intent); 

 

下面是我做的demo,需要两个工程:

工程一:

java :

package com.example.calledactdemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    private Button mStartBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mStartBtn=(Button)findViewById(R.id.button2);
        mStartBtn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent i=new Intent("android.intent.action.TESTING");
                i.addCategory("test");
//                i.setClassName("com.example.callingactdemo", "com.example.callingactdemo.MainActivity");
                MainActivity.this.startActivity(i);
                
            }
            
        });
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
View Code

xml :

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.calledactdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.calledactdemo.MainActivity"
            android:exported="true"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.TESTED"></action>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

工程二:
java :

package com.example.callingactdemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    private Button mStartBtn;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mStartBtn=(Button)findViewById(R.id.button2);
        mStartBtn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent i=new Intent("android.intent.action.TESTED");
                i.addCategory("android.intent.category.DEFAULT");
//                i.setAction("android.intent.action.TESTED");
//                i.setClassName("com.example.calledactdemo", "com.example.calledactdemo.MainActivity");
                MainActivity.this.startActivity(i);
                
            }
            
        });
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
View Code

xml :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.callingactdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.callingactdemo.MainActivity"
            
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.TESTING"></action>
                <category android:name="test" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        
    </application>

</manifest>

上面是设置各种各样限定条件,相当于有偿服务.

如果直接通过引用包名,就会无视上面的条件:

工程一修改如下:

Intent i=new Intent();
                i.setClassName("com.example.callingactdemo", "com.example.callingactdemo.MainActivity");
                MainActivity.this.startActivity(i);

工程二修改如下:

Intent i=new Intent();
                i.setClassName("com.example.calledactdemo", "com.example.calledactdemo.MainActivity");
                MainActivity.this.startActivity(i);

其他不变,同样可以互相启动.

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/3612659.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值