- 浏览: 173235 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
zhongyue1q:
您好,我想继续开发DBExplorer系统,您说说一下您的QQ ...
推荐一款使用Extjs做GUI的数据库浏览工具--DBExplorer -
huangyabin001:
你好现在遇到一个问题,我现在的工作是修改系统bug,现在有个b ...
Android2.1消息应用(Messaging)源码学习笔记之二 -
sunjunliangsunjun:
Android2.1消息应用(Messaging)源码学习笔记之二 -
java-admin:
1:bitbucket
免费支持private repo,最多 ...
Code host选择 -
jialeadmin:
期待下文字数补足
[翻译]Groovy入门指南——01初学者教程
Android2.1消息应用(Messaging)源码学习笔记之二
在上一篇学习笔记中,我从整理构成应用的主要组件开始,学习了相关的源代码,基本了解了Activity、Service、Rec eiver等组件的主要 职责和任务,接下来我将对重点功能的实现方法进行深入学习,了解它们的实现逻辑、涉及哪些API调用,以及是否与相关协议符合等各个方面的情况。
新消息呼入时系统的 响应过程及方法
Messaging应用对新消息呼入事件的 响应, 有3个配置选项可以由用户自己做出选择:
A.铃声 :用户可以选择已有 铃声/或者静音作为新消息呼入的提醒 ;
该选项的配置是在MessagingPreferenceActivity.RingtonePreference中完成的,它通过ringtoneType属性将系统中的可用声音分为:①铃声(ringtone)、②通知(notification)、③警报(alarm)3种类型,指定类型后最终会通过RingtoneManager. ACTION_RINGTONE_PICKER选取到具体的
声音资源。
用户指定铃声被播放的关键在MessagingNotification工具类中,当有新消息时它的updateNewMessageIndicator()方法会被调用,该方法对
Notification.
sound属性做了设置,使得铃音
的
最终得以
播放。当然在该方法中还包括了对状态栏图标、震动效果的处理逻辑。
而铃音被“适时
”播放的关键是:MM会在TransactionService的update方法(你是否还记得那个观察者模式,该方法是具体业务完成后的回调
)中针对NOTIFICATION_TRANSACTION和RETRIEVE_TRANSACTION两种业务调用
MessagingNotification
工具类
,而SMS则是在SmsReceiverService的handleSmsReceived()方法中进行调用。
B.震动 :开启后有新消息呼入时会震动提醒。 响应过程 和铃声的 响应 机制完全一样,重点都在 MessagingNotification的 updateNewMessageIndicator()方法中 ;
C.状态栏通知 :用户可以决定是否在状态栏上显示一个代表新消息的小图标, 响应过程 和铃声的 响应 机制基本一样 ,但它的触发不止是在信息呼入时,还会在信息发送失败、设备重新启动等情况下被调用,当然不同情况在状态栏会有不同的icon。
Messaging应用初始化以及简单的Cache系统
Messaging应用定义了自己的Application对象,详见 AndroidManifest.xml中的<application android:name="MmsApp" ,其中MmsApp就是com.android.mms.MmsApp类,在该类中分别处理了创建-onCreate、终止-onTerminate、配置改变-onConfigurationChanged 三个生命周期回调方法,其中在onCreate方法进行了重要的系统初始化工作:
public void onCreate() { super.onCreate(); PreferenceManager.setDefaultValues(this, R.xml.preferences, false); MmsConfig.init(this);//读取系统配置参数 ContactInfoCache.init(this);//启动联系人信息缓存系统 Contact.init(this);//初始化联系人工具类 DraftCache.init(this);//初始化草稿缓存系统 Conversation.init(this);//初始化会话对象访问工具 DownloadManager.init(this);//初始化下载管理器 RateController.init(this);//初始化进度控制器 DrmUtils.cleanupStorage(this);//Drm本地数据清理 LayoutManager.init(this);//初始化部件管理器 SmileyParser.init(this);//初始化SMIL解析器 }
其中除了全局工具类MmsConfig、LayoutManager、SmileyParser等对象的初始化之外,其余部分都是Cache系统的启动,本节将初步分析这些Cache系统的功能作用以及实现方法:
- ContactInfoCache联系人信息缓存 :init方法其实是呼叫私有构建器,创建了该类的全局单实例对象。该类的职责是缓存联系人数据表中的查询结果,并提供相关方法访问联系人的常用信息,例如:显示名称等。该类中的getContactInfo()方法是非常有用的方法,你可以以给点的电话号码或E-mail地址作为参数查询联系人的常用信息,并且查询结果是被缓存下来的。与该类配合使用的还有Contact类,它同样内置了缓存系统,还有代表多个联系人的联系人列表对象ContactList,它也提供了很多方便使用的方法,用于组织联系人的基本信息,以及调用RecipientIdCache类的初始化方法,进一步向Cache系统丰富联系人的详细信息。
- DraftCache草稿信息缓存 :init方法将触发构建器的调用,然后调用rebuildCache()方法,这会查询数据库,将其中所有草稿信息的会话ID全部缓存起来,供外部程序使用。
其它执行初始化的全局工具类,我会在后面相关环节谈及 。
会话Conversation的概念及其实现方法
会话Conversation是一种新的信息组织形式,不同于“ 传统 功能 ”以发件箱\收件箱\草稿箱,等 文件夹的 方式来 组织信息,会话会把上下文相关的“往<--->来”信息组织在一起,以方便用户查看管理。所谓上下文相关是指:若某条信息是对另一条信息的‘回复 ’,则认为它们是 上下文相关的。
Messaging应用的首页就是会话列表页面——ConversationList,它列出了用户所有往来 信息,及其未发出的草稿信息,这些内容都来自于ConversationListAdapter适配器。
与会话列表相关的查询操作封装在com.android.mms.data.Conversation类中,它是查询会话信息的接口,并在必要时创建新会话(一个全新信息还未有对应的上下文信息时 )。该类在应用启动的第一时刻就已经用一个后台线程 开始 加载会话列表了(加载到Cache中):
MmsApp.onCreate()方法调用了 Conversation.init()方法,而该初始化方法是实现如下:
public static void init(final Context context) { new Thread(new Runnable() { public void run() { cacheAllThreads(context); } }).start(); }
cacheAllThreads()方法是关键,它将从content://mms-sms/conversations/位置查询数据,并在查询过程中标示了正在loading的状态——mLoadingThreads=true,它将查询出来的数据构建成Conversation对象放入Cache(或更新已存在于Cache中的对象),最后清理掉在Cache中存在,而未存在于查询结果中存在的 Conversation对象 (即清理无效的会话数据)。
然而令我奇怪的是,listView中显示的数据并非来自Cache中,而始于异步查询工具 AsyncQueryHandler的子类 ThreadListQueryHandler 它以异步方式查询并得到会话列表,该查询开始于对 Conversation. startAsyncQuery()方法的调用。查询完成后, 在 mQueryHandler中 回 调了mListAdapter.changeCursor(cursor) ,而此时才真正为 Adapter注入了有效的 Cursor对象 。
草稿信息也会在会话列表中出现,因为在 保存 草稿信息时 , WorkingMessage .saveDraft()会最终呼叫到 Conversation. ensureThreadId方法,它会保证在数据表 (mmssms.db中的threads表) 中创建对应的会话记录,使其正确的显示在会话列表页面。
接收者编辑器RecipientsEditor的实现方法
一条信息可以发送给1到多个 目标 用户——它们被称为“接收者 ” ,以电话号码、E-Mail地址等形式存在。 “接收者 ” 通常是从“联系人应用”中选择或由用户直接输入。
在Messaging应用中,用于输入
接收
者的控件有独立实现——RecipientsEditor,它继承自MultiAutoCompleteTextView,
我们知道
AutoCompleteTextView组件提供了输入时推荐可选项的功能,而
Multi...则意为着可输入多个项目(各项目间以逗号分隔),并分别推荐可选项。
推荐选项的数据源
来自RecipientsAdapter
适配器
,它从ContactsProvider中读取MOBILE,WORK_MOBILE,MMS
三种类型
的电话号码作为推荐选项,在用户输入时自动匹配并推荐
。
说起接收者我们就不得不讨论Contact(代表接收者)、ContactList(代表接收者列表) 两个重要的类,他们提供了常用的组织联系人基本信息的方法,非常易于使用,同时它们也涉及到 Cache缓存系统 。
SMS <--->MMS 自动转换机制
在Messaging应用中, 编写普通短信SMS和编写彩信MMS的功能是整合在一起的,程序通过特定条件在两种 消息 类型之间 自动 转换,转换机制的入口时ComposeMessageActivity.toastConvertInfo()方法。初始创建的信息是SMS类型,当 出现 以下操作\ 或者条件成立时,会自动将消息从SMS转化为MMS:
- setSubject:为消息设置主题 ,通过为Subject编辑框mSubjectTextEditor设置addTextChangedListener而获得回调 ;
- setAttachment:为消息添加附件 (如:图片\视频) ,通过选项菜单MENU_ADD_ATTACHMENT实现,由showAddAttachmentDialog弹出附件类型列表,并通过addAttachment方法予以响应处理(打开新Activity——SubActivity),然后通过onActivityResult回调方法 最终执行到 WorkingMessage.setAttachment 方法;
- addressContainsEmail :接收地址中包含E-Mail地址 ,接收者输入框(mRecipientsEditor)有TextChangedListener——mRecipientsWatcher,它在接收者文本内容发生改变时调用mWorkingMessage.setHasEmail()方法以触发消息类型的自动转换机制;
- LengthRequires:消息内容的长度超过SMS标准容量 ,用于输入消息文本内容的控件时EditText类型的mTextEditor,它有一个 TextChangedListener——mTextEditorWatcher,当消息文本内容被输入时会调用到updateCounter()方法,该方法计算了消息长度,并在符合条件时调用 mWorkingMessage.setLengthRequiresMms()方法来改变消息类型;
精确捕获具体操作以及条件状态发生变化的关键是——WorkingMessage类,该类代表了正在创建中的消息对象(我们知道 ComposeMessageActivity 类描绘了创建信息的UI,UI之后的数据对象便是WorkingMessage) 它记录着因UI操作而引起的各种状态变化,并将所有变化最终都通过 WorkingMessage.update()方法来予以执行实施。
另外一些状态变化被定义在WorkingMessage.MessageStatusListener接口中 (注意:当前ComposeMessageActivity是该接口的唯一实现者 )包括消息类型发生改变时的回调,以及 WorkingMessage对象生命周期阶段的回调 :
- onProtocolChanged:消息类型发生改变——即在SMS <----> MMS之间发生变化,该方法在ComposeMessageActivity中的实现是调用了toastConvertInfo(),它显示了Toast提示,通知用户消息类型发生了改变;
- onAttachmentChanged:附件发生变化 (反映在 WorkingMessage.setAttachment方法 ) ——即在编辑MMS过程中添加/删除(在mAttachmentEditorHandler处理句柄中) 附件内容时回调;
- onPreMessageSent: 消息 发送前,通过runOnUiThread方法在UI线程中调用了resetMessage(),这似乎是个现场清理逻辑,TODO:留待以后仔细学习吧。
- onMessageSent: 消息 发送前,这并不代表消息发生成功,仅仅是指将消息投递的工作交给了底层网络而已。在 ComposeMessageActivity 中的实现会重新调用startMsgListQuery()方法,获得当前会话下的消息列表;
-
onMaxPendingMessagesReached:当发送队列满载时该方法被回调,在现有的实现中会将当前消息保存为草稿,并给用户一个恰当的提示;
以上就是消息类型的自动转换机制,以及消息状态变化监听器,这样的设计使得我们能够以更简单的方式添加针对 WorkingMessage 的新功能。
彩信MMS构成元素的类型以及编码格式
在3GPP的《MMS Media formats and codecs》规范中,详细定义了构成彩信的基本元素类型及其编码格式,其中包括:文本(Text)、语音(Speech)、声音(Audio)、合成声音(Synthetic audio)、静态图片(Still Image)、Bitmap图片(Bitmap graphics)、视频(Video)、矢量图(Vector graphics),
Messaging应用中,对以上各种元素及格式提供了广泛的支持,其中3个大类:图片、视频、音频 ,每种都可以选择现有文件或即时拍摄录制,对文件格式的支持详见下表:
项目 | Messaging | 协议 | 备注 |
文本 | text/plain | text/plain, 无格式文本,可UTF-8,ISO-8859-1 | |
图片 | image/jpeg | 静态图片,jpeg,jfif | |
image/jpg | |||
image/gif | |||
image/png | Bitmap点阵图,GIF87a,GIF89a,PNG | ||
image/vnd.wap.wbmp | |||
视频 | video/3gpp | ||
video/3gpp2 | |||
video/h263 | H.264(AVC),H.263 Profile 3 Level | ||
video/mp4 | MPEG-4 | ||
音频 | audio/aac | ||
audio/amr | Speech:AMR,Enhanced aacPlus,Extended AMR-WB | ||
audio/imelody | |||
audio/mid | Synthetic audio:MIDI | ||
audio/midi | |||
audio/mp3 | |||
audio/mpeg3 | |||
audio/mpeg | |||
audio/mpg | |||
audio/mp4 | |||
audio/x-mid | |||
audio/x-midi | |||
audio/x-mp3 | |||
audio/x-mpeg3 | |||
audio/x-mpeg | |||
audio/x-mpg | |||
audio/3gpp | |||
application/ogg | |||
|
从协议看并没有非常明确的支持要求,而Messaging应用对MMS构成元素的支持却相当广泛。
SMS业务实现机制分析
SMS业务包括:短信呼入、短信发出、SMS投递报告, 以及 本地存储等几个方面,以下我们将对应源代码,全面剖析各个业务的处理过程和实现方法:
- 呼入 :有短信呼入时系统会发出android.provider.Telephony.SMS_RECEIVED广播,这最会调用到PrivilegedSmsReceiver的onReceiveWithPrivilege方法,在该方法内启动了处理呼入业务的SmsReceiverService类,该类持有一个后台工作线程并在ServiceHandler处理句柄中调用handleSmsReceived()方法来处理SMS呼入事件,具体代码如下:
private void handleSmsReceived(Intent intent) { SmsMessage[] msgs = Intents.getMessagesFromIntent(intent); Uri messageUri = insertMessage(this, msgs); //省略...... if (messageUri != null) { MessagingNotification.updateNewMessageIndicator(this, true); } }
可以看出基本流程是:从intent中读取消息数据,调用insertMessage进行本地存储,然后再调用MessagingNotification的updateNewMessageIndicator()方法来通知用户。
仔细探究insertMessage()方法的实现,会发现它并非名副其实,它首先处理class zero类型的短信——直接显示,然后再判断是否 "replace short message" 若是则进行替换更新(update),否则才执行真正的insert将数据存储到数据库中。
- 发出 :发送消息的触发点在“消息创建页面”的mSendButton按钮和选项菜单MENU_SEND上,它们调用了isPreparedForSending, confirmSendMessageIfNeeded两个方法,前者为发送前进行预检查,后者在条件成立的情况下发送消息。首先看预检查的基本逻辑:
private boolean isPreparedForSending() { int recipientCount = recipientCount(); return recipientCount > 0 && recipientCount <= MmsConfig.getRecipientLimit() && (mWorkingMessage.hasAttachment() || mWorkingMessage.hasText()); }
逻辑 很简单,首先要有接收者并且接收者的个数不能超过限制,然后是必须要有文本内容或者必须要有附件内容(针对彩信而言)。
接下来是 confirmSendMessageIfNeeded方法了:它首先检查了“接收者输入框mRecipientsEditor是否可见 ”(当‘回复’信息时不可见,因为已有潜在接收者) ,不可见则直接调用sendMessage方法,否则会调用 mRecipientsEditor的相关方法验证接收者的有效性 :首先会检查是否有无效的接收者地址,如果有再检查是否所有接收者都是无效的,如果全是无效的则告知用户不能发送,否则弹出提示框——允许用户选择忽略无效地址,而向其它有效的接收者地址发送,这些检查都通过后,就来到了重要的 sendMessage方法,sendMessage方法 首先检查当前系统是否是在紧急呼叫模式(emergency callback mode ) ,如果是则显示提示界面并终止发送。否则直接调用WorkingMessage.send方法进行发送。
WorkingMessage.send方法首先调用prepareForSave()进行预处理——确认接收者列表、处理彩信相关的:syncTextToSlideshow、removeSubjectIfEmpty等等问题;然后取得所属会话对象mConversation,取得信息文本内容、再判断是否是SMS类型,若是 则直接在一个新线程运行sendSmsWorker()方法,紧接着就是调用接收者缓存系统的相关更新方法——RecipientIdCache.updateNumbers()。
sendSmsWorker是发送SMS类型短信的核心方法,它在开始和结束分别调用了消息发送前-onPreMessageSent和消息发送后-onMessageSent两个生命周期方法。它直接取得会话id、目标地址,然后将实际发送任务交给业务实体类SmsMessageSender。
SmsMessageSender类是负责发送SMS信息的关键业务类,它首先在构建器中取得消息文本、目标地址、时间戳、服务中心号码等重要信息,然后在sendMessage方法中执行实际的发送操作:核心工具类依然是SmsManager.getDefault(),然后由divideMessage方法将消息文本分割成若干符合规范长度的片段,再取得投递报告的设置状态,然后通过工具类将消息写入Sms.Outbox(短消息发件箱)位置,最后是针对每个目标接收者调用sendMultipartTextMessage方法完成消息发送,而对于消息发送结果进行响应的关键在sentIntent列表中,请看如下的关键代码:
sentIntents.add(PendingIntent.getBroadcast(mContext, 0, new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,uri,mContext,SmsReceiver.class), 0));
消息发送完成后会发出Intent.action=SmsReceiverService.MESSAGE_SENT_ACTION 的广播信息,并强制接收者为SmsReceiver,而该接收者最终会委托给SmsReceiverService类的handleSmsSent方法进行处理。
- 投递报告 :发送消息方法的sendMultipartTextMessage专门有一个系统广播的参数用于 报告 投递情况的状态,关键代码如下:
deliveryIntents.add(PendingIntent.getBroadcast(mContext, 0, new Intent(MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION, uri, mContext, MessageStatusReceiver.class) ,0));
关键在于Intent.action= MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION 的广播信息,并且显式指定了处理该广播的目标类MessageStatusReceiver,该类首先取得回应广播(Intent)中的PDU,然后更新了数据库中的消息状态 。
- 本地存储 :将SMS数据 存储到本地数据库中的几个关键在SmsReceiverService类的storeMessage、replaceMessage方法中,下面我们就来详细分析这两个方法的实现: …………待续 …………待续 …… : …………待续 …… 。。。
MMS业务实现机制分析
彩信收发时网络连接的创建过程
在Android系统所在的移动设备上,可以存在多个潜在的网络连接通道,例如:GPRS、Wi-Fi、UMTS等 等 。对于移动数据网络GPRS而言还有APN的概念。APN(Access Point Name) 中文称为 “接入点”,它是手机建立无线数据网络连接的必要参数,事实上它就像我们所熟知的代理服务器 一样 ,作为终端访问网络的 入口 代理而存在 。以中国移动的GPRS为例,常用的APN有两种:CMWAP、CMNET。一般情况下各个APN都可能成功发起网络连接,但根据移动网络的运营情况,不同的数据业务在不同的接入点上可能有不同的计费方式。
Android系统中建立网络连接的方法是调用ConnectivityManager工具类的 startUsingNetworkFeature()方法,方法执行结果——即连接是否成功建立的状态值,由命名为 ConnectivityManager.CONNECTIVITY_ACTION常量的Intent广播消息来通知。
在Messaging应用中,用于建立( 收发彩信的 )网络连接的代码在TransactionService服务类的beginMmsConnectivity()方法中:
// Phone.FEATURE_ENABLE_MMS is String "enableMMS" ConnectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
而用于监听网络连接是否建立成功 的 监听器,分别在 TransactionService.onCreate() 和TransactionService.onDestroy()方法中 进行注册与解除 :
//注册监听器 in TransactionService.onCreate() mConnectivityListener = new NetworkConnectivityListener(); mConnectivityListener.registerHandler(mServiceHandler, EVENT_DATA_STATE_CHANGED); mConnectivityListener.startListening(this);
//解除注册监听器 in TransactionService.onDestroy() mConnectivityListener.unregisterHandler(mServiceHandler); mConnectivityListener.stopListening(); mConnectivityListener = null;
在当前的SDK中,NetworkConnectivityListener类被@hide了, 无法直接访问,阅读其源代码可以知道它创建了一个内置的、用于接收特定广播消息的ConnectivityBroadcastReceiver类,并将网 络连接的创建结果封装到NetworkInfo、Reason等属性中,并且它 以向mServiceHandler发送特定Message来达到对业务方法的回调效果 。
原
来在阅读TransactionService类的注释时了解到,MM可以透过mobile data network 和 wi-fi
network两种方式来收发。但阅读具体源码后发现并不是这样,收发彩信的网络连接只能是
ConnectivityManager.TYPE_MOBILE类型。
网络连接建立广播最终会转化为mServiceHandler收到的TransactionService.EVENT_DATA_STATE_CHANGED消息, mServiceHandler首先验证连接有效性,再通过sendMessageDelayed()方法建立时间间隔为30秒的计时器,轮询调用 beginMmsConnectivity()方法,以保持连接的持续存在。TransactionService把所有信息收发业务置于“任务队列(mProcessing & mPending)”中,并依次进行处理,因此在所有任务处理完成之前保持连接的持续存在是很重要的。
…………;。。
MMS信息本地存储机制分析
:…………;。。
………;。。
………未完成.....
评论
发表评论
-
[转]Android设备的屏幕尺寸规格
2011-06-25 14:15 1574[转]Android设备的屏幕尺寸规格 原文: ... -
[转]Android Make脚本简记
2011-06-25 14:11 5302[转]Android Make脚本简记 原文地址: ... -
Android中SQLite操作示例
2011-06-22 10:40 3100Android中SQLite操作示例 在Andro ... -
Mms应用彩信接收过程分析
2011-06-15 16:45 0Mms应用彩信接收过程分 ... -
[转] build/envsetup.sh 脚本简记
2011-05-30 11:14 2646本文转自:http://blogold.c ... -
在Eclipse+ADT中开发Android系统的内置应用
2011-05-19 16:19 2091在Eclipse+ADT中开发Android系统的内置应用 ... -
探究Android中浏览器UA的生成策略
2011-05-05 14:43 3249探究Android中浏览器UA的生成策略 Andr ... -
Android中Adapter、AdapterView的分析及使用
2011-04-27 11:50 0Android中Adapter、AdapterView的分析及 ... -
Android应用APK签名初探
2011-03-08 11:37 0Android应用APK签名初探 需要澄清的概念: ... -
查看栈信息中 .so文件里地址对应的方法名称
2011-02-21 14:54 2745在Android开发中,涉及到JNI时,有时会报告非常底层栈信 ... -
Android源码版本中的tag与分支
2011-08-21 19:12 2966Android源码版本中的tag与分支 ... -
Android的大屏幕
2010-12-17 13:21 0Android的大屏幕 1、需要在AndroidMan ... -
【转】[译]ANDROID Porting系列
2011-08-21 19:11 1430[译]ANDROID Porting系列 一、A ... -
Android中JNI编程的那些事儿
2010-11-26 11:32 8062Android中JNI编程的那些事儿 首先说明,A ... -
Android声音管理方法
2011-08-21 19:10 1945Android声音管理方法 手机都有声音模式,声音 ... -
详解Android中的屏幕方向
2010-10-11 16:59 16774详解Android中的屏幕方向 屏幕方向 是对A ... -
让Android设备助你进行视频聊天
2010-10-10 14:49 0开源Android视频聊天软件 http://sourcef ... -
再说Android中实现全屏的方法
2010-10-09 17:01 1366Android中实现全屏的方法 实现全屏的方法在网 ... -
【转】Andriod 源码开发,打包so到apk
2011-08-21 18:56 2285命令方式将so文件 打包 ... -
【转】在Android平台实现手机关机的功能
2010-08-27 09:07 0从拥有O1的那天起,就盼望有自动开关机的功能,然而Androi ...
相关推荐
Android2.1消息应用(Messaging)源码学习笔记.pdf
spring-messaging源码,可以直接导入Eclipse工程里面!
Android Cloud to Device Messaging Framework
Android Instant Messaging Application VIL - Very Important Link's V-City Demo-App PlayStore Installation-Tutorial Features User registration User authentication Adding a new friend by username ...
Odoo Mobile Messaging Client v2.0 Odoo Mobile Client is Enterprise Social Client based on Android, enables you to access your Odoo Wall Messages from inbox and groups, encourage you to updated with ...
Android 自动消息演示 这是一个简单的演示应用程序,用于演示 Android Auto Messaging API 的用法。
使用http request和socket实现的Android即时通讯应用 原始源码:https://code.google.com/p/simple-android-instant-messaging-application/ 最新源码:https://github.com/Pirngruber/AndroidIM
Appium_Android_MessagingApp Android Messaging应用程序的自动化IntelliJ先决条件确保Appilum本地服务器在(或者您可以在上更改url) TestNG插件必须安装在IntelliJ Idea上脚步来自版本控制的新项目> git>复制此URL...
《Android 4高级编程(第3版)》由Android权威专家编写,涵盖了所有最新的内容,是学习使用Android 4SDK开发移动应用程序的理想指南。本书见解深刻,帮助经验丰富的Android开发人员充分挖掘Android4的新特性的潜力...
Instant-messaging信息提示源码 即时通讯实例,信息提示框! 转换页面的时候,在页面左下角显示待处理的信息提示框!
使用谷歌的GCM服务(Google Cloud Messaging)实现Android消息推送
Messaging消息队列的使用 简单介绍消息队列的使用
Informatica Ultra Messaging是当今领先的低延迟消息传递软件,被世界各地的资本市场广泛应用。Ultra Messaging部署在全世界 170 多个生产环境中,能够轻松处理传统消息收发软件技术无力应对的数据量。
Avaya Modular Messaging(模块化语音消息处理)解决方案结合了Avaya世界一流的消息处理技术和行业标准,为客户提供了一种经济高效且灵活的途径,使其无论在当前还是未来,都能轻松实现消息处理系统投资最大化。...
赠送jar包:spring-messaging-5.0.8.RELEASE.jar; 赠送原API文档:spring-messaging-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-messaging-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...
该组件可以很好地集成到任何Android手机或平板电脑中,可以通过Fragment或Activity呈现Engage Digital Messaging,并具有丰富的自定义选项,可以完美地适合您的应用程序。 有关Engage Digital Messaging的更多信息...
商业源码-编程源码-Instant-messaging信息提示源码.zip
A messaging library for Android A messaging library for Android A messaging library for Android 地址 :https://github.com/Slyce-Inc/SlyceMessaging
Instant Apache ActiveMQ Messaging Application Development How-to源码
资源来自pypi官网。 资源全名:oslo.messaging-5.35.3-py2.py3-none-any.whl