Intent 详解(一)

news/2024/7/5 14:18:18

前言:通过重新翻看android入门书籍,才发现原来自己露掉了那么多基础知道。原以为有了C的基础,快速开发应该是没有问题的了,但没有遇到问题的时候还是海搜,只知道这么写能完成这个功能,但为什么要这么写还是不太清楚,看来还是要好好把基础打一打,把android基础看完以后,再看看JAVA的基础知识。关于这个问题,写两篇,这篇基础知识讲解,下一篇代码实战。


相关文章:

《intent详解(二)》


一、Intent是什么

1、定义

Intent被译作意图,其实还是很能传神的,Intent期望做到的,就是把实现者和调用者完全解耦,调用者专心将以意图描述清晰,发送出去,就可以梦想成真,达到目的。

这个解释还是有点不太好理解,下面还有一个:Intent是一种运行时绑定(run-time binding)机制,它能在程序运行过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来完成请求。比如,有一个Activity希望打开网页浏览器查看某一网页的内容,那么这个Activity只需要发出WEB_SEARCH_ACTION给Android,Android就会根据Intent的请求内容,查询各组件注册时声明的IntentFilter,找到网页浏览器的Activity来浏览网页。 这个解释好像理解起来就容易好多,我们通过intent传入某种意图,而android就会根据这种意图,自动寻找合适的activity来启动,如果有多个条件符合的activity,就以列表的方式让用户手动选择一个。

2、显示Intent与隐式Intent

这两个概念刚开始不太好理解,先看两个通过intent启动activity的代码:

例一:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent();  
  2. intent.setClass(Context packageContext, OtherActivity.class);  
  3. startActivity(intent);  
例二:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent();  
  2. intent.setAction(Intent.ACTION_NEW);  
  3. startActivity(intent);  
从这两段代码中可以明显看出,同样是startActivity,但第一个明确指出是启动OtherActivity,而在第二个例子中,并没有明确指出要启动哪个activity!

这两种书写方式就分别是显示Intent(例一)、隐式Intent(例二);

  • 显式intent是指明确指出此intent是启动哪个activity.
  • 隐式intent是指并没有指出要启动哪个activity,而要系统自动去判断并启动匹配的activity.

3、显式Intent小结

有两种方式来显示的指示要启动的Activity:

方式一:(通过setClassName)

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent();  
  2. //表示希望启动com.example.test_permission包中的com.example.test_permission.MainActivity  
  3. intent.setClassName("com.example.test_permission""com.example.test_permission.MainActivity");  
  4. startActivity(intent);  


方式二:(通过SetClass)
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent();  
  2. intent.setClass(Context packageContext, OtherActivity.class);  
  3. startActivity(intent);  
同样,setClass(Context packageContext, OtherActivity.class);是指启动packageContext包里的OtherActivity.class类;

二、针对隐式intent,Activity的匹配原则

上面我们讲了隐式intent是要靠系统自动去匹配并启动某个activity的。那系统是怎样匹配activity的呢,系统是怎样知道这个actitiy就是某个intent想要的呢。

某个activity能不能被某个intent激活,要看这个activity是不是符合这个intent的要求,而某个activity能被哪个intent激活是有定义的,定义就在AndroidManifest.xml

打开AndroidManifest.xml,找到任意一个activity,一般都能看到一段代码,举个例子,我随便复制一个,如下:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <activity  
  2.     android:name=".MainActivity"  
  3.     android:label="@string/app_name" >  
  4.     <intent-filter>  
  5.         <action android:name="android.intent.action.MAIN" />  
  6.   
  7.         <category android:name="android.intent.category.LAUNCHER" />  
  8.     </intent-filter>  
  9. </activity>  
看这里有一对标签<intent-filter>……</intent-filter>
在这个标签里定义的所有东东都是用来定义该activity可以被哪些intent激活的,如果匹配,就会被激活!!!!!

在<intent-filter>里有以下几个属性可以让intent来匹配:Action、Category、Data;下面逐一介绍:

1、Action:该activity可以执行的动作

该标识用来说明这个activity可以执行哪些动作,所以当隐式intent传递过来action时,如果跟这里<intent-filter>所列出的任意一个匹配的话,就说明这个activity是可以完成这个intent的意图的,可以将它激活!!!!

常用的Action如下所示:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ACTION_CALL activity 启动一个电话.  
  2. ACTION_EDIT activity 显示用户编辑的数据.  
  3. ACTION_MAIN activity 作为Task中第一个Activity启动  
  4. ACTION_SYNC activity 同步手机与数据服务器上的数据.  
  5. ACTION_BATTERY_LOW broadcast receiver 电池电量过低警告.  
  6. ACTION_HEADSET_PLUG broadcast receiver 插拔耳机警告  
  7. ACTION_SCREEN_ON broadcast receiver 屏幕变亮警告.  
  8. ACTION_TIMEZONE_CHANGED broadcast receiver 改变时区警告.  
两条原则:

  • 一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。
  • 如果Intent请求的Action和<intent-filter>中个任意一条<action>匹配,那么该Intent就可以激活该activity(前提是除了action的其它项也要通过)
两条注意:

如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

  •  如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent-filter>匹配。
  •  反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

2、Category:于指定当前动作(Action)被执行的环境

即这个activity在哪个环境中才能被激活。不属于这个环境的,不能被激活。

常用的Category属性如下所示:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.  CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。表示所有intent都可以激活它   
  2.   
  3. CATEGORY_HOME:设置该组件为Home Activity。  
  4.   
  5. CATEGORY_PREFERENCE:设置该组件为Preference。   
  6.   
  7. CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。   
  8.   
  9. CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。表示该activity只能用来浏览网页。   
  10.   
  11. CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。  
注意:

如果该activity想要通过隐式intent方式激活,那么不能没有任何category设置,至少包含一个android.intent.category.DEFAULT

3、Data  执行时要操作的数据

在目标<data/>标签中包含了以下几种子元素,他们定义了url的匹配规则:

  • android:scheme 匹配url中的前缀,除了“http”、“https”、“tel”...之外,我们可以定义自己的前缀
  • android:host 匹配url中的主机名部分,如“google.com”,如果定义为“*”则表示任意主机名
  • android:port 匹配url中的端口
  • android:path 匹配url中的路径

在XML中声明可以操作的data域应该是这样的:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <activity android:name=".TargetActivity">  
  2. <intent-filter>  
  3.     <action android:name="com.scott.intent.action.TARGET"/>  
  4.     <category android:name="android.intent.category.DEFAULT"/>  
  5.     <data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/>  
  6. </intent-filter>  
  7. </activity>  
注意:

这个标识比较特殊,它定义了执行此Activity时所需要的数据,也就是说,这些数据是必须的!!!!!所有如果其它条件都足以激活该Activity,但intent却没有传进来指定类型的Data时,就不能激活该activity!!!!

三、Intent隐式传递方法

上面我们讲了一个Activity能被某隐式Intent唤醒的原则,只有这些全部匹配的intent才能唤醒这个Activity,下面我们就讲讲怎么向隐式intent传递这些参数,以便与activity匹配将向唤醒。

1、Action

使用Intent的一个构造方法即可实现传递Action参数:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public Intent(String action) {  
  2.     mAction = action;  
  3. }  
对于有如下声明的Activity:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <activity android:name=".TargetActivity">  
  2.     <intent-filter>  
  3.         <action android:name="com.scott.intent.action.TARGET"/>   
  4.         <category android:name="android.intent.category.DEFAULT"/>  
  5.     </intent-filter>  
  6. </activity>  
要激活这个Activity,就需要如下这样构造Intent:(直接向intent中传递action的name值)

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void gotoTargetActivity(View view) {  
  2.     Intent intent = new Intent("com.scott.intent.action.TARGET");  
  3.     startActivity(intent);  
  4. }  
这样就可以启动我们上面的这个activity了。

注意这里再次提醒,一个activity可以有多个action,只要有一个匹配就可以被启动。同样,如果仅指定某个action,而多个activity都具有这个action的话,系统会列出列表供用户选择执行哪一个activity.

2、Category

一个intent对象可以有任意个category。intent类定义了许多category常数.
  • addCategory()方法为一个intent对象增加一个category,
  • removeCategory删除一个category,
  • getCategories()获取intent所有的category.

3、Data

有两种传递data的方式:

第一种:利用构造函数:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public Intent(String action, Uri uri) {  
  2.     mAction = action;  
  3.     mData = uri;  
  4. }  
第二种:利用Intent::SetData(URI uri)
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent("com.scott.intent.action.name");  
  2. intent.setData(Uri.parse("scheme://host:port/parth"));  
  3. startActivity(intent);  
举个例子: (改动下上面的action的例子)

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <activity android:name=".TargetActivity">  
  2.     <intent-filter>  
  3.         <action android:name="com.scott.intent.action.TARGET"/>  
  4.         <category android:name="android.intent.category.DEFAULT"/>  
  5.         <data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/>  
  6.     </intent-filter>  
  7. </activity>  
这个时候如果要启动这个TargetActivity只指定action就不够了,我们需要为其设置data值,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent("com.scott.intent.action.TARGET");  
  2. intent.setData(Uri.parse("scott://com.scott.intent.data:7788/target"));  
  3. startActivity(intent);  
此时,url中的每个部分和TargetActivity配置信息中全部一致才能跳转成功,否则就被系统拒绝。

注意:

不过有时候对path限定死了也不太好,比如我们有这样的url:(scott://com.scott.intent.data:7788/target/hello)(scott://com.scott.intent.data:7788/target/hi)

这个时候该怎么办呢?我们需要使用另外一个元素:android:pathPrefix,表示路径前缀。
我们把android:path="/target"修改为android:pathPrefix="/target",然后就可以满足以上的要求了。

4、Extras

这个参数不参与匹配activity,而仅作为额外数据传送到另一个activity中,接收的activity可以将其取出来。这些信息并不是激活这个activity所必须的。也就是说激活某个activity与否只上action、data、catagory有关,与extras无关。而extras用来传递附加信息,诸如用户名,用户密码什么的。

可通过putXX()和getXX()方法存取信息;也可以通过创建Bundle对象,再通过putExtras()和getExtras()方法来存取。

通过bundle对象传递

发送方

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent = new Intent("com.scott.intent.action.TARGET");    
  2. Bundle bundle = new Bundle();    
  3. bundle.putInt("id"0);    
  4. bundle.putString("name""scott");    
  5. intent.putExtras(bundle);    
  6. startActivity(intent);    
接收方:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Bundle bundle = intent.getExtras();  
  2. int id = bundle.getInt("id");  
  3. String name = bundle.getString("name");  


更多参数传递方法见《通过Intent传递类对象》


5、附《Intent调用常见系统组件方法》

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 调用浏览器  
  2. Uri webViewUri = Uri.parse("http://blog.csdn.net/zuolongsnail");  
  3. Intent intent = new Intent(Intent.ACTION_VIEW, webViewUri);  
  4.   
  5. // 调用地图  
  6. Uri mapUri = Uri.parse("geo:100,100");  
  7. Intent intent = new Intent(Intent.ACTION_VIEW, mapUri);  
  8.   
  9. // 播放mp3  
  10. Uri playUri = Uri.parse("file:///sdcard/test.mp3");  
  11. Intent intent = new Intent(Intent.ACTION_VIEW, playUri);  
  12. intent.setDataAndType(playUri, "audio/mp3");  
  13.   
  14. // 调用拨打电话  
  15. Uri dialUri = Uri.parse("tel:10086");  
  16. Intent intent = new Intent(Intent.ACTION_DIAL, dialUri);  
  17. // 直接拨打电话,需要加上权限<uses-permission id="android.permission.CALL_PHONE" />  
  18. Uri callUri = Uri.parse("tel:10086");  
  19. Intent intent = new Intent(Intent.ACTION_CALL, callUri);  
  20.   
  21. // 调用发邮件(这里要事先配置好的系统Email,否则是调不出发邮件界面的)  
  22. Uri emailUri = Uri.parse("mailto:zuolongsnail@163.com");  
  23. Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri);  
  24. // 直接发邮件  
  25. Intent intent = new Intent(Intent.ACTION_SEND);  
  26. String[] tos = { "zuolongsnail@gmail.com" };  
  27. String[] ccs = { "zuolongsnail@163.com" };  
  28. intent.putExtra(Intent.EXTRA_EMAIL, tos);  
  29. intent.putExtra(Intent.EXTRA_CC, ccs);  
  30. intent.putExtra(Intent.EXTRA_TEXT, "the email text");  
  31. intent.putExtra(Intent.EXTRA_SUBJECT, "subject");  
  32. intent.setType("text/plain");  
  33. Intent.createChooser(intent, "Choose Email Client");  
  34.   
  35. // 发短信  
  36. Intent intent = new Intent(Intent.ACTION_VIEW);  
  37. intent.putExtra("sms_body""the sms text");  
  38. intent.setType("vnd.android-dir/mms-sms");  
  39. // 直接发短信  
  40. Uri smsToUri = Uri.parse("smsto:10086");  
  41. Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);  
  42. intent.putExtra("sms_body""the sms text");  
  43. // 发彩信  
  44. Uri mmsUri = Uri.parse("content://media/external/images/media/23");  
  45. Intent intent = new Intent(Intent.ACTION_SEND);  
  46. intent.putExtra("sms_body""the sms text");  
  47. intent.putExtra(Intent.EXTRA_STREAM, mmsUri);  
  48. intent.setType("image/png");  
  49.   
  50. // 卸载应用  
  51. Uri uninstallUri = Uri.fromParts("package""com.app.test"null);  
  52. Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri);  
  53. // 安装应用  
  54. Intent intent = new Intent(Intent.ACTION_VIEW);  
  55. intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.apk"), "application/vnd.android.package-archive");  
  56.   
  57. // 在Android Market中查找应用  
  58. Uri uri = Uri.parse("market://search?q=愤怒的小鸟");           
  59. Intent intent = new Intent(Intent.ACTION_VIEW, uri);  

至此本文就结束了。

下一篇用简单的几个实例,来具体讲解隐式intent的匹配与调用原理。

参考文章 :

《Android中Intent组件详解》

《android Intent机制详解》

《基础总结篇之九:Intent应用详解》

《Intent详解》

《Intent总结》

《Intent中的四个重要属性——Action、Data、Category、Extras》


请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/38399723 不胜感激!!!!!!



http://www.niftyadmin.cn/n/3649569.html

相关文章

[ASP.NET]重构Session确实让代码简洁干净了不少

CodeProject的这篇文章确实对我有所启迪&#xff0c;http://www.codeproject.com/useritems/SessionWrapper.asp#xx1208856xx。诚如作者所说&#xff0c;我们经常在ASP.NET用许多类似于下面的代码来检测Session中存储的对象&#xff0c;来防止Session过期后存储的变量丢失问题&…

redis修改配置重启命令_如何从命令行更改Redis的配置

redis修改配置重启命令介绍 (Introduction) Redis is an open-source, in-memory key-value data store. Redis has several commands that allow you to make changes to the Redis server’s configuration settings on the fly. This tutorial will go over some of these c…

SSH连接工具FinalShell的安装与使用

常见的SSH连接工具有好多&#xff0c;我以前常用的是xshellxftp组合。虽然需要付费&#xff0c;但是免费版已经基本满足我的需求。关于xshell和xftp的安装和使用可以参考我以前的博客&#xff1a;Xftp和Xshelll的安装—远程连接linux FinalShell是一体化的的服务器,网络管理软件…

[j2me]利用kSOAP让MIDP设备与WebService之间传递类对象

[j2me]利用kSOAP让MIDP设备与WebService之间传递类对象编写者日期关键词郑昀ultrapower2005-8-14J2me webservice soa ksoap serialization MIDP CLDC中国移动GPRS网络的连接方式有两种类型&#xff0c;一种是WAP&#xff0b;GPRS&#xff0c;接入名称叫CMWAP&#xff0c;一种是…

盖茨比乔布斯_盖茨比中的自定义字体

盖茨比乔布斯Choosing the right font can add great value to a site and enhance the user experience. The right font-loading strategy, however, can be somewhat of a challenge. That’s why Gatsby provides several developer-friendly solutions for all of our fon…

Android中GridView使用

GridView(网格视图)是按照行列的方式来显示内容的&#xff0c;一般用于显示图片&#xff0c;图片等内容&#xff0c;比如实现九宫格图&#xff0c;用GridView是首选&#xff0c;也是最简单的。主要用于设置Adapter。 GridView常用的XML属性&#xff1a; 属性名称 描述 an…

旧版Chrome浏览器的安装和使用——chrome63

虽然新版的Chrome浏览器很好用&#xff0c;但是界面风格我还是喜欢旧版的浏览器。我的电脑上有新版和旧版两个。不过正常情况下谷歌浏览器只能安装一个。我的做法是新版的浏览器正常安装&#xff0c;旧版的有点类似eclipse&#xff0c;解压就可以使用。不过使用前面需要解决一个…

javascript 引擎_V8引擎和JavaScript优化技巧

javascript 引擎V8 is Google’s engine for compiling our JavaScript. Firefox has it’s own engine called SpiderMonkey, it’s quite similar to V8 but there are differences. We will be discussing the V8 engine in this article. V8是Google用来编译JavaScript的引…