您的位置:首页 > 移动开发 > Android开发

【android_温故知新】使用 Intent 和 IntentFilter 进行通信

2015-12-28 21:44 507 查看
Intent 对象简述
使用 Intent 启动不同组件的方法

Intent 的属性及 intent-filter 配置
Component 属性
温馨提示

ActionCategory 属性与 intent-filter 配置
温馨提示

指定 ActionCategory 调用系统 Activity

标准的 Category 常量及对应的字符串
实例查看并获取联系人电话

实例返回系统 Home 桌面

DataType 属性与 intent-filter 配置
温馨提示

温馨提示

温馨提示

实例使用 ActionData 属性启动系统 Activity

Extra 属性

Flag 属性

Intent 对象简述

android 的应用程序包含三种重要组件:Activity、Service、BroadcastReceiver,应用程序采用了一致的方式来启动它们—-都是依靠 Intent 来启动的,Intent 就封装了程序想要启动程序的意图。不仅如此,Intent 还可用于与被启动组件交换信息。

使用 Intent 启动不同组件的方法

组件类型启动方法
ActivitystartActivity(Intent intent)
startActivityForResult(Intent intent,int requestCode)
ServiceComponentName startService(Intent service)
boolean bindService(Intent service,ServiceConnection conn,int flags)
BroadcastReceiversendBroadcast(Intent intent)
sendBroadcast(Intent intent,String receiverPermission,BroadcastReceiver scheduler,int initialCode,String initialData,Bundle initialExtras)
sendOrderedBroadcast(Intent intent,String receiverPermission)
sendStickyBroadcast(Intent intent)
sendStickyOrderedBroadcast(Intent intent,BroadcastReceiver resultReceiver,Handler scheduler,int initialCode,String initialData,Bundle initialExtras)
Intent 对象大致包含 Component、Action、Category、Data、Type、Extra 和 Flag 这 7 种属性,其中 Component 用于明确指定需要启动的目标组件,而 Extra 则用于“携带”需要交换的数据

Intent 的属性及 intent-filter 配置

Component 属性

Intent 的 Component 属性需要接受一个 ComponentName 对象,ComponentName 对象包含如下几个构造器。

1. ComponentName(String pkg,String cls):创建 pkg 所在包下的 cls 类所对应的组件。

2. ComponentName(Context pkg,String cls):创建 pkg 所对应的包下的 cls 类所对应的组件。

3. ComponentName(Context pkg,Class

温馨提示

android 应用的 Context 代表了访问该应用环境信息的接口,而 android 应用的包名则作为应用的唯一标识,因此 android 应用的 Context 对象与该应用的包名有一一对应的关系。上面三个 setClass()方法正是指定组件的包名(分别通过 Context 指定或 String 指定)和实现类(分别通过 Class 指定或通过 String 指定)。

指定 Component 属性的 Intent 已经明确了它将要启动哪个组件,因此这种 Intent 也被称为显式 Intent,没有指定 Component 属性的 Intent 被称为隐式 Intent—-隐式 Intent 没有明确指定要启动哪个组件,应用将会根据 Intent 指定的规则去启动符合条件的组件,但具体是哪个组件则不明确。

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建一个ComponentName对象
ComponentName comp = new ComponentName(MainActivity.this,
SecondActivity.class);
Intent intent = new Intent();
// 为Intent设置Component属性
intent.setComponent(comp);
startActivity(intent);
}
});
}
}


实际上,上面的代码完全可以简化为如下形式:

// 根据指定组件类来创建 Intent
Intent intent = new Intent(ComponentAttr.this,SecondActivity.class);


public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
EditText show = (EditText) findViewById(R.id.show);
// 获取该Activity对应的Intent的Component属性
ComponentName comp = getIntent().getComponent();
// 显示该ComponentName对象的包名、类名
show.setText("组件包名为:" + comp.getPackageName()
+ "\n组件类名为:" + comp.getClassName());
}
}


Action、Category 属性与 intent-filter 配置

Intent 的 Action、Category 属性的值都是一个普通的字符串,其中 Action 代表该 Intent 所要完成的一个抽象“动作”,而 Category 则用于为 Action 增加额外的附加类别信息。通常 Action 属性会与 Category 属性结合使用。

Action 要完成的只是一个抽象动作,这个动作具体由哪个组件(或许是 Activity,或许是 BroadcastReceiver)来完成,Action 这个字符串本身就不管。比如 android 提供的标准 Action:Intent.ACTION_VIEW,它只表示一个抽象的查看操作,但具体查看什么,启动哪个 Activity 来查看,Intent.ACTION_VIEW 并不知道—-这取决于 Activity 的 < intent-filter…/ > 配置,只要某个 Activity 的< intent-filter…/ > 配置中包含了该 ACTION_VIEW,该 Activity 就有可能被启动。

public class MainActivity extends Activity {
public final static String CRAZYIT_ACTION =
"org.yonga.intent.action.CRAZYIT_ACTION";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建Intent对象
Intent intent = new Intent();
// 为Intent设置Action属性(属性值就是一个普通字符串)
intent.setAction(MainActivity.CRAZYIT_ACTION);
startActivity(intent);
}
});
}
}


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.yonga.intent" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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=".SecondActivity"
android:label="@string/app_name">
<intent-filter>
<!-- 指定该Activity能响应Action为指定字符串的Intent -->
<action android:name="org.yonga.intent.action.CRAZYIT_ACTION" />
<!-- 指定该Activity能响应Action属性为helloWorld的Intent -->
<action android:name="helloWorld" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>

</manifest>


< intent-filter…/ >元素里通常可包含如下子元素。

0~N 个< action…/ >子元素。

0~N 个< category…/ >子元素。

0~1 个< data…/ >子元素。

温馨提示

< intent-filter…/ >元素也可以是< service…/ >、< receiver…/ >两个元素的子元素,用于表明它们可以响应的 Intent。

< action…/ >、< category…/ >子元素的配置非常简单,它们都可以指定 android:name 属性,该属性的值就是一个普通的字符串。

当< activity…/ >元素的< intent-filter…/ >子元素里包含多个< action…/ >子元素(相当于指定了多个字符串)时,就表明该 Activity 能响应 Action 属性值为其中任意一个字符串的 Intent。

public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
EditText show = (EditText) findViewById(R.id.show);
// 获取该Activity对应的Intent的Action属性
String action = getIntent().getAction();
// 显示Action属性
show.setText("Action为:" + action);
}
}


接下来的示例程序将会示范 Category 属性的用法。该程序的第一个 Activity 的代码如下。

public class MainActivity extends Activity {
// 定义一个Action常量
final static String CRAZYIT_ACTION =
"org.crazyit.intent.action.CRAZYIT_ACTION";
// 定义一个Category常量
final static String CRAZYIT_CATEGORY =
"org.crazyit.intent.category.CRAZYIT_CATEGORY";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent();
// 设置Action属性
intent.setAction(MainActivity.CRAZYIT_ACTION);
// 添加Category属性
intent.addCategory(MainActivity.CRAZYIT_CATEGORY);
startActivity(intent);
}
});
}
}


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.yonga.intent" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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=".SecondActivity"
android:label="@string/app_name">
<intent-filter>
<!-- 指定该Activity能响应action为指定字符串的Intent -->
<action android:name="org.yonga.intent.action.CRAZYIT_ACTION" />
<!-- 指定该Activity能响应category为指定字符串的Intent -->
<category android:name="org.yonga.intent.category.CRAZYIT_CATEGORY" />
<!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

</application>

</manifest>


public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
EditText show = (EditText) findViewById(R.id.show);
// 获取该Activity对应的Intent的Action属性
String action = getIntent().getAction();
// 显示Action属性
show.setText("Action为:" + action);
EditText cate = (EditText) findViewById(R.id.cate);
// 获取该Activity对应的Intent的Category属性
Set<String> cates = getIntent().getCategories();
// 显示Category属性
cate.setText("Category属性为:" + cates);
}
}


指定 Action、Category 调用系统 Activity

Intent 代表了启动某个程序组件的“意图”,实际上 Intent 对象不仅可以启动本应用内程序组件,也可以启动 android 系统的其他应用程序组件,包括系统自带的程序组件—-只要权限允许。

启动 Activity 的标准的 Action 常量及对应的字符串

Action 常量对应字符串简单说明
ACTION_MAINandroid:intent.action.MAIN应用程序入口
ACTION_VIEWandroid:intent.action.VIEW查看指定数据
ACTION_ATTACH_DATAandroid.intent.action.ATTACH_DATA指定某块数据将被附加到其他地方
ACTION_EDITandroid:intent.action.EDIT编辑指定数据
ACTION_PICKandroid:intent.action.PICK从列表中选择某项,并返回所选的数据
ACTION_CHOOSERandroid:intent.action.CHOOSER显示一个 Activity 选择器
ACTION_GET_CONTENTandroid:intent.action.GET_CONTENT让用户选择数据,并返回所选数据
ACTION_DIALandroid:intent.action.DIAL显示拨号面板
ACTION_CALLandroid:intent.action.CALL直接向指定用户打电话
ACTION_SENDandroid:intent.action.SEND向其他人发送数据
ACTION_SENDTOandroid:intent.action.SENDTO向其他人发送消息
ACTION_ANSWERandroid:intent.action.ANSWER应答电话
ACTION_INSERTandroid:intent.action.INSERT插入数据
ACTION_DELETEandroid:intent.action.DELETE删除数据
ACTION_RUNandroid:intent.action.RUN运行数据
ACTION_SYNCandroid:intent.action.SYNC执行数据同步
ACTION_PICK_ACTIVITYandroid:intent.action.PICK_ACTIVITY用于选择 Activity
ACTION_SEARCHandroid:intent.action.SEARCH执行搜索
ACTION_WEB_SEARCHandroid:intent.action.WEB_SEARCH执行 Web 搜索
ACTION_FACTORY_TESTandroid:intent.action.FACTORY_TEST工厂测试的入口点

标准的 Category 常量及对应的字符串

Category 常量对应字符串简单说明
CATEGORY_DEFULTandroid.intent.category.DEFULT默认的 Category
CATEGORY_BROWSABLEandroid.intent.category.BROWSABLE指定该 Activity 能被浏览器安全调用
CATEGORY_TABandroid.intent.category.TAB指定 Activity 作为 TabActivity 的 Tab 页
CATEGORY_LAUNCHERandroid.intent.category.LAUNCHERActivity 显示顶级程序列表
CATEGORY_INFOandroid.intent.category.INFO用于提供包信息
CATEGORY_HOMEandroid.intent.category.HOME设置该 Activity 随系统启动而运行
CATEGORY_PREFERENCEandroid.intent.category.PREFERENCE该 Activity 是参数面板
CATEGORY_TESTandroid.intent.category.TEST该 Activity 是一个测试
CATEGORY_CAR_DOCKandroid.intent.category.CAR_DOCK指定手机被插入汽车底座(硬件)时运行该 Activity
CATEGORY_DESK_DOCKandroid.intent.category.DESK_DOCK指定手机被插入桌面底座(硬件)时运行该 Activity
CATEGORY_CAR_MODEandroid.intent.category.CAR_MODE设置该 Activity 可在车载环境下使用

实例:查看并获取联系人电话

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<!-- 显示联系人姓名的文本框 -->
<EditText
android:id="@+id/show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:cursorVisible="false"/>
<!-- 显示联系人的电话的文本框 -->
<EditText
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:cursorVisible="false"/>
<Button
android:id="@+id/bn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查看联系人"/>
</LinearLayout>


public class MainActivity extends Activity {
final int PICK_CONTACT = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建Intent
Intent intent = new Intent();
// 设置Intent的Action属性
intent.setAction(Intent.ACTION_GET_CONTENT);
// 设置Intent的Type属性
intent.setType("vnd.android.cursor.item/phone");
// 启动Activity,并希望获取该Activity的结果
startActivityForResult(intent, PICK_CONTACT);
}
});
}

@Override
public 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));
String phoneNumber = "此联系人暂未输入电话号码";
//根据联系人查询该联系人的详细信息
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.
Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = " + contactId, null, null);
if (phones.moveToFirst()) {
//取出电话号码
phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract
.CommonDataKinds.Phone.NUMBER));
}
// 关闭游标
phones.close();
EditText show = (EditText) findViewById(R.id.show);
//显示联系人的名称
show.setText(name);
EditText phone = (EditText) findViewById(R.id.phone);
//显示联系人的电话号码
phone.setText(phoneNumber);
}
// 关闭游标
cursor.close();
}
break;
}
}
}


由于上面的程序需要查看系统联系人信息,因此不要忘了向该应用的 AndroidManifest.xml 文件中增加响应的权限,也就是 AndroidManifest.xml 文件中增加如下配置:

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


实例:返回系统 Home 桌面

本实例将会提供一个按钮,当用户单击该按钮时,系统将会返回 Home 桌面。这也需要通过 Intent 来实现,程序为 Intent 设置合适的 Action、Category属性,并根据该 Intent 来启动 Activity 即可返回 Home 桌面。

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建Intent对象
Intent intent = new Intent();
// 为Intent设置Action、Category属性
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
});
}
}


Data、Type 属性与 intent-filter 配置

Data 属性通常用于向 Action 属性提供操作的数据。Data 属性接受一个 Uri 对象,一个 Uri 对象通常通过如下形式的字符串来表示:

content://com.android.contacts/contacts/1

tel:123


例如上面给出的 content://com.android.contacts/contacts/1,其中 content 是 scheme 部分,com.android.contacts 是 host 部分,port 部分被省略了,/contacts/1 是 path 部分。

Type 属性用于指定该 Data 属性所指定 Uri 对应的 MIME 类型,这种 MIME 类型可以是任何自定义的 MIME 类型,只要符合 abc/xyz 格式的字符串即可。

Data 属性与 Type 属性的关系比较微妙,这两个属性会互相覆盖,例如:

1. 如果 Intent 先设置 Data 属性,后设置 Type 属性,那么 Type 属性将会覆盖 Data 属性。

2. 如果 Intent 先设置 Type 属性,后设置 Data 属性,那么 Data 属性将会覆盖 Type 属性。

3. 如果希望 Intent 既有 Data 属性,也有 Type 属性,则应该调用 Intent 的 setDataAndType()方法。

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

public void overrideType(View source) {
Intent intent = new Intent();
// 先为Intent设置Type属性
intent.setType("abc/xyz");
// 再为Intent设置Data属性,覆盖Type属性
intent.setData(Uri.parse("lee://www.fkjava.org:8888/test"));
Toast.makeText(this, intent.toString(), Toast.LENGTH_LONG).show();
}

public void overrideData(View source) {
Intent intent = new Intent();
// 先为Intent设置Data属性
intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath"));
// 再为Intent设置Type属性,覆盖Data属性
intent.setType("abc/xyz");
Toast.makeText(this, intent.toString(), Toast.LENGTH_LONG).show();
}

public void dataAndType(View source) {
Intent intent = new Intent();
// 同时设置Intent的Data、Type属性
intent.setDataAndType(Uri.parse("lee://www.fkjava.org:8888/mypath"),
"abc/xyz");
Toast.makeText(this, intent.toString(), Toast.LENGTH_LONG).show();
}
}


在 AndroidManifest.xml 文件中为组件声明 Data、Type 属性都通过< data…/ >元素,< data…/ >元素的格式如下:

< data android:mimeType=""
android:scheme=""
android:host=""
android:port=""
android:path=""
android:pathPrefix=""
android:pathPattern="" />


上面的< data…/ >

1. mimeType:用于声明该组件所能匹配的 Intent 的 Type 属性。

2. scheme:用于声明该组件所能匹配的 Intent 的 Data 属性的 scheme部分。

3. host:用于声明该组件所能匹配的 Intent 的 Data 属性的 host 部分。

4. port:用于声明该组件所能匹配的 Intent 的 Data 属性的 port 部分。

5. path:用于声明该组件所能匹配的 Intent 的 Data 属性的 path 部分。

6. pathPrefix:用于声明该组件所能匹配的 Intent 的 Data 属性的 path 前缀。

7. pathPattern:用于声明该组件所能匹配的 Intent 的 Data 属性的 path 字符串模板。

Intent 的 Type 属性也用于指定该 Intent 的要求,对应组件中< intent-filter…/ >元素的< data…/ >子元素的 mimeType 属性必须与此相同,才能启动该组件。

Intent 的 Data 属性则略有差异,程序员为 Intent 指定 Data 属性时,Data 属性的 Uri 对象实际上可分为 scheme、host、port 和 path 部分,此时并不要求被启动组件的< intent-filter…/ >中< data…/ >子元素的 android:scheme、android:host、android:port、android:path 完全满足。

Data 属性的“匹配”过程则有些差别,它会先检查< intent-filter…/ >里的< data…/ >子元素,然后:

1. 如果目标组件的< data…/ >子元素只指定了 android:scheme 属性,那么只要 Intent 的 Data 属性的 scheme 部分与 android:scheme 属性相同,即可启动该组件。

2. 如果目标组件的< data…/ >子元素只指定了 android:scheme、android:host 属性,那么只要 Intent 的 Data 属性的 scheme、host 部分与 android:scheme 、android:host属性相同,即可启动该组件。

3. 如果目标组件的< data…/ >子元素只指定了 android:scheme、android:host、android:port 属性,那么只要 Intent 的 Data 属性的 scheme、host、port 部分与 android:scheme 、android:host、android:port 属性相同,即可启动该组件。

温馨提示

如果< data…/ >子元素只有 android:port 属性,没有指定 anroid:host 属性,那么 android:port 属性将不会起作用。

4. 如果目标组件的< data…/ >子元素只指定了 android:scheme、android:host、android:path 属性,那么只要 Intent 的 Data 属性的 scheme、host、path 部分与 android:scheme 、android:host、android:path 属性相同,即可启动该组件。

温馨提示

如果< data…/ >子元素只有 android:path 属性,没有指定 anroid:host 属性,那么 android:path 属性将不会起作用。

5. 如果目标组件的< data…/ >子元素只指定了 android:scheme、android:host、android:host、android:path 属性,那么就要 Intent 的 Data 属性的 scheme、host、port、path 部分依次与 android:scheme 、android:host、android:port、android:path 属性相同,才能启动该组件。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.crazyit.intent" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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:icon="@drawable/ic_scheme"
android:name=".SchemeActivity"
android:label="指定scheme的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,即可启动该Activity -->
<data android:scheme="lee" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_host"
android:name=".SchemeHostPortActivity"
android:label="指定scheme、host、port的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888即可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_sp"
android:name=".SchemeHostPathActivity"
android:label="指定scheme、host、path的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,且host是www.fkjava.org
path是/mypath,即可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:path="/mypath" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_path"
android:name=".SchemeHostPortPathActivity"
android:label="指定scheme、host、port、path的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 需要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888,且path是/mypath,才可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888"
android:path="/mypath"/>
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_type"
android:name=".SchemeHostPortPathTypeActivity"
android:label="指定scheme、host、port、path、type的Activity">
<intent-filter>
<action android:name="xx"/>
<category android:name="android.intent.category.DEFAULT" />
<!-- 需要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888,且path是/mypath
且type是abc/xyz,才可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888"
android:path="/mypath"
android:mimeType="abc/xyz"/>
</intent-filter>
</activity>

</application>

</manifest>


第 1 个 Activity:只要 Intent 的 Data 属性的 scheme 是 lee,即可启动该 Activity。

第 2 个 Activity:只要 Intent 的 Data 属性的 scheme 是 lee,且 host 是 www.fkjava.org,port 是 8888,即可启动该 Activity。

第 3 个 Activity:只要 Intent 的 Data 属性的 scheme 是 lee,且 host 是 www.fkjava.org,path 是/mypath,即可启动该 Activity。

第 4 个 Activity:需要 Intent 的 Data 属性的 scheme 是 lee,且 host 是 www.fkjava.org,port 是 8888,path 是/mypath,才可启动该 Activity。

第 5 个 Activity:需要 Intent 的 Data 属性的 scheme 是 lee,且 host 是 www.fkjava.org,port 是 8888,path 是/mypath,type 是 abc/xyz,才可启动该 Activity。

温馨提示

上面配置 Activity 的< intent-filter…/ >元素时,< action…/ >子元素的 name 属性是随意指定的,这是必需的,如果希望< data…/ >子元素能正常起作用,至少要配置一个< action…/ >子元素,但该子元素的 android:name 属性值可以任意的字符串。

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

public void scheme(View source) {
Intent intent = new Intent();
// 只设置Intent的Data属性
intent.setData(Uri.parse("lee://www.crazyit.org:1234/test"));
startActivity(intent);
}

public void schemeHostPort(View source) {
Intent intent = new Intent();
// 只设置Intent的Data属性
intent.setData(Uri.parse("lee://www.fkjava.org:8888/test"));
startActivity(intent);
}

public void schemeHostPath(View source) {
Intent intent = new Intent();
// 只设置Intent的Data属性
intent.setData(Uri.parse("lee://www.fkjava.org:1234/mypath"));
startActivity(intent);
}

public void schemeHostPortPath(View source) {
Intent intent = new Intent();
// 只设置Intent的Data属性
intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath"));
startActivity(intent);
}

public void schemeHostPortPathType(View source) {
Intent intent = new Intent();
// 同时设置Intent的Data、Type属性
intent.setDataAndType(Uri.parse("lee://www.fkjava.org:8888/mypath")
, "abc/xyz");
startActivity(intent);
}
}


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.crazyit.intent" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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:icon="@drawable/ic_scheme"
android:name=".SchemeActivity"
android:label="指定scheme的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,即可启动该Activity -->
<data android:scheme="lee" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_host"
android:name=".SchemeHostPortActivity"
android:label="指定scheme、host、port的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888即可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_sp"
android:name=".SchemeHostPathActivity"
android:label="指定scheme、host、path的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 只要Intent的Data属性的scheme是lee,且host是www.fkjava.org
path是/mypath,即可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:path="/mypath" />
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_path"
android:name=".SchemeHostPortPathActivity"
android:label="指定scheme、host、port、path的Activity">
<intent-filter>
<action android:name="xx" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 需要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888,且path是/mypath,才可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888"
android:path="/mypath"/>
</intent-filter>
</activity>
<activity
android:icon="@drawable/ic_type"
android:name=".SchemeHostPortPathTypeActivity"
android:label="指定scheme、host、port、path、type的Activity">
<intent-filter>
<action android:name="xx"/>
<category android:name="android.intent.category.DEFAULT" />
<!-- 需要Intent的Data属性的scheme是lee,且host是www.fkjava.org
port是8888,且path是/mypath
且type是abc/xyz,才可启动该Activity -->
<data android:scheme="lee"
android:host="www.fkjava.org"
android:port="8888"
android:path="/mypath"
android:mimeType="abc/xyz"/>
</intent-filter>
</activity>

</application>

</manifest>


实例:使用 Action、Data 属性启动系统 Activity

一旦为 Intent 同时制定了 Action、Data 属性,android 就可根据指定的数据类型来启动特定的应用程序,并对指定数据执行相应的操作。

下面是几个 Action 属性、Data 属性的结合。

ACTION_VIEW content://com.android.contacts/contacts/1:显示标识为 1 的联系人信息。

ACTION_EDIT content://com.android.contacts/contacts/1:编辑标识为 1 的联系人信息。

ACTION_DIAL content://com.android.contacts/contacts/1:显示向标识为 1 的联系人拨号的界面。

ACTION_VIEW tel:123:显示向指定号码 123 拨号的界面。

ACTION_DIAL tel:123:显示向指定号码 123 拨号的界面。

ACTION_VIEW content://contacts/people/:显示所有联系人列表的信息,通过这种组合可以非常方便地查看系统联系人。

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮添加一个监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建Intent
Intent intent = new Intent();
String data = "http://www.crazyit.org";
// 根据指定字符串解析出Uri对象
Uri uri = Uri.parse(data);
// 为Intent设置Action属性
intent.setAction(Intent.ACTION_VIEW);
// 设置Data属性
intent.setData(uri);
startActivity(intent);
}
});
Button edit = (Button) findViewById(R.id.edit);
// 为edit按钮添加一个监听器
edit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建Intent
Intent intent = new Intent();
// 为Intent设置Action属性(动作为:编辑)
intent.setAction(Intent.ACTION_EDIT);
String data = "content://com.android.contacts/contacts/1";
// 根据指定字符串解析出Uri对象
Uri uri = Uri.parse(data);
// 设置Data属性
intent.setData(uri);
startActivity(intent);
}
});
Button call = (Button) findViewById(R.id.call);
// 为call按钮添加一个监听器
call.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 创建Intent
Intent intent = new Intent();
// 为Intent设置Action属性(动作为:拨号)
intent.setAction(Intent.ACTION_DIAL);
String data = "tel:13800138000";
// 根据指定字符串解析出Uri对象
Uri uri = Uri.parse(data);
// 设置Data属性
intent.setData(uri);
startActivity(intent);
}
});
}
}


Extra 属性

Intent 的 Extra 属性通常用于在多个 Action 之间进行数据交换,Intent 的 Extra 属性值应该是一个 Bundle 对象,Bundle 对象就像一个 Map 对象,它可以存入多个 key-value 对,这样就可以通过 Intent 在不同 Activity 之间进行数据交换了。

Flag 属性

FLAG_ACTIVITY_BROUGHT_TO_FRONT:如果通过该 Flag 启动的 Activity 栈中有 Activity A,此时以该旗标启动 Activity B(即 Activity B 是以 FLAG_ACTIVITY_BROUGHT_TO_FRONT 旗标启动的),然后在 Activity B 中启动 Activity C、D,如果此时在 Activity D 中再启动 Activity B,将直接把 Activity 栈中的 Activity B 带到前台。此时 Activity 栈中情形是 Activity A、C、D、B。

FLAG_ACTIVITY_CLEAR_TOP:该 Flag 相当于加载模式中的 singleTask,通过这种 Flag 启动的 Activity 将会把启动的 Activity 之上的 Activity 全部弹出 Activity 栈,例如,Activity 栈中包含 A、B、C、D 四个 Activity,如果采用该 Flag 从 Activity D 跳转到 Activity B,那么此时 Activity 栈中只包含 A、B 两个 Activity。

FLAG_ACTIVITY_NEW_TASK:默认的启动旗标,该旗标控制重新创建一个新的 Activity。

FLAG_ACTIVITY_NO_ANIMATION:该旗标控制启动 Activity 时不使用过渡动画。

FLAG_ACTIVITY_NO_HISTORY:该旗标控制被启动的 Activity 将不会保留在 Activity 栈中。例如,Activity 栈中原来有 A、B、C 三个 Activity,此时在 Activity C 中以该 Flag 启动 Activity D,Activity D 再启动 Activity E,此时 Activity 栈中只有 A、B、C、E 四个 Activity,Activity D 不会保留在 Activity 栈中。

FLAG_ACTIVITY_REORDER_TO_FRONT:该 Flag 控制如果当前已有 Activity,则直接将该 Activity 带到前台。例如,现在 Activity 栈中有 A、B、C、D 四个 Activity,如果使用 FLAG_ACTIVITY_REORDER_TO_FRONT 旗标来启动 Activity B,那么启动后的 Activity 栈中情形为 A、C、D、B。

FLAG_ACTIVITY_SINGLE_TOP:该 Flag 相当于加载模式中的 singleTop 模式,例如,原来 Activity 栈中有 A、B、C、D 四个 Activity,在 Activity D 中再次启动 Activity D,Activity 栈中依然还是 A、B、C、D 四个 Activity。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 实例 intent action