Android之旅-Intent与Intent Filter[上]
Intent代表了Android应用的启动“意图”,Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,取决于Intent的各个属性。
一、显式的Intent
明确指定了要启动的组件的Intent我们称为显式的Intent
例如:
java代码- packagecom.example.testintent;
- importandroid.app.Activity;
- importandroid.content.ComponentName;
- importandroid.content.Intent;
- importandroid.os.Bundle;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- publicclassMainActivityextendsActivity{
- Buttonbutton;
- @Override
- PRotectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- button=(Button)findViewById(R.id.button1);
- button.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- ComponentNamecomp=newComponentName(MainActivity.this,SecondActivity.class);
- Intentintent=newIntent();
- intent.setComponent(comp);
- startActivity(intent);
- }
- });
- }
- }
注意在manifest文件里注册SecondActivity
Intent的Componet属性需要接收一个ComponentName对象,ComponetName对象其实是一个指定包和要启动的Activity路径的类,有如下几个构造
Java代码
- componentName(Stringpkg,Stringcls)
- componentName(Contextpkg,Stringcls)
- componentName(Contextpkg,Class<?>cls)
componentName(Parcel in)
除了这个属性之外Intent还包含了如下三个方法:
Java代码- setClass(ContextpackageContext,Class<?>cls)
- setClassName(ContextpackageContext,StringclassName)
- setClassName(StringpackageName,StringclassName)
上面的代码可以简化为如下代码:
Java代码- Intentintent=newIntent(MainActivity.this,SecondActivity.class);
- startActivity(intent);
二、隐式的Intent
没有明确指定要启动的组件的Intent我们称为隐式的Intent
Intent除了上面的Componet属性外还有Action、Category属性
Action代表Intent所要完成的一个抽象动作,而Category则是动作附加的类别信息。
例如:
Java代码- packagecom.example.testintent;
- importandroid.app.Activity;
- importandroid.content.ComponentName;
- importandroid.content.Intent;
- importandroid.os.Bundle;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- publicclassMainActivityextendsActivity{
- Buttonbutton;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- button=(Button)findViewById(R.id.button1);
- button.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- Intentintent=newIntent();
- intent.setAction("com.example.intent.action.TEST_ACTION");
- startActivity(intent);
- }
- });
- }
- }
manifest文件中配置
Java代码- <activity
- android:name=".SecondActivity">
- <intent-filter>
- <actionandroid:name="com.example.intent.action.TEST_ACTION"/>
- <categoryandroid:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
一个Intent只能指定一个Action属性,可以包含多个Category属性,当程序创建时,默认启动category为DEFAULT的组件。
接下来我们来看看Category属性的用法
Java代码
- publicvoidonClick(Viewarg0){
- Intentintent=newIntent();
- intent.setAction("com.example.intent.action.TEST_ACTION");
- intent.addCategory("android.intent.category.TEST_CATEGERY");
- startActivity(intent);
- }
manifest文件中配置
Java代码
- <activity
- android:name=".SecondActivity">
- <intent-filter>
- <actionandroid:name="com.example.intent.action.TEST_ACTION"/>
- <categoryandroid:name="android.intent.category.DEFAULT"/>
- <categoryandroid:name="android.intent.category.TEST_CATEGERY"/>
- </intent-filter>
- </activity>
可以看出其实是根据Action和Category两个属性共同决定启动哪个Activity的,Category可以有多个,只要满足其中的一个即可。
实际上Intent不仅可以启动我们定义的Activity,也可以启动系统和其他应用的Activity
ACTION_MAIN 应用程序入口ACTION_VIEW 显示指定数据ACTION_ATTACH_DATA 指定某块数据将被附加到其他地方ACTION_EDIT 编辑指定数据ACTION_PICK 从列表中选择某项,并返回所选数据ACTION_CHOOSER 显示一个Activity选择器ACTION_GET_CONTENT 让用户选择数据,并返回所选数据ACTION_DIAL 显示拨号面板ACTION_CALL 直接向指定用户打电话ACTION_SEND 向其他人发送数据ACTION_SENDTO 向其他人发送消息ACTION_ANSWER 应答电话ACTION_INSERT 插入数据ACTION_DELETE 删除数据ACTION_RUN 运行数据ACTION_SYNC 执行数据同步ACTION_PICK_ACTIVITY 用于选择ActivityACTION_SEARCH 执行搜索ACTION_WEB_SEARCH 执行web搜索ACTION_FACTORY_TEST 工厂测试的入口点
这里仅列出部分更多关于Action和Category属性请参阅:http://developer.android.com/reference/android/content/Intent.html
三、一个获取通讯录的实例:
Java代码
- packagecom.example.testintent;
- importandroid.app.Activity;
- importandroid.content.Intent;
- importandroid.database.Cursor;
- importandroid.net.Uri;
- importandroid.os.Bundle;
- importandroid.provider.ContactsContract;
- importandroid.provider.ContactsContract.Contacts;
- importandroid.support.v4.content.CursorLoader;
- importandroid.util.Log;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- publicclassMainActivityextendsActivity{
- privatestaticfinalStringTAG="MainActivity";
- Buttonbutton;
- finalintPICK_CONTACT=0;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- button=(Button)findViewById(R.id.button1);
- button.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- Intentintent=newIntent();
- intent.setAction(Intent.ACTION_GET_CONTENT);
- intent.setType("vnd.android.cursor.item/phone");
- startActivityForResult(intent,PICK_CONTACT);
- }
- });
- }
- @Override
- protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
- super.onActivityResult(requestCode,resultCode,data);
- switch(requestCode){
- casePICK_CONTACT:
- if(resultCode==Activity.RESULT_OK){
- //获取返回数据
- UricontactData=data.getData();
- CursorLoadercursorLoader=newCursorLoader(this,contactData,null,null,null,null);
- Cursorcursor=cursorLoader.loadInBackground();
- if(cursor.moveToFirst()){
- StringcontactId=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
- Stringname=cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
- Log.i(TAG,"姓名:"+name);
- //根据联系人查看详细信息
- Cursorphones=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
- ContactsContract.CommonDataKinds.Phone.