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开发相关文章

转自http://blog.csdn.net/flowingflying/article/details/9364799

【转】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. linux c编程:信号(一)

    信号是软件中断,很多比较重要的应用程序都需要处理信号.并且信号提供了一种处理异步事件的方法.如终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道中的下一个程序 很多条件都可以产生信号,比如 ...

  2. LeetCode:长度最小的子数组【209】

    LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...

  3. ubuntu14.04 pygame安装 python2.7

    系统:ubuntu14.04 LTS amd64python版本:2.7.6pygame版本:1.9.1release别这种方法了,这么安装不知道什么原因就出现了问题,在使用pygame.image. ...

  4. 《程序员代码面试指南》第一章 栈和队列 最大值减去最小值小于或等于num的数量

    题目 给定整数数组arr和整数num,共返回多少的数组满足如下情况 max(arr[i...j]) - min(arr[i...j]) <= num max(arr[i...j])表示数组arr ...

  5. 《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree

    题目 给出一个无重复元素的数组,构造此数组的MaxTree, java代码 /** * @Description: 构造数组的MaxTree * @Author: lizhouwei * @Creat ...

  6. path.join()和path.resolve()区别

    一.区别 1.path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径. 2.path.resolve() 方法将路径或路径片段的序列解析 ...

  7. 【Flask】filter 常用查询条件

    1. equal    2. not equal  3. like, ilike  4.in  5. not in 6. is null  7. is not null  8. and  9. or ...

  8. 介绍几款Web服务器性能压力测试工具

    一.http_load 程序非常小,解压后也不到100K http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载. 但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般 ...

  9. spring学习(5)

    bean配置 启用注解 <context:annotation-config/> 使用spring的特殊bean 对bean BeanPostProcessor spring本身提供的特殊 ...

  10. java反射(二)

    java的很多框架都是基于反射的.