Android开发之旅: Intents和Intent Filters(实例部分)

简介:

引言

上篇我们介绍了Intents和Intent Filters的理论部分,主要是介绍了:activitiesservicesbroadcastreceivers三种组件的Intent机制两种Intent(显式和隐式)及它们如何去匹配目的组件、Intent对象包含哪些信息、Intent Filters的action & category & data。

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

  • 例子(需求)描述
  • STEP1、添加用于显示通讯录的布局文件
  • STEP2、添加Button的点击事件
  • STEP3、添加通讯录活动
  • STEP4、解析通讯录返回的数据
  • STEP5、在清单文件AndroidManifest.xml中注册通讯录活动和读取Contact数据库的权限
  • 总结

例子(需求)描述

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

  • 用户可以先编辑短信,然后再去通讯录中选择相应的人并发生给他。
  • 用户可以在短信内容中插入通讯录中联系人的号码。

我们的这个例子就是要说明如何实现这个功能。要实现这个功能,即是创建一个新的Activity选择(ACTION_PICK)通讯录中的数据,它会显示通讯录中的所有联系人并让用户选择,然后关闭并返回一个联系人的URI给短信程序。下面介绍如何一步一步实现类似的功能,而且是在之前Android 开发之旅:短信的收发及在android模拟器之间实践(一)中发送SMS的例子(TextMessage)基础上加上从通讯录中选择联系人的功能。

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

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

====================================contact.xml

<?xmlversion="1.0"encoding="utf-8"?>

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

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<ListViewandroid:id="@+id/contactListView"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

/>

</LinearLayout>

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

<?xmlversion="1.0"encoding="utf-8"?>

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

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

android:layout_height="fill_parent">

<TextViewandroid: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文件中加入如下代码:

<Buttonandroid:layout_width="wrap_content"

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

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

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

STEP2、添加Button的点击事件

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

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

btnContact.setOnClickListener(new View.OnClickListener() {

@Override

publicvoid onClick(View v) {

// TODO Auto-generated method stub

Intent intent = new Intent(Intent.ACTION_PICK,

ContactsContract.Contacts.CONTENT_URI);

startActivityForResult(intent, PICK_CONTACT);

}

});

STEP3、添加通讯录活动

添加一个类文件,类名为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;

importandroid.widget.SimpleCursorAdapter;

import android.widget.AdapterView.OnItemClickListener;

publicclass ContactPick extends Activity {

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

@Override

publicvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Intent orgIntent=getIntent();

Uri queryUri=orgIntent.getData();

final Cursor c = managedQuery(queryUri,

null,

null,

null,

null);

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

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

SimpleCursorAdapter adapter = newSimpleCursorAdapter(this,

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

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

lv.setAdapter(adapter);

lv.setOnItemClickListener(new OnItemClickListener() {

@Override

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

}

});

}

}

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

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

@Override

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

}

}

}

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

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

<?xmlversion="1.0"encoding="utf-8"?>

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

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

android:versionName="1.0">

<application>

<activityandroid:name=".TextMessage"android:label="@string/app_name">

<intent-filter>

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

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

</intent-filter>

</activity>

<activityandroid:name=".ContactPick"android:label="@string/app_name">

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

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

</activity>

</application>

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

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

</manifest>

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

  • <actionandroid:name="android.intent.action.PICK"/>使用户能够可以在通讯录列表中选择一个,然后将选择的联系人的 URL返回给调用者。
  • <categoryandroid:name="android.intent.category.DEFAULT"/>这是默认的category,如果不知道category系统会自动加上。这个属性是让使其能够被像Context.startActivity()等找到。要说明的的是,如果列举了多个category,这个活动仅会去处理那些Intent中都包含了所有列举的category的组件。

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

<intent-filter>

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

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

</intent-filter>

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

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

图1、主界面

图2、点击contact按钮之后

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

总结

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

  • Cursor类它跟我们平时用的数据库中的游标类似,它提供了对从数据库返回的结果的随机读写操作。如我们例子中用到的,通过 managedQuery方法 查询数据库并返回结果,然后利用 Cursor对它进行操作。下面介绍 Cursor类的几个方法(我们例子中用到的,更多的方法请自行查阅相关资料):
    • public abstract int getColumnIndexOrThrow (String columnName):返回给定列名的索引(注意:从0开始的),或者当列名不存在时抛出llegalArgumentException异常;
    • public abstract boolean moveToFirst ():移动到第一行。如果Cursor为空,则返回FALSE
    • public abstract boolean moveToPosition (int position):将游标移动到一个指定的位置,它的范围在-1 <= position <= count。如果position位置不可达,返回FALSE
  • managedQuery方法:根据指定的URI路径信息返回包含特定数据的Cursor对象,应用这个方法可以使Activity接管返回数据对象的生命周期。参数:
    URI: Content Provider 需要返回的资源索引
    Projection: 用于标识有哪些columns需要包含在返回数据中
    Selection: 作为查询符合条件的过滤参数,类似于SQL语句中Where之后的条件判断
    SelectionArgs: 同上
    SortOrder: 用于对返回信息进行排序
  • SimpleCursorAdapter允许你绑定一个游标的列到ListView上,并使用自定义的layout显示每个项目。SimpleCursorAdapter的创建,需要传入当前的上下文、一个layout资源,一个游标和两个数组:一个包含使用的列的名字,另一个(相同大小)数组包含View中的资源ID,用于显示相应列的数据值。

本系列的其它文章:




本文转自吴秦博客园博客,原文链接:http://www.cnblogs.com/skynet/archive/2010/07/31/1789534.html,如需转载请自行联系原作者

相关文章
|
3天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
8天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
10天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
10天前
|
存储 API 开发工具
探索安卓开发:从基础到进阶
【10月更文挑战第37天】在这篇文章中,我们将一起探索安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和建议。我们将从安卓开发的基础开始,逐步深入到更复杂的主题,如自定义组件、性能优化等。最后,我们将通过一个代码示例来展示如何实现一个简单的安卓应用。让我们一起开始吧!
|
XML Android开发 数据格式
Android 标签栏pagerslidingtabstrip用法实例(含Demo)
Android 标签栏pagerslidingtabstrip用法实例(含Demo)
Android 标签栏pagerslidingtabstrip用法实例(含Demo)
|
XML Android开发 数据格式
|
12天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
下一篇
无影云桌面