原文:[置顶] Android菜鸟的成长笔记(8)——Intent与Intent Filter(上)
Intent代表了Android应用的启动“意图”,Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,取决于Intent的各个属性。
一、显式的Intent
明确指定了要启动的组件的Intent我们称为显式的Intent
例如:
package com.example.testintent; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { ComponentName comp = new ComponentName(MainActivity.this, SecondActivity.class); Intent intent = new Intent(); intent.setComponent(comp); startActivity(intent); } }); } }
注意在manifest文件里注册SecondActivity
Intent的Componet属性需要接收一个ComponentName对象,ComponetName对象其实是一个指定包和要启动的Activity路径的类,有如下几个构造
componentName(String pkg, String cls)
componentName(Context pkg, String cls)
componentName(Context pkg, Class<?> cls)
componentName(Parcel in)
除了这个属性之外Intent还包含了如下三个方法:
setClass(Context packageContext, Class<?> cls )
setClassName(Context packageContext, String className)
setClassName(String packageName, String className )
上面的代码可以简化为如下代码:
Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent);
二、隐式的Intent
没有明确指定要启动的组件的Intent我们称为隐式的Intent
Intent除了上面的Componet属性外还有Action、Category属性
Action代表Intent所要完成的一个抽象动作,而Category则是动作附加的类别信息。
例如:
package com.example.testintent; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(); intent.setAction("com.example.intent.action.TEST_ACTION"); startActivity(intent); } }); } }
manifest文件中配置
<activity android:name=".SecondActivity"> <intent-filter > <action android:name="com.example.intent.action.TEST_ACTION"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
一个Intent只能指定一个Action属性,可以包含多个Category属性,当程序创建时,默认启动category为DEFAULT的组件。
接下来我们来看看Category属性的用法
public void onClick(View arg0) { Intent intent = new Intent(); intent.setAction("com.example.intent.action.TEST_ACTION"); intent.addCategory("android.intent.category.TEST_CATEGERY"); startActivity(intent); }
manifest文件中配置
<activity android:name=".SecondActivity"> <intent-filter > <action android:name="com.example.intent.action.TEST_ACTION"/> <category android:name="android.intent.category.DEFAULT"/> <category android: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 用于选择Activity
ACTION_SEARCH 执行搜索
ACTION_WEB_SEARCH 执行web搜索
ACTION_FACTORY_TEST 工厂测试的入口点
这里仅列出部分更多关于Action和Category属性请参阅:http://developer.android.com/reference/android/content/Intent.html
三、一个获取通讯录的实例:
package com.example.testintent; 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.provider.ContactsContract.Contacts; import android.support.v4.content.CursorLoader; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; Button button; final int PICK_CONTACT = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_GET_CONTENT); intent.setType("vnd.android.cursor.item/phone"); startActivityForResult(intent, PICK_CONTACT); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case PICK_CONTACT: if(resultCode == Activity.RESULT_OK){ //获取返回数据 Uri contactData = data.getData(); CursorLoader cursorLoader = new CursorLoader(this, contactData, null, null, null, null); Cursor cursor = cursorLoader.loadInBackground(); if(cursor.moveToFirst()){ String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); Log.i(TAG, "姓名:" + name); //根据联系人查看详细信息 Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); if(phones.moveToFirst()){ System.out.println("进来了"); String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Log.i(TAG, "电话:" + phoneNumber); } //关闭游标 phones.close(); } //关闭游标 cursor.close(); } break; default: break; } } }