天天看点

Android开发之旅: Intents和Intent Filters(实例部分)引言例子(需求)描述STEP1、添加用于显示通讯录的布局文件STEP2、添加Button的点击事件STEP3、添加通讯录活动STEP4、解析通讯录返回的数据STEP5、在清单文件AndroidManifest.xml中注册通讯录活动和读取Contact数据库的权限总结

Intent的重要性,我不再着重介绍了,但我还是要说:Intent能够使应用程序突破沙盒与外界交流,者这使得Android的世界变得丰富多彩!本篇将用实例来介绍,如何应用Intent,而且继续用SMS方面的例子来阐述。本文的主要内容如下:

例子(需求)描述

STEP1、添加用于显示通讯录的布局文件

STEP2、添加Button的点击事件

STEP3、添加通讯录活动

STEP4、解析通讯录返回的数据

STEP5、在清单文件AndroidManifest.xml中注册通讯录活动和读取Contact数据库的权限

总结

用手机发过SMS的人都知道:

用户可以先编辑短信,然后再去通讯录中选择相应的人并发生给他。

用户可以在短信内容中插入通讯录中联系人的号码。

我们用一个ListView来显示整个通讯录,其中用TextView显示每一记录。它们的xml文件分别为contact.xml、listitemlayout,如下所示:

====================================contact.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"   

>   

<ListView android:id="@+id/contactListView"   

    android:layout_width="fill_parent"   

    android:layout_height="wrap_content"   

    />   

</LinearLayout>   

=================================== listitemlayout   

    android:orientation="vertical" android:layout_width="fill_parent"   

    android:layout_height="fill_parent">   

    <TextView android:id="@+id/itemTextView" android:layout_width="wrap_content"   

    android:layout_height="wrap_content" android:padding="10px"   

    android:textSize="16px" android:textColor="#FFF" />   

</LinearLayout>  

为了能够打开通讯录,我们还需要在TextMessage程序中加入一个Button btnContact,通过点击btnContact激活显示通讯录的活动。这只需在main.xml文件中加入如下代码:

<Button android:layout_width="wrap_content"   

        android:layout_height="wrap_content" android:text="@string/btnContact"   

        android:id="@+id/btnContact"                            /> 

记得还有在values/strings.xml中相应的加入<string name="btnContact">contact</string>。

在上面准备工作做完之后,我们需要监听btnContact的点击事件,当用户点击btnContact时,跳转显示通讯录界面,当用户选择一个联系人之后,返回SMS程序的主界面。这里就要用到了伟大的Intent啦!

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

btnContact.setOnClickListener(new View.OnClickListener() {   

    @Override   

    public void onClick(View v) {   

        // TODO Auto-generated method stub   

        Intent intent = new Intent(Intent.ACTION_PICK,   

                ContactsContract.Contacts.CONTENT_URI);   

        startActivityForResult(intent, PICK_CONTACT);   

    }   

});  

添加一个类文件,类名为ContactPick(表示通讯录活动名)继承Activity。它的主要功能就是获取从SMS主程序传递来的Intent并提取数据;然后去查询通讯录数据库,取出数据并填充到STEP1中定义的ListView;最后,还需要添加当用户选择一个联系人的事件onItemClick,将结果返回给SMS主程序,这里也用到了我们伟大的Intent啦!代码如下:

package skynet.com.cnblogs.www;   

import android.app.Activity;   

import android.content.Intent;   

import android.database.Cursor;   

import android.net.Uri;   

import android.os.Bundle;   

import android.provider.ContactsContract;   

import android.view.View;   

import android.widget.AdapterView;   

import android.widget.ListView;   

import android.widget.SimpleCursorAdapter;   

import android.widget.AdapterView.OnItemClickListener;   

public class ContactPick extends Activity {   

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

    public void onCreate(Bundle savedInstanceState) {   

        super.onCreate(savedInstanceState);   

        setContentView(R.layout.main);   

        Intent orgIntent=getIntent();   

        Uri queryUri=orgIntent.getData();           

        final Cursor c = managedQuery(queryUri,   

                null,   

                null);   

        String[] fromColumns=new String[]{ContactsContract.Contacts.DISPLAY_NAME};   

        int[] toLayoutIDs = new int[] { R.id.itemTextView };   

        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,   

                R.layout.listitemlayout, c, fromColumns, toLayoutIDs);   

        ListView lv = (ListView) findViewById(R.id.contactListView);   

        lv.setAdapter(adapter);   

        lv.setOnItemClickListener(new OnItemClickListener() {   

            @Override   

            public void onItemClick(AdapterView<?> parent, View view, int pos,   

                    long id) {   

                c.moveToPosition(pos);       

                int rowId = c.getInt(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));   

                Uri outURI = Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + rowId);   

                Intent outData = new Intent();   

                outData.setData(outURI);   

                setResult(Activity.RESULT_OK,outData);   

                finish();   

            }   

        });   

}  

从通讯录活动返回之后,我们从返回的Intent中提取数据并填充到填写电话号码的EditView中。代码主要如下:

@Override   

public void onActivityResult(int reqCode, int resCode, Intent data) {   

    super.onActivityResult(reqCode, resCode, data);   

    switch (reqCode) {   

    case (PICK_CONTACT): {   

        if (resCode == Activity.RESULT_OK) {   

            String name;                   

            Uri contactData = data.getData();   

            Cursor c = managedQuery(contactData, null, null, null, null);   

            c.moveToFirst();   

            name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));   

            TextView tv;   

            tv = (TextView)findViewById(R.id.edtPhoneNo);   

            tv.setText(name);   

        }   

        break;   

主要工作基本做完了,现在我们只需要注册通讯录活动和读取Contact数据的权限了。完整的清单文件代码如下:

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

    package="skynet.com.cnblogs.www" android:versionCode="1"   

    android:versionName="1.0">   

    <application>   

        <activity android:name=".TextMessage" 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=".ContactPick" android:label="@string/app_name">   

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

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

    </application>   

    <uses-permission android:name="android.permission.SEND_SMS" />   

    <uses-permission android:name="android.permission.READ_CONTACTS" />   

</manifest>  

注意通讯录活动的Intent Filters,它的action是android.intent.action.PICK;category是android.intent.category.DEFAULT。现在我们分析一下这个Intent Filter:

<action android:name="android.intent.action.PICK" />:使用户能够可以在通讯录列表中选择一个,然后将选择的联系人的 URL返回给调用者。

<category android:name="android.intent.category.DEFAULT" />:这是默认的category,如果不知道category系统会自动加上。这个属性是让使其能够被像Context.startActivity()等找到。要说明的的是,如果列举了多个category,这个活动仅会去处理那些Intent中都包含了所有列举的category的组件。

我们还可以在清单文件中看到TextMessage活动的Intent Filter:

<intent-filter>   

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

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

</intent-filter>  

它指TextMessage活动定是真个程序的入口并且TextMessage会列举在Launcher即启动列表中。

程序运行结果如下图所示:

<a target="_blank" href="http://blog.51cto.com/attachment/201008/110805163.png"></a>

图1、主界面

<a target="_blank" href="http://blog.51cto.com/attachment/201008/110835890.png"></a>

图2、点击contact按钮之后

<a target="_blank" href="http://blog.51cto.com/attachment/201008/110919471.png"></a>

图3、选择一个联系人之后

我们用发短信中选择联系人的例子说明Intent和Intent Filter,这里体现了两个活动之间如何通过Intent和Intent Filter来交互,这也是我们在编写Android应用程序的时候经常遇到了。本文除了上述的主要内容之外,还涉及别的知识点,下面列举几个个人认为比较有用的知识点:

Cursor类它跟我们平时用的数据库中的游标类似,它提供了对从数据库返回的结果的随机读写操作。如我们例子中用到的,通过managedQuery方法 查询数据库并返回结果,然后利用Cursor对它进行操作。下面介绍Cursor类的几个方法(我们例子中用到的,更多的方法请自行查阅相关资料):

public abstract boolean moveToFirst ():移动到第一行。如果Cursor为空,则返回FALSE

public abstract boolean moveToPosition (int position):将游标移动到一个指定的位置,它的范围在-1 &lt;= position &lt;= count。如果position位置不可达,返回FALSE

managedQuery方法:根据指定的URI路径信息返回包含特定数据的Cursor对象,应用这个方法可以使Activity接管返回数据对象的生命周期。参数:

URI: Content Provider 需要返回的资源索引

Projection: 用于标识有哪些columns需要包含在返回数据中

Selection: 作为查询符合条件的过滤参数,类似于SQL语句中Where之后的条件判断

SelectionArgs: 同上

SortOrder: 用于对返回信息进行排序

SimpleCursorAdapter允许你绑定一个游标的列到ListView上,并使用自定义的layout显示每个项目。SimpleCursorAdapter的创建,需要传入当前的上下文、一个layout资源,一个游标和两个数组:一个包含使用的列的名字,另一个(相同大小)数组包含View中的资源ID,用于显示相应列的数据值。

本系列的其它文章:

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365407">Android 开发之旅:环境搭建及HelloWorld</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365402">Android 开发之旅:HelloWorld项目的目录结构</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365394">Android 开发之旅:android架构</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365392">Android 开发之旅:应用程序基础及组件</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365389">Android 开发之旅:应用程序基础及组件(续)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365383">Android 开发之旅:活动与任务</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365379">Android 开发之旅:进程与线程</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365375">Android 开发之旅:组件生命周期(一)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365371">Android 开发之旅:组件生命周期(二)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365362">Android 开发之旅:组件生命周期(三)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/365358">Android 开发之旅:又见Hello World!</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/363569">Android 开发之旅:深入分析布局文件&amp;又是"Hello World!"</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/363552">Android 开发之旅:view的几种布局方式及实践</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/363493">Android 开发之旅:短信的收发及在android模拟器之间实践(一)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/363451">Android 开发之旅:短信的收发及在android模拟器之间实践(二)</a>

<a target="_blank" href="http://skynet.blog.51cto.com/1943397/363442">Android开发之旅: Intents和Intent Filters(理论部分)</a>

     本文转自Saylor87 51CTO博客,原文链接:http://blog.51cto.com/skynet/365413,如需转载请自行联系原作者