Messaging项目说明

Messaging

介绍

一款系统短信应用

项目结构

app:主程序

chips:系统扩展控件

photoviewer:图片预览器

项目说明

数据加载(同步mmssms.db数据)

  1. 同步工作从 BugleApplication 创建时发起;
    依次执行 DataModel.immediateSync –> SyncManager.immediateSync –> SyncMessagesAction.sync 在这里创建 SyncMessagesAction 对象;

  2. 然后将该SyncMessagesAction对象交由 DataModel 的 ActionService 对象来执行任务;

  3. ActionService 通过 ActionServiceImpl 来启动一个 IntentService;

  4. 在 ActionServiceImpl 里执行 SyncMessagesAction 的 executeAction 方法;

  5. 在SyncMessagesAction 的 executeAction 方法中判断如果需要执行同步操作,调用 requestBackgroundWork 方法将自己加入 mBackgroundAction队列;

  6. 执行 Action 的sendBackgroundActions 方法来启动后台任务,这时会传入 DataModel 的 BackgroundWorker 对象;

  7. BackgroundWorker 通过 BackgroundWorkerService 来启动一个 InentService 来执行任务;

  8. 在 BackgroundWorkerService 里调用SyncMessagesAction 的 doBackgroundWork 方法执行后台操作,并将结果用Bundle返回;

  9. 调用 ActionServiceImpl 的 handleResponseFromBackgroundWorker 或 handleFailureFromBackgroundWorker 方法,启动一个 IntentService 来处理成功或失败的响应。
    在 ActionServiceImpl 里执行 SyncMessagesAction 的 processBackgroundWorkResponse 或 processBackgroundWorkFailure 来处理响应。

数据库说明(bugle_db同步mmssms.db的数据)

数据库中数据表:conversations,messages,parts,participants,conversation_participants

视图:draft_parts_view ,coversation_image_parts_view ,conversation_list_view

数据表
数据表 conversation_participants
字段数据类型说明
conversation_idint会话人属于那一场会话
participant_idint会话人id
数据表 conversations
字段数据类型说明
_idint主键ID
sms_thread_idintSMS/MMS Thread ID from the system provider
nameString信息名称
latest_message_idint最新消息id
snippet_textString最新更新的消息的内容(彩信为主题,短信为正文)会话列表中显示的简要消息
subject_textString会话列表中显示的简要消息
preview_uriString预览Uri
preview_content_typeString预览Uri类型
show_draftint是否显示当前草稿
draft_snippet_textString最新的草稿简要
draft_subject_textString最新的草稿主题
draft_preview_uriString草稿预览uri
draft_preview_content_typeString草稿预览uri类型
archive_statusarchive_status会话是否归档
sort_timestampint时间戳用于排序
last_read_timestampint最新阅读短信时间戳
iconString会话Icon
participant_contact_idint参与者联系人ID(如果此对话只有一个参与者)。否则为-1
participant_lookup_keyString参与者查找键(如果此对话只有一个参与者)。否则为空
participant_normalized_destinationString参与者的标准化目的地(如果此对话只有一个参与者)。否则为空。
current_self_idString自身的id?
participant_countint参与者人数不包括自己(因此1:1的比例为1或更大的比例为1:1)
notification_enabledint对话是否启用通知
notification_sound_uriString通知铃声
notification_vibrationint是否启动震动
include_email_addrint会话包含Email?
sms_service_centerString短信中心号码
IS_ENTERPRISEint是否是企业对话
is_topint是否置顶(后期添加字段)
数据表 messages
字段数据类型说明
idint主键
conversation_idint会话id关联conversations中id
sender_idint发送该消息的会话人id
sent_timestampint发送消息时间戳
received_timestampint接收消息时间戳
message_protocolint信息类型:短信息、彩信或彩信通知
message_statusint消息状态
seenint是否被用户在通知中看见0和1
readint是否被用户已阅读0和1
sms_message_uriString来自平台提供程序的消息ID
sms_priorityint信息的优先级
sms_message_sizeint彩信大小
mms_subjectString彩信主题
mms_transaction_idStringMMS通知的事务id
mms_content_locationString彩信通知的内容位置
mms_expiryint过期时间
raw_statusint详细的状态比如那条短信是发送成功还是失败
self_idint代表处理此消息的sim卡的参与者
retry_start_timestampint开始重试的时间。用于计算重试窗口,当重试发送/下载邮件。
collectedint收藏
recycledint回收
数据表 parts
字段数据类型说明
_idINT主键自增
message_idINT附件属于那条消息
conversation_idINT附件属于那次会话
textString附件文字
uriString附件内容uri
content_typeString附件内容类型
widthINT此附件的缓存宽度(用于加载时的布局)
heightINT此附件的缓存高度(用于加载时的布局)
timestampINT同message表中时间戳
数据表 participants
字段数据类型说明
_idINT主键
sub_idINT参与者关联的sim卡的订阅id。在L中引入。对于早期版本,将始终使用默认的-1。对于多sim卡设备(或sim卡已更改的情况)单个设备,可能有几个不同的sub_id值
sim_slot_idINT此自参与者的活动SIM(插入设备中)的插槽。如果自参与者与任何活动SIM不对应,这将是链接android.telephony.SubscriptionManager.对于所有非自参与者,该列将被忽略
normalized_destinationString如果可能,电话号码将以标准E164格式存储。这是一个独特的对于给定参与者,我们不能用同一个电话号码处理多个参与者,因为我们不知道消息来自哪一个。这也可以是电子邮件地址,在这种情况下,它与显示的地址相同
send_destinationString发送短信的号码
display_destinationString添加行时,根据设备的区域设置对电话号码进行用户友好的格式设置
full_nameString全名
first_nameString
profile_photo_uriString头像
contact_idINT联系人id
lookup_keyString包含有关如何在联系人查找中查找联系人信息的提示的字符串
blockedINT是否该用户被拦截
subscription_colorINT订阅的颜色?
subscription_nameString订阅的名字?
contact_destinationString存储在此参与者的联系人中的确切目的地
视图
conversation_list_view

查询对话列表

SELECT conversations._id AS _id,
       conversations.name AS name,
       conversations.current_self_id AS current_self_id,
       conversations.archive_status AS archive_status,
       messages.read AS read,
       conversations.icon AS icon,
       conversations.participant_contact_id AS participant_contact_id,
       conversations.participant_lookup_key AS participant_lookup_key,
       conversations.participant_normalized_destination AS participant_normalized_destination,
       conversations.sort_timestamp AS sort_timestamp,
       conversations.show_draft AS show_draft,
       conversations.draft_snippet_text AS draft_snippet_text,
       conversations.draft_preview_uri AS draft_preview_uri,
       conversations.draft_subject_text AS draft_subject_text,
       conversations.draft_preview_content_type AS draft_preview_content_type,
       conversations.preview_uri AS preview_uri,
       conversations.preview_content_type AS preview_content_type,
       conversations.participant_count AS participant_count,
       conversations.notification_enabled AS notification_enabled,
       conversations.notification_sound_uri AS notification_sound_uri,
       conversations.notification_vibration AS notification_vibration,
       conversations.include_email_addr AS include_email_addr,
       messages.message_status AS message_status,
       messages.raw_status AS raw_status,
       messages._id AS message_id,
       participants.first_name AS snippet_sender_first_name,
       participants.display_destination AS snippet_sender_display_destination,
       conversations.IS_ENTERPRISE AS IS_ENTERPRISE,
       conversations.is_top AS is_top,
       conversations.snippet_text AS snippet_text,
       conversations.subject_text AS subject_text
  FROM conversations
       LEFT JOIN
       messages ON (conversations.latest_message_id = messages._id) 
       LEFT JOIN
       participants ON (messages.sender_id = participants._id) 
 ORDER BY conversations.sort_timestamp DESC;
coversation_image_parts_view

查询图片列表

SELECT messages.conversation_id AS conversation_id,
       parts.uri AS uri,
       participants.full_name AS _display_name,
       parts.uri AS contentUri,
       NULL AS thumbnailUri,
       parts.content_type AS contentType,
       participants.display_destination AS display_destination,
       messages.received_timestamp AS received_timestamp,
       messages.message_status AS message_status
  FROM messages
       LEFT JOIN
       parts ON (messages._id = parts.message_id) 
       LEFT JOIN
       participants ON (messages.sender_id = participants._id) 
 WHERE parts.content_type LIKE image/%
 ORDER BY messages.received_timestamp ASC,
          parts._id ASC;
draft_parts_view

查询草稿附件

SELECT parts._id AS _id,
       parts.message_id AS message_id,
       parts.text AS text,
       parts.uri AS uri,
       parts.content_type AS content_type,
       parts.width AS width,
       parts.height AS height,
       messages.conversation_id AS conversation_id
  FROM messages
       LEFT JOIN
       parts ON (messages._id = parts.message_id) 
 WHERE messages.message_status = 3;

短信发送流程

ComposeMessageView:由mSendButton点击事件进行发起。

InsertNewMessageAction:插入到数据库

SendMessageAction:数据插入成功后调用,执行发送操作

MmsManager:最终调用SmsManager进行发送

短信接收流程

SmsDeliverReceiver:发送短信收到的广播

ReceiveSmsMessageAction:接收短信动作逻辑处理比如插入数据库

BugleNotifications:通知处理,显示通知

数据缓存

其中包含缓存管理(MemoryCacheManager)和媒体资源管理(MediaResourceManager)两部分。
缓存管理使用的是android.util.LRUCache,是最近最少使用(Latest recently used)缓存算法的实现

主要类说明

主页:ConversationListActivity,ConversationListFragment,ConversationListAdapter,ConversationListData

信息列表:ConversationActivity,ConversationFragment,ConversationMessageAdapter,ConversationData

新增对话:ConversationActivity

设置页面:ApplicationSettingsFragment

高级设置:PerSubscriptionSettingsActivity,ContactPickerFragment(选择联系人)

图片预览:BuglePhotoViewActivity

名片预览:VCardDetailActivity,VCardDetailFragment

参与者名单和选项:PeopleAndOptionsActivity,PeopleAndOptionsFragment

附件选择:AttachmentChooserActivity,AttachmentChooserFragment

其他

libframesequence.so(gif图片显示库)编译,依赖于libgiflib.so

giftranscode.so(gif图片转码库)编译,依赖于libgiflib.so

编译命令:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk

编码——>ENCODING_7BIT

  • /** The maximum number of payload septets per message */
    public static final int MAX_USER_DATA_SEPTETS = 160; //单条信息160个字节(ASCII码对应的纯英文字符)
    
    /**
    
    * The maximum number of payload septets per message if a user data header
    * is present. This assumes the header only contains the
    * CONCATENATED_8_BIT_REFERENCE element.
      */
      public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;//对于ASCII码对应的纯英文字符,长短信中每条短信的长度为153字节,7字节标记分页信息等协议
    

对于纯英文,1字符占用1字节 所以相当于第一条160个字符 第二条160-7-7=146个字符(第一条信息的协议信息也占用了第二条的长度)

第三条及以上,160-7=153个字符。

编码——>ENCODING_16BIT (处理包含中文等非ASSICC码字符的短信)

  • /** The maximum number of payload bytes per message */
    public static final int MAX_USER_DATA_BYTES = 140;//单条信息140个字节(包含中文等非ASCII码字符的信息)
    
    
    /**
    
    * The maximum number of payload bytes per message if a user data header
    * is present. This assumes the header only contains the
    * CONCATENATED_8_BIT_REFERENCE element.
      */
      public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;//包含中文等非ASCII码字符的信息,长短信每条最大长度为140-6=134字节,6个字节用于标记分页信息
    

对于包含中文字符的信息,1字符占用2字节,140/2=70, 134/2=67, 6/2=3 所以相当于第一条70个字符 第二条70-3-3=64字符(第一条信息的分页信息也占用了第二条的长度) 第三条及以上70-3=67字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值