我正在编写一个 Android APK 来通过 SMS 管理 GPS 跟踪器。我的软件有一个特殊的通知部分,可以解码设备通过 SMS 消息发送的所有警报。问题是一些电话公司对 SMS 长度使用不同的限制,所以我的代码由于消息被截断而失败。我测试了三个不同的本地公司,其中一些使用 140 个字符,而另一些使用 70 个字符。我的问题...是否有任何可靠的方法来获取该参数?我已经阅读了所有 SDK 文档,除了明显的常量 MAX_USER_DATA_BYTES 之外没有发现任何类似的东西。
问问题
3448 次
1 回答
2
由于这是一个非常复杂的问题,需要将标准和协议的不同部分拼凑在一起,我决定将我找到的所有信息发布给像我这样需要解决这个问题的人。
所有检查都应直接在 PDU 数据中完成,访问位和字节,在 SmsMessage 中使用getPdu()
或直接从SMSPDU
中的 Bundle 访问数组。onReceive()
BroadcastReceiver
首先,我们需要检查两件事来检测多部分短信:
- 的存在
IDH
,位 6 inPDU_TYPE
- 中存在多部分指示符,信息
IDH
的第二个字节UDH
在检测到多部分消息后,我们需要通过检查 CSMS 标识符、部分数量和部分索引来识别属于同一多部分的消息。
/**
* EXAMPLE OF A PDU
*
* 07 length of SMSC info in bytes
* 91 type of address
* 551218317600 SMSC address (variable size)
* 04 PDU_TYPE to check for IDH embedded test bit 6 0=not UDH 1=has UDH
* 0B address length in nibbles, here is 11 nibbles so its 6 bytes
* 81 address type
* 1089920478F1 sender number (variable size)
* 00 TP-PID
* 08 TP-DCS
* 31105161225188 TP-SCTS timestamp
* 38 TP-UDL user data length
* [USER DATA STARTS HERE] When UDH info is embedded, starts in first
* bytes of user data
*
* EXAMPLE OF UDH for 8 bit CSMS reference (unique number, indicates
* parts belong to same message)
*
* 05 UDH length in bytes
* 00 For multipart 8 bits CSMS it is 00, for 16bits CSMS it is 08
* 03 length of header
* 48 CSMS reference number, this identify SMSs that belong
* to same multi-part
* 02 total parts of this sequence (in this case, 2 parts)
* 02 sequence number (in this case, 2 of 2)
*
*
* EXAMPLE OF UDH for 16 bit CSMS reference (unique number, indicates
* parts belong to same message)
*
* 06 UDH length in bytes
* 00 For multipart 8 bits CSMS it is 00, for 16bits CSMS it is 08
* 04 length of header
* 4823 16 bits CSMS reference number, this identify SMSs that belong
* to the same multi-part
* 02 total parts of this sequence (in this case, 2 parts)
* 01 sequence number (in this case, 1 of 2)
*
*/
// SOME HELPERS TO CHECK FOR MULTIPART INSIDE PDU
private final byte UDH_BITMASK = 0x60;
private final byte MULTIPART_8BITSEQ = 0x00;
private final byte MULTIPART_16BITSEQ = 0x08;
private final int TP_ADDLENGTH_LEN=1;
private final int TP_ADDTYPE_LEN=1;
private final int TP_PID_LEN=1;
private final int TP_DCS_LEN=1;
private final int TP_SCTS_LEN=7;
private final int TP_UDL_LEN=1;
/**
* Check if this PDU message is multi part
* @param pdu
* @return
*/
private boolean isMultiPart(byte[] pdu)
{
// get length of first part+1 SMSC index to PDU type
int idx= pdu[0]+TP_ADDLENGTH_LEN;
if((pdu[idx] & UDH_BITMASK) != 0) // has UDH ??
{
// 00=length of UDH 01=type
int udataidx = getUserDataIndex(pdu);
if( (pdu[udataidx+1] == MULTIPART_8BITSEQ)
|| (pdu[udataidx+1] == MULTIPART_16BITSEQ))
return true;
}
return false;
}
/**
* Return index for user data part. Used to retrieve UDH info
* @param pdu
* @return
*/
private int getUserDataIndex(byte[] pdu)
{
// get index to ADDRESS length
int idx=pdu[0]+ TP_ADDLENGTH_LEN + TP_ADDTYPE_LEN;
// get length in nibbles
int oalength = pdu[idx];
// convert to bytes with padding for odd values
int oalengthinbytes = (oalength + 1) / 2;
return(idx + TP_ADDLENGTH_LEN + TP_ADDTYPE_LEN + oalengthinbytes +
TP_PID_LEN + TP_DCS_LEN + TP_SCTS_LEN + TP_UDL_LEN);
}
于 2013-01-16T14:50:48.200 回答