Android中Intent应用

来源:互联网 发布:涨乐理财软件下载 编辑:程序博客网 时间:2024/06/06 05:57

什么是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来表示数据,譬如在联系人应用中, 指向联系人1URI可能为:content://contacts/1 (content provider提供的数据类型是content) 。 结合Actiondata可以基本表达出意图,

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

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

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

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

除了Actiondata之外,还有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 里的(actiondatacategory)三个属性来寻找和匹配接收端。

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类有一个按钮用来启动TestView

程序的代码非常简单,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机制,来启动TestView,关键的代码是下面这行: 

Intent intent =new Intent();

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

startActivity(intent);

 

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

Intent(Context packageContext, Class<?> cls)

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

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);

}

}

 

TestView仅仅是调用setContentView来显示test_View.xml中的内容而已。 

下一步在AndroidManifest.xml 文件中注册ActivityAndroidManifest.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> 

Intent机制即使在程序内部显式指定接收者,也还是需要在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);

}

});

}

}

 

注意比较它与IntentDemot的不同之处主要在于初始化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对象,这是因为,要启动的TestActivityCrossIntentTest不在同一个包中,要指定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 FilterAction主要的目的,是为了让其他需要调用这个Activity的程序能够顺利的调用它。除了Action之外,Intent Filter还可以设置CategoryData等,用来更加精确的匹配IntentActivity

隐式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 FilterAction,才能被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>