Android - 概述

Android - 意图和过滤器

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_SEARCH Intent发送到Android Intent Resolver以在Web浏览器中打开给定的URL. Intent Resolver解析一系列活动,并选择最适合您的Intent的一个,在本例中为Web Browser Activity.然后,Intent Resolver会将您的网页传递到Web浏览器并启动Web浏览器活动.

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


以上示例将在Android搜索引擎上搜索 it1352,并在您的活动中提供it1352的结果

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

Sr.No方法&描述
1

Context.startActivity()

将Intent对象传递给此方法以启动新活动或获取现有活动做新事物.

2

Context.startService()

意图object被传递给此方法以启动服务或向正在进行的服务发送新指令.

3

Context.sendBroadcast()

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

意图对象

Intent对象是一组信息,由接收意图的组件使用el作为Android系统使用的信息.

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

动作

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

Intent对象中的操作可以是由setAction()方法设置并由getAction()读取.

数据

向意图过滤器添加数据规范.规范可以只是数据类型(mimeType属性),只是URI,或者是数据类型和URI. URI由每个部分的单独属性指定 :

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

  • 如果没有为intent过滤器指定方案,则忽略所有其他URI属性.

  • 如果未指定主机对于过滤器,将忽略port属性和所有路径属性.

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

动作/数据对的一些示例是 :

Sr.No.行动/数据对&描述
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 is android.intent.action.SYNC

9

ACTION_SYSTEM_TUTORIAL

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

10

ACTION_TIMEZONE_CHANGED

它暗示时间区域已更改

11

ACTION_UNINSTALL_PACKAGE

它用于运行默认卸载程序

类别

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

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

Extras

这将是键值对以获取应传递给处理意图的组件的其他信息.可以分别使用putExtras()和getExtras()方法设置和读取附加内容.

标志

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

Sr.No标志&安培;描述
1

FLAG_ACTIVITY_CLEAR_TASK

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

2

FLAG_ACTIVITY_CLEAR_TOP

如果设置,并且正在启动的活动已经在当前任务中运行,然后不是启动该活动的新实例,而是关闭其上的所有其他活动,并且此意图将被传递到(现在在顶部)旧的活动作为新的意图.

3

FLAG_ACTIVITY_NEW_TASK

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

组件名称

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

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

意图类型

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

意图

显式意图

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

Explicit Intents

这些意图通过名称和目标组件指定目标组件它们通常用于应用程序内部消息 - 例如激活开始从属服务或启动姐妹活动.例如 :

// 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内置应用程序的功能.

Step描述
1您将使用Android studio IDE创建一个Android应用程序,并将其命名为 com.example.saira_000.myapplication 下的我的应用程序 .
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的内容 file :

<?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 .要从Android Studio运行应用程序,请打开项目的一个活动文件,然后单击运行Eclipse Run Icon icon从工具栏.Android Studio在你的AVD上安装应用程序并启动它,如果你的设置和应用程序一切正常,它将显示以下模拟器窗口&减去;

Android意图屏幕

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

Android Intent Browser

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

意图过滤器

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

以下是 AndroidManifest.xml 文件的一部分示例,用于指定活动 com.example.My Application.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调用此活动.查看,或使用 com.example.My Application.LAUNCH 操作,前提是他们的类别是 android.intent.category.DEFAULT .

< data> 元素指定要调用的活动所期望的数据类型,并且对于上面的示例,我们的自定义活动期望数据以"http://"<

可能存在意图可以通过多个活动或服务的过滤器的情况,可以询问用户要激活哪个组件.如果找不到目标,则会引发异常.

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

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

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

  • 每个< data> element可以指定URI和数据类型(MIME媒体类型).对于URI的每个部分,都有单独的属性,如 scheme,host,port path .只有当类型与过滤器中列出的类型匹配时,包含URI和数据类型的Intent对象才会传递测试的数据类型部分.

示例

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

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

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

package com.example.it13527.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.
               it13527.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.it13527.myapplication;

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


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.it13527.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>


Following will be the content of res/layout/custom_view.xml file  :

<?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>


Following will be the content of  res/values/strings.xml to define two new constants  :

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


Following is the default content of  AndroidManifest.xml  :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.it13527.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.it13527.myapplication.CustomActivity">

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

      </activity>
   </application>

</manifest>


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

Android Custom Activity

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

Android Two Activities

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

Android Custom Activity Runs

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

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


Android Exception Screen