Intent Filter用法

452 阅读3分钟

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

在我们在程序里想通过外部应用去执行一个请求的时候,一般是通过Intent。那么Android是如何知道使用哪个应用程序(和组件)来响应这个请求呢?使用Intent Filiter,应用程序可以声明它们支持的数据和动作。Intent代表了对在某个数据集上执行的动作请求,Intent Filiter,则声明了一个特定的应用程序组件能够对一个类型的数据执行操作。

Intent Filiter下可以使用如下标签:

action: 使用android:name属性指定要为之服务的动作的名称。每个Intent Filiter必须要有至少一个action(标签)。

category: 使用android:name属性来指定应该在哪种情况下为action提供服务。每个Intent Filiter可以包含多个category标签。即可以指定自己的category,也可以使用android提供的标准值。

data: data标签允许指定组件可以执行的数据类型。根据情况,也可以包含多个数据标签。可以使用以下属性的任意组合来指定你的组件所支持的数据。

android:host: 指定一个有效的主机名

android:minetype: 指定组件可以执行的数据类型

android:path: 指定URI的有效路径值

android:port: 指定主机的有效端口

android:scheme: 要求一种特定的模式(如content或http)

   <activity
       android:name=".MyActivity"
       android:label="@string/app_name" >
       <intent-filter>
           <action android:name="android.intent.action.VIEW" />
           <category android:name="android.intent.category.DEFAULT" />
           <category android:name="android.intent.category.BROWSABLE" />
           <data android:scheme="http" android:host="www.csdn.com"/>
       </intent-filter>
   </activity>

Android如何解析Intent Filter

当startActivity中传入一个隐式Intent时,决定启动哪一个Activity的过程叫做intent解析。目的是找出最匹配的Intent Filter

1: Android将已安装包的可用的Intent Filter放到一个表中。

2: 解析Intent时相关联的动作或者类型不匹配的Intent Filter将会从列表中移除

      如果Intent Filter包含了指定action(动作),那么就认为动作匹配了。如果检查到没有任何一个动作和Intent指定的动作匹配时,就认为动作匹配失败了

      对category匹配来说,Intent Filter必须包含待解析的Intent中的所有category,当然还可以包含其它的

3: 最后Intent的数据URI的每一部分都和Intent Filter的data标签进行比较。如果Intent Filter指定了scheme,host/authoriy,path或者MIME类型,那么这些值都要和Intent的URI比较。任意一个不匹配都会把Intent Filter从列表移除。没有指定数据值的Intent Filter将会和所有的Intent数据值匹配。

4: 当隐式启动一个Activity时,如果这个进程解析出多个组件,那么所有可能匹配的组件都会呈现给用户。对于Broadcast Receiver,每个匹配的接收器将接收Broastcast Intent

下面写了个测试程序,简单明了。

    package com.example.testintentfilter;

    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;

    //下面注释的方式也是可行的
    public class MainActivity extends Activity {

    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	}

    	public void start1(View v) {
    		
    		Intent intent = new Intent();
    		Uri uri = Uri.parse("http://blog.csdn.net/chenliqiang12345678");
    		intent.setAction("myaction");
    		intent.setDataAndType(uri, "a/b"); //
    		startActivity(intent);
    		//这里需要注意的是,Type属性和Data属性一般会出现相互覆盖的情况,如果希望Intent既有Data属性也有Type属性,必须通过setDataAndType()方法来实现。
    		
    		
    /*		Intent intent = new Intent("myaction", Uri.parse("http://blog.csdn.net/chenliqiang12345678"));
    		startActivity(intent);
    		*/
    	}

    	public void start2(View v) {
    		Uri uri = Uri.parse("http://blog.csdn.net/chenliqiang12345678");
    		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    		startActivity(intent);
    		
    /*		Intent intent = new Intent();
    		intent.setAction("android.intent.action.VIEW");
    		Uri content_url = Uri.parse("http://blog.csdn.net/chenliqiang12345678");
    		intent.setData(content_url);
    		startActivity(intent);*/
    	}
    	
    	public void start3(View v) {
    		Intent intent = new Intent();
    		intent.setAction("android.intent.action.VIEW");
    		Uri content_url = Uri.parse("http://blog.csdn.net/chenliqiang12345678");
    		intent.setData(content_url);
    		intent.setClassName("com.UCMobile", "com.UCMobile.main.UCMobile");  //此处指定UC浏览器打开网页,当前packageName为:com.UCMobile className:为com.UCMobile.main.UCMobile
    		startActivity(intent);
    	}
    }


    package com.example.testintentfilter;

    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.Toast;

    public class TestActivity extends Activity {

    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_test);
    		
    		String action = this.getIntent().getAction();
    		final Uri data = this.getIntent().getData();
    		String type = this.getIntent().getType();
    		Toast.makeText(this, "action is:"+action+"\r\nuri is :"+data.toString()+"\r\ntype is :"+type+"\r\n2s latter will be open", Toast.LENGTH_SHORT).show();
    		new Handler().postDelayed(new Runnable() {
    			@Override
    			public void run() {
    				Intent intent = new Intent();
    				intent.setAction("android.intent.action.VIEW");
    				intent.setData(data);
    				startActivity(intent);				
    			}
    		}, 2000);
    		
    		
    	}
    }


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

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

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

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.example.testintentfilter.TestActivity"
                android:label="@string/title_activity_test" >
                
                <intent-filter >
                    <action android:name="myaction"/>
                    <category android:name="android.intent.category.DEFAULT" /> 
                    <data  android:scheme="http" android:path="blog.csdn.net/chenliqiang12345678"/>
                    <!-- <data  android:scheme="http" android:host="blog.csdn.net" android:path="/chenliqiang12345678"/> -->
                    <data android:mimeType="a/b"></data>
                </intent-filter>
                
            </activity>
        </application>

    </manifest>

本文是从我CSDN博客里迁移过来的