高通android 7.0彩信发送过程中使用到的google pdu
2017-09-14 10:42
316 查看
对于彩信与数据库的交互操作,google并没有将这部分代码放在Mms中,而是放在framework中的pdu部分。
具体代码路径是在:opt\telephony\src\java\com\google\android\mms\pdu
现在我们来先简单介绍下。从发送彩信过程中需要使用到的类分析。
我们从前面博客知道,发送彩信涉及到的Pdu有:
SendReq sendReq = makeSendReq(conv, subject);
PduPersister p = PduPersister.getPduPersister(mContext);
GenericPdu pdu = p.load(mMessageUri);
SendReq sendReq = (SendReq) pdu;
其中间接涉及到的还有EncodedStringValue,CharacterSets,MutimediaMessagePdu,PduBody,PduHeaders等。
SendReq.java
是否还记得前面,我们在介绍彩信发送流程,就有使用到这个类,这个就是存放这发送请求信息的一个类。
其类结构如下:
SendReq
MultimediaMessagePdu
GenericPdu
我们会将发送的信息都存放到里面去,其方法
addBcc 应该是仿造邮件,暗抄送
addCc 抄送
setContentType 设置内容类型,这里是"application/vnd.wap.multipart.related".getBytes()
setDeliveryReport设置是否需要发送报告,发送了就会有报告
setExpiry设置短信下载超时时间
setMessageSize设置彩信大小
setMessageClass 设置的是PduHeaders.MESSAGE_CLASS_PERSONAL_STR = "personal",我们注意到pdu表的m_cls字段就是这个值,表示这是一条个人彩信,还有MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"广告。
setReadReport设置是否需要送达报告,发送成功会有报告
setTo设置收件人
setTransactionId 默认是通过下面方法生成的,跟当前时间有关的一个唯一的Transaction传输的Id。
private byte[] generateTransactionId() {
String transactionId = "T" + Long.toHexString(System.currentTimeMillis());
return transactionId.getBytes();
}
MultimediaMessagePdu.java 多媒体信息Pdu
其有一个PduBody类型的成员变量,它存放着彩信附件的内容
setBody 设置彩信内容
setSubject 设置主题
addTo 设置收件人
setPriority 设置优先级(什么用?),彩信发送设置的是PduHeaders.PRIORITY_NORMAL普通级别
setDate 设置日期
GenericPdu.java 彩信的不同操作,例如发送,接收,下载等,不同的操作的信息类都是继承自它。
有一个PduHeaders类型的成员变量,它存放这彩信的头部信息,也就是一些除了彩信内容之外的信息,例如收件人之类
setMessageType 设置彩信类型,发送的类型是PduHeaders.MESSAGE_TYPE_SEND_REQ,其他的可以看PduHeaders定义的其他类型
setMmsVersion 设置彩信版本
public static final int MMS_VERSION_1_3 = ((1 << 4) | 3);
public static final int MMS_VERSION_1_2 = ((1 << 4) | 2);
public static final int MMS_VERSION_1_1 = ((1 << 4) | 1);
public static final int MMS_VERSION_1_0 = ((1 << 4) | 0);
// Current version is 1.2.
public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2;默认彩信版本是1_2,不同版本的区别是?
setFrom 设置发件人
上面的方法,除了setBody之外,其他的都是将信息放入到PduHeaders中,并且每一项都有对应的索引声明在PduHeaders中,例如PduHeaders.FROM。
所以PduHeaders就是有关彩信的头部信息的一个集合类。
mHeaderMap = new HashMap<Integer, Object>();我们可以看到,上面设置的信息都是放在这里面的一个hashMap的。
setOctet(int value, int field)
setTextString(byte[] value, int field)
setEncodedStringValue(EncodedStringValue value, int field)
setEncodedStringValues(EncodedStringValue[] value, int field)
setLongInteger(long value, int field
上面的都是很容易从参数就可以了解到,例如setOctet就是存放int,int入mHeaderMap中的。这里需要了解的是EncodedStringValue 。
EncodedStringValue.java 所以这个是对一个字符串,进行一定的编码后重新获取到的数据
我们举个例子来说明下。
public void setTo(EncodedStringValue[] value) {
mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
}
在Mms中是这样调用的
EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(dests);
if (encodedNumbers != null) {
req.setTo(encodedNumbers);
}
private int mCharacterSet;编码类型,这里默认是CharacterSets.DEFAULT_CHARSET = MIMENAME_UTF_8 = "utf-8";也就是utf-8。
private byte[] mData;经过编码后的数据,String的getBytes(CharacterSets.DEFAULT_CHARSET_NAME)
CharacterSets.java
基本都是常量,跟字符串的信息相关,例如编码类型。
PduBody.java
这个跟数据库part表对应
在Mms中,是调用PduBody pb = slideshow.toPduBody(); sendReq.setBody(pb);,所以他是跟Mms的SlideshowModel对应的。
private Vector<PduPart> mParts = null;
private Map<String, PduPart> mPartMapByContentId = null;
private Map<String, PduPart> mPartMapByContentLocation = null;
private Map<String, PduPart> mPartMapByName = null;
private Map<String, PduPart> mPartMapByFileName = null;
PduPart.java 每一条part记录对应一个PduPart对象
PduPersister.java
这个类就是数据库和应用的一个交互的接口,利用它可以将彩信的数据pdu保存到数据库中,也可以将彩信数据从数据库中读取后转换为pdu,供Mms等使用。
public static PduPersister getPduPersister(Context context) {
if ((sPersister == null)) {
sPersister = new PduPersister(context);
} else if (!context.equals(sPersister.mContext)) {
sPersister.release();
sPersister = new PduPersister(context);
}
return sPersister;
}单例模式,但是不是普通的单例模式,每个场景下,不同context下的是不一样的。
updateHeaders(Uri uri, SendReq sendReq) 根据sendReq更新pdu表的字段
move 更新pdu的Mms.MESSAGE_BOX字段,例如发件箱,草稿箱等类型
persist
persist(GenericPdu pdu, Uri uri, boolean createThreadId, boolean groupMmsEnabled,
HashMap<Uri, InputStream> preOpenedFiles)
其实也是更新pdu的字段,但是这里处理的事情更多。具体更新的字段读者自行看代码。
我们前面分析彩信发送流程的时候说过,在createDraftMmsMessage方法执行完后,彩信附件内容就会插入到part表中。
PduBody pb = slideshow.toPduBody();
sendReq.setBody(pb);
然后调用persist
我们针对这部分来分析下代码
if (pdu instanceof MultimediaMessagePdu) {
body = ((MultimediaMessagePdu) pdu).getBody();
// Start saving parts if necessary.
if (body != null) {
int partsNum = body.getPartsNum();
if (partsNum > 2) {
// For a text-only message there will be two parts: 1-the SMIL, 2-the text.
// Down a few lines below we're checking to make sure we've only got SMIL or
// text. We also have to check then we don't have more than two parts.
// Otherwise, a slideshow with two text slides would be marked as textOnly.
textOnly = false;//长短信会转化为彩信,当只有文字,则有两条记录,smile和text,所以大于2肯定是不止文字了。
}
for (int i = 0; i < partsNum; i++) {
PduPart part = body.getPart(i);
messageSize += part.getDataLength();
persistPart(part, dummyId, preOpenedFiles);
// If we've got anything besides text/plain or SMIL part, then we've got
// an mms message with some other type of attachment.
String contentType = getPartContentType(part);//part表ct字段,例如图片有image/jpeg类型,文字为text/plain类型
if (contentType != null && !ContentType.APP_SMIL.equals(contentType)
&& !ContentType.TEXT_PLAIN.equals(contentType)) {
textOnly = false;
}
}
}
}
updatePart看了之后,就是解析PduPart,更新part表
persistPart看了之后,就是解析PduPart,更新part表
GenericPdu load(Uri uri)
PduPart[] loadParts(long msgId)
其他的PduComposer和PduParse后面博客讲,这个都是从数据库加载数据后生成pdu的。
PduBody pb = slideshow.toPduBody(); 这个Mms跟Pdu的转换也在后面的博客进行分析,并且会详细介绍SlideshowModel类型。
麻烦如果对大家有帮助的话,帮忙顶下。谢谢了!!
具体代码路径是在:opt\telephony\src\java\com\google\android\mms\pdu
现在我们来先简单介绍下。从发送彩信过程中需要使用到的类分析。
我们从前面博客知道,发送彩信涉及到的Pdu有:
SendReq sendReq = makeSendReq(conv, subject);
PduPersister p = PduPersister.getPduPersister(mContext);
GenericPdu pdu = p.load(mMessageUri);
SendReq sendReq = (SendReq) pdu;
其中间接涉及到的还有EncodedStringValue,CharacterSets,MutimediaMessagePdu,PduBody,PduHeaders等。
SendReq.java
是否还记得前面,我们在介绍彩信发送流程,就有使用到这个类,这个就是存放这发送请求信息的一个类。
其类结构如下:
SendReq
MultimediaMessagePdu
GenericPdu
我们会将发送的信息都存放到里面去,其方法
addBcc 应该是仿造邮件,暗抄送
addCc 抄送
setContentType 设置内容类型,这里是"application/vnd.wap.multipart.related".getBytes()
setDeliveryReport设置是否需要发送报告,发送了就会有报告
setExpiry设置短信下载超时时间
setMessageSize设置彩信大小
setMessageClass 设置的是PduHeaders.MESSAGE_CLASS_PERSONAL_STR = "personal",我们注意到pdu表的m_cls字段就是这个值,表示这是一条个人彩信,还有MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"广告。
setReadReport设置是否需要送达报告,发送成功会有报告
setTo设置收件人
setTransactionId 默认是通过下面方法生成的,跟当前时间有关的一个唯一的Transaction传输的Id。
private byte[] generateTransactionId() {
String transactionId = "T" + Long.toHexString(System.currentTimeMillis());
return transactionId.getBytes();
}
MultimediaMessagePdu.java 多媒体信息Pdu
其有一个PduBody类型的成员变量,它存放着彩信附件的内容
setBody 设置彩信内容
setSubject 设置主题
addTo 设置收件人
setPriority 设置优先级(什么用?),彩信发送设置的是PduHeaders.PRIORITY_NORMAL普通级别
setDate 设置日期
GenericPdu.java 彩信的不同操作,例如发送,接收,下载等,不同的操作的信息类都是继承自它。
有一个PduHeaders类型的成员变量,它存放这彩信的头部信息,也就是一些除了彩信内容之外的信息,例如收件人之类
setMessageType 设置彩信类型,发送的类型是PduHeaders.MESSAGE_TYPE_SEND_REQ,其他的可以看PduHeaders定义的其他类型
setMmsVersion 设置彩信版本
public static final int MMS_VERSION_1_3 = ((1 << 4) | 3);
public static final int MMS_VERSION_1_2 = ((1 << 4) | 2);
public static final int MMS_VERSION_1_1 = ((1 << 4) | 1);
public static final int MMS_VERSION_1_0 = ((1 << 4) | 0);
// Current version is 1.2.
public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2;默认彩信版本是1_2,不同版本的区别是?
setFrom 设置发件人
上面的方法,除了setBody之外,其他的都是将信息放入到PduHeaders中,并且每一项都有对应的索引声明在PduHeaders中,例如PduHeaders.FROM。
所以PduHeaders就是有关彩信的头部信息的一个集合类。
mHeaderMap = new HashMap<Integer, Object>();我们可以看到,上面设置的信息都是放在这里面的一个hashMap的。
setOctet(int value, int field)
setTextString(byte[] value, int field)
setEncodedStringValue(EncodedStringValue value, int field)
setEncodedStringValues(EncodedStringValue[] value, int field)
setLongInteger(long value, int field
上面的都是很容易从参数就可以了解到,例如setOctet就是存放int,int入mHeaderMap中的。这里需要了解的是EncodedStringValue 。
EncodedStringValue.java 所以这个是对一个字符串,进行一定的编码后重新获取到的数据
我们举个例子来说明下。
public void setTo(EncodedStringValue[] value) {
mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
}
在Mms中是这样调用的
EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(dests);
if (encodedNumbers != null) {
req.setTo(encodedNumbers);
}
private int mCharacterSet;编码类型,这里默认是CharacterSets.DEFAULT_CHARSET = MIMENAME_UTF_8 = "utf-8";也就是utf-8。
private byte[] mData;经过编码后的数据,String的getBytes(CharacterSets.DEFAULT_CHARSET_NAME)
CharacterSets.java
基本都是常量,跟字符串的信息相关,例如编码类型。
PduBody.java
这个跟数据库part表对应
在Mms中,是调用PduBody pb = slideshow.toPduBody(); sendReq.setBody(pb);,所以他是跟Mms的SlideshowModel对应的。
private Vector<PduPart> mParts = null;
private Map<String, PduPart> mPartMapByContentId = null;
private Map<String, PduPart> mPartMapByContentLocation = null;
private Map<String, PduPart> mPartMapByName = null;
private Map<String, PduPart> mPartMapByFileName = null;
PduPart.java 每一条part记录对应一个PduPart对象
PduPersister.java
这个类就是数据库和应用的一个交互的接口,利用它可以将彩信的数据pdu保存到数据库中,也可以将彩信数据从数据库中读取后转换为pdu,供Mms等使用。
public static PduPersister getPduPersister(Context context) {
if ((sPersister == null)) {
sPersister = new PduPersister(context);
} else if (!context.equals(sPersister.mContext)) {
sPersister.release();
sPersister = new PduPersister(context);
}
return sPersister;
}单例模式,但是不是普通的单例模式,每个场景下,不同context下的是不一样的。
updateHeaders(Uri uri, SendReq sendReq) 根据sendReq更新pdu表的字段
move 更新pdu的Mms.MESSAGE_BOX字段,例如发件箱,草稿箱等类型
persist
persist(GenericPdu pdu, Uri uri, boolean createThreadId, boolean groupMmsEnabled,
HashMap<Uri, InputStream> preOpenedFiles)
其实也是更新pdu的字段,但是这里处理的事情更多。具体更新的字段读者自行看代码。
我们前面分析彩信发送流程的时候说过,在createDraftMmsMessage方法执行完后,彩信附件内容就会插入到part表中。
PduBody pb = slideshow.toPduBody();
sendReq.setBody(pb);
然后调用persist
我们针对这部分来分析下代码
if (pdu instanceof MultimediaMessagePdu) {
body = ((MultimediaMessagePdu) pdu).getBody();
// Start saving parts if necessary.
if (body != null) {
int partsNum = body.getPartsNum();
if (partsNum > 2) {
// For a text-only message there will be two parts: 1-the SMIL, 2-the text.
// Down a few lines below we're checking to make sure we've only got SMIL or
// text. We also have to check then we don't have more than two parts.
// Otherwise, a slideshow with two text slides would be marked as textOnly.
textOnly = false;//长短信会转化为彩信,当只有文字,则有两条记录,smile和text,所以大于2肯定是不止文字了。
}
for (int i = 0; i < partsNum; i++) {
PduPart part = body.getPart(i);
messageSize += part.getDataLength();
persistPart(part, dummyId, preOpenedFiles);
// If we've got anything besides text/plain or SMIL part, then we've got
// an mms message with some other type of attachment.
String contentType = getPartContentType(part);//part表ct字段,例如图片有image/jpeg类型,文字为text/plain类型
if (contentType != null && !ContentType.APP_SMIL.equals(contentType)
&& !ContentType.TEXT_PLAIN.equals(contentType)) {
textOnly = false;
}
}
}
}
updatePart看了之后,就是解析PduPart,更新part表
persistPart看了之后,就是解析PduPart,更新part表
GenericPdu load(Uri uri)
PduPart[] loadParts(long msgId)
其他的PduComposer和PduParse后面博客讲,这个都是从数据库加载数据后生成pdu的。
PduBody pb = slideshow.toPduBody(); 这个Mms跟Pdu的转换也在后面的博客进行分析,并且会详细介绍SlideshowModel类型。
麻烦如果对大家有帮助的话,帮忙顶下。谢谢了!!
相关文章推荐
- 高通android 7.0短信发送流程
- 高通android 7.0彩信重发机制
- 高通Android 4.4 彩信发送流程
- Android BroadCast 各种注册和发送方式的特点整理以及7.0以上版本的使用变化
- Android接收彩信时解析PDU的过程记录
- 使用AT指令发送PDU短信的全过程
- 使用NOKIA MMS LIBRARY发送中国移动彩信
- 使用SQLServer2000 发送邮件详细配置过程
- Google Android JNI使用方法
- 在Android1.5应用程序开发过程中使用JUnit
- Google_android_JNI使用方法
- Google_android_JNI使用方法
- Setup Factory 7.0使用总结六:安装过程中安装系统组件
- android 发送短信,彩信,邮件代码
- Android中发送短信和彩信
- 还原Android PDU彩信
- android ktv 开发过程4-android 使用ffmpeg
- JAVAMAIL使用Google邮件服务器发送邮件
- 使用SQLServer2000 发送邮件详细配置过程
- Google_android_JNI使用方法