Nokia MMS Library是一个开放源代码的Java MMS开发包,里面包含了源码、文档、示例程序等,很容易就能学会。下面是用这个包发送彩信的方法:
1、电脑通过GPRS/EDGE MODEM或手机连接移动梦网,注意,必须是移动梦网(CMWAP),不是互联网(CMNET),如果手动拨号,一般是拨*99***1#或*99***2#,拨通之后打开命令行窗口,telnet 10.0.0.172 80,如果能够连上就证明拨通了。为了简单起见,连接前最好把网线或其他网络连接方式断开(可以route命令修改Windows路由表指定发送彩信的路由,但是比较麻烦)。
2、修改Nokia MMS Library samples目录下的OriginatingApp.java文件,在setMessage()方法里把下面几句修改一下,其中手机号码填写自己测试接收的手机号,注意号码前要加+86
//mm.setFrom("+358990000066/TYPE=PLMN");
mm.addToAddress("+86手机号码/TYPE=PLMN");
//mm.addToAddress("123.124.125.125/TYPE=IPv4");
//mm.addToAddress("1234:5678:90AB:CDEF:FEDC:BA09:8765:4321/TYPE=IPv6");
//mm.addToAddress(john.doe@nokia.com);
在构造函数里,修改下面这句:
sender.setMMSCURL("http://mmsc.monternet.com");
由于中国移动彩信需要通过代理才能发送,所以必须设置代理,把main()方法改成如下内容:
public static void main (String[] args) {
String strProxy="10.0.0.172";
String strPort="80";
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",strProxy);
systemProperties.setProperty("http.proxyPort",strPort);
OriginatingApp oa = new OriginatingApp();
}
3、注意彩信内容的文件放在适当的目录
4、运行之后会输出如下信息:
Message sent to http://mmsc.monternet.com
Response code: 200 OK
PROXY-CONNECTION: Keep-Alive
DATE: Tue, 17 Jun 2008 03:34:34 GMT
X-HUAWEI-MMSC-FROM: 86xxxxxxxxxxx
SERVER: Resin/3.0.7
CONNECTION: Keep-Alive
CONTENT-TYPE: application/vnd.wap.mms-message
VIA: HTTP/1.1 GDSZ-PS-WAP10-GW007(infoX-WISG, Huawei Technologies)
X-HUAWEI-MMSC-CODE: -128
X-HUAWEI-MMSC-TID: 0000000066
CONTENT-LENGTH: 41
KEEP-ALIVE: timeout=30, max=49
X-HUAWEI-MMSC-TO: +86xxxxxxxxxxx
之后将会有一条彩信发送到手机上。
问题与解决方案:
彩信的内容和标题如果包含中文的话,手机接收到的时候显示成乱码,这是因为使用了ascii编码的缘故,需要修改MMEncoder.java这个文件,把编码改成UTF-8,同时短信内容文件sample_text.txt也应改为UTF-8编码。
Nokia MMS Library下载地址:
http://www.forum.nokia.com/info/sw.nokia.com/id/a6be91b1-2c2b-49a9-abfd-3c259db9bd0c/Getting_Started_with_MMS.zip.html
下面是修改过的OriginatingApp.java和MMEncoder.java:
/*
* @(#)OriginatingApp.java 1.1
*
* Copyright (c) Nokia Corporation 2002
*
*/
import java.io.*;
import java.util.*;
import java.net.*;
import com.nokia.mms.*;
public class OriginatingApp {
public OriginatingApp() {
MMMessage mm = new MMMessage();
SetMessage(mm);
AddContents(mm);
MMEncoder encoder=new MMEncoder();
encoder.setMessage(mm);
try {
encoder.encodeMessage();
byte[] out = encoder.getMessage();
MMSender sender = new MMSender();
sender.setMMSCURL("http://mmsc.monternet.com");
sender.addHeader("X-NOKIA-MMSC-Charging", "100");
MMResponse mmResponse = sender.send(out);
System.out.println("Message sent to " + sender.getMMSCURL());
System.out.println("Response code: " + mmResponse.getResponseCode() + " " + mmResponse.getResponseMessage());
Enumeration keys = mmResponse.getHeadersList();
while (keys.hasMoreElements()){
String key = (String) keys.nextElement();
String value = (String) mmResponse.getHeaderValue(key);
System.out.println(key + ": " + value);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void SetMessage(MMMessage mm) {
mm.setVersion(IMMConstants.MMS_VERSION_10);
mm.setMessageType(IMMConstants.MESSAGE_TYPE_M_SEND_REQ);
mm.setTransactionId("0000000066");
mm.setDate(new Date(System.currentTimeMillis()));
//mm.setFrom("+358990000066/TYPE=PLMN");
mm.addToAddress("+86xxxxxxxxxx/TYPE=PLMN");
//mm.addToAddress("123.124.125.125/TYPE=IPv4");
//mm.addToAddress("1234:5678:90AB:CDEF:FEDC:BA09:8765:4321/TYPE=IPv6");
//mm.addToAddress("john.doe@nokia.com");
mm.setDeliveryReport(true);
mm.setReadReply(false);
mm.setSenderVisibility(IMMConstants.SENDER_VISIBILITY_SHOW);
mm.setSubject("测试标题字符串");
mm.setMessageClass(IMMConstants.MESSAGE_CLASS_PERSONAL);
mm.setPriority(IMMConstants.PRIORITY_LOW);
mm.setContentType(IMMConstants.CT_APPLICATION_MULTIPART_MIXED);
// In case of multipart related message and a smil presentation available
// mm.setContentType(IMMConstants.CT_APPLICATION_MULTIPART_RELATED);
// mm.setMultipartRelatedType(IMMConstants.CT_APPLICATION_SMIL);
// mm.setPresentationId("<A0>"); // where <A0> is the id of the content containing the SMIL presentation
}
private void AddContents(MMMessage mm) {
/*Path where contents are stored*/
//String path = getPath();
String path=".\\";
// Adds text content
MMContent part1 = new MMContent();
byte[] buf1 = readFile(path + "sample_text.txt");
part1.setContent(buf1, 0, buf1.length);
part1.setContentId("<0>");
part1.setType(IMMConstants.CT_TEXT_PLAIN);
mm.addContent(part1);
// Adds image content
MMContent part2 = new MMContent();
byte[] buf2 = readFile(path + "sample_image.jpg");
part2.setContent(buf2, 0, buf2.length);
part1.setContentId("<1>");
part2.setType(IMMConstants.CT_IMAGE_JPEG);
mm.addContent(part2);
}
private byte[] readFile(String filename) {
int fileSize=0;
RandomAccessFile fileH=null;
// Opens the file for reading.
try {
fileH = new RandomAccessFile(filename, "r");
fileSize = (int) fileH.length();
} catch (IOException ioErr) {
System.err.println("Cannot find " + filename);
System.err.println(ioErr);
System.exit(200);
}
// allocates the buffer large enough to hold entire file
byte[] buf = new byte[fileSize];
// reads all bytes of file
int i=0;
try {
while (true) {
try {
buf[i++] = fileH.readByte();
} catch (EOFException e) {
break;
}
}
} catch (IOException ioErr) {
System.out.println("ERROR in reading of file"+filename);
}
return buf;
}
private String getPath() {
URL url = getClass().getResource(getClass().getName() + ".class");
String classPath = url.getHost() + url.getFile();
int pos = classPath.lastIndexOf("/");
return classPath.substring(0, pos + 1);
}
public static void main (String[] args) {
String strProxy="10.0.0.172";
String strPort="80";
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",strProxy);
systemProperties.setProperty("http.proxyPort",strPort);
OriginatingApp oa = new OriginatingApp();
}
}
/*
* @(#)MMEncoder.java 1.1
*
* Copyright (c) Nokia Corporation 2002
*
*/
package com.nokia.mms;
import java.util.Date;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.io.*;
/**
* The MMEncoder class encodes Multimedia Message object (MMMessage)
* into an array of bytes according to the specification WAP-209-MMSEncapsulation
* (WAP Forum).
*
*/
public class MMEncoder implements IMMConstants {
private MMMessage m_Message;
private boolean m_bMessageAvailable;
private boolean m_bMultipartRelated;
private boolean m_bMessageEcoded;
private ByteArrayOutputStream m_Out;
public MMEncoder() {
super();
reset();
}
/**
* Resets the Decoder object.
*
*/
public void reset() {
m_Message = null;
m_bMultipartRelated = false;
m_bMessageAvailable = false;
m_bMessageEcoded = false;
m_Out = null;
}
/**
* Sets the Multimedia Message to be encoded.
*/
public void setMessage(MMMessage msg) {
m_Message = msg;
m_bMessageAvailable = true;
}
/**
* Retrieve the buffer of byte representing the encoded Multimedia Message.
* This method has to be called after the calling to encodeMessasge()
*
* @return the array of bytes representing the Multmedia Message
*/
public byte[] getMessage() {
if (m_bMessageEcoded) {
return m_Out.toByteArray();
} else {
return null;
}
}
/**
* Encode known content type assignments.
* List of the content type assignments can be found from WAP-203-WSP, Table 40
* This version is compliant with Approved version 4-May-2000
*
* @return assigned number
*/
private byte encodeContentType(String sContentType) {
if(sContentType.equalsIgnoreCase("*/*"))
return 0x00;
else
if(sContentType.equalsIgnoreCase("text/*"))
return 0x01;
else
if(sContentType.equalsIgnoreCase("text/html"))
return 0x02;
else
if(sContentType.equalsIgnoreCase("text/plain"))
return 0x03;
else
if(sContentType.equalsIgnoreCase("text/x-hdml"))
return 0x04;
else
if(sContentType.equalsIgnoreCase("text/x-ttml"))
return 0x05;
else
if(sContentType.equalsIgnoreCase("text/x-vCalendar"))
return 0x06;
else
if(sContentType.equalsIgnoreCase("text/x-vCard"))
return 0x07;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.wml"))
return 0x08;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.wmlscript"))
return 0x09;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.channel"))
return 0x0A;
else
if(sContentType.equalsIgnoreCase("multipart/*"))
return 0x0B;
else
if(sContentType.equalsIgnoreCase("multipart/mixed"))
return 0x0C;
else
if(sContentType.equalsIgnoreCase("multipart/form-data"))
return 0x0D;
else
if(sContentType.equalsIgnoreCase("multipart/byteranges"))
return 0x0E;
else
if(sContentType.equalsIgnoreCase("multipart/alternative"))
return 0x0F;
else
if(sContentType.equalsIgnoreCase("application/*"))
return 0x10;
else
if(sContentType.equalsIgnoreCase("application/java-vm"))
return 0x11;
else
if(sContentType.equalsIgnoreCase("application/x-www-form-urlencoded"))
return 0x12;
else
if(sContentType.equalsIgnoreCase("application/x-hdmlc"))
return 0x13;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.wmlc"))
return 0x14;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.wmlscriptc"))
return 0x15;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.channelc"))
return 0x16;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.uaprof"))
return 0x17;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.wtls-ca-certificate"))
return 0x18;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.wtls-user-certificate"))
return 0x19;
else
if(sContentType.equalsIgnoreCase("application/x-x509-ca-cert"))
return 0x1A;
else
if(sContentType.equalsIgnoreCase("application/x-x509-user-cert"))
return 0x1B;
else
if(sContentType.equalsIgnoreCase("image/*"))
return 0x1C;
else
if(sContentType.equalsIgnoreCase("image/gif"))
return 0x1D;
else
if(sContentType.equalsIgnoreCase("image/jpeg"))
return 0x1E;
else
if(sContentType.equalsIgnoreCase("image/tiff"))
return 0x1F;
else
if(sContentType.equalsIgnoreCase("image/png"))
return 0x20;
else
if(sContentType.equalsIgnoreCase("image/vnd.wap.wbmp"))
return 0x21;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.*"))
return 0x22;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.mixed"))
return 0x23;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.form-data"))
return 0x24;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.byteranges"))
return 0x25;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.alternative"))
return 0x26;
else
if(sContentType.equalsIgnoreCase("application/xml"))
return 0x27;
else
if(sContentType.equalsIgnoreCase("text/xml"))
return 0x28;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.wbxml"))
return 0x29;
else
if(sContentType.equalsIgnoreCase("application/x-x968-cross-cert"))
return 0x2A;
else
if(sContentType.equalsIgnoreCase("application/x-x968-ca-cert"))
return 0x2B;
else
if(sContentType.equalsIgnoreCase("application/x-x968-user-cert"))
return 0x2C;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.si"))
return 0x2D;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.sic"))
return 0x2E;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.sl"))
return 0x2F;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.slc"))
return 0x30;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.co"))
return 0x31;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.coc"))
return 0x32;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.multipart.related"))
return 0x33;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.sia"))
return 0x34;
else
if(sContentType.equalsIgnoreCase("text/vnd.wap.connectivity-xml"))
return 0x35;
else
if(sContentType.equalsIgnoreCase("application/vnd.wap.connectivity-wbxml"))
return 0x36;
else
return 0;
}
private int unsignedByte(byte value) {
if (value<0) {
return (value+256);
} else {
return value;
}
}
private void writeValueLength(long value) {
if (value <=30)
m_Out.write((int)value);
else {
m_Out.write(31);
int data[] = EncodeUintvarNumber(value);
int numValue;
for(int i = 1; i <= data[0]; i++) {
numValue = data[i];
m_Out.write(numValue);
}
}
}
private void writeUintvar(long value) {
int data[] = EncodeUintvarNumber(value);
int numValue;
for(int i = 1; i <= data[0]; i++) {
numValue = data[i];
m_Out.write(numValue);
}
}
/**
* Encodes the Multimedia Message set by calling setMessage(MMMessage msg)
*/
public void encodeMessage() throws MMEncoderException {
int numValue;
String strValue;
m_bMessageEcoded = false;
m_bMultipartRelated = false;
if(!m_bMessageAvailable)
throw new MMEncoderException("No Multimedia Messages set in the encoder");
try {
m_Out = new ByteArrayOutputStream();
if(!m_Message.isMessageTypeAvailable()) {
m_Out.close();
throw new MMEncoderException("Invalid Multimedia Message format.");
}
byte nMessageType = m_Message.getMessageType();
switch(nMessageType) {
default:
{
m_Out.close();
throw new MMEncoderException("Invalid Multimedia Message format.");
}
case MESSAGE_TYPE_M_DELIVERY_IND: // ---------------------------- m-delivery-ind
// ------------------- MESSAGE TYPE --------
m_Out.write(FN_MESSAGE_TYPE + 0x80);
m_Out.write(nMessageType);
// ------------------- MESSAGE ID ------
if(m_Message.isMessageIdAvailable()) {
m_Out.write(FN_MESSAGE_ID + 0x80);
m_Out.write(m_Message.getMessageId().getBytes());
m_Out.write(0x00);
} else {
m_Out.close();
throw new MMEncoderException ("The field Message-ID of the Multimedia Message is null");
}
// ------------------- VERSION -------------
m_Out.write(FN_MMS_VERSION + 0x80);
if(!m_Message.isVersionAvailable()) {
numValue = MMS_VERSION_10;
} else {
numValue = m_Message.getVersion();
}
m_Out.write(numValue);
// ------------------- DATE ----------------
if(m_Message.isDateAvailable()) {
long secs=(m_Message.getDate()).getTime() / 1000;
int data[] = EncodeMultiByteNumber(secs);
if(data == null) {
m_Out.close();
throw new MMEncoderException("An error occurred encoding the sending date of the Multimedia Message");
}
m_Out.write(FN_DATE + 0x80);
int nCount = data[0];
m_Out.write(nCount);
for(int i = 1; i <= nCount; i++) {
m_Out.write(data[i]);
}
}
// ------------------- TO ------------------
if(m_Message.isToAvailable()) {
Vector sAddress = m_Message.getTo();
int nAddressCount = sAddress.size();
if(sAddress == null) {
m_Out.close();
throw new MMEncoderException("The field TO of the Multimedia Message is set to null.");
}
for(int i = 0; i < nAddressCount; i++) {
strValue = ((MMAddress)sAddress.elementAt(i)).getFullAddress();
if(strValue != null) {
m_Out.write(FN_TO + 0x80);
m_Out.write(strValue.getBytes());
m_Out.write(0x00);
}
}
} else {
m_Out.close();
throw new MMEncoderException("No recipient specified in the Multimedia Message.");
}
// ------------------- MESSAGE-STATUS ----------------
if(m_Message.isStatusAvailable()) {
m_Out.write(FN_STATUS + 0x80);
m_Out.write(m_Message.getMessageStatus());
} else {
m_Out.close();
throw new MMEncoderException ("The field Message-ID of the Multimedia Message is null");
}
break;
case MESSAGE_TYPE_M_SEND_REQ: // ---------------------------- m-send-req
// ------------------- MESSAGE TYPE --------
m_Out.write(FN_MESSAGE_TYPE + 0x80);
m_Out.write(nMessageType);
// ------------------- TRANSACTION ID ------
if(m_Message.isTransactionIdAvailable()) {
m_Out.write(FN_TRANSACTION_ID + 0x80);
m_Out.write(m_Message.getTransactionId().getBytes());
m_Out.write(0x00);
}
// ------------------- VERSION -------------
m_Out.write(FN_MMS_VERSION + 0x80);
if(!m_Message.isVersionAvailable()) {
numValue = MMS_VERSION_10;
} else {
numValue = m_Message.getVersion();
}
m_Out.write(numValue);
// ------------------- DATE ----------------
if(m_Message.isDateAvailable()) {
long secs=(m_Message.getDate()).getTime() / 1000;
int data[] = EncodeMultiByteNumber(secs);
if(data == null) {
m_Out.close();
throw new MMEncoderException("An error occurred encoding the sending date of the Multimedia Message");
}
m_Out.write(FN_DATE + 0x80);
int nCount = data[0];
m_Out.write(nCount);
for(int i = 1; i <= nCount; i++) {
m_Out.write(data[i]);
}
}
// ------------------- FROM ----------------
if(m_Message.isFromAvailable()) {
m_Out.write(FN_FROM + 0x80);
strValue = (m_Message.getFrom()).getFullAddress();
if(strValue == null) {
m_Out.close();
throw new MMEncoderException("The field from is assigned to null");
}
// Value-length
writeValueLength(strValue.length()+2);
// Address-present-token
m_Out.write(0x80);
// Encoded-string-value
m_Out.write(strValue.getBytes());
m_Out.write(0x00);
} else {
// Value-length
m_Out.write(1);
m_Out.write(0x81);
}
// ------------------- TO ------------------
if(m_Message.isToAvailable()) {
Vector sAddress = m_Message.getTo();
int nAddressCount = sAddress.size();
if(sAddress == null) {
m_Out.close();
throw new MMEncoderException("The field TO of the Multimedia Message is set to null.");
}
for(int i = 0; i < nAddressCount; i++) {
strValue = ((MMAddress)sAddress.elementAt(i)).getFullAddress();
if(strValue != null) {
m_Out.write(FN_TO + 0x80);
m_Out.write(strValue.getBytes());
m_Out.write(0x00);
}
}
}
// ------------------- CC ------------------
if(m_Message.isCcAvailable()) {
Vector sAddress = m_Message.getCc();
int nAddressCount = sAddress.size();
if(sAddress == null) {
m_Out.close();
throw new MMEncoderException("The field CC of the Multimedia Message is set to null.");
}
for(int i = 0; i < nAddressCount; i++) {
strValue = ((MMAddress)sAddress.elementAt(i)).getFullAddress();
if(strValue != null) {
m_Out.write(FN_CC + 0x80);
m_Out.write(strValue.getBytes());
m_Out.write(0x00);
}
}
}
// ------------------- BCC ------------------
if(m_Message.isBccAvailable()) {
Vector sAddress = m_Message.getBcc();
int nAddressCount = sAddress.size();
if(sAddress == null) {
m_Out.close();
throw new MMEncoderException("The field BCC of the Multimedia Message is set to null.");
}
for(int i = 0; i < nAddressCount; i++) {
strValue = ((MMAddress)sAddress.elementAt(i)).getFullAddress();
if(strValue != null) {
m_Out.write(FN_BCC + 0x80);
m_Out.write(strValue.getBytes());
m_Out.write(0x00);
}
}
}
if (!(m_Message.isToAvailable() || m_Message.isCcAvailable() || m_Message.isBccAvailable())) {
m_Out.close();
throw new MMEncoderException("No recipient specified in the Multimedia Message.");
}
// ---------------- SUBJECT --------------
if(m_Message.isSubjectAvailable()) {
m_Out.write(FN_SUBJECT + 0x80);
/*
m_Out.write(m_Message.getSubject().getBytes());
*/
//上面是默认编码,下面是utf-8编码
m_Out.write(m_Message.getSubject().getBytes("utf-8").length+2);
m_Out.write(0xEA);
m_Out.write(m_Message.getSubject().getBytes("utf-8"));
///////////////////////////////////////
m_Out.write(0x00);
}
// ------------------- DELIVERY-REPORT ----------------
if(m_Message.isDeliveryReportAvailable()) {
m_Out.write(FN_DELIVERY_REPORT + 0x80);
if (m_Message.getDeliveryReport()==true)
m_Out.write(0x80);
else
m_Out.write(0x81);
}
// ------------------- SENDER-VISIBILITY ----------------
if(m_Message.isSenderVisibilityAvailable()) {
m_Out.write(FN_SENDER_VISIBILITY + 0x80);
m_Out.write(m_Message.getSenderVisibility());
}
// ------------------- READ-REPLY ----------------
if(m_Message.isReadReplyAvailable()) {
m_Out.write(FN_READ_REPLY + 0x80);
if (m_Message.getReadReply()==true)
m_Out.write(0x80);
else
m_Out.write(0x81);
}
// ---------------- MESSAGE CLASS ---------
if(m_Message.isMessageClassAvailable()) {
m_Out.write(FN_MESSAGE_CLASS + 0x80);
m_Out.write(m_Message.getMessageClass());
}
// ---------------- EXPIRY ----------------
if(m_Message.isExpiryAvailable()) {
long secs=(m_Message.getExpiry()).getTime() / 1000;
int data[] = EncodeMultiByteNumber(secs);
if(data == null) {
m_Out.close();
throw new MMEncoderException("An error occurred encoding the EXPIRY field of the Multimedia Message. The field is set to null");
}
int nCount = data[0];
m_Out.write(FN_EXPIRY + 0x80);
// Value-length
writeValueLength(nCount+2);
if (m_Message.isExpiryAbsolute()) {
// Absolute-token
m_Out.write(0x80);
} else {
// Relative-token
m_Out.write(0x81);
}
// Date-value or Delta-seconds-value
for(int i = 0; i <= nCount; i++) {
m_Out.write(data[i]);
}
}
// ---------------- DELIVERY TIME ----------------
if(m_Message.isDeliveryTimeAvailable()) {
long secs=(m_Message.getDeliveryTime()).getTime() / 1000;
int data[] = EncodeMultiByteNumber(secs);
if(data == null) {
m_Out.close();
throw new MMEncoderException("The field DELIVERY TIME of the Multimedia Message is set to null.");
}
int nCount = data[0];
m_Out.write(FN_DELIVERY_TIME + 0x80);
// Value-length
writeValueLength(nCount+2);
if (m_Message.isDeliveryTimeAbsolute()) {
// Absolute-token
m_Out.write(0x80);
} else {
// Relative-token
m_Out.write(0x81);
}
// Date-value or Delta-seconds-value
for(int i = 0; i <= nCount; i++) {
m_Out.write(data[i]);
}
}
// ---------------- PRIORITY ----------------
if(m_Message.isPriorityAvailable()) {
m_Out.write(FN_PRIORITY + 0x80);
m_Out.write(m_Message.getPriority());
}
// ---------------- CONTENT TYPE ----------------
if(m_Message.isContentTypeAvailable()) {
m_bMultipartRelated = false;
m_Out.write(FN_CONTENT_TYPE + 0x80);
byte ctype=encodeContentType(m_Message.getContentType());
if (ctype==0x33) {
// application/vnd.wap.multipart.related
m_bMultipartRelated = true;
int valueLength=1;
String mprt = m_Message.getMultipartRelatedType();
valueLength += mprt.length()+2;
String start = m_Message.getPresentationId();
valueLength += start.length()+2;
// Value-length
writeValueLength(valueLength);
// Well-known-media
m_Out.write(0x33+0x80);
// Parameters
// Type
m_Out.write(0x09+0x80);
m_Out.write(mprt.getBytes());
m_Out.write(0x00);
// Start
m_Out.write(0x0A+0x80);
m_Out.write(start.getBytes());
m_Out.write(0x00);
} else {
if (ctype > 0x00)
m_Out.write(ctype + 0x80);
else {
m_Out.write(m_Message.getContentType().getBytes());
m_Out.write(0x00);
}
}
} else {
m_Out.close();
throw new MMEncoderException("The field CONTENT TYPE of the Multimedia Message is not specified.");
}
// -------------------------- BODY -------------
int nPartsCount = m_Message.getNumContents();
m_Out.write(nPartsCount);
MMContent part = null;
for(int i = 0; i < nPartsCount; i++) {
part = m_Message.getContent(i);
boolean bRetVal = EncodePart(part);
if (!bRetVal) {
m_Out.close();
throw new MMEncoderException("The entry having Content-id = " + part.getContentId() + " cannot be encoded.");
}
}
break;
}
m_Out.close();
m_bMessageEcoded = true;
} catch (IOException e) {
throw new MMEncoderException("An IO error occurred encoding the Multimedia Message.");
}
}
private int[] EncodeMultiByteNumber(long lData) {
int data[] = new int[32];
long lDivider = 1L;
int nSize = 0;
long lNumber = lData;
for(int i = 0; i < 32; i++)
data[i] = 0;
for(int i = 4; i >= 0; i--) {
lDivider = 1L;
for(int j = 0; j < i; j++)
lDivider *= 256L;
int q = (int)(lNumber / lDivider);
if(q != 0 || nSize != 0) {
int r = (int)(lNumber % lDivider);
data[nSize + 1] = q;
lNumber = r;
nSize++;
}
}
data[0] = nSize;
return data;
}
private int[] EncodeUintvarNumber(long lData) {
int data[] = new int[32];
long lDivider = 1L;
int nSize = 0;
long lNumber = lData;
for(int i = 0; i < 32; i++)
data[i] = 0;
for(int i = 4; i >= 0; i--) {
lDivider = 1L;
for(int j = 0; j < i; j++)
lDivider *= 128L;
int q = (int)(lNumber / lDivider);
if(q != 0 || nSize != 0) {
int r = (int)(lNumber % lDivider);
data[nSize + 1] = q;
if(i != 0)
data[nSize + 1] += 128;
lNumber = r;
nSize++;
}
}
data[0] = nSize;
return data;
}
private boolean EncodePart(MMContent part) throws IOException {
if(part == null)
return false;
int nHeadersLen = 0; // nHeadersLen = nLengthOfContentType + nLengthOfHeaders
int nContentType = 0;
int nLengthOfHeaders=0;
int nLengthOfContentType=0;
// -------- HeadersLen = ContentType + Headers fields ---------
if ((part.getContentId().length()>0) && (m_bMultipartRelated)) {
if (part.getContentId().getBytes()[0]=='<') {
nLengthOfHeaders = 2 + (part.getContentId()).length() + 1;
// 2 = 0xC0 (Content-ID) + 0x22 (quotes)
// 1 = 0x00 (at the end of the contentID)
} else {
nLengthOfHeaders = 1 + (part.getContentId()).length()+1;
// 1 = 0x8E (Content-Location)
// 1 = 0x00 (end string)
}
}
// -------- DataLen -------------
long lDataLen = part.getLength();
// -------- ContentType ---------
nContentType = encodeContentType(part.getType()) + 128;
if (nContentType>0x80) {
// ---------- Well Known Content Types ------------------------------
if (nContentType == 0x83) { // text/plain
nLengthOfContentType = 4;
// 4 = 0x03 (Value Length)+ 0x83(text/plain) + 0x81 (Charset) + 0x83 (us-ascii code)
nHeadersLen = nLengthOfContentType + nLengthOfHeaders;
// write HeadersLen
writeUintvar(nHeadersLen);
// write DataLen
writeUintvar(lDataLen);
// write ContentType
m_Out.write(0x03); // length of content type
m_Out.write(nContentType);
m_Out.write(0x81); // charset parameter
//m_Out.write(0x83); // us-ascii code
m_Out.write(0xEA);//utf-8
} else {
nLengthOfContentType = 1;
nHeadersLen = nLengthOfContentType + nLengthOfHeaders;
// write HeadersLen
writeUintvar(nHeadersLen);
// write DataLen
writeUintvar(lDataLen);
// write ContentType
m_Out.write(nContentType);
}
} else {
// ----------- Don't known Content Type
if (part.getType().equalsIgnoreCase(CT_APPLICATION_SMIL)) {
nLengthOfContentType = 1 + part.getType().length() + 3;
// 1 = 0x13 (Value Length)
// 3 = 0x00 + 0x81 (Charset) + 0x83 (us-ascii code)
nHeadersLen = nLengthOfContentType + nLengthOfHeaders;
// write HeadersLen
writeUintvar(nHeadersLen);
// write DataLen
writeUintvar(lDataLen);
// write ContentType
m_Out.write(0x13); //13 characters, actually part.getType().length()+1+1+1
m_Out.write(part.getType().getBytes());
m_Out.write(0x00);
m_Out.write(0x81); // charset parameter
//m_Out.write(0x83); // ascii-code
m_Out.write(0xEA);//utf-8
} else {
nLengthOfContentType = part.getType().length() + 1;
// 1 = 0x00
nHeadersLen = nLengthOfContentType + nLengthOfHeaders;
// write HeadersLen
writeUintvar(nHeadersLen);
// write DataLen
writeUintvar(lDataLen);
// write ContentType
m_Out.write(part.getType().getBytes());
m_Out.write(0x00);
}
}
// writes the Content ID or the Content Location
if ((part.getContentId().length()>0) && (m_bMultipartRelated)) {
if (part.getContentId().getBytes()[0]=='<') {
System.out.println("--->QUOTED!!");
m_Out.write(0xC0);
m_Out.write(0x22);
m_Out.write(part.getContentId().getBytes());
m_Out.write(0x00);
} else {
// content id
m_Out.write(0x8E);
m_Out.write(part.getContentId().getBytes());
m_Out.write(0x00);
}
}
// ----------- Data --------------
byte data[] = part.getContent();
m_Out.write(data);
return true;
}
}