Android(安卓)之 sms 短信
Android 之 sms 短信
分类:Android 2011-09-05 10:14 482人阅读 评论(0) 收藏 举报概述
SMS(Short Messaging Service), 即我们经常使用的短信服务。它是一种存储和转发服务。也就是说,短消息并不是直接从发送人发送到接收人,而始终通过 SMS 中心进行转发的。如果接收人处于未连接状态(可能电话已关闭),则消息将在接收人再次连接时发送。
短信长度一般为140个字节,70个字符。既然我们经常使用短信,那么今天我们就来分析一下短信的实现。
说明:本文主要根据android应用层的sms代码来进行分析的,并结合了SMSpopup.有不到位的地方欢迎指正并补充
短信结构
_id//短消息序号
thread_id//对话的序号
address//收件人
person//
date//日期
protocol//协议
read//是否阅读
status//状态
type//类型 (收发)
reply_path_present//
subject//主题
body//短消息内容
service_center//服务中心
相关类图
上面几个类是涉及到sms的部分类的类图,其中涉及到键盘锁定状态、指示灯提示、通话状态等的判断,从而决定短信来的时候该怎么样去处理和提示。
短信接收
先来看看短信的接收,在android中,短信的接收需要在manifest.xml中配置广播接收器,如下:
[java] view plain copy
- <receiverandroid:name=".SmsReceiver">
- <intent-filter>
- <actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
- </intent-filter>
- </receiver>
- /**
- *接收到短信的处理放在该service中去进行处理
- */
- publicstaticvoidbeginStartingService(Contextcontext,Intentintent){
- synchronized(mStartingServiceSync){
- if(Log.DEBUG)Log.v("SMSReceiverService:beginStartingService()");
- if(mStartingService==null){
- //电源管理,决定是否亮指示灯、键盘、屏幕等
- PowerManagerpm=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mStartingService=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- Log.LOGTAG+".SmsReceiverService");
- mStartingService.setReferenceCounted(false);
- }
- mStartingService.acquire();
- context.startService(intent);
- }
- }
- /**
- *处理接收到的短信息
- */
- privatevoidhandleSmsReceived(Intentintent){
- Bundlebundle=intent.getExtras();
- if(bundle!=null){
- //获得消息
- SmsMessage[]messages=SmsPopupUtils.getMessagesFromIntent(intent);
- if(messages!=null){
- notifyMessageReceived(newSmsMmsMessage(context,messages,System.currentTimeMillis()));
- }
- }
- }
- /**
- *从包装了SMS_RECEIVED_ACTION的intent中获取pdu信息
- */
- publicstaticfinalSmsMessage[]getMessagesFromIntent(Intentintent){
- Object[]messages=(Object[])intent.getSerializableExtra("pdus");
- if(messages==null){
- returnnull;
- }
- if(messages.length==0){
- returnnull;
- }
- byte[][]pduObjs=newbyte[messages.length][];
- for(inti=0;i<messages.length;i++){
- pduObjs[i]=(byte[])messages[i];
- }
- byte[][]pdus=newbyte[pduObjs.length][];
- intpduCount=pdus.length;
- SmsMessage[]msgs=newSmsMessage[pduCount];
- for(inti=0;i<pduCount;i++){
- pdus[i]=pduObjs[i];
- msgs[i]=SmsMessage.createFromPdu(pdus[i]);
- }
- returnmsgs;
- }
- /**
- *获取短信息并加入到view上
- */
- privatevoidsetupMessages(Bundleb,booleannewIntent){
- //Storebundle
- bundle=b;
- //从bundle中获取短消息
- SmsMmsMessagemessage=newSmsMmsMessage(getApplicationContext(),bundle);
- mSmsPopups.addMessage(message);
- if(!newIntent){
- //TODO:moveoffUIthread
- mSmsPopups.addMessages(
- SmsPopupUtils.getUnreadMessages(this,message.getMessageId()));
- }
- mSmsPopups.refreshPrivacy();
- }
来看下时序图:
[java] view plain copy在接收到短信的时候,需要有一些提示,比如指示灯点亮、屏幕点亮、键盘点亮等。这个主要通过PowerManager来控制。关于PowerManager,可以参看我之间写的一篇文章:http://blog.csdn.net/xieqibao/article/details/6562256
ServiceHandler的handleMessage方法中处理消息,判断消息的类型是mms、sms,在handleSmsReceived中处理接收到的sms短信
[java] view plain copy下面方法中主要是从pdu中获取信息,关于pdu的详细信息可以参考:http://wenku.baidu.com/view/d0d0093e0912a216147929b1.html
[java] view plain copy最终获取到短信息后决定该怎么去进行展示,在smspopup中,是通过弹窗的形式,把短信息显示在activity中
[java] view plain copy短信发送
- /**
- *回复短信息
- *
- */
- publicbooleanreplyToMessage(StringquickReply){
- //首先要标记短信为已读
- setMessageRead();
- //发送新的短信息
- SmsMessageSendersender=
- newSmsMessageSender(context,newString[]{fromAddress},quickReply,getThreadId());
- returnsender.sendMessage();
- }
- /**
- *发送短信息入口
- *@return
- */
- @SuppressWarnings("deprecation")
- publicbooleansendMessage(){
- if(!(mThreadId>0)){
- returnfalse;
- }
- //如果消息文本为空,那就不发消息了
- if((mMessageText==null)||(mNumberOfDests==0)){
- returnfalse;
- }
- //获得短信管理器
- SmsManagersmsManager=SmsManager.getDefault();
- for(inti=0;i<mNumberOfDests;i++){
- //按照短信息允许的最大字数来拆分短信
- ArrayList<String>messages=smsManager.divideMessage(mMessageText);
- intmessageCount=messages.size();
- ArrayList<PendingIntent>deliveryIntents=newArrayList<PendingIntent>(messageCount);
- ArrayList<PendingIntent>sentIntents=newArrayList<PendingIntent>(messageCount);
- //140个字节,70字符。
- if(splitMessage){
- for(intj=0;j<messageCount;j++){
- Uriuri=null;
- try
- //把短信息加入到provider中
- uri=addMessage(mContext.getContentResolver(),mDests[i],messages.get(j),
- null,mTimestamp,requestDeliveryReport,mThreadId);
- }catch(SQLiteExceptione){
- //TODO:showerrorhere
- //SqliteWrapper.checkSQLiteException(mContext,e);
- }
- PendingIntentdeliveryReportIntent=null;
- if(requestDeliveryReport){
- deliveryReportIntent=
- PendingIntent.getBroadcast(mContext,0,
- newIntent(MESSAGING_STATUS_RECEIVED_ACTION,uri)
- .setClassName(MESSAGING_PACKAGE_NAME,MESSAGING_STATUS_CLASS_NAME),0);
- }
- PendingIntentsentIntent=
- PendingIntent.getBroadcast(mContext,0,
- newIntent(SmsReceiverService.MESSAGE_SENT_ACTION,uri)
- .setClass(mContext,SmsReceiver.class),0);
- smsManager.sendTextMessage(
- mDests[i],mServiceCenter,messages.get(j),sentIntent,deliveryReportIntent);
- }
- }
- returnfalse;
- }
总结
1. sms短信主要涉及到短信的发送、接收、提示,以及短信的本地保存等,涉及到的点相对还是比较多的。了解下还是很有必要的。
http://blog.csdn.net/xieqibao/article/details/6748716
更多相关文章
- android中的进程与线程的理解
- (转)Android(安卓)Contacts(二)—— SMS 短信 与 Contacts 联系人
- android多线程机制
- android消息处理——Thread、Looper、Handler
- Android(安卓)Handler之从主线程往子线程发消息(一)
- Android(安卓)的Handler、Looper和MessageQueue的关系和实现原理
- Android异步2:深入详解 Handler+Looper+MessageQueue
- Android(安卓)Handler机制详解
- EventBus粘性事件