Cla*_*dio 3 sms encoding android
我正在开发一个 Android 应用程序,它通过 SMS 向远程设备发送命令。这些命令都是常规短信,其中一些以前缀开头A@@。为了测试该应用程序,我使用 Android 4.3 手机和 Android 2.3 手机向其他手机发送了一些“命令”。
当我在 Android 4.3 手机上运行该应用程序时,接收端的短信在任何设备上都显示得很好,但如果我使用 Android 2.3 发送命令,它们会像在A\xc2\xbf\xc2\xbfAndroid 4.3 手机上一样收到,但会正常A@@到达在 Android 2.3 或 iPhone 上。在目标设备(它使用 GSM 调制解调器)上,消息类似于A(字符“A”加两个空格 - ASCII 0x20),因此我怀疑发送者正在使用不同的编码。我觉得奇怪的是@符号甚至不是扩展的 ASCII 字符,所以我想知道为什么它会以 ASCII 之外的其他字符集进行编码。
谁能解释这里发生了什么?如果 Android 2.3 设备确实使用其他编码,有没有办法在发送 SMS 之前强制其使用 ASCII?
\n\n发送代码如下:
\n\n@Override\npublic void sendCommand(String command) {\n //TODO: Send SMS with \'command\' as its text message\n SmsManager sms=SmsManager.getDefault();\n PendingIntent piSent=PendingIntent.getBroadcast(this, 0,\n new Intent("SMS_SENT"), 0);\n PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0,\n new Intent("SMS_DELIVERED"), 0);\n String phone = txtPhone.getText().toString();\n sms.sendTextMessage(phone, null, command, piSent, piDelivered);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n其中参数command is always the concatenation of the prefix with some other text, like this:
String SmsPrefix = new String("A@@");\nsendCommand(SmsPrefix + "AT+DEACT");\nRun Code Online (Sandbox Code Playgroud)\n\n更新:
\n\n有人向我暗示,问题可能与运营商有关,而不是与 Android 系统本身有关。我住在巴西,我的 Android 2.3 设备使用的是该运营商TIM,就像我们使用的 iPhone 一样。Android 4.3 设备使用该运营商Claro。我发现,如果我拿到TIMSIM卡并将其放在Android 4.3设备上,接收端也显示乱码@,所以看来是运营商TIM is messing up the SMS sent through their network. I will try the new suggestions from @PMunch below so we can possibly find a workaround, but we can be sure already it wasn\'t really some kind of bug corrected from Android 2.3 to 4.3.
确实看起来像一个编码问题。可能您尝试以 ASCII 形式发送,但接收方尝试以不同的编码对其进行解析。如果您在发送方和接收方都明确指定编码,那么它应该可以工作。
\n\n编辑:
\n\n这将获取字符数组并使用 US-ASCII 编码从中创建一个字符串。
\n\nString newString = new String(oldString.getBytes("US-ASCII"), "US-ASCII"));
编辑2:
\n\n结果 GSM 不使用常规的 US-ASCII,而是使用它自己的GSM 字母表。似乎正在发生的事情是@(ASCII 0x40)被直接翻译成GSM字母表\xc2\xa1(颠倒的感叹号,GSM 0x40)。这不会影响常规文本字符,因为它们共享相同的地址(加号 0x2B 也相同)。然后,当转换回来时,它会尝试将其假定的 GSM 字母转换为 ASCII,这意味着之前的 @ 符号的 0x40 现在是一个颠倒的感叹号。这是一个在常规 ASCII 中不存在的符号,因此被一个未知的字符符号取代,显然是 Android 2.3 中的倒置问号和 GSM 接收器中的空格。缺乏从 ASCII 到 GSM 转换的问题似乎已在 Android 2.3 和 Android 4.3 之间得到修复。
\n\n如果您尝试使用 Android 指定这是一个 ASCII 字符串,new String ("A@@","ISO-8859-1")它可能会自行进行转换。如果没有,您可能必须自己做(这样的事情可能会有所帮助)。如果@是您需要支持的唯一特殊字符,那么您当然可以自己编码该单个字符(\\0\\0 for @@)。
编辑3:
\n\nEdit2 包含多个操作,您尝试了什么?解释整个 GSM/ASCII 的事情:\nASCII 使用它的前 32 个字符作为控制字符。这些字符对于 GSM 来说是不必要的,因此被其他字符替换。计算机上用于终止字符串的空字符不用于文本消息。它们被设置为 140 个八位位组,任何空白空间都简单地用填充字符填充。因此 ASCII 中的空字符 0x00 用于其他字符,即字符@。如果您查看 GSM 字母表和 ASCII 字母表,您会发现前 32 个字符被希腊字符和其他一些字符替换。如果您查看其余的字符,它们大多位于正确的位置,@ 字符是不正确的字符之一。例如,如果您尝试输入,_您应该会得到类似的结果。当你说“@结果是”A时,你的意思是“A@@变成”A还是“它变成” AAA?在查看 Unicode Inc. 提供的 Unicode 转换时,我还发现了一些有趣的东西:
0x00 is NULL (when followed only by 0x00 up to the\nend of (fixed byte length) message, possibly also up to\nFORM FEED. But 0x00 is also the code for COMMERCIAL AT\nwhen some other character (CARRIAGE RETURN if nothing else)\ncomes after the 0x00.
因此,如果您尝试仅发送A@@,那么最后两个 @ 可能会被解释为填充字符而不是 @ 字符。不管您所在地区的运营商似乎在它们之间进行了一些转换,您是否尝试过使用sendDataMessage作为原始数据字节发送字符?telephony.GsmAlphabet 的函数byte[] stringToGsm7BitPacked(String data) throws EncodeException应该可以帮助您将字符串转换为 GSM 字母表。
| 归档时间: |
|
| 查看次数: |
2664 次 |
| 最近记录: |