Android 之 sms 短信
概述
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
- <receiver android:name=".SmsReceiver">
- <intent-filter>
- "android.provider.Telephony.SMS_RECEIVED" />
- </intent-filter>
- </receiver>
来看下时序图:
1. /**
2. * 接收到短信的处理放在该service中去进行处理
3. */
4. public static void beginStartingService(Context context, Intent intent) {
5. synchronized (mStartingServiceSync) {
6. if (Log.DEBUG) Log.v("SMSReceiverService: beginStartingService()");
7. if (mStartingService == null) {
8. //电源管理,决定是否亮指示灯、键盘、屏幕等
9. PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
10. mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
11. ".SmsReceiverService");
12. false);
13. }
14. mStartingService.acquire();
15. context.startService(intent);
16. }
17. }
在接收到短信的时候,需要有一些提示,比如指示灯点亮、屏幕点亮、键盘点亮等。这个主要通过PowerManager来控制。关于PowerManager,可以参看我之间写的一篇文章:javascript:void(0)
ServiceHandler的handleMessage方法中处理消息,判断消息的类型是mms、sms,在handleSmsReceived中处理接收到的sms短信
1. /**
2. * 处理接收到的短信息
3. */
4. private void handleSmsReceived(Intent intent) {
5. Bundle bundle = intent.getExtras();
6. if (bundle != null) {
7. //获得消息
8. SmsMessage[] messages = SmsPopupUtils.getMessagesFromIntent(intent);
9. if (messages != null) {
10. new SmsMmsMessage(context, messages,System.currentTimeMillis()));
11. }
12. }
13. }
下面方法中主要是从pdu中获取信息,关于pdu的详细信息可以参考:http://wenku.baidu.com/view/d0d0093e0912a216147929b1.html
1. /**
2. * 从包装了SMS_RECEIVED_ACTION的intent中获取pdu信息
3. */
4. public static final SmsMessage[] getMessagesFromIntent(Intent intent) {
5. "pdus");
6. if (messages == null) {
7. return null;
8. }
9. if (messages.length == 0) {
10. return null;
11. }
12. byte[][] pduObjs = new byte[messages.length][];
13. for (int i = 0; i < messages.length; i++) {
14. byte[]) messages[i];
15. }
16. byte[][] pdus = new byte[pduObjs.length][];
17. int pduCount = pdus.length;
18. new SmsMessage[pduCount];
19. for (int i = 0; i < pduCount; i++) {
20. pdus[i] = pduObjs[i];
21. msgs[i] = SmsMessage.createFromPdu(pdus[i]);
22. }
23. return msgs;
24. }
最终获取到短信息后决定该怎么去进行展示,在smspopup中,是通过弹窗的形式,把短信息显示在activity中
1. /**
2. * 获取短信息并加入到view上
3. */
4. private void setupMessages(Bundle b, boolean newIntent) {
5. // Store bundle
6. bundle = b;
7. // 从bundle中获取短消息
8. new SmsMmsMessage(getApplicationContext(), bundle);
9. mSmsPopups.addMessage(message);
10. if (!newIntent) {
11. // TODO: move off UI thread
12. mSmsPopups.addMessages(
13. this, message.getMessageId()));
14. }
15. mSmsPopups.refreshPrivacy();
16. }
短信发送
1. /**
2. * 回复短信息
3. *
4. */
5. public boolean replyToMessage(StringquickReply) {
6. //首先要标记短信为已读
7. setMessageRead();
8. // 发送新的短信息
9. SmsMessageSender sender =
10. new SmsMessageSender(context, newString[] {fromAddress}, quickReply, getThreadId());
11. return sender.sendMessage();
12. }
13. /**
14. * 发送短信息入口
15. * @return
16. */
17. @SuppressWarnings("deprecation")
18. public boolean sendMessage() {
19. if (!(mThreadId > 0)) {
20. return false;
21. }
22. //如果消息文本为空,那就不发消息了
23. if ((mMessageText == null) ||(mNumberOfDests == 0)) {
24. return false;
25. }
26. //获得短信管理器
27. SmsManager smsManager =SmsManager.getDefault();
28. for (int i = 0; i < mNumberOfDests; i++){
29. //按照短信息允许的最大字数来拆分短信
30. ArrayList<String> messages =smsManager.divideMessage(mMessageText);
31. int messageCount = messages.size();
32. new ArrayList<PendingIntent>(messageCount);
33. new ArrayList<PendingIntent>(messageCount);
34. // 140个字节,70字符。
35. if (splitMessage) {
36. for (int j = 0; j < messageCount;j++) {
37. null;
38. try
39. //把短信息加入到provider中
40. uri =addMessage(mContext.getContentResolver(), mDests[i], messages.get(j),
41. null, mTimestamp,requestDeliveryReport, mThreadId);
42. catch (SQLiteException e) {
43. // TODO: show error here
44. //SqliteWrapper.checkSQLiteException(mContext, e);
45. }
46. null;
47. if (requestDeliveryReport) {
48. deliveryReportIntent =
49. 0,
50. newIntent(MESSAGING_STATUS_RECEIVED_ACTION, uri)
51. 0);
52. }
53. PendingIntent sentIntent =
54. 0,
55. newIntent(SmsReceiverService.MESSAGE_SENT_ACTION, uri)
56. class), 0);
57. smsManager.sendTextMessage(
58. mDests[i], mServiceCenter,messages.get(j), sentIntent, deliveryReportIntent);
59. }
60. }
61. return false;
62. }
总结
1. sms短信主要涉及到短信的发送、接收、提示,以及短信的本地保存等,涉及到的点相对还是比较多的。了解下还是很有必要的。