android发送与接收超长短信

android发送与接收超长短信

android接收发送短信,支持的最大字符数是70个,实际是67个字符,如果发送的短信超过了该数目,那就需要用到sendMultipartTextMessage()方法

public void sendMultipartTextMessage (
        String destinationAddress,
        String scAddress,
        ArrayList<String> parts,
        ArrayList<PendingIntent> sentIntents,
        ArrayList<PendingIntent> deliveryIntents)

使用divideMessage方法分割短信再发送

private void sendMessage(String destAddress, String content, Uri uri) {
    SmsManager smsManager = SmsManager.getDefault();
    List<String> divideContents = smsManager.divideMessage(content);
    Log.e("txrjsms", "divide into " + divideContents.size() + " parts.");
    for (String text : divideContents) {
        Log.i("txrjsms", text+"(length:"+text.length()+")");
        // smsManager.sendTextMessage(destAddress, null, text, getSentIntent(uri), null);
    }
}

查看日志

07-21 09:51:59.641: E/txrjsms(22832): divide into 2 parts.
07-21 09:51:59.641: I/txrjsms(22832): 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01234(length:153)
07-21 09:51:59.641: I/txrjsms(22832): 56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ(length:68)

分割短信之SmsManager.divideMessage(String text)

ArrayList<String> android.telephony.SmsManager.divideMessage(String text)

android-sdk-windowssourcesandroid-16android elephonySmsManager.java

public ArrayList<String> divideMessage(String text) {
    return SmsMessage.fragmentText(text);
}

分割短信之SmsMessage.fragmentText(String text)

ArrayList<String> android.telephony.SmsMessage.fragmentText(String text)

android-sdk-windowssourcesandroid-16android elephonySmsMessage.java

导入手机类型常量PHONE_TYPE_CDMA

import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;

在TelephonyManager中定义手机类型常量

/** No phone radio. */
public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE;
/** Phone radio is GSM. */
public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
/** Phone radio is CDMA. */
public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
/** Phone is via SIP. */
public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP;

实现SmsManager.fragmentText(String text)

public static ArrayList<String> android.telephony.SmsManager.fragmentText(String text) {

   int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); 
    TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
        com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false) :
        com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false);

    // TODO(cleanup): The code here could be rolled into the logic
    // below cleanly if these MAX_* constants were defined more
    // flexibly...

    int limit;
    if (ted.codeUnitSize == ENCODING_7BIT) {
        int udhLength;
        if (ted.languageTable != 0 && ted.languageShiftTable != 0) {
            udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES;
        } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) {
            udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE;
        } else {
            udhLength = 0;
        }

        if (ted.msgCount > 1) {
            udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE;
        }

        if (udhLength != 0) {
            udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH;
        }

        limit = MAX_USER_DATA_SEPTETS - udhLength;
    } else {
        if (ted.msgCount > 1) {
            limit = MAX_USER_DATA_BYTES_WITH_HEADER;
        } else {
            limit = MAX_USER_DATA_BYTES;
        }
    }

   int pos = 0;  // Index in code units.
    int textLen = text.length();
    ArrayList<String> result = new ArrayList<String>(ted.msgCount);
    while (pos < textLen) {
       int nextPos = 0;  // Counts code units.
        if (ted.codeUnitSize == ENCODING_7BIT) {
            if (activePhone == PHONE_TYPE_CDMA && ted.msgCount == 1) {
                // For a singleton CDMA message, the encoding must be ASCII...
                nextPos = pos + Math.min(limit, textLen - pos);
            } else {
                // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode).
                nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit,
                        ted.languageTable, ted.languageShiftTable);
            }
        } else {  // Assume unicode.
            nextPos = pos + Math.min(limit / 2, textLen - pos);
        }
        if ((nextPos <= pos) || (nextPos > textLen)) {
            Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
                      nextPos + " >= " + textLen + ")");
            break;
        }
        result.add(text.substring(pos, nextPos));
        pos = nextPos;
    }
    return result;
}

发送信息的三种方法(在android.telephony.SmsManager中定义)

SmsManager.getDefault().sendDataMessage(destinationAddress, scAddress, destinationPort, data, sentIntent, deliveryIntent);
SmsManager.getDefault().sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
SmsManager.getDefault().sendMultipartTextMessage(destinationAddress, scAddress, parts, sentIntents, deliveryIntents);

发送信息方法一

void sendTextMessage(
        String destinationAddress,
        String scAddress,
        String text,
        PendingIntent sentIntent,
        PendingIntent deliveryIntent)

Send a text based SMS. 发送SMS文本

Parameters:
destinationAddress the address to send the message to 目的地址
scAddress is the service center address or null to use the current default SMSC 服务中心地址(OR默认的SMSC)
text the body of the message to send 信息内容
sentIntent if not NULL this PendingIntent is broadcast when the message is sucessfully sent, or failed. 信息发送成功或失败触发
deliveryIntent if not NULL this PendingIntent is broadcast when the message is delivered to the recipient. The raw pdu of the status report is in the extended data ("pdu"). 信息抵达收信人触发
Throws:
IllegalArgumentException - if destinationAddress or text are empty 目的地址或短信内容为空抛出异常

发送信息方法二

void sendMultipartTextMessage(
        String destinationAddress,
        String scAddress,
        ArrayList<String> parts,
        ArrayList<PendingIntent> sentIntents,
        ArrayList<PendingIntent> deliveryIntents)

Send a multi-part text based SMS. The callee should have already divided the message into correctly sized parts by calling divideMessage. 发送SMS多部分文本。要求先调用divideMessage()方法将信息分割成多个部分。

Parameters:
destinationAddress the address to send the message to
scAddress is the service center address or null to use the current default SMSC
parts an ArrayList of strings that, in order, comprise the original message
sentIntents if not null, an ArrayList of PendingIntents (one for each message part) that is broadcast when the corresponding message part has been sent.
deliveryIntents if not null, an ArrayList of PendingIntents (one for each message part) that is broadcast when the corresponding message part has been delivered to the recipient. The raw pdu of the status report is in the extended data ("pdu").
Throws:
IllegalArgumentException - if destinationAddress or data are empty

使用sendMultipartTextMessage()方法发送长信息给10010,收不到回复

07-21 11:19:36.834: E/txrjsms(23832): divide into 2 parts.
07-21 11:19:36.834: I/txrjsms(23832): 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01234(length:153)
07-21 11:19:36.834: I/txrjsms(23832): 56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ(length:68)
07-21 11:19:36.834: E/txrjsms(23832): send long message. // MessageListActivity’s log
07-21 11:19:41.048: E/txrjsms(23832): send (1/2) msg success. // SendSmsReceiver’s log
07-21 11:19:45.663: E/txrjsms(23832): send (2/2) msg success. // SendSmsReceiver’s log

07-21 11:28:59.003: E/txrjsms(24429): divide into 2 parts.
07-21 11:28:59.003: I/txrjsms(24429): 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
07-21 11:28:59.003: I/txrjsms(24429): 1234567890 1234567890 1234567890 1234567890(length:153)
07-21 11:28:59.003: I/txrjsms(24429):  1234567890 1234567890 1234567890 1234567890 1234567890 1234567890(length:66)
07-21 11:28:59.003: E/txrjsms(24429): send long message.
07-21 11:29:03.016: E/txrjsms(24429): send (1/2) msg success.
07-21 11:29:06.980: E/txrjsms(24429): send (2/2) msg success.

使用sendTextMessage()方法发送的信息给10010,收到回复。

由于信息比较长,被分割成了两条,因此收到两条回复。

分割更长的信息。中文怎么分割成67个字符呢

07-21 11:38:56.295: E/txrjsms(24778): divide into 6 parts.
07-21 11:38:56.295: I/txrjsms(24778): 984路
07-21 11:38:56.295: I/txrjsms(24778): 去程:九华山庄-大柳树环岛南-小汤山马坊-北京太阳城-种禽公司-平坊-平西府-东三旗-东三旗南站-天通苑太平庄-天通西苑北-(length:67)
07-21 11:38:56.375: I/txrjsms(24778): 天通西苑南-东小口-城铁立水桥站-立水桥北站-立水桥-大羊坊-北苑-辛店村-科荟路东口-华汇商厦-慧忠北里-大屯南-炎黄艺术馆-安慧桥(length:67)
07-21 11:38:56.395: I/txrjsms(24778): 北-安慧桥东-惠新里-对外经贸大学-中日医院-太阳宫桥-西坝河-静安庄-三元桥-燕莎桥南-亮马桥-农业展览馆-团结湖-甜水园街北口-甜(length:67)
07-21 11:38:56.405: I/txrjsms(24778): 水园北里-金台路口南-红庙路口北-八王坟北-四惠枢纽站 (43站)
07-21 11:38:56.405: I/txrjsms(24778): 回程:四惠枢纽站-八王坟北-红庙路口北-金台路口南-甜水园北里-甜(length:67)
07-21 11:38:56.425: I/txrjsms(24778): 水园街北口-团结湖-农业展览馆-亮马桥-燕莎桥南-三元桥-静安庄-西坝河-和平东桥北-中日医院-对外经贸大学-惠新里-安苑东里-安慧桥(length:67)
07-21 11:38:56.435: I/txrjsms(24778): 北-炎黄艺术馆-大屯南-慧忠北(length:15)

2013年7月22日 上午 测验发送长短信成功(短信中没有*号,避免违禁内容才加上*号)

07-22 07:00:51.828: E/txrjsms(6251): MessageListActivity.sendMultipartTextMessage
07-22 07:00:51.828: E/txrjsms(6251): divide into 2 parts.
07-22 07:00:51.828: I/txrjsms(6251): 中华人民共和国中央军事委员会主席毛*泽东。 中华人民共和国中央军事委员会主席毛*泽东。 中华人民共和国中央军事委员会主席毛*泽东。 中华人民(length:67) 
07-22 07:00:51.828: I/txrjsms(6251): 共和国中央军事委员会主席毛*泽东。 中华人民共和国中央军事委员会主席毛*泽东。(length:37)
07-22 07:00:51.828: E/txrjsms(6251): send long message.
07-22 07:00:55.582: E/txrjsms(6251): send (1/2) msg success.
07-22 07:01:00.586: E/txrjsms(6251): send (2/2) msg success.
07-22 07:01:05.121: E/txrjsms(6251): MessageListActivity.onPause
07-22 07:01:05.271: E/txrjsms(6251): MessageListActivity.onResume
07-22 07:01:05.281: E/txrjsms(6251): ShowSmsActivity.onDestroy // 因为此短信已经读过,所以不再弹窗显示出来。

07-22 07:05:33.202: E/txrjsms(6251): MessageListActivity.sendMultipartTextMessage
07-22 07:05:33.202: E/txrjsms(6251): divide into 2 parts.
07-22 07:05:33.202: I/txrjsms(6251): 中华人民共和国中央军事委员会主席毛*泽东。中华人民共和国中央军事委员会主席毛*泽东。中华人民共和国中央军事委员会主席毛*泽东。中华人民共和国(length:67)
07-22 07:05:33.202: I/txrjsms(6251): 中央军事委员会主席毛*泽东。中华人民共和国中央军事委员会主席毛*泽东。(length:33)
07-22 07:05:33.202: E/txrjsms(6251): send long message.
07-22 07:05:37.326: E/txrjsms(6251): send (1/2) msg success.
07-22 07:05:41.841: E/txrjsms(6251): send (2/2) msg success.
07-22 07:05:46.746: E/txrjsms(6251): MessageListActivity.onPause
07-22 07:05:47.086: E/txrjsms(6251): MessageListActivity.onResume
07-22 07:05:47.086: E/txrjsms(6251): ShowSmsActivity.onDestroy

两次发送长短信都成功,但是内容有一点不同。第1次有4个空格,第2次没有空格。第1次比第2次多4个字符。

07-22 07:11:20.101: E/txrjsms(6251): MessageListActivity.sendMultipartTextMessage
07-22 07:11:20.101: E/txrjsms(6251): divide into 2 parts.
07-22 07:11:20.101: I/txrjsms(6251): 中华人民共和国中央军事委员会主席毛*泽东.中华人民共和国中央军事委员会主席毛*泽东.中华人民共和国中央军事委员会主席毛*泽东.中华人民共和国(length:67)
07-22 07:11:20.101: I/txrjsms(6251): 中央军事委员会主席毛*泽东.中华人民共和国中央军事委员会主席毛*泽东.(length:33)
07-22 07:11:20.101: E/txrjsms(6251): send long message.
07-22 07:11:23.824: E/txrjsms(6251): send (1/2) msg success.
07-22 07:11:28.799: E/txrjsms(6251): send (2/2) msg success.

原文地址:https://www.cnblogs.com/fengzhblog/p/3203558.html