AndroidIntent和IntentFilter


Android Intent 是要执行的操作的抽象描述。它可以与 startActivity 一起使用来启动Activity,broadcastIntent 可以将它发送到任何感兴趣的BroadcastReceiver组件, startService(Intent)或 bindService(Intent,ServiceConnection,int) 可以与后台服务进行通信。

意图本身是一个Intent对象,是一个被动数据结构,包含要执行的操作的抽象描述。

例如,假设您有一个活动需要启动电子邮件客户端并使用您的Android设备发送电子邮件。为此,您的活动会将ACTION_SEND以及相应的 选择器 发送到Android Intent Resolver。指定的选择器为用户提供了适当的界面,以便选择如何发送电子邮件数据。

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

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

发电子邮件

例如,假设您有一个需要在Android设备上的Web浏览器中打开URL的活动。为此,您的活动将ACTION_WEB_SEARCHIntent发送到Android Intent Resolver以在Web浏览器中打开给定的URL。Intent Resolver会解析一系列活动,并选择最适合您Intent的活动,在本例中为Web浏览器活动。然后,IntentResolver会将您的网页传递到Web浏览器并启动Web浏览器活动。

String q = "codingdict";
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH );
intent.putExtra(SearchManager.QUERY, q);
startActivity(intent);

上面的示例将在android搜索引擎上搜索为 codingdict ,它会在您的活动中提供codingdict的结果

有各种机制可以为每种类型的组件提供意图 - 活动,服务和广播接收器。

序号 Method & Description
1

Context.startActivity()

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

2

Context.startService()

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

3

Context.sendBroadcast()

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

意图对象

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

Intent对象可以根据通信或要执行的内容包含以下组件 -

行动

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

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

数据

将数据规范添加到intent过滤器。规范可以只是数据类型(mimeType属性),只是URI,或者是数据类型和URI。URI由每个部分的单独属性指定 -

指定URL格式的这些属性是可选的,但也是相互依赖的 -

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

setData()方法仅将数据指定为URI,setType()仅将其指定为MIME类型,setDataAndType()将其指定为URI和MIME类型。URI由getData()读取,类型由getType()读取。

行动/数据对的一些例子是 -

序号 Action/Data Pair & Description
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

它将是同步数据,Constant Value是android.intent.action.SYNC

9

ACTION_SYSTEM_TUTORIAL

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

10

ACTION_TIMEZONE_CHANGED

它暗示了时区的变化

11

ACTION_UNINSTALL_PACKAGE

它用于运行默认卸载程序

类别

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

您可以在下面的部分中查看Intent Filters的详细信息,以了解我们如何使用类别来选择与Intent相对应的适当活动。

附加功能

这将是键值对,以获取应传递给处理意图的组件的其他信息。可以分别使用putExtras()getExtras()方法设置和读取附加内容。以下是AndroidIntent标准额外数据列表

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

序号 标志和描述
1

FLAG_ACTIVITY_CLEAR_TASK

如果在传递给Context.startActivity()的Intent中设置,则此标志将导致在活动开始之前清除与活动关联的任何现有任务。也就是说,活动成为否则为空任务的新根,并且任何旧活动都已完成。这只能与FLAG_ACTIVITY_NEW_TASK一起使用。

2

FLAG_ACTIVITY_CLEAR_TOP

如果已设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是将关闭其上的所有其他活动,并将此Intent传递给(现在开启) top)旧活动作为新的意图。

3

FLAG_ACTIVITY_NEW_TASK

此标志通常由想要呈现“启动器”样式行为的活动使用:它们为用户提供可以完成的单独事物的列表,否则完全独立于启动它们的活动。

组件名称

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

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

意图类型

Android支持以下两种类型的意图

意图

明确的意图

显式意图将连接应用程序的内部世界,假设您想要将一个活动连接到另一个活动,我们可以通过显式意图执行此引用,下面的图像通过单击按钮将第一个活动连接到第二个活动。

明确的意图

这些意图通过其名称指定目标组件,它们通常用于应用程序内部消息 - 例如启动从属服务或启动姐妹活动的活动。例如 -

// Explicit Intent by specifying its class name
Intent i = new Intent(FirstActivity.this, SecondActivity.class);

// Starts TargetActivity
startActivity(i);

隐含意图

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

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

上面的代码将给出如下所示的结果

意图

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

// Get bundle object at appropriate place in your code
Bundle extras = getIntent().getExtras();

// Extract data using passed keys
String value1 = extras.getString("Key1");
String value2 = extras.getString("Key2");

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

描述
1 您将使用Android studio IDE创建Android应用程序,并com.example.saira_000.myapplication包下将其命名为My Application
2 修改src / main / java / MainActivity.java文件并添加代码以定义两个对应的两个按钮即ie。启动浏览器并启动手机。
3 修改布局XML文件res / layout / activity_main.xml以在线性布局中添加三个按钮。
4 运行应用程序以启动Android模拟器并验证应用程序中所做更改的结果。

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

package com.example.saira_000.myapplication;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
   Button b1,b2;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      b1=(Button)findViewById(R.id.button);
      b1.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v) {
            Intent i = new Intent(android.content.Intent.ACTION_VIEW,
               Uri.parse("http://www.example.com"));
            startActivity(i);
         }
      });

      b2=(Button)findViewById(R.id.button2);
      b2.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Intent i = new Intent(android.content.Intent.ACTION_VIEW,
               Uri.parse("tel:9510300000"));
            startActivity(i);
         }
      });
   }
}

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin"
   tools:context=".MainActivity">

   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Intent Example"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />

   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point"
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_below="@+id/textView1"
      android:layout_centerHorizontal="true" />

   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView2"
      android:layout_centerHorizontal="true" />

   <EditText
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editText"
      android:layout_below="@+id/imageButton"
      android:layout_alignRight="@+id/imageButton"
      android:layout_alignEnd="@+id/imageButton" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Start Browser"
      android:id="@+id/button"
      android:layout_alignTop="@+id/editText"
      android:layout_alignRight="@+id/textView1"
      android:layout_alignEnd="@+id/textView1"
      android:layout_alignLeft="@+id/imageButton"
      android:layout_alignStart="@+id/imageButton" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Start Phone"
      android:id="@+id/button2"
      android:layout_below="@+id/button"
      android:layout_alignLeft="@+id/button"
      android:layout_alignStart="@+id/button"
      android:layout_alignRight="@+id/textView2"
      android:layout_alignEnd="@+id/textView2" />
</RelativeLayout>

以下是 res / values / strings.xml 的内容, 用于定义两个新常量

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">My Applicaiton</string>
</resources>

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

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

   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
      <activity android:name=".MainActivity">
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
   </application>
</manifest>

让我们尝试运行 我的应用 程序。我假设您在进行环境设置时创建了 AVD 。要从AndroidStudio运行应用程序,请打开项目的某个活动文件,然后单击工具栏中的“运行” Eclipse运行图标图标.AndroidStudio会在您的AVD上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示以下模拟器窗口 -

Android意图屏幕

现在点击 Start Browser 按钮,它将启动配置的浏览器并显示http://www.example.com,如下所示

Android Intent Browser

类似地,您可以使用“开始电话”按钮启动电话界面,这样您就可以拨打已经给出的电话号码。

意图过滤器

您已经了解了如何使用Intent来调用另一个活动。Android操作系统使用过滤器来精确定位可以通过指定的一组操作,类别,与Intent关联的数据方案来处理Intent的活动,服务和广播接收器集。您将在清单文件中使用 <intent-filter>元素列出与任何活动,服务或广播接收器关联的操作,类别和数据类型。

以下是 AndroidManifest.xml 文件的一部分示例,用于指定活动 com.example.MyApplication.CustomActivity ,可以通过上述两个操作之一调用,一个类别和一个数据

<activity android:name=".CustomActivity"
   android:label="@string/app_name">

   <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <action android:name="com.example.My Application.LAUNCH" />
      <category android:name="android.intent.category.DEFAULT" />
      <data android:scheme="http" />
   </intent-filter>

</activity>

一旦此活动与上述过滤器一起定义,其他活动将能够使用 android.intent.action.VIEW 或使用 com.example.MyApplication.LAUNCH操作调用此活动,前提是其类别为 android.intent .category.DEFAULT

所述 <data>元素指定由活动所期望的数据类型被称为和用于上述例子提供了自定义活动预计数据开始与“HTTP://”可能存在意图可以通过多于一个活动或服务的过滤器的情况,可以询问用户激活哪个组件。如果找不到目标,则会引发异常。

在调用活动之前有以下测试Android检查

  • 过滤器<intent-filter>可以列出多个动作,如上所示,但此列表不能为空; 过滤器必须包含至少一个<action>元素,否则它将阻止所有意图。如果提到了多个操作,则Android会在调用活动之前尝试匹配上述操作之一。

  • 过滤器<intent-filter>可列出零个,一个或多个类别。如果没有提到的类别,那么Android总是通过此测试,但如果提到了多个类别,那么对于通过类别测试的意图,Intent对象中的每个类别必须与过滤器中的类别匹配。

  • 每个<data>元素都可以指定URI和数据类型(MIME媒体类型)。URI的每个部分都有单独的属性,如 方案,主机,端口和 路径。包含URI和数据类型的Intent对象仅在其类型与筛选器中列出的类型匹配时才传递测试的数据类型部分。

以下示例是对上述示例的修改。在这里,我们将看到如果一个intent调用两个活动定义,Android如何解决冲突,接下来如何使用过滤器调用自定义活动,第三个是如果Android没有为intent定义适当的活动,则是例外情况。

描述
1 您将使用android studio创建一个Android应用程序,并com.example.codingdict7.myapplication包下将其命名为My Application ;
2 修改src / Main / Java / MainActivity.java文件并添加代码以定义与布局文件中定义的三个按钮对应的三个侦听器。
3 添加一个新的src / Main / Java / CustomActivity.java文件,以使一个自定义活动由不同的意图调用。
4 修改布局XML文件res / layout / activity_main.xml以在线性布局中添加三个按钮。
添加一个布局XML文件res / layout / custom_view.xml以添加一个简单的<TextView>以通过intent显示传递的数据。
6 修改AndroidManifest.xml以添加<intent-filter>以定义调用自定义活动的意图的规则。
7 运行应用程序以启动Android模拟器并验证应用程序中所做更改的结果。

以下是修改后的主活动文件 src / MainActivity.java的内容 。

package com.example.codingdict7.myapplication;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
   Button b1,b2,b3;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      b1=(Button)findViewById(R.id.button);
      b1.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v) {
            Intent i = new Intent(android.content.Intent.ACTION_VIEW,
               Uri.parse("http://www.example.com"));
            startActivity(i);
         }
      });

      b2 = (Button)findViewById(R.id.button2);
      b2.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Intent i = new Intent("com.example.
               codingdict7.myapplication.
                  LAUNCH",Uri.parse("http://www.example.com"));
            startActivity(i);
         }
      });

      b3 = (Button)findViewById(R.id.button3);
      b3.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Intent i = new Intent("com.example.
               My Application.LAUNCH",
                  Uri.parse("https://www.example.com"));
            startActivity(i);
         }
      });
   }
}

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

package com.example.codingdict7.myapplication;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by codingdict7 on 8/23/2016.
 */
public class CustomActivity extends Activity {
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.custom_view);
      TextView label = (TextView) findViewById(R.id.show_data);
      Uri url = getIntent().getData();
      label.setText(url.toString());
   }
}

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.example.codingdict7.myapplication.MainActivity">

   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Intent Example"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />

   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point"
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_below="@+id/textView1"
      android:layout_centerHorizontal="true" />

   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView2"
      android:layout_centerHorizontal="true" />

   <EditText
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/editText"
      android:layout_below="@+id/imageButton"
      android:layout_alignRight="@+id/imageButton"
      android:layout_alignEnd="@+id/imageButton" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Start Browser"
      android:id="@+id/button"
      android:layout_alignTop="@+id/editText"
      android:layout_alignLeft="@+id/imageButton"
      android:layout_alignStart="@+id/imageButton"
      android:layout_alignEnd="@+id/imageButton" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Start browsing with launch action"
      android:id="@+id/button2"
      android:layout_below="@+id/button"
      android:layout_alignLeft="@+id/button"
      android:layout_alignStart="@+id/button"
      android:layout_alignEnd="@+id/button" />
   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Exceptional condition"
      android:id="@+id/button3"
      android:layout_below="@+id/button2"
      android:layout_alignLeft="@+id/button2"
      android:layout_alignStart="@+id/button2"
      android:layout_toStartOf="@+id/editText"
      android:layout_alignParentEnd="true" />
</RelativeLayout>

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

<?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">
   <TextView android:id="@+id/show_data"
      android:layout_width="fill_parent"
      android:layout_height="400dp"/>
</LinearLayout>

以下是 res / values / strings.xml 的内容, 用于定义两个新常量

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">My Application</string>
</resources>

以下是 AndroidManifest.xml 的默认内容

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

   <application
      android:allowBackup = "true"
      android:icon = "@mipmap/ic_launcher"
      android:label = "@string/app_name"
      android:supportsRtl = "true"
      android:theme = "@style/AppTheme">
      <activity android:name = ".MainActivity">
         <intent-filter>
            <action android:name = "android.intent.action.MAIN" />
            <category android:name = "android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>

      <activity android:name="com.example.codingdict7.myapplication.CustomActivity">

         <intent-filter>
            <action android:name = "android.intent.action.VIEW" />
            <action android:name = "com.example.codingdict7.myapplication.LAUNCH" />
            <category android:name = "android.intent.category.DEFAULT" />
            <data android:scheme = "http" />
         </intent-filter>

      </activity>
   </application>

</manifest>

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

Android自定义活动

现在让我们从第一个按钮“使用VIEWAction启动浏览器”开始。在这里,我们使用过滤器“android.intent.action.VIEW”定义了我们的自定义活动,并且已经有一个针对Android定义的VIEW动作的默认活动,即启动Web浏览器,因此android显示以下两个选项来选择您的活动想要发布。

Android两项活动

现在,如果您选择浏览器,那么Android将启动Web浏览器并打开example.com网站,但如果您选择IndentDemo选项,那么Android将启动CustomActivity,它只会捕获传递的数据,并在文本视图中显示如下

Android自定义活动运行

现在返回使用后退按钮并单击“使用LAUNCH操作启动浏览器”按钮,此处Android应用过滤器以选择定义活动,它只需启动您的自定义活动

再次,回到使用后退按钮并单击“异常条件”按钮,这里Android尝试找出给定意图的有效过滤器,但它没有找到定义的有效活动,因为这次我们使用数据作为 https 而不是 http 虽然我们正在给出正确的操作,但Android会引发异常并显示以下屏幕

Android异常屏幕