Android Intent开发 Intent-filter

1,Intent的基础用法

Intent是android中各activity之间通信的一个很重要的类,一般我们是这么使用的

 

//创建一个intent 
Intent intent = new Intent(); 

//压值进intent中 
//intent是基于一种基于Map的数据结构 
//传我们的基本数据类型的可以之间key,value方式传值 
intent.putExtra("hello","Hello world"); 
//但是,传一个对象的时要注意,该对象要实现序列化窗口才可以传值 
//putExtra(String name, Serializable value) 
Demo demo = new Demo(); 
intent.putExtra("Demo",demo); 
//然后,我们把这个intent传到另外一个activity 
intent.setClass(xxx.this,zzz.class); 
startActivity(intent); 
//------- 
//目标activity 
//获取传过来的intent 
Intent intent = getIntent(); 
//从Intent中获取值 
String hello = intent.getStringExtra("Demo"); 
Demo demo = (Demo)intent.getSerializable("Demo"); 


以上代码就是最基础的Intent的用法

2,深入Intent的构造和Intent-filter的基础入门

首先我们看下Intent的构造方法

 

Intent() 
//Create an empty intent. 

Intent(Intent o) 
//Copy constructor. 

Intent(String action) 
//Create an intent with a given action. 

Intent(String action, Uri uri) 
//Create an intent with a given action and for a given data url. 

Intent(Context packageContext, Class<?> cls) 
//Create an intent for a specific component. 

Intent(String action, Uri uri, Context packageContext, Class<?> cls) 
//Create an intent for a specific component with a specified action and data. 


出这些构造方法中我们,可以看出,新建一个Intent其实可以设置很多东西,这里我说说componentName,action,category,data

componentName

componentName 直译的话就是组件的名字的意思,如果我们写的一个类当作成一个组件,那么这个componentName就是用来封装我们写的这些类的位置.

 

//创建一个component的对象 
ComponentName componentName = new ComponentName(Context.this, xxx.class); 

Intent intent  = new Intent(); 
Intent.setComponent(componentName); 
startActivity(intent); 

//---------- 
//在xxxactivity中 
ComponentName comp = getIntent().getComponent(); 
String packageName = comp.getPackName(); 
String className = comp.getClassName(); 


其实细心的同学可以发现,其实跟setClass(),没什么区别吗,而且,还比setClass()麻烦,其实,setClass()是封装了这个功能而已,最实现还是要用到这个类.

Action,category,data简单入门

我感觉,学intent 和 intent-filter把action,category,data搞清楚才算真正的掌握了intent的用法.

Action
如果学过Structs2的同学应该不会陌生,所谓的action就是发送一个特定的请求,然后,由一个符合这个请求的activity响应

官方文档中是这么说action的:

The action largely determines how the rest of the intent is structured — particularly the data and extras fields — much as a method name determines a set of arguments and a return value. For this reason, it's a good idea to use action names that are as specific as possible, and to couple them tightly to the other fields of the intent. In other words, instead of defining an action in isolation, define an entire protocol for the Intent objects your components can handle.

我简要说下我理解的大义,有错欢迎指出

action 在很大一部分程度上决定你的intent 是如何构建的,特别是还有data,和 额外的一些字段,还有更多的是如何决定方法名,设置数组和返回的参数.由于这个原因,这是一个很好的方法去尽可能的具体的使用action,用action把这些字段紧密的联系在一起.另外,灵活定义你的action,然后把它定义在一个文档中为你的intent对象的组建能够正常处理

渣翻译…可能比谷歌翻译还有烂…有错欢迎指出!!!!!!!!!!!!!

category
要使一个action能够正常运行,category是必不可少的,关于category详细介绍请看开发者文档中的intent and intent-filter

这里说下注意的细节和使用.

首先,这句话是很重要的..取之于官方文档

Therefore, activities that are willing to receive implicit intents must include "android.intent.category.DEFAULT" in their intent filters.

这句话,告诉我们在intent-filter(可以用xml创建也可以用代码创建,这里主要讲xml的创建),必须添加一个android.intent.category.DEFAULT,至于,不添加会发生什么事…我花了半个小时的排错告诉我是无法运行的

 

//在我们要运行的activity中添加 
<activity android:name=".SecondActivity" android:label="second"> 
	<intent-filter > 
		<action android:name="kg.tom.TEST"/> 
		<category android:name="android.intent.category.DEFAULT" /> 
	</intent-filter> 
</activity> 


//firstActivity 
//在创建好的一个监听器里面方法中写上 
Intent intent = new Intent(); 
intent.setAction("kg.tom.TEST"); 
//利用action来运行相应的activity 
startActivity(intent); 


 

注意:每个intent只能设置一个action,但是,可以设置多个category,这里的组合问题,自己好好想想吧.

data
因为就是一些参数的介绍,看官方文档就好了,我是这样理解这个DATA,例如,我们一个Mp3播放器,当我们在任务管理器中点击一个MP3文件,MP3这个文件就是一个data,就会触发我们,在intent-filter匹配这个Mp3,<data />的activity运行..

 

显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent。显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。
隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent。它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息.由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。

隐式启动Intent

  Android系统寻找与Intent请求意图最匹配的组件具体的选择方法是:
Android将Intent的请求内容和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组件.如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。
Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含组件的过滤器(即可以匹配哪些Intent请求)。
一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响应隐式Intent请求。 
一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和 IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准Action \Data\ Category,而Extra和Flag在解析收到Intent时是并不起作用的

Intent过滤器:

  应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描述该组件所能响应Intent请求——组件希望接收什么类型的请求行为,什么类型的请求数据。
如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的Intent Filter。
隐式Intent和Intent Filter进行比较时的三要素是Intent的动作、数据以及类别。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。

Action测试

<intent-filter>  
	<action android:name=”com.example.project.SHOW_CURRENT” />   
	<action android:name=”com.example.project.SHOW_RECENT” />   
	<action android:name=”com.example.project.SHOW_PENDING” /> 
</intent-filter>  


一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。
如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。
如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

(1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent- filter>匹配;

(2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个 Intent请求就将顺利地通过<intent-filter>的行为测试。


 Category测试

<intent-filter >
	<category android:name=”android.Intent.Category.DEFAULT” /> 
	<category android:name=”android.Intent.Category.BROWSABLE” /> 
</intent-filter> 


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

Data测试:

<intent-filter> 
	<data android:type=”video/mpeg” android:scheme=”http” . . /> 
	<data android:type=”audio/mpeg” android:scheme=”http” . . /> 
</intent-filter>  


<data>元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试

演示一个例子,用Intent隐身启动activity,并显示Action和Category的值,这个例子用到了两个Activity,两个布局,要注意到是在AndroidMainFest里设置uses-permission

首先来看布局文件main.xml

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     >
 <Button android:id="@+id/bt1"
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="intent隐身启动test"
     />
 </LinearLayout>


 

second.xml文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id = "@+id/et1" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <EditText android:id ="@+id/et2" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>


 

然后给大家看一下AndroidMainFest里的代码

View Code 
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="cn.shaoyangjiang.com"
       android:versionCode="1"
       android:versionName="1.0">
     <uses-sdk android:minSdkVersion="8" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name">
         <activity android:name=".IntentFilterActivity"
                   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=".Second"
                   android:label="@string/app_name">
         <intent-filter>
         <!-- 指定该Activity能响应action为指定字符串的Intent -->
                 <action android:name="cn.shaoyangjiang.cn.com" />
         <!-- 指定该Activity能响应category为指定字符串的Intent -->
                 <category android:name="cn.shaoyangjiang.cn" />
         <!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
                 <category android:name="android.intent.category.DEFAULT" />   
             </intent-filter>      
         </activity>    
     </application>
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
 </manifest>


 

第三步:修改intentfilterActivity.java文件

 package cn.shaoyangjiang.com;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 
 public class IntentFilterActivity extends Activity {
     //定义一个Action常量
     final static String shao = "cn.shaoyangjiang.cn.com"; 
     //定义一个Category常量
     final static String yang = "cn.shaoyangjiang.cn";
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         Button button1 = (Button)findViewById(R.id.bt1);
         button1.setOnClickListener(new OnClickListener() {        
             @Override
             public void onClick(View arg0) {
                 Intent intent = new Intent();
                 //设置Action属性
                 intent.setAction(shao);
                 //添加Category属性
                 intent.addCategory(yang);
                 startActivity(intent);
             }
         });
     }
 }


 

最后一部是second.java文件

 package cn.shaoyangjiang.com;
 
 import java.util.Set;
 import android.app.Activity;
 import android.os.Bundle;
 import android.widget.EditText;
 
 public class Second extends Activity{
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.second);
         EditText editText1 =(EditText)findViewById(R.id.et1);
         //获取该Activity对应的Intent的Action属性
         String actionValue = getIntent().getAction();
         //显示Action属性
         editText1.setText("Action: "+actionValue);
         EditText editText2 = (EditText)findViewById(R.id.et2);
         //获取该Activity对应的Intent的Category属性
         Set<String> cate= getIntent().getCategories();
         //显示Action属性
         editText2.setText("Categoties: "+cate);    
     }    
 }


 

效果图:



参考: http://www.cnblogs.com/Android_2011/archive/2011/06/12/2078643.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值