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. Unix/Linux环境C编程入门教程(18) kali-linuxCCPP开发环境搭建

    1. Kali linux是BT5的晋级版本,用于信息安全.基于Debian7内核.新建虚拟机. 2. 选择默认虚拟机 3. 选择稍后安装操作系统 4.选择Linux Debian7 64位,因为Ka ...

  2. opensatck 使用devstack在 laptop上的 网络配置

    http://docs.openstack.org/developer/devstack/guides/neutron.html Physical Network Setup In most case ...

  3. openstack中文文档

    http://www.openstack.cn/p392.html   openStack Hacker中文文档 http://docs.mirantis.com/fuel-dev/develop/a ...

  4. 取得正在运行的Activity

    在main.xml中: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...

  5. DB Query Analyzer 5.04 is released, 63 articles concerned have been published

    DB Query Analyzer 5.04 is released, 63 articles concerned have been published DB QueryAnalyzer is pr ...

  6. 使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)

    前言 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图.视频时间.尺寸等),跳过直接写在线播放部分的章节.从Vitamio的介绍可以看得出,其支持http ...

  7. C# foreach获取集合元素索引的坑

    ,}; foreach(var prepareId in prepareIds) { Console.WriteLine(prepareIds.IndexOf(prepareId)); } 执行结果如 ...

  8. bootstrap的导航改造

    在使用bootstrap制作后台时用到了响应式导航条,其中dropdown组件更是用的比较多,用的多需要点击的就多,dropdown默认鼠标左键单击才展开,如果使用鼠标放上去(hover)就展开则会省 ...

  9. Request和Response详解

    转自:http://zhidao.baidu.com/link?url=8BI0cjlcFdBSJKHTZlpo874eqtbTJoZfrh3miQgM_05RvSER8skPiBc1wSPZtXT8 ...

  10. JVM学习之实例分析JVM安全体系

    转自:http://www.importnew.com/17093.html,感谢分享 类加载器的作用就是将真实的class文件根据位置将该Java类的字节码装入内存,并生成对应的Class对象.用户 ...