zoukankan      html  css  js  c++  java
  • android intent隐身启动和Intent过滤器

    显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent。显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。
    隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent。它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息.由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。

    隐式启动Intent

      Android系统寻找与Intent请求意图最匹配的组件具体的选择方法是:
    Android将Intent的请求内容和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组件.如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。
    Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含组件的过滤器(即可以匹配哪些Intent请求)。
    一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响应隐式Intent请求。 
    一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和 IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准Action \Data\ Category,而Extra和Flag在解析收到Intent时是并不起作用的

    Intent过滤器:

      应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描述该组件所能响应Intent请求——组件希望接收什么类型的请求行为,什么类型的请求数据。
    如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的Intent Filter。
    隐式Intent和Intent Filter进行比较时的三要素是Intent的动作、数据以及类别。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。

    Action测试:<intent-filter>   <action android:name=”com.example.project.SHOW_CURRENT” />   <action android:name=”com.example.project.SHOW_RECENT” />   <action android:name=”com.example.project.SHOW_PENDING” /> </intent-filter>   
    一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。
    如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。
    如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。 (1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent- filter>匹配; (2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个 Intent请求就将顺利地通过<intent-filter>的行为测试。

    Category测试:<intent-filter > <category android:name=”android.Intent.Category.DEFAULT” /> <category android:name=”android.Intent.Category.BROWSABLE” /> </intent-filter>   
    只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该 Intent请求通过测试.
    IntentFilter中多余的<category>声明并不会导致匹配失败。
    一个没有指定任何类别测试的 IntentFilter仅仅只会匹配没有设置类别的Intent请求。

    Data测试:

    <intent-filter> <data android:type=”video/mpeg” android:scheme=”http” . . /> <data android:type=”audio/mpeg” android:scheme=”http” . . /> </intent-filter>   
    <data>元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试

    演示一个例子,用Intent隐身启动activity,并显示Action和Category的值,这个例子用到了两个Activity,两个布局,要注意到是在AndroidMainFest里设置uses-permission

    首先来看布局文件main.xml

    View Code
     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:orientation="vertical"
    4 android:layout_width="fill_parent"
    5 android:layout_height="fill_parent"
    6 >
    7 <Button android:id="@+id/bt1"
    8 android:layout_width="fill_parent"
    9 android:layout_height="wrap_content"
    10 android:text="intent隐身启动test"
    11 />
    12 </LinearLayout>

    second.xml文件

    View Code
     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout
    3 xmlns:android="http://schemas.android.com/apk/res/android"
    4 android:orientation="vertical"
    5 android:layout_width="match_parent"
    6 android:layout_height="match_parent">
    7 <EditText android:id = "@+id/et1"
    8 android:layout_width="fill_parent"
    9 android:layout_height="wrap_content"/>
    10 <EditText android:id ="@+id/et2"
    11 android:layout_width="fill_parent"
    12 android:layout_height="wrap_content"/>
    13 </LinearLayout>

    然后给大家看一下AndroidMainFest里的代码

    View Code
     1 <?xml version="1.0" encoding="utf-8"?>
    2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3 package="cn.shaoyangjiang.com"
    4 android:versionCode="1"
    5 android:versionName="1.0">
    6 <uses-sdk android:minSdkVersion="8" />
    7
    8 <application android:icon="@drawable/icon" android:label="@string/app_name">
    9 <activity android:name=".IntentFilterActivity"
    10 android:label="@string/app_name">
    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
    17 <activity android:name=".Second"
    18 android:label="@string/app_name">
    19 <intent-filter>
    20 <!-- 指定该Activity能响应action为指定字符串的Intent -->
    21 <action android:name="cn.shaoyangjiang.cn.com" />
    22 <!-- 指定该Activity能响应category为指定字符串的Intent -->
    23 <category android:name="cn.shaoyangjiang.cn" />
    24 <!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
    25 <category android:name="android.intent.category.DEFAULT" />
    26 </intent-filter>
    27 </activity>
    28 </application>
    29 <uses-permission android:name="android.permission.READ_CONTACTS" />
    30 <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    31 </manifest>

    第三步:修改intentfilterActivity.java文件

      

    View Code
     1 package cn.shaoyangjiang.com;
    2
    3 import android.app.Activity;
    4 import android.content.Intent;
    5 import android.os.Bundle;
    6 import android.view.View;
    7 import android.view.View.OnClickListener;
    8 import android.widget.Button;
    9
    10 public class IntentFilterActivity extends Activity {
    11 //定义一个Action常量
    12 final static String shao = "cn.shaoyangjiang.cn.com";
    13 //定义一个Category常量
    14 final static String yang = "cn.shaoyangjiang.cn";
    15 @Override
    16 public void onCreate(Bundle savedInstanceState) {
    17 super.onCreate(savedInstanceState);
    18 setContentView(R.layout.main);
    19 Button button1 = (Button)findViewById(R.id.bt1);
    20 button1.setOnClickListener(new OnClickListener() {
    21 @Override
    22 public void onClick(View arg0) {
    23 Intent intent = new Intent();
    24 //设置Action属性
    25 intent.setAction(shao);
    26 //添加Category属性
    27 intent.addCategory(yang);
    28 startActivity(intent);
    29 }
    30 });
    31 }
    32 }

    最后一部是second.java文件

    View Code
     1 package cn.shaoyangjiang.com;
    2
    3 import java.util.Set;
    4 import android.app.Activity;
    5 import android.os.Bundle;
    6 import android.widget.EditText;
    7
    8 public class Second extends Activity{
    9 @Override
    10 protected void onCreate(Bundle savedInstanceState) {
    11 super.onCreate(savedInstanceState);
    12 setContentView(R.layout.second);
    13 EditText editText1 =(EditText)findViewById(R.id.et1);
    14 //获取该Activity对应的Intent的Action属性
    15 String actionValue = getIntent().getAction();
    16 //显示Action属性
    17 editText1.setText("Action: "+actionValue);
    18 EditText editText2 = (EditText)findViewById(R.id.et2);
    19 //获取该Activity对应的Intent的Category属性
    20 Set<String> cate= getIntent().getCategories();
    21 //显示Action属性
    22 editText2.setText("Categoties: "+cate);
    23 }
    24 }

    效果图:






  • 相关阅读:
    JavaEE Tutorials (25)
    洛谷 P2677 超级书架 2
    洛谷 P1029 最大公约数和最小公倍数问题
    洛谷 P1305 新二叉树
    洛谷 P3817 小A的糖果
    洛谷 P1618 三连击(升级版)
    洛谷 P2097 资料分发1
    洛谷 P1068 分数线划定
    洛谷 P1207 [USACO1.2]双重回文数 Dual Palindromes
    洛谷 P1223 排队接水
  • 原文地址:https://www.cnblogs.com/shaoyangjiang/p/2377066.html
Copyright © 2011-2022 走看看