文档章节

Pro Android学习笔记(十一):了解Intent(中)

simpower
 simpower
发布于 2014/10/04 11:55
字数 1756
阅读 23
收藏 0
点赞 0
评论 0

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

共有 人打赏支持
simpower
粉丝 24
博文 422
码字总数 20207
作品 0
海淀
程序员
《Android开发艺术探索》Activity | 生命周期 | 启动模式 | Flags | IntentFilter action data的匹配规则 (一)

说几点 1.文章中大部分(所有吧)的内容都是与《Android开发艺术探索》书中写的内容是一致的,所以可以说是直接copy了一遍(没办法,作者写的太好了)。 2.为什么要copy一遍呢?,主要还是为...

a_zhon ⋅ 05/09 ⋅ 0

andriod-四大组件之广播Broadcast-短信的收发

我想几乎所有的安卓开发者,第一个接触到的四大组件之一就是activity,而我在之前的文章中也写过, 在activity里面getContext是大佬级别的存在(可以看前几章), 那么四大组件中的广播Broad...

九尾74 ⋅ 05/24 ⋅ 0

《Pro ASP.NET MVC 3 Framework》学习笔记目录

《Pro ASP.NET MVC 3 Framework》简介: 作者: Adam Freeman 和 Steven Sanderson 出版社: Apress; New 平装: 820页 语种: 英语 ISBN: 1430234040 声明:笔记里面按我自己的理解翻译了大部分...

mszhangxuefei ⋅ 2012/02/07 ⋅ 0

张高兴的 Xamarin.Android 学习笔记:(一)环境配置

  最近在自学 Xamarin 和 Android ,同时发现国内在做 Xamarin 的不多。我在自学中间遇到了很多问题,而且百度到的很多教程也有些过时,现在打算写点东西稍微总结下,顺便帮后人指指路了。...

张高兴 ⋅ 2017/01/13 ⋅ 0

Flutter 中文站上线,我整理了一份 8 小时上手指南!

Hi,大家好,我是承香墨影! 距离 Google 在 2018 世界移动大会上发布 Flutter 的 Beta 版本,Flutter 是 Google 用以帮助开发者在 Android 和 iOS 两个平台,同时开发高质量原生应用的全新移...

承香墨影 ⋅ 04/17 ⋅ 0

Android P Beta!您想要知道的所有更新内容都在这里

I/O 大会的第一天,我们公布了下一个版本的 Android,也就是 Android P 的 beta 版本。Android P 将 AI 定位为操作系统的核心,并侧重于提供智能且简洁的体验。让我们一起来了解下这个版本带...

谷歌开发者 ⋅ 05/10 ⋅ 0

从问题到解决方案到应用-android-ApiDemo入口源代码学习及应用

一.问题 在android的学习中我们经常需要做做一些小demo。 (1)一个demo建立一个项目: demo多了,项目就多了,会有各种不方便。 (2)于是,建立一个demo项目来,然后,第一个Activity呢,主界...

李海珍 ⋅ 2012/11/24 ⋅ 4

Activity启动模式的理解

一、理解 Tasks and Back Stack(任务和后台堆栈) 一个 App 对应一个 Task,该app 内的所有 activity 被安排在一个后台堆栈里。 多窗口模式下:一个windows下可能由多个 Task,系统为每个窗...

Agnes2017 ⋅ 05/04 ⋅ 0

Android实例剖析笔记(一)

开卷语 俗话说,“熟读唐诗三百首,不会作诗也会吟”。最近收集了很多Android的示例代码,从这些代码的阅读和实验中学习到很多知识,从而产生写这个系列的打算,目标就是一步步跟着实例进行动...

嗯哼9925 ⋅ 01/07 ⋅ 0

Intent Android 详解

Intents and Intent Filters 三种应用程序基本组件 activity, service和broadcast receiver——是使用称为intent的消息来激活的。 Intent消息传递是一种组件间运行时绑定的机制. intent是Int...

长平狐 ⋅ 2012/10/09 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

中标麒麟(龙芯版)7.0优盘安装

########################################## 制作U盘安装盘: 1.准备U盘: PMON环境下U盘必须格式化成ext3; 昆仑固件环境下可以格式化成ext3,ext4 2.把整个镜像 xxx.iso 复制到U盘下面 3....

gugudu ⋅ 4分钟前 ⋅ 0

老司机写的大数据建模五步走

本文将尝试来梳理一下数据建模的步骤,以及每一步需要做的工作。 01 第一步:选择模型或自定义模式 这是建模的第一步,我们需要基于业务问题,来决定可以选择哪些可用的模型。 比如,如果要预...

gulf ⋅ 13分钟前 ⋅ 0

PacificA 一致性协议解读

PacificA 的 paper 在 08 年左右发出来的,比 Raft 早了 6,7 年。 在 PacificA 论文中,他们强调该算法使用范围是 LAN (Local Area Network),讲白了就是对跨机房不友好。 不管是 ZAB,Raf...

黑客画家 ⋅ 15分钟前 ⋅ 0

盘符图标个性化

设置自己的专属盘符图标 准备ico格式的图片文件一个,在根目录下创建autorun.inf文件 文件内容 [Autorun]icon=logo.ico 重新启动或者插拔U盘即可看到结果...

阿豪boy ⋅ 15分钟前 ⋅ 0

Windows下QQ聊天记录中图片的默认存放位置

Windows下QQ聊天记录中图片的默认存放位置在设置中是没有说明的。 实测位置在:D:\Documents\Tencent Files\974101467\Image 其中: “974101467”为对应的QQ号; “C2C”为个人之间的聊天图...

临江仙卜算子 ⋅ 22分钟前 ⋅ 0

GC 的三种基本实现方式

参考资料《代码的未来》(作者: [日] 松本行弘)。 由于并非本人原著(我只是个“搬运工“),SO 未经本人允许请尽情转载。 另外个人像说明一下这里所说的GC指泛指垃圾回收机制,而单指Jav...

xixingzhe ⋅ 22分钟前 ⋅ 0

Android双击退出

/** * 菜单、返回键响应 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(keyCode......

王先森oO ⋅ 27分钟前 ⋅ 0

idea 整合 vue 启动

刚学习Vue 搭建了一个项目 只能命令启动 Idea里面不会启动 尝试了一下修改启动的配置 如下: 1.首先你要保证你的package.json没有修改过 具体原因没有看 因为我改了这个name的值 就没办法启动...

事儿爹 ⋅ 32分钟前 ⋅ 0

redis在windows环境的后台运行方法

在后台运行,首先需要安装redis服务,命令为 redis-server.exe --service-install redis.windows.conf --loglevel verbose 启动,命令为 redis-server --service-start 停止,命令为 redis-...

程序羊 ⋅ 35分钟前 ⋅ 0

比特币现金开发者提出新的交易订单规则

本周,四位比特币现金的四位开发者和研究员:Joannes Vermorel(Lokad),AmaurySéchet(比特币ABC),Shammah Chancellor(比特币ABC)和Tomas van der Wansem(Bitcrust)共同发表了一篇关...

lpy411 ⋅ 39分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部