`

android下发送中文短消息

阅读更多

android下发送中文短消息

 

在android中用直接使用smsManager.sendTextMessage()方法发送中文或其它unicode字符会显示不正确。

目前来说想正确发送中文,需要自己构造PDU,然后在JAVA中用反射调用SmsManager的private sendRawPdu方法来实现。

参考:http://www.android123.com.cn/androidkaifa/180.html

上文中只说了PDU构造实现原理,具体怎么使用没有涉及。俺这再补一把,直接贴出代码。其实android本身SDK就有相应方法以UCS2编码发送,只是默认不会调用。

以下代码G1下测试通过

public class SmsHelper {

public static final int MAX_USER_DATA_BYTES = 140;

private Context mContext;

public SmsHelper(Context c) {
mContext = c;
}

public void sendUnicodeMessage(String phone, String text) {

SmsManager smsManager = SmsManager.getDefault();

Class clazz = smsManager.getClass();

try {

Class[] types = new Class[4];
types[0] = byte[].class;
types[1] = byte[].class;
types[2] = Class.forName("android.app.PendingIntent");
types[3] = Class.forName("android.app.PendingIntent");

Object[] params = new Object[4];
params[0] = null;
params[1] = getSubmitPdu(null, phone, text).encodedMessage;
params[2] = PendingIntent
.getBroadcast(mContext, 0, new Intent(), 0);
// params[2] = null;
params[3] = null;

Method m = clazz.getDeclaredMethod("sendRawPdu", types);
m.setAccessible(true);
m.invoke(smsManager, params);

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message) {

if (message == null || destinationAddress == null) {
return null;
}

SubmitPdu ret = new SubmitPdu();

byte mtiByte = (byte) (0x01 | 0x00);

ByteArrayOutputStream bo = getSubmitPduHead(scAddress,
destinationAddress, mtiByte, false, ret);

byte[] userData, textPart;
// Encoding to the 7-bit alphabet failed. Let's see if we can
// send it as a UCS-2 encoded message

try {
textPart = message.getBytes("utf-16be");
} catch (UnsupportedEncodingException uex) {
uex.printStackTrace();
return null;
}

userData = textPart;

if (userData.length > MAX_USER_DATA_BYTES) {
// Message too long
return null;
}

// TP-Data-Coding-Scheme
// Class 3, UCS-2 encoding, uncompressed
bo.write(0x0b);

// (no TP-Validity-Period)

// TP-UDL
bo.write(userData.length);

bo.write(userData, 0, userData.length);

ret.encodedMessage = bo.toByteArray();

return ret;
}

private static ByteArrayOutputStream getSubmitPduHead(String scAddress,
String destinationAddress, byte mtiByte,
boolean statusReportRequested, SubmitPdu ret) {

ByteArrayOutputStream bo = new ByteArrayOutputStream(
MAX_USER_DATA_BYTES + 40);

// SMSC address with length octet, or 0
if (scAddress == null) {
ret.encodedScAddress = null;
} else {
ret.encodedScAddress = PhoneNumberUtils
.networkPortionToCalledPartyBCDWithLength(scAddress);
}

// TP-Message-Type-Indicator (and friends)
if (statusReportRequested) {
// Set TP-Status-Report-Request bit.
mtiByte |= 0x20;
}
bo.write(mtiByte);

// space for TP-Message-Reference
bo.write(0);

byte[] daBytes;

daBytes = PhoneNumberUtils
.networkPortionToCalledPartyBCD(destinationAddress);

// destination address length in BCD digits, ignoring TON byte and pad
// TODO Should be better.
bo.write((daBytes.length - 1) * 2
- ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));

// destination address
bo.write(daBytes, 0, daBytes.length);

// TP-Protocol-Identifier
bo.write(0);

return bo;
}

}


 



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics