android下发送中文短消息
16lz
2021-01-23
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 messagetry {textPart = message.getBytes("utf-16be");} catch (UnsupportedEncodingException uex) {uex.printStackTrace();return null;}userData = textPart;if (userData.length > MAX_USER_DATA_BYTES) {// Message too longreturn null;}// TP-Data-Coding-Scheme// Class 3, UCS-2 encoding, uncompressedbo.write(0x0b);// (no TP-Validity-Period)// TP-UDLbo.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 0if (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-Referencebo.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 addressbo.write(daBytes, 0, daBytes.length);// TP-Protocol-Identifierbo.write(0);return bo;}}
更多相关文章
- android studio 更新 Gradle错误解决方法
- Android 内核源代码交叉编译
- [转]Android DNS 代码分析
- Android 3.0 r1 API中文文档(105) ―― ViewParent
- 哪里可以下载Android的源代码
- 第一章 开始启程,你的第一行Android代码
- Android 3.0 r1中文API文档(103) ―― InputMethodManager [输入
- Android API 中文 (53) ―― BaseAdapter