首页 > 代码库 > 解决:insert Vodafone sim card,open the mms read report,when receive the read report,cann't download..

解决:insert Vodafone sim card,open the mms read report,when receive the read report,cann't download..

insert Vodafone sim card,open the mms read report,when receive the read report,cann‘t download the message

Test steps:
1.insert Vodafone sim card
2.open the mms read report
3.send the mms successfully
4.when receive the read report

这里的环境需要描述一下:在国内不会出现这个问题,该问题在土耳其测试发现,经过分析主要因国内外网络差异导致。

问题大概意思是在国外发送一条彩信,对方成功接收,发送方测试会接收一条阅读报告。该阅读报告是以彩信的方式接收。这个时候问题来了,彩信无法自动下载,点击下载按钮也无法完成下载(这里从界面时的确可以这么理解,分析代码之后才发现彩信数据已经下载成功,只是在解析的时候格式不兼容导致解析发生异常,返回null。)

因此经过分析打开NotificationTransaction.java中的log,从log中得到已经下载好的彩信数据,然后在国内用此模拟数据来解决问题。

            if (retrieveConfData != null) {(这里添加注释的意思也就是在这里输出log,得到国外模拟数据,然后在国内进行模拟测试)
                //if (Log.isLoggable(LogTag.TRANSACTION, Log.DEBUG)) {
                    Log.v(TAG, "NotificationTransaction: retrieve data=http://www.mamicode.com/" +
                            HexDump.dumpHexString(retrieveConfData));//HexDump这个工具类很重要,如果有时间大家仔细阅读一下源码(可以将16进制字符串和字节数组进行转换)

                //}

当然,最终修改解决问题的实在解析pdu和持久化保存的PduParser.java类。

case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
                if (LOCAL_LOGV) {
                    Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF");
                }
                RetrieveConf retrieveConf =
                    new RetrieveConf(mHeaders, mBody);

                byte[] contentType = retrieveConf.getContentType();
                if (null == contentType) {
                    if (LOCAL_LOGV)
                        Log.v(LOG_TAG, "contentType is null");
                    return null;
                }
                String ctTypeStr = new String(contentType);
                if (LOCAL_LOGV)
                    Log.v(LOG_TAG, "ctTypeStr is l"+ctTypeStr);
                if (ctTypeStr.equals(ContentType.MULTIPART_MIXED)
                        || ctTypeStr.equals(ContentType.MULTIPART_RELATED)
                        || ctTypeStr.equals(ContentType.TEXT_PLAIN)//这里是添加对“text/plain”格式彩信的兼容
                        || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
                    // The MMS content type must be "application/vnd.wap.multipart.mixed"
                    // or "application/vnd.wap.multipart.related"
                    // or "application/vnd.wap.multipart.alternative"
                    return retrieveConf;
                } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
                    // "application/vnd.wap.multipart.alternative"
                    // should take only the first part.
                    PduPart firstPart = mBody.getPart(0);
                    mBody.removeAll();
                    mBody.addPart(0, firstPart);
                    return retrieveConf;
                }
                return null;

下面这发现异常的时候忽视异常:

protected static PduBody parseParts(ByteArrayInputStream pduDataStream) {
        if (pduDataStream == null) {
            if (LOCAL_LOGV)
                Log.v(LOG_TAG, "pduDataStream is null");
            return null;
        }

        int count = parseUnsignedInt(pduDataStream); // get the number of parts
        PduBody body = new PduBody();

        for (int i = 0 ; i < count ; i++) {
            int headerLength = parseUnsignedInt(pduDataStream);
            int dataLength = parseUnsignedInt(pduDataStream);
            PduPart part = new PduPart();
            int startPos = pduDataStream.available();
            if (startPos <= 0) {
                // Invalid part.
                return body;//这里原本是返回null
            }


            /* parse part‘s content-type */
            HashMap<Integer, Object> map = new HashMap<Integer, Object>();
            byte[] contentType = parseContentType(pduDataStream, map);
            if (null != contentType) {
                part.setContentType(contentType);
            } else {
                if (LOCAL_LOGV)
                    Log.v(LOG_TAG, "contentType isn‘t null");
                part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*"
            }

            /* get name parameter */
            byte[] name = (byte[]) map.get(PduPart.P_NAME);
            if (null != name) {
                part.setName(name);
            }
            else{
                if (LOCAL_LOGV)
                    Log.v(LOG_TAG, "name isn‘t null");
            }
            /* get charset parameter */
            Integer charset = (Integer) map.get(PduPart.P_CHARSET);
            if (null != charset) {
                part.setCharset(charset);
            }
            else{
                if (LOCAL_LOGV)
                    Log.v(LOG_TAG, "charset isn‘t null");
            }
            /* parse part‘s headers */
            int endPos = pduDataStream.available();
            int partHeaderLen = headerLength - (startPos - endPos);
            if (partHeaderLen > 0) {
                if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) {
                    // Parse part header faild.
                    if (LOCAL_LOGV)
                        Log.v(LOG_TAG, "Parse part header faild.");
                    //return null;
                }
            } else if (partHeaderLen < 0) {
                // Invalid length of content-type.
                if (LOCAL_LOGV)
                    Log.v(LOG_TAG, "Invalid length of content-type.");
                //return null;
            }

            /* FIXME: check content-id, name, filename and content location,
             * if not set anyone of them, generate a default content-location
             */
            if ((null == part.getContentLocation())
                    && (null == part.getName())
                    && (null == part.getFilename())
                    && (null == part.getContentId())) {
                part.setContentLocation(Long.toOctalString(
                        System.currentTimeMillis()).getBytes());
            }

            /* get part‘s data */
            if (dataLength > 0) {
                byte[] partData = http://www.mamicode.com/new byte[dataLength];
                String partContentType = new String(part.getContentType());
                pduDataStream.read(partData, 0, dataLength);
                if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) {
                    // parse "multipart/vnd.wap.multipart.alternative".
                    PduBody childBody = parseParts(new ByteArrayInputStream(partData));
                    // take the first part of children.
                    part = childBody.getPart(0);
                } else {
                    // Check Content-Transfer-Encoding.
                    byte[] partDataEncoding = part.getContentTransferEncoding();
                    if (null != partDataEncoding) {
                        String encoding = new String(partDataEncoding);
                        if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
                            // Decode "base64" into "binary".
                            partData = http://www.mamicode.com/Base64.decodeBase64(partData);
                        } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
                            // Decode "quoted-printable" into "binary".
                            partData = http://www.mamicode.com/QuotedPrintable.decodeQuotedPrintable(partData);
                        } else {
                            // "binary" is the default encoding.
                        }
                    }
                    else{
                        if (LOCAL_LOGV)
                            Log.v(LOG_TAG, "partDataEncoding isn‘t null");
                    }
                    if (null == partData) {
                        log("Decode part data error!");
                        return null;
                    }
                    else{
                        if (LOCAL_LOGV)
                            Log.v(LOG_TAG, "partData isn‘t null");
                    }
                    part.setData(partData);
                }
            }

            if(LOCAL_LOGV)
                Log.v(LOG_TAG,"checkPartPosition is "+checkPartPosition(part));
            /* add this part to body */
            if (THE_FIRST_PART == checkPartPosition(part)) {
                /* this is the first part */
                body.addPart(0, part);
            } else {
                /* add the part to the end */
                body.addPart(part);
            }
        }

        return body;
    }