Android中Intent应用

什么是Intent

在一个Android 应用中, Intent 是对执行某个操作的一个抽象描述, Intent 负责提供组件之间相互调用的相关信息传递,实现调用者和被调用者之间的解耦。

二、Intent 的属性:

Intent是对执行某个操作的一个抽象描述,其描述的内容包括,对执行动作 Action 的描述、对操作数据的描述、还有 4 种附加属性的描述。分别介绍如下:
 
 Action  ,对执行动作的描述,是个字符串,是对所将执行的动作的描述,在Intent 类中定义了一些字符串常量作为标准动作,譬如:

public   static   final  String  ACTION_DIAL = "android.intent.action.DIAL" ;

public   static   final  String  ACTION_SENDTO  = "android.intent.action.SENDTO" ;

还可以自定义Action ,并定义相应的 Activity 来处理我们自定义的行为。

data ,是对执行动作所要操作的数据的描述,Android 中采用 URI 来表示数据,譬如在联系人应用中, 指向联系人 1 URI 可能为: content://contacts/1 ( content provider 提供的数据类型是 content)  。 结合 Action data 可以基本表达出意图 ,

·  VIEW_ACTION content://contacts/1 — 显示标识符为 ”1″ 的联系人的详细信息

·  EDIT_ACTION content://contacts/1 — 编辑标识符为 ”1″ 的联系人的详细信息

·  VIEW_ACTION content://contacts/ — 显示所有联系人的列表

·  PICK_ACTION content://contacts/ — 显示所有联系人的列表,并且允许用户在列表中选择一个联系人,然后把这个联系人返回给父 activity 。例如:电子邮件客户端可以使用这个  Intent ,要求用户在联系人列表中选择一个联系人。

除了Action data 之外,还有 4 个属性。

catagory 类别 ,是被请求组件的额外描述信息,Intent 类中也定义了一组字符串常量表示 Intent 不同的类别。完整的列表可以看 API 文档中 Intent 类的相应部分。

public   static   final  String  CATEGORY_LAUNCHER  = "android.intent.category.LAUNCHER" ;

Public   static   final   String   CATEGORY_PREFERENCE  = "android.intent.category.PREFERENCE" ;

 

extra 附加信息, 除了data 之外,还可以通过 extra 附加信息, extra 属性使用 Bundle 类型 进行数据传递,我们可以把 Bundle 当做 HashMap 来理解,附加数据可以通过  intent.putExtras()  和  intent.getExtras()  进行传入和读取。 就像这样,获取附加信息:  Bundle bundle = intent.getExtras();

添加附加信息: Bundle bundle = new Bundle(); intent.putExtras(bundle);

component 组件 ,显式指定Intent 的目标组件的名称。如果指定了 component 属性,系统会直接使用它指定的组件,而非匹配查找。

type 数据类型, 显式指定Intent 的数据类型,一般 Intent 的数据类型都能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型和不再进行推导。

解析Intent

Intent是一种在不同组件之间传递的请求信息,是应用程序发出的请求和意图,作为一个完整的消息传递机制, Intent 不仅需要发送端,还需要接收端。

当指定了component 属性后,就是显式的指定了目标组件,也就是接收端。如果没有明确指定目标组件,那么 Android 系统会使用  Intent  里的( action data category )三个属性来寻找和匹配接收端。

IntentFilter

应用程序组件可以使用IntentFilter 来向系统说明自己可以响应和处理那些 Intent 请求。组件一般通过 AndroidManifest.xml 文件的 <Intent-Filter> 描述。

  < activity   android:name = ".ButtonDemo"

                   android:label = "@string/app_name" >

              < intent-filter >

                 < action   android:name = "android.intent.action.MAIN"   />

                 < category   android:name = "android.intent.category.LAUNCHER"   />

             </ intent-filter >

         </ activity >

 

Intent的用法

一、 显式的 Intent(Explicit Intent)

²  同一个应用程序中的Activity切换

通常一个应用程序中需要多个 UI 屏幕,也就需要多个 Activity 类,并且在这些 Activity 之间进行切换,这种切换就是通过 Intent 机制来实现的。

在同一个应用程序中切换 Activity 时,我们通常都知道要启动的 Activity 具体是哪一个,因此常用显式的 Intent 来实现。下面的例子用来实现一个非常简单的应用程序 IntentDemo ,它包括两个 UI 屏幕也就是两个 Activity—— IntentDemo 类和 TestView 类, IntentDemo 类有一个 按钮用来启动 Test View

程序的代码非常简单, IntentDemo类源代码

package  com.wang.android.demo.intent;

import  android.app.Activity;

import  android.content.Intent;

import  android.os.Bundle;

import  android.view.View;

import  android.widget.Button;

public   class  IntentDemo  extends  Activity {

     public   void  onCreate(Bundle savedInstanceState) {

         super .onCreate(savedInstanceState);

        setContentView(R.layout. main );

        Button start_button=(Button)findViewById(R.id. Start );

        start_button.setOnClickListener( new  Button.OnClickListener(){

public   void  onClick(View v) {

Intent intent = new  Intent();

intent.setClass(IntentDemo. this , TestView. class );

startActivity(intent);

}});

    }

}

 

上面的代码中,主要是为“ Start  _ activity ”按钮添加了 OnClickListener 使得按钮被点击时执行 onClick() 方法, onClick() 方法中则利用了 Intent 机制,来启动 Test View ,关键的代码是下面这 行:  

Intent intent = new  Intent();

intent.setClass(IntentDemo. this , TestView. class );

startActivity(intent);

 

这里定义 Intent 对象时所用到的是 Intent 的构造函数之一:

Intent ( Context  packageContext,  Class <?> cls)

两个参数分别指定 Context Class ,由于将 Class 设置为 TestActivity.class ,这样便显式的指定了 Test View 类作为该 Intent 接收者,通过后面的startActivity() 方法便可启动 Test View

TestView.java类的源代码:

package  com.wang.android.demo.intent;

 

import  android.app.Activity;

import  android.os.Bundle;

 

public   class  TestView  extends  Activity{

protected   void  onCreate(Bundle savedInstanceState) {

//  TODO  Auto-generated method stub

super .onCreate(savedInstanceState);

setContentView(R.layout. test_activity );

}

}

 

Test View 仅仅是调用 setContentView 来显示 test_ View .xml 中的内容而已。  

下一步在 AndroidManifest.xml   文件中注册 Activity AndroidManifest.xml   源代码如下:

<? xml   version = "1.0"   encoding = "utf-8" ?>

< manifest   xmlns:android = "http://schemas.android.com/apk/res/android"

       package = "com.wang.android.demo.intent"

       android:versionCode = "1"

       android:versionName = "1.0" >

     < application   android:icon = "@drawable/icon"   android:label = "@string/app_name" >

         < activity   android:name = ".IntentDemo"

                   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 = ".TestView" ></ activity >

     </ application >

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

</ manifest >  

I ntent 机制即使在 程序内部 显式指定 接收者,也还是需要在 AndroidManifest.xml 中声明。这个过程并不像一个简单的函数调用,显式的 Intent 也同样 经过了Android 应用程序框架所提供的支持,从满足条件的 Activity 中进行选择,如果不在 AndroidManifest.xml 中进行声明,则 Android 应用程序框架找不到所需要的 Activity

²  不同应用程序之间的Activity切换

上面的例子我们所做的是在同一应用程序中进行 Activity 的切换,那么在不同的应用程序中,是否也能这么做呢,答案是肯定的,不过对应的代码要稍作修改。本例中我们需要两个应用程序,可利用上例中的 IntentDemo 新建一个 IntentTest   应用程序。

IntentTest 源代码:

package  com.android.demo.intent;

 

import  android.app.Activity;

import  android.content.Intent;

import  android.os.Bundle;

import  android.view.View;

import  android.widget.Button;

 

public   class  IntentTest  extends  Activity {

     /** Called when the activity is first created. */

     @Override

     public   void  onCreate(Bundle savedInstanceState) {

super .onCreate(savedInstanceState);

// 按照main.xml來渲染用戶界面

setContentView(R.layout. main );

Button start_button = (Button) findViewById(R.id. StartButton );

// 为拨号按钮设置一个点击事件观察者

start_button.setOnClickListener( new  Button.OnClickListener() {

// 实现监听器接口的匿名内部类,其中监听器本身是View类的内部接口

// 实现接口必须实现的onClick方法

@Override

public   void  onClick(View v) {

Intent intent =  new  Intent();

intent.setClassName( "com.wang.android.demo.intent" ,

"com.wang.android.demo.intent.TestView" );

// 去调用那些可以处理拨号行为的Activity

startActivity(intent);

}

});

}

}

 

注意比较它与 IntentDemo t 的不同之处主要在于初始化 Intent 对象的过程:  

Intent intent =  new  Intent();

intent.setClassName( "com.wang.android.demo.intent" ,

"com.wang.android.demo.intent.TestView" );

 

这里采用了 Intent 最简单的不带参数的构造函数,然后通过 setClassName() 函数来指定要启动哪个包中的哪个 Activity 而不是像上例中的通过 Intent ( Context  packageContext,  Class <?> cls) 这个构造函数来初始化Intent 对象,这是因为,要启动的 TestActivity CrossIntentTest 不在同一个包中,要指定 Class 参数比较麻烦,所以通常启动不同程序的 Activity 时便采用上面的 setClassName() 的方式  

另外我们还需要修改SimpleIntentTest 程序中的 AndroidManifest.xml 文件,为 TestActivity 的声明添加 Intent Filter  

         < activity   android:name = ".TestView" >

         < intent-filter >

         < action   android:name = "android.intent.action.DEFAULT" />

         </ intent-filter >

         </ activity >

对于不同应用之间的 Activity 的切换,这里需要在 Intent Filter 中设置至少一个 Action ,否则其他的应用将没有权限调用这个 Activity   设置Intent Filter Action 主要的目的,是为了让其他需要调用这个 Activity 的程序能够顺利的调用它。除了 Action 之外, Intent Filter 还可以设置 Category Data 等,用来更加精确的匹配 Intent Activity

隐式 Intent(Implicit Intent)

  如果 Intent 机制仅仅提供上面的显式 Intent 用法的话,这种相对复杂的机制似乎意义并不是很大。确实, Intent 机制更重要的作用在于下面这种隐式的 Intent ,即 Intent 的发送者不指定接收者,很可能不知道也不关心接收者是谁,而由 Android 框架去寻找最匹配的接收者。

²  最简单的隐式Intent

IntentDemo 稍做修改,做一个简单的拨打电话的 demo 。源代码如下:

package  com.wang.android.demo.intent;

 

import  android.app.Activity;

import  android.content.Intent;

import  android.net.Uri;

import  android.os.Bundle;

import  android.view.View;

import  android.widget.Button;

import  android.widget.EditText;

 

public   class  IntentDemo  extends  Activity {

/** Called when the activity is first created. */

@Override

public   void  onCreate(Bundle savedInstanceState) {

super .onCreate(savedInstanceState);

// 按照main.xml來渲染用戶界面

setContentView(R.layout. main );

// 获取可编辑的电话号码框和拨号按钮

final  EditText phoneNumberEditText = (EditText) findViewById(R.id. PhoneNumberEditText );

Button dialing = (Button) findViewById(R.id. dialing );

// 为拨号按钮设置一个点击事件观察者

dialing.setOnClickListener( new  Button.OnClickListener() {

// 实现监听器接口的匿名内部类,其中监听器本身是View类的内部接口

// 实现接口必须实现的onClick方法

@Override

public   void  onClick(View v) {

// 获得可编辑文本框中的值,也就是电话号码

String phoneNumber = phoneNumberEditText.getText().toString();

// new Intent(行为,数据),其中action_dial是拨号行为,数据是电话号码

Intent intent =  new  Intent(Intent. ACTION_DIAL , Uri

. parse ( "tel://"  + phoneNumber));

// 去调用那些可以处理拨号行为的Activity

startActivity(intent);

}

});

}

}

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" >

< EditText   android:id = "@+id/PhoneNumberEditText"   android:text = "请输入电话号码"   android:textSize = "15sp"

android:layout_width = "fill_parent"   android:layout_height = "wrap_content" ></ EditText >

< Button   android:id = "@+id/dialing"   android:text = "@string/dialing"

android:layout_width = "wrap_content"   android:layout_height = "wrap_content" ></ Button >

</ LinearLayout >

 

AndroidManifest.xml 源代码:

<? xml   version = "1.0"   encoding = "utf-8" ?>

< manifest   xmlns:android = "http://schemas.android.com/apk/res/android"

       package = "com.wang.android.demo.intent"

       android:versionCode = "1"

       android:versionName = "1.0" >

     < application   android:icon = "@drawable/icon"   android:label = "@string/app_name" >

         < activity   android:name = ".IntentDemo"

                   android:label = "@string/app_name" >

             < intent-filter >

                 < action   android:name = "android.intent.action.MAIN"   />

                 < category   android:name = "android.intent.category.LAUNCHER"   />

          < intent-filter >

< action   android:name = "android.intent.action.CALL_BUTTON"   ></ action >

< category   android:name = "android.intent.category.DEFAULT" >

            </ category >

</ intent-filter >

             </ intent-filter >

         </ activity >

     </ application >

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

 

</ manifest >  

 

²   增加一个接收者

事实上接收者如果希望能够接收某些 Intent ,通过在 AndroidManifest.xml 中增加 Activity 的声明,并设置对应的 Intent Filter Action ,才能被 Android 的应用程序框架所匹配。

AndroidManifest.xml 文件,将 IntentDemo 的声明部分改为:  

         < activity   android:name = ".IntentDemo"

                   android:label = "@string/app_name" >

             < intent-filter >

                 < action   android:name = "android.intent.action.MAIN"   />

                 < category   android:name = "android.intent.category.LAUNCHER"   />

           < intent-filter >

< action   android:name = "android.intent.action.CALL_BUTTON"   ></ action >

< category   android:name = "android.intent.category.DEFAULT" ></ category >

</ intent-filter >

             </ intent-filter >

         </ activity >

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值