最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Android parsing of bMessage for MIME message - Stack Overflow

programmeradmin2浏览0评论

We are trying to figure out how to properly format a put BMSG when sending it to an Android devices so it will push it onwards to the receivers. The type of BMSG we are attempting is TYPE=MMS and when we're debugging it on the Android platform to see how it should be formatted our test string looks like:

String testMsgStr ="BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:UNREAD\r\nTYPE:MMS\r\nFOLDER:\r\nBEGIN:BENV\r\nBEGIN:VCARD\r\nVERSION:2.1\r\nN:0706500000\r\nTEL:0706500000\r\nEND:VCARD\r\nBEGIN:BBODY\r\nENCODING:8BIT\r\nCHARSET:UTF-8\r\nLANGUAGE:UNKNOWN\r\nLENGTH:1050\r\nBEGIN:MSG\r\nDate: Fri, 17 Jan 2025 12:12:57 +0100\r\nFrom: <+46727007316>;\r\nTo: Test Test <+467065000000>;\r\nContent-Type: application/vnd.wap.multipart.related; boundary=--=_cd6e9876-cee0-4260-b62a-84793cc623d4\r\n\r\n----=_cd6e9876-cee0-4260-b62a-84793cc623d4\r\nContent-Type: application/smil; charset=\"utf-8\"\r\nContent-Location: smil.xml\r\nContent-ID: <smil>\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n<smil><head><layout><root-layout/><region id=\"Image\" fit=\"meet\" top=\"0\" left=\"0\" height=\"100%\" width=\"100%\"/></layout></head><body><par dur=\"5000ms\"><img src=\"image000000.gif\" region=\"Image\" /></par></body></smil>\r\n----=_cd6e9876-cee0-4260-b62a-84793cc623d4\r\nContent-Type: image/gif\r\nContent-Location: image000000.gif\r\nContent-ID: <image000000>\r\nContent-Transfer-Encoding: Base64\r\n\r\nR0lGODlhMgAyAIAAAAAAAP///yH5BAAAAAAALAAAAAAyADIAAAJ5jI+py+0Po5y02ouz3rz7D27A\nCI7AZJpdSj5q0Ipn6rzwyan2Yscai6vpgrIdA0gMQVjKpvMJjUqnF1ySikX4stot9+ZFXatjSdhi\nFHvSyzO53HC/4Qr2z57A3+VgKK2ut8YERqeEVPj097XI2Oj4CBkpOUlZaelYAAA7\n\r\n----=_cd6e9876-cee0-4260-b62a-84793cc623d4--\r\nEND:MSG\r\nEND:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n";

The problem we're facing is that the Android library that handles this data will read each line. The specific issue is regarding parsing the actual MSG. When it finds BEGIN:MSG\r\n it will then read each line using this function:

        private byte[] getLineAsBytes() {
            int readByte;
            /* TODO: Actually the vCard spec. allows to break lines by using a newLine
             * followed by a white space character(space or tab). Not sure this is a good idea to
             * implement as the Bluetooth MAP spec. illustrates vCards using tab alignment,
             * hence actually showing an invalid vCard format...
             * If we read such a folded line, the folded part will be skipped in the parser
             * UPDATE: Check if we actually do unfold before parsing the input stream
             */
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            try {
                while ((readByte = mInStream.read()) != -1) {
                    System.out.print((char) readByte);
                    if (readByte == '\r') {
                        if ((readByte = mInStream.read()) != -1 && readByte == '\n') {
                            if (output.size() == 0) {
                                continue; /* Skip empty lines */
                            } else {
                                break;
                            }
                        } else {
                            output.write('\r');
                        }
                    } else if (readByte == '\n' && output.size() == 0) {
                        /* Empty line - skip */
                        continue;
                    }
                    output.write(readByte);
                }
            } catch (IOException e) {
                Log.w(TAG, e);
                return null;
            }
            return output.toByteArray();
        }

until it reaches END:MSG\r\n.

For every line it appends it to a string and when it reaches END:MSG it has the full MSG-string. As you can see in the getLineAsBytes() function this will remove all \r\n from the lines before returning it.

When the whole message has been read it tries to parse it as MIME. In that part of the code it starts like this:

   private void parseMime(String message) {
        // Check for null String, otherwise NPE will cause BT to crash
        if (message == null) {
            Log.e(TAG, "parseMime called with a NULL message, terminating early");
            return;
        }
        /* Overall strategy for decoding:
         * 1) split on first empty line to extract the header
         * 2) unfold and parse headers
         * 3) split on boundary to split into parts (or use the remaining as a part,
         *    if part is not found)
         * 4) parse each part
         * */
        String[] messageParts;
        String[] mimeParts;
        String remaining = null;
        String messageBody = null;
        message = message.replaceAll("\\r\\n[ \\\t]+", ""); // Unfold
        messageParts = message.split("\r\n\r\n", 2); // Split the header from the body
        if (messageParts.length != 2) {
            // Handle entire message as plain text
            messageBody = message;
        } else {
            remaining = parseMimeHeaders(messageParts[0]);
            // If we have some text not being a header, add it to the message body.
            if (remaining != null) {
                messageBody = remaining + messageParts[1];
                if (D) {
                    Log.d(TAG, "parseMime remaining=" + remaining);
                }
            } else {
                messageBody = messageParts[1];
            }
        }

as you can see it tries to find \r\n\r\n in the String so it can separate the headers from the body. But the previous code that reads all the data line by line has already removed any \r\n. So we're trying to figure out if there is any way we can format our data-string differently so that this official Android code actually works.

Or does anyone know if this is a known issue in Android?

发布评论

评论列表(0)

  1. 暂无评论