Android(安卓)意图

Android 意图(Intent)是对要执行的操作的抽象描述。它可以与 startActivity 一起用于启动 ActivitybroadcastIntent 用于将其发送到任何感兴趣的 广播接收器 组件,startService(Intent)bindService(Intet,ServiceConnection,int) 用于与后台服务通信。

意图本身是一个 intent 对象,它是一个被动数据结构,保存对要执行的操作的抽象描述。

例如,假设您有一个需要启动电子邮件客户端并使用 Android 设备发送电子邮件的活动。为此,您的 Activity 将向 Android 意向解析程序发送一个 ACTION_SEND 以及相应的选择器。指定的选择器为用户提供了正确的界面来选择如何发送电子邮件数据。

  1. Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
  2. email.putExtra(Intent.EXTRA_EMAIL, recipients);
  3. email.putExtra(Intent.EXTRA_SUBJECT, subject.getText().toString());
  4. email.putExtra(Intent.EXTRA_TEXT, body.getText().toString());
  5. startActivity(Intent.createChooser(email, "Choose an email client from..."));

上面的语法调用 startActivity 方法来启动电子邮件活动,结果如下所示:

例如,假设您有一个活动需要在 Android 设备上的 web 浏览器中打开 URL。为此,Activity 将向 Android Intent Resolver 发送 ACTION_WEB_SEARCH Intent,以在 WEB 浏览器中打开给定的 URL。意向解析程序解析一系列 Activity,并选择与您的意向最匹配的 Activity,在本例中为 Web 浏览器。然后,意向解析程序将您的网页传递给 web 浏览器,并启动 web 浏览器 Activity

  1. String q = "cankaoshouce";
  2. Intent intent = new Intent(Intent.ACTION_WEB_SEARCH );
  3. intent.putExtra(SearchManager.QUERY, q);
  4. startActivity(intent);

上面的例子将在 android 搜索引擎上搜索 "cankaoshouce",并在您的 Activity 中给出搜索结果。不同的机制可以将意图传递给每种类型的(活动(Activity),服务(Service)和广播接收器(Broadcast Receivers))传递意图(Indent)的单独机制。

编号方法 & 描述
1

Context.startActivity()

Intent 对象被传递给此方法以启动新 Activity 或获取现有 Activity 以执行新操作。

2

Context.startService()

Intent 对象被传递给此方法以启动服务或向正在进行的服务传递新指令。

3

Context.sendBroadcast()

Intent 对象被传递给此方法,以将消息传递给所有感兴趣的广播接收器。


Intent 对象

Intent 对象是一组信息,用于接收 Intent 以及 Android 系统使用的信息的组件。

根据 Intent 对象正在通信或将要执行的内容,Intent 对象可以包含以下组件:

执行动作(Action)

这是 Intent 对象的必需部分,并且是一个字符串,用于命名要执行的动作 - 或在广播意图的情况下,是已发生并要报告的动作。动作很大程度上决定了其余意图对象的结构。Intent 类定义了许多与不同 intent 对应的动作常量。这是 Android Intent 标准操作 的列表。

可以通过 setAction() 方法设置 Intent 对象中的动作,并通过 getAction() 读取该动作。

数据(Data)

将数据规范添加到意向过滤器。规范可以只是数据类型(mimeType 属性),也可以是 URI,或者是数据类型和 URIURI 由其每个部分的单独属性指定,这些指定 URL 格式的属性是可选的,但也相互依赖:

  • 如果没有为意图过滤器指定方案,则忽略所有其他 URI 属性。
  • 如果未为筛选器指定主机,则会忽略端口属性和所有路径属性。

setData() 方法仅将数据指定为 URIsetType() 仅将其指定为 MIME 类型,而 setDataAndType() 将其同时指定为 URIMIME 类型。URIgetData() 读取,类型由 getType() 读取。

动作/数据对的一些实例如下:

编号动作/数据对 & 描述
1

ACTION_VIEW content://contacts/people/1

显示标识符为 "1" 的人员的信息。

2

ACTION_DIAL content://contacts/people/1

显示填写了姓名的电话拨号器。

3

ACTION_VIEW tel:123

显示填写了给定号码的电话拨号器。

4

ACTION_DIAL tel:123

显示填写了给定号码的电话拨号器。

5

ACTION_EDIT content://contacts/people/1

编辑标识符为 "1" 的人员的信息。

6

ACTION_VIEW content://contacts/people/

显示用户可以浏览的人员列表。

7

ACTION_SET_WALLPAPER

显示选择壁纸的设置

8

ACTION_SYNC

它会同步数据,常数值是 android.intent.action.sync

9

ACTION_SYSTEM_TUTORIAL

它将启动平台定义的教程(默认教程或启动教程)。

10

ACTION_TIMEZONE_CHANGED

当时区改变时就会调起

11

ACTION_UNINSTALL_PACKAGE

用于运行默认卸载程序

类别(Category)

类别是 Intent 对象的可选部分,它是一个字符串,其中包含有关应处理该意图的组件类型的其他信息。addCategory() 方法将类别放置在 Intent 对象中,removeCategory() 删除先前添加的类别,并且 getCategories() 获取对象中当前所有类别的集合。这是 Android Intent 标准类别 的列表。

附加功能(Extra)

这将在键值对中提供附加信息,这些附加信息应传递给处理该意图的组件。可以分别使用 putExtras()getExtras() 方法设置和读取附加功能。这是 Android Intent 标准附加数据 的列表。

标志(Flag)

这些标志是 Intent 对象的可选部分,指示 Android 系统如何启动活动,以及启动后如何处理 Activity 活动等。

编号标志 & 描述
1

FLAG_ACTIVITY_CLEAR_TASK

如果在传递给 Context.startActivity() 的 Intent 中进行设置,则此标志将导致在 Activity 开始之前清除与该 Activity 相关联的所有现有任务。也就是说,该 Activity 成为原本空的任务的新 Root,并且所有旧 Activity 都已完成。只能与 FLAG_ACTIVITY_NEW_TASK 结合使用。

2

FLAG_ACTIVITY_CLEAR_TOP

如果已设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是关闭其上的所有其他活动,并且此 Intent 将作为新 Intent 交付给(现在位于顶部)旧 Activity

3

FLAG_ACTIVITY_NEW_TASK

此标志通常用于希望呈现 "launcher" 启动器样式行为的 Activity:它们为用户提供了一个可以完成的单独事情的列表,否则,该列表将完全独立于启动它们的 Activity 运行。

组件名称(component)

这个可选字段是一个 android ComponentName 对象,代表 ActivityServiceBroadcastReceiver 类。如果已设置,则将 Intent 对象传递到指定类的实例,否则 Android 使用 Intent 对象中的其他信息来定位合适的目标。

组件名称由 setComponent()setClass()setClassName() 设置,并由 getComponent() 读取。


意图类型

Android 支持以下两种意图:

Explicit Intents(显示意图)

显式意图将被连接到应用程序的内部世界,假设您想将一个活动(activity)连接到另一个活动(activity),我们可以通过显式意图进行引用,下图是通过单击按钮将第一个活动连接到第二个活动。

这些意图通过名称指定目标组件,通常用于应用程序内部消息,例如启动附属服务或启动同级活动(activity)的活动。例如:

  1. // 通过指定其类名来显式意图
  2. Intent i = new Intent(FirstActivity.this, SecondActivity.class);
  3. // 启动目标 Activity
  4. startActivity(i);
Implicit Intents(隐示意图)

这些意图不会命名目标,并且组件名称的字段保留为空白。隐式意图通常用于激活其他应用程序中的组件。例如:

  1. Intent read1=new Intent();
  2. read1.setAction(android.content.Intent.ACTION_VIEW);
  3. read1.setData(ContactsContract.Contacts.CONTENT_URI);
  4. startActivity(read1);

以上代码将给出如下结果:

接收意图的目标组件可以使用 getExtras() 方法获取源组件发送的额外数据。例如:

  1. // 在代码中的适当位置获取包对象
  2. Bundle extras = getIntent().getExtras();
  3. // 使用传递的key提取数据
  4. String value1 = extras.getString("Key1");
  5. String value2 = extras.getString("Key2");

实例

以下示例显示了 Android Intent 启动各种 Android 内置应用程序的功能。

步骤描述
1您将使用 Android Studio IDE 创建一个 Android 应用程序,并在 com.cankaoshouce.helloworld 包下将其命名为 HelloWorld。
2修改 src/main/java/MainActivity.java 文件并添加代码以定义对应于两个按钮的两个侦听器。启动浏览器并启动电话。
3修改布局 XML 文件 res/layout/activity_main.xml,以在线性布局中添加 3 个按钮。
4运行应用程序以启动 Android 模拟器,并验证应用程序中所做更改的结果。

以下是修改后的主活动文件 src/com.example.My Application/MainActivity.java 的内容:

  1. package com.cankaoshouce.helloworld;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.net.Uri;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.widget.Button;
  8. public class MainActivity extends Activity {
  9. Button b1,b2;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. b1=(Button)findViewById(R.id.button);
  15. b1.setOnClickListener(new View.OnClickListener() {
  16. @Override
  17. public void onClick(View v) {
  18. Intent i = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("https://cankaoshouce.com"));
  19. startActivity(i);
  20. }
  21. });
  22. b2=(Button)findViewById(R.id.button2);
  23. b2.setOnClickListener(new View.OnClickListener() {
  24. @Override
  25. public void onClick(View v) {
  26. Intent i = new Intent(android.content.Intent.ACTION_VIEW,
  27. Uri.parse("tel:9510300000"));
  28. startActivity(i);
  29. }
  30. });
  31. }
  32. }

以下是 res/layout/activity_main.xml 文件的内容:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical" >
  7. <TextView
  8. android:id="@+id/textView1"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:layout_alignParentTop="true"
  12. android:layout_centerHorizontal="true"
  13. android:layout_marginTop="65dp"
  14. android:text="Intent(意图)实例"
  15. android:textSize="30dp" />
  16. <TextView
  17. android:id="@+id/textView2"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:layout_below="@+id/textView1"
  21. android:layout_centerHorizontal="true"
  22. android:layout_marginTop="41dp"
  23. android:text="参考手册"
  24. android:textColor="#ff87ff09"
  25. android:textSize="30dp" />
  26. <ImageButton
  27. android:id="@+id/imageButton"
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. android:layout_below="@+id/textView2"
  31. android:layout_alignParentEnd="true"
  32. android:layout_centerHorizontal="true"
  33. android:layout_marginTop="60dp"
  34. android:layout_marginEnd="45dp"
  35. android:src="@drawable/logo" />
  36. <EditText
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:id="@+id/editText"
  40. android:layout_below="@+id/imageButton"
  41. android:layout_alignRight="@+id/imageButton"
  42. android:layout_alignEnd="@+id/imageButton" />
  43. <Button
  44. android:id="@+id/button"
  45. android:layout_width="wrap_content"
  46. android:layout_height="wrap_content"
  47. android:layout_alignStart="@+id/imageButton"
  48. android:layout_alignLeft="@+id/imageButton"
  49. android:layout_alignTop="@+id/editText"
  50. android:layout_alignEnd="@+id/textView1"
  51. android:layout_alignRight="@+id/textView1"
  52. android:layout_marginStart="28dp"
  53. android:layout_marginLeft="28dp"
  54. android:layout_marginTop="40dp"
  55. android:layout_marginEnd="-27dp"
  56. android:layout_marginRight="-27dp"
  57. android:text="启动浏览器" />
  58. <Button
  59. android:id="@+id/button2"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:layout_below="@+id/button"
  63. android:layout_alignStart="@+id/button"
  64. android:layout_alignLeft="@+id/button"
  65. android:layout_alignEnd="@+id/textView2"
  66. android:layout_alignRight="@+id/textView2"
  67. android:layout_marginStart="48dp"
  68. android:layout_marginLeft="48dp"
  69. android:layout_marginTop="43dp"
  70. android:layout_marginEnd="-48dp"
  71. android:layout_marginRight="-48dp"
  72. android:text="启动电话" />
  73. </RelativeLayout>

以下是 AndroidManifest.xml 的默认内容:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.cankaoshouce.helloworld">
  4. <application
  5. android:allowBackup="true"
  6. android:icon="@mipmap/ic_launcher"
  7. android:label="@string/app_name"
  8. android:supportsRtl="true"
  9. android:theme="@style/AppTheme">
  10. <activity android:name=".MainActivity">
  11. <intent-filter>
  12. <action android:name="android.intent.action.MAIN" />
  13. <category android:name="android.intent.category.LAUNCHER" />
  14. </intent-filter>
  15. </activity>
  16. </application>
  17. </manifest>

让我们尝试运行您的 My Application 应用程序。我假设您在进行环境设置时已创建了 AVD。要从 Android Studio 运行该应用程序,请打开项目的 activity 文件之一,然后运行图标从工具栏中单击 Eclipse Run Icon 图标。Android Studio 会将其安装在您的 AVD 上并启动它,如果设置和应用程序一切正常,它将显示在模拟器上窗口。

现在单击 "启动浏览器" 按钮,将启动已配置的浏览器并显示 https://cankaoshouce.com

类似的方法,您可以使用开始电话按钮启动电话界面,这将让您可以拨打已经给定的电话号码。