Intent的构成

Intent能够带有action,data(由URI表达),extra data(key/value map,键值对),指定的类名(成为component name)。一个intent至少携带上述的一个内容。

Action。Action名,在上一笔记中已经给出两种样例,一种是系统自带的,如Intent.ACTION_DAIL,一种是开发人员通过AndroidManifest.xml进行注冊的,在创建intent时给出:Intent intent=new Intent(String action_name);。action_name字符串的名字前缀是类名。

Data。由不同action决定有效的URI的格式。intent.setData(Uri.parse(”xxxxxx”));。被唤起的activity能够同activity.getIntent()来获得intent,然后通该intent的getData()来获取数据。

//触发方。 

Intent i = new Intent(actionName);

String uriStr = "wei://www.flowingflying.com";

i.setData(Uri.parse(uriStr));

this.startActivity(i);

//被触发方。须要在AndroidManifest.xml中在intent-filter中注冊data信息,后文具体说明

Intent intent = this.getIntent();

String data = intent.getData();

通用的action即数据传递。Action和唤起的并不是是一对一的,比如Intent.ACTION_VIEW依据data,唤起不同的应用。这样的一对多,也就是通用的action,在manifest中注冊时,须要声明数据(URI)的要求。详细能够參考:http://developer.android.com/guide/topics/manifest/data-element.html。ACTION_VIEW是通过schema进行区分。通过class名字、action名字等方式进行指定的称为explicit
intent,能够一对多的称为implicit intent。

<activity......>

    <intent-filter> 

         <action android:name="android.intent.action.VIEW" />

         <data android:scheme="http"/>

         <data android:scheme="https"/>


    </intent-filter>

</activity>

假设我们自己的intent要传递data,也必需要在manifest中注冊data,否则intent会唤起失败,报告ActivityNotFoundException的异常。

比較经常使用的还有MIME type,比如注冊<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />表示要查看notes的集合(即文件夹),而注冊<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />则表示查看详细item,即查看详细的note。

扩展数据(Extra data)传递。uri的方式限制了信息的传递量。Extra的格式key/value对,key名字通常以包名开头,而value能够是不论什么基础数据类型,或者是实现android.os.Parcelable的对象。

在IntentTestDemo.java(通过intent i唤起IntentBasicViewActivity)通过以下传递extra数据。

1、extra数据以bundle的方式在intent中存放,假设已经有bundle,将新的键值对增加当中,假设没有bundle,则创建一个。未来确保key的唯一性

2、key名通常以包名开头,本例以常量方式,实际为:cn.flowingflying.android.pro.extra.string。

3、以下是最最简单据类型,还能够是array,比如putExtra(String name, int[] values);

      能够是Serializable对象,如putExtra(String name, Serializable value);以及Parcelable对象,如putExtra(String name,Parcelable value); 。

      能够将bundle进行传递,如putExtra(String name, Bundle value);,

      能够将Intent进行传递,如putExtra(String name, Intent anotherIntent);

      能够支持Array list:如putIntegerArrayListExtra(String name, ArrayList arrayList); putParcelableArrayListExtra(String name, ArrayList arrayList);和putStringArrayListExtra(String name, ArrayList arrayList)

     【注意】在intent中传递的不是reference(指针),而是copy一份,我们改动对象,并不会影响已经copy进intent中bundle的数据,这点须要很注意。

i.putExtra(IntentBasicViewActivity.EXTRA_FLOWINGFLYING_STRING, "Hello, Intent! ");



在IntentBasicViewActivity.java中通过下面代码获取extra数据。

Intent intent = this.getIntent();

Bundle b = intent.getExtras(); 

String s =  b.getString(EXTRA_FLOWINGFLYING_STRING));

Android系统有已定义的key值,详细參见http://developer.android.com/reference/android/content/Intent.html#EXTRA_ALARM_COUNT

使用Component来唤起Activity

之前样例,我们通过action name来唤起Activity。对于explicit intent,即明白指定调用哪个activity,能够通过给出该Component的的package name和class name来进行调用。以下我们试验採用四种类似的方式进行调用,这四种方式本质没有差别。

private void basicTest1(){

    Intent intent = new Intent();

   //方式1:setComponent(ComponentName name);

    intent.setComponent(new ComponentName("cn.flowingflying.android.pro",

                                                                                 "cn.flowingflying.android.pro.IntentBasicViewActivity"));

    startActivity(intent);

}

//要写完整的class Name,不能写IntentBasicViewActivity或者.IntentBasicViewActivity,否则报告找不到Activity的错误

private void basicTest2(){

    Intent intent = new Intent(); 

    //方式2:setClassName(String packageName, String classNameInThatPackage); 

   intent.setClassName("cn.flowingflying.android.pro",   

                                       "cn.flowingflying.android.pro.IntentBasicViewActivity");


    startActivity(intent);

}

//要写完整的class Name,不能写IntentBasicViewActivity或者.IntentBasicViewActivity,否则报告找不到Activity的错误

private void basicTest3(){

    Intent intent = new Intent();

   //方式3:setClassName(Context context, String classNameInThatContext);

    intent.setClassName(this,"cn.flowingflying.android.pro.IntentBasicViewActivity");

    startActivity(intent);

}

private void basicTest4(){

    Intent intent = new Intent();

    //方式4:setClass(Context context, Class classObjectInThatContext);

   intent.setClass(this,IntentBasicViewActivity.class);

    startActivity(intent);

}

Intent的Category属性

在AndroidManifest.xml中,我们能够设置intent的category,比如:

<activity ……>

    <intent-filter>

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>

</activity>

在应用启动是,将寻找Activity标记为CATEGORY_LAUNCHER来载入。Android定义了多个Category,详细能够在http://developer.android.com/reference/android/content/Intent.html#CATEGORY_ALTERNATIVE中查阅。比如CATEGORY_HOME能够作为该应用的home
screen,而CATEGORY_GADGET适合嵌入到某个activity中。

以下是两个样例。样例1指明了action name,因为存在多个匹配,系统将列出来,供用户进行选择,例如以下。

样例2在样例1的基础上添加了intent.addCategory(Intent.CATEGORY_LAUNCHER);,添加对Category名字的匹配,能够看到系统进行了进一步的过滤。:

我们能够通过PackageManager在代码中,能够不唤起intent就获得匹配的activity信息。例如以下

Intent intent = new Intent(Intent.ACTION_MAIN,null);

intent.addCategory(Intent.CATEGORY_LAUNCHER);

PackageManager pm = getPackageManager();

List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);




for(ResolveInfo ri : list){ 

    String packageName = ri.activityInfo.packageName;

    String className = ri.activityInfo.name

    ... ....

    //有了packageName和className,就能够进行分析,然后通过Intent i= new Intent(packaname,className); startActivity(i);唤起我们所需的acitivity。 

}

然而,通过PackageManager获得匹配的Activity的数量多于样例中系统提供给用户选择的activities的数量,为何?特别是没有将本应用显示出来。通过category筛选属于implicit intent的调用方式,不属于指定软件包名及类名的explicit intent的精确调用方式,对于implicit
intent调用须要进行声明,例如以下:

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

    <intent-filter>

        <action android:name="android.intent.action.MAIN" /> 

        <category android:name="android.intent.category.LAUNCHER" />

        <category android:name="android.intent.category.DEFAULT"/>

    </intent-filter>

</activity>

activity的intent-filter中能够有多个category描写叙述,当中CATEGORY_DEFAULT表示能够使用implicit intent调用,当我们添加此项声明后,本应用就出如今匹配的activity列表中。相同,对于通过action name来调用的,不指定包名和类名的,也属于implicit intent,相同须要进行CATEGORY_DEFAULT的声明,否则会出现ActivityNotFoundException的错误。假设activity没有在intent
fliter中设置为CATEGORY_DEFAULT,我们能够用PackageManager获取匹配的activities的信息,分析后得到确切的包名和类名,通过explicit的方式唤起该activity。

此外Android说假设从launcher screen唤起时不须要DEFAULT,也就是此时acitivty仅仅需MAIN和LAUNCHER,当然我们也能够DEFAULT设上。Android在DEFAULT上似乎有些繁杂,简单说假设我们不希望App被其它App通过implicit调用,我们就不要设置DEFAULT。

在category中有一个有趣的类别:<category android:name="android.intent.category.HOME"/>,我们在MainActivity以及另外一个Activity添加该类别。

<application ...... >

    <activity ...... >

        <intent-filter>

            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.HOME"/>

            <category android:name="android.intent.category.LAUNCHER" />

            <category android:name="android.intent.category.DEFAULT"/>

        </intent-filter>

    </activity>

    <activity android:name=".IntentBasicViewActivity" android:label="@string/intent_basic_test">

        <intent-filter>

                <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.HOME"/>

            <category android:name="android.intent.category.DEFAULT"/>

        </intent-filter>

    </activity>

    ......

</application>

左图在代码中通过PackageManager来查看匹配CATEGORY_HOME的信息;中图通过StartActivity(intent)来唤起匹配CATEGORY_HOME的Activities时,系统给予用户的选择,假设在应用中按Home键,有相同效果;右图为退出应用,按Home键,要求进入Home UI时,系统给予用户的选择。

相关链接: 我的Android开发相关文章

Pro Android学习笔记(十一):了解Intent(中)的更多相关文章

  1. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

  2. Pro Android学习笔记 ActionBar(1):Home图标区

     Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...

  3. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  4. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

  5. 【转】 Pro Android学习笔记(三五):Menu(6):XML方式 & PopUp菜单

    目录(?)[-] 利用XML创建菜单 XML的有关属性 onClick事件 Pop-up菜单 利用XML创建菜单 在代码中对每个菜单项进行设置,繁琐且修改不灵活,不能适配多国语言的要求,可以利用资源进 ...

  6. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  7. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  8. Pro Android学习笔记(一三七):Home Screen Widgets(3):配置Activity

    文章转载仅仅能用于非商业性质,且不能带有虚拟货币.积分.注冊等附加条件.转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei. 通过widget定义 ...

  9. 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...

  10. 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode

    目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...

随机推荐

  1. [C#]6.0新特性浅谈

    原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...

  2. Flex中如何通过设置GridLines对象的horizontalAlternateFill样式交错显示LineSeries图表背景颜色的例子

    原文 http://blog.minidx.com/2008/11/27/1652.html 接下来的例子演示了Flex中如何通过设置GridLines对象的horizontalAlternateFi ...

  3. VC实现将对话框最小化到系统托盘

    1.minisysDlg.h头文件设置: 1)public: void setTray();//设置托盘    NOTIFYICONDATA nid;//NOTIFYICONDATA结构包含了系统用来 ...

  4. C#.NET学习笔记1---C#.NET简介

    C#.NET学习笔记1---C#.NET简介 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com -------------- ...

  5. Qt on Android:QTableView不显示选中虚框

    在使用 QTableView 或 QTableWidget 时.有时我们不想要选中虚框,能够实现一个 ItemDelegate ,重写 drawFocus() 和 drawCheck()  两个虚函数 ...

  6. iOS通知NSNotificationCenter

    NSNotificationCenter消息通信 作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的. 注册通知:即要在什么地方接受消息 [[NSNotificat ...

  7. dubbo+zookeeper+spring+springMVC+mybatis的使用

    读前声明:由于本人水平有限,有错误或者描述不恰当的地方请指出来,勿喷!第一次写博客. 源码下载链接:http://files.cnblogs.com/files/la-tiao-jun-blog/du ...

  8. dp状态压缩-铺砖问题

    题目:有一个n行m列的地板,需要用 1*2小砖铺盖,小砖之间互相不能重叠,问有多少种不同的铺法? 示范: 解法:用F[i][j]存放第i行的第j状态(j为十进制,转为二进制即是状态)有多少种方案. 用 ...

  9. KMP字符串匹配

    #include<iostream> using namespace std; #define MAX 255 typedef unsigned char BYTE; typedef BY ...

  10. C++ Builder平台使用Indy9开发自动FTP程序01

    Indy9与CB自带的Indy8不同处还是挺多的.首先就是图标变漂亮了,其次很多Method都重写了.它主要是依据Delph里的函数,力求与之相通.不同点在本系列的后续章节中会一一介绍. 在写ftp代 ...