本科毕业论文 Google Android手机嵌入式系统的研究与开发
Activity的消息只会发给Activity而不会发给Service或者Intent Receiver。Service的消息也只会发给Service,Intent Receiver的消息只会发给Intent Receiver。只有了解了Intent的组成我们才能对使用Intent开发短信的接收功能,因为miniSMS短信息接收功能需要用到Android的Intent机制。Intent由以下几个部分组成:
①Intent组件名属性。该组件名指的是Intent目标组件的名称,由目标组件类名和目标组件所在应用程序的包名组成。但是Intent组件名可有可以没有,如果给出了目标组件的名称,那该Intent就作为一个显示消息,Intent消息传递给指出的组件,如果没有指定目标组件名的话,那则是一个隐式消息,Android则会通过对Intent内的其他消息与已注册的IntentFilter进行比较,然后选择一个最适合的目标组件来响应这个消息。
②Action属性。Action描述了Intent所触发动作名字的字符串。理论上可以用任何字符串来描述Action,但是在Intent类中,用静态常量字符串的形式定义了与Android系统有关的Action字符串。例如ACTION_MAIN、ACTION_VIEW和ACTION_EDIT等。在之前写好的miniSMS的AndroidManifest.xml分析中我们看到Activity中的Intent-Filter
标
签
中
有
这
么
一
行
android: name=\这个就是Intent的Action的例子,而ACTION_MAIN就是和android.intent.action.MAIN所对应的,表示是主程序的入口。ACTION_VIEW表示根据Intent中Data的类型,打开想对应的应用程序来显示数据。ACTION_EDIT打开编辑Data里指定数据相对应的应用程序。 ③Data属性。Intent中描述要操作数据的URI(Universal Resource Identifier.通用资源标识符)和数据类型。对于有些操作是需要有相对应的操作数据的。例如,对于ACTION_EDIT来说,可以用电话号码,短信息等可编辑的URI作为其操作数据。但是对ACTION_CALL来说,它的数据就只能是电话号码。在Android的Intent机制中,组件与相对应的数据的匹配是很重要的,如果数据类型匹配错误的话,相对应的应用程序则不会执行。所以,在每次使用Intent时都要注意相关的数据类型和格式。这样程序就不会错误。 ④Category属性。这个部分是对被请求组件的而外描述信息。同样的Android也在Intent类中定义了一组静态常量字符串表示不同类型的Intent。例如CATEGORY_LAUNCHER、CATEGORY_BROWSABLE和CATEGORY_HOME。在之前的例子中我们已近见到过CATEGORY_LAUNCHER了,它表示目标Activity是应用程序中最先被执行的Activity,CATEGORY_BROWSABLE则是说目标Activity能够通过网页浏览器中点击链接而激活,而CATEGORY_HOME是指该Activity是开机后显示的Activity或者是按下HOME键后显示的Activity。 ⑤Extra属性。在连接两个不同组件时,有时需要在Intent中附加一些额外的信 25 本科毕业论文 Google Android手机嵌入式系统的研究与开发 息,例如短信的内容等,以便将数据传入目标Activity中。另外Extra是通过bundle对象来保存数据,bundle对象提供了一系列的put和get方法来设置、获取相应的信息。 ⑥Flag属性。用于表示一些状态的标示符。比如说FLAG_KEEP_SCREEN_ON则表示禁止屏幕休眠。 在AndroidManifest.xml中我们看到一个“intent-filter”标签,而这个标签的内容就是应用程序组件通知Android自己处理隐式Intent的IntentFilter过滤器。IntentFilter描述一个组件能够响应Intent的范围,比如说该组件希望接受什么类型的请求,什么类型的数据等。在这之前先说一下隐式Intent和显示的Intent。 之前说过,如果Intent中包含了目标组件名的时候,该Intent就为显示的,而不包含目标组件名则该Intent为隐式的。在显示Intent中,由目标组件名唯一确定目标组件,与之匹配的组件是确定的而且是唯一的,从这可以看出,一般的显示Intent多用于应用程序内部传递消息。对于隐式Intent却恰恰相反,没有明确目标组件的名称。因此,需要由Android系统帮忙进行寻找与Intent请求最为匹配的组件,这样待选的组件可能是一个或者多个。Android系统中有一个叫做IntentFilter的过滤器,将Intent的内容与这个过滤器进行比较,如果IntentFilter中有一个组件匹配该Intent,那么Android就自动选择该组件作为该隐式Intent的目标组件。然后用该组件响应这个Intent。 任何一个Android应用程序,都要在AndroidManifest.xml中指出自己所包含组件的IntentFilter,一个没有声明IntentFilter的组件只能响应那些使用自己组件名字的显示Intent请求,而无法显示隐式Intent请求。但是一个声明了IntentFilter的组件不仅可以响应隐式Intent同时还可以响应显示的Intent。另外,在Android选择组件响应隐式Intent时,一般以Intent的Action属性、Data属性和Category属性作为参考标准。当一个Intent消息进行匹配组件时,先要检查这三个属性,在匹配中如果任何一个属性不匹配的话,Android都不会将该隐式Intent传递给该目标组件。 结合之前介绍的AndroidManifest.xml配置文件来具体说明下。这个例子中定义了一个叫做HelloAndroid的Activity,以及定义了该Activity的IntentFilter过滤器。部分代码如下 26 本科毕业论文 Google Android手机嵌入式系统的研究与开发 当这个应用程序运行时,会发出一个Intent,这个Intent中的Action属性中的值一定ACTION_MAIN,Category属性中的值也一定是CATEGORY_LAUNCHER。这个Intent到AndroidManifest.xml中进行比较,发现miniSMS这个Activity中的action的值和ACTION_MAIN匹配,则action匹配成功,接着和category进行比较,发现和CATEGORY_LAUNCHER匹配,category匹配成功,因为后面没有其他值了。所以就Android就选择miniSMS作为响应这个Intent的组件,接着便调用miniSMS这个Activity。 为 在明白了Android的Intent机制以及明白了Intent的组成以后我们开始编写SmsReceiver 的 Intent Receiver , 而 它 响 应 的 是 miniSMS的短信接收功能。在AndroidManifest.xml中我们看到,我们注册了一个名android.provider.Telephony.SMS_RECEIVED行为。当系统收到一条短信时,会向所有Intent Receiver广播这样一个Intent,SmsReceiver会收到这个Intent并调用SmsReceiver.java代码作出响应。 SmsReceiver作为一个Intent Receiver,所以它是一个BroadcastReceiver的子类。前面对Intent描述中说过,Intent的Extra属性是存放Intent的一些而外信息,如短信内容等。这里我们就需要用到这个属性,同时之前还说过,Extra属性是用bundle对象来存储数据的,这样我们就可以通过一个bundle来获取Intent 的Extra属性中的短信息内容。 public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle =intent.getExtras(); SmsMessage[] msgs=null; 同时我们再建立SmsMessage 对象的msgs数组,用来存放获取的短信息发件人和短信内容等信息,最后我们用一个提示框来显示收到的短信息,这样一个短信的接收程序就完成了。 Object[] pdus=(Object[])bundle.get(\msgs=new SmsMessage[pdus.length]; for(int i=0;i msgs[i]=SmsMessage.createFromPdu((byte[])pdus[i]); str +=\str +=\ str +=msgs[i].getMessageBody().toString(); str +=\ Toast.makeText(context, str, Toast.LENGTH_SHORT).show(); 27 本科毕业论文 Google Android手机嵌入式系统的研究与开发 我们通过Intent Receiver产生了一个短息接收的程序,之前我们也已近做好了 AndroidManifest.xml,设计好了UI,生成了发送短信的程序,下面我们再虚拟机中测试一下。 3.3.6 虚拟机中运行 在Eclipse的run菜单中点击run,这时就会启动Android虚拟机,当虚拟机启动以后,会自动加载miniSMS应用,我们可以看到,启动的这个虚拟机名字叫做android15r1:5554,其中5554是android15r1这个虚拟机监听的端口号。这时我们再到DOS下创建另外一个AVD,名字叫做avd15r11。之后Eclipse的Windows菜单下选择Android SDK and AVD Manager选项。在Virtual Device启动avd15r11,可以看到其名字为avd15r11:5556。当avd15r11启动后,在Eclipse的miniSMS项目中点击选择run,这时候会弹出一个对话框让你选择虚拟机,选择avd15r11,之后,就会在这个虚拟机中部署miniSMS应用了。 我们在avd15r11中的电话号码栏输入5554,内容是“hello,this is 5556”,之后点击发送后,在avd15r1中能看到短信已发送的提示。同时,在android15r1的下方会看到SMS from 5556的提示,后面并显示短信的内容。同时,android15r1中的系统自带的短信功能也会收到这条短信,因为miniSMS和系统自带的短信功能都响应了android.provider.Telephony.SMS_RECEIVED这个Intent,这个事例也很好的说明了之前所说的Intent机制。 图3-5 miniSMS在虚拟机中的测试 28
相关推荐: