为什么是"@"?被翻译成“¿"在Android 2.3上通过短信发送时? [英] Why is a "@" being translated to "¿" when sent through SMS on Android 2.3?

查看:60
本文介绍了为什么是"@"?被翻译成“¿"在Android 2.3上通过短信发送时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序,该程序通过SMS将命令发送到远程设备.这些命令都是常规文本消息,其中一些以前缀 A @@ 开头.为了测试该应用程序,我使用Android 4.3手机和Android 2.3手机向其他手机发送了一些命令".

I'm developing an Android application which sends commands to a remote equipment through SMS. The commands are all regular text messages, and some of them start with the prefix A@@. To test the app I sent some "commands" to other phones using an Android 4.3 phone and also an Android 2.3 phone.

当我在Android 4.3手机上运行该应用程序时,接收端的SMS可以在任何设备上正常显示,但是如果我使用Android 2.3发送命令,则它们会以A¿¿,但在Android 2.3或iPhone上通常以 A @@ 到达.在目标设备上(它使用GSM调制解调器),该消息类似于 A (字符"A"加上两个空格-ASCII 0x20),因此我怀疑发送者使用的是不同的编码.我发现奇怪的是, @ 符号甚至都不是扩展的ASCII字符,所以我想知道为什么它仍将以除ASCII之外的其他字符集进行编码.

When I run the app on the Android 4.3 phone, the SMS on the receiving end shows just fine on any device, but if I use the Android 2.3 to send the commands they get received as A¿¿ on an Android 4.3 phone but arrive as normally as A@@ either on an Android 2.3 or an iPhone. On the target equipment (it uses a GSM modem) the message gets like A (character "A" plus two spaces - ASCII 0x20), so I suspect the sender is using a different encoding. What I find strange is the @ symbol is not even an extended ASCII char, so I'm wondering why it would be encoded in some other charset than ASCII anyway.

有人可以解释这里发生了什么吗?如果Android 2.3设备确实在使用其他编码,是否可以在发送SMS之前将其强制为ASCII?

Can anyone explain what is happening here? If the Android 2.3 device is really using another encoding, is there a way to force it to ASCII before sending the SMS?

发送代码如下:

@Override
public void sendCommand(String command) {
    //TODO: Send SMS with 'command' as its text message
    SmsManager sms=SmsManager.getDefault();
    PendingIntent piSent=PendingIntent.getBroadcast(this, 0,
                                       new Intent("SMS_SENT"), 0);
    PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0,
                                            new Intent("SMS_DELIVERED"), 0);
    String phone = txtPhone.getText().toString();
    sms.sendTextMessage(phone, null, command, piSent, piDelivered);
}

其中参数 command 始终是前缀与其他一些文本的串联,例如:

Where the parameter command is always the concatenation of the prefix with some other text, like this:

String SmsPrefix = new String("A@@");
sendCommand(SmsPrefix + "AT+DEACT");

更新:

我从某人那里暗示到问题可能与运营商有关,而不是与Android系统本身有关.我住在巴西,我的Android 2.3设备使用的是运营商 TIM ,与我们使用的iPhone相同.Android 4.3设备正在使用运营商 Claro .我发现的是,如果我得到 TIM SIM卡并将其放在Android 4.3设备上,则接收端也会显示乱码的 @ ,因此看来运营商 TIM 弄乱了通过其网络发送的SMS.我将在下面尝试@PMunch的新建议,以便我们可以找到一种解决方法,但可以肯定的是,这并不是从Android 2.3到4.3所纠正的某种错误.

I had a hint from someone that problem might be related to the carrier, not to the Android system itself. I live in Brazil and my Android 2.3 device was using the carrier TIM, just the same as the iPhone we used. The Android 4.3 device was using the carrier Claro. What I found is that, if I get the TIM SIM card and put it on the Android 4.3 device the receiving end also shows the garbled @, so it seems the carrier 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格式发送,但接收方试图以其他编码方式进行解析.如果您在发送方和接收方上都明确指定了编码,那么它应该可以工作.

Really seems like an encoding issue. It might be that you try to send as ASCII but the receiver tries to parse it in a different encoding. If you explicitly specify encoding on both sender and receiver end it should work.

这将获取字符数组并使用US-ASCII编码从中创建一个字符串.

This would get the character array and create a string from it all using US-ASCII encoding.

String newString = new String(oldString.getBytes("US-ASCII"),"US-ASCII"));

事实证明GSM不使用常规的US-ASCII,而是使用它自己的 GSM字母.似乎正在发生的情况是,@(ASCII 0x40)直接以¡(上下感叹号GSM 0x40)转换为GSM字母表.这不会影响常规文本字符,因为它们共享相同的地址(与加号0x2B相同).然后,当转换回它时,它会尝试将它假定的GSM-字母转换为ASCII码,这意味着以前的@符号的0x40现在是一个倒置的感叹号.这是常规ASCII中不存在的符号,因此被未知的字符符号代替,显然是Android 2.3中的颠倒问号和GSM接收器中的空格.从ASCII到GSM的这种缺乏转换似乎已在Android 2.3和Android 4.3之间得到解决.

Turns out GSM doesn't use regular US-ASCII, rather it uses it's own GSM alphabet. What seems to be happening is that the @ (ASCII 0x40) is translated into the GSM alphabet directly as ¡ (Upside down exlamation mark, GSM 0x40). This won't affect regular text characters as they share the same addresses (same for the plus sign 0x2B). Then when converted back it tries to convert it frow what it assumes is GSM-alphabet to ASCII, meaning the 0x40 of the earlier @ sign is now an upside down exclamation mark. This is a sign that does not exist in regular ASCII and is therefore replaced by an unknown character symbol, apparently an upside down question mark in Android 2.3 and a space in the GSM receiver. This lack of conversion from ASCII to GSM seems to have been fixed between Android 2.3 and Android 4.3.

如果您尝试使用 new String("A @@","ISO-8859-1")向Android指定这是一个ASCII字符串,则它可能会自己进行转换.如果不是这样,您可能必须自己做(类似于

If you try to specify to Android that this is an ASCII string by using new String ("A@@","ISO-8859-1") it might do the conversion in it's own. If not you might have to do it yourself (Something like this might help). If @ is the only special character you need to support then you could of course encode that single character yourself(\0\0 for @@).

Edit2包含多个操作,您尝试了什么?要解释整个GSM/ASCII内容:ASCII将其前32个字符用作控制字符.这些字符对于GSM来说是不必要的,因此已被其他字符替换.在用于终止字符串的计算机上,空字符不用于文本消息.它们设置为140个八位位组,任何空白都仅用填充符填充.因此,ASCII中的空字符0x00用于其他字符,即 @ 字符.如果您查看GSM字母和ASCII字母,您会看到32个首字符被希腊字符和其他一些字符代替.如果您查看其余的字符,它们大多在正确的位置,则@字符是不正确的字符之一.例如,如果尝试键入 _ ,您应该会得到类似的结果.当您说 @ A 的形式出现时,您的意思是说 A @@ 成为 A 或成为 AAA ?通过Unicode Inc.提供的Unicode转换,我还发现了一些有趣的东西:

Edit2 included multiple actions, what did you try? To explain the whole GSM/ASCII thing: ASCII uses it's first 32 characters as control characters. These characters were deemed unnecessary for GSM and so they were replaced with other characters. The null character, on computers used to terminate a string, is not used for text messages. They are set at 140 octets and any empty space is simply filled with filler characters. So the null character 0x00 in ASCII is used for something else, the @ character. If you look at the GSM alphabet and the ASCII alphabet you will see that the 32 first characters are replaced by Greek characters and some others. If you look at the remaining characters they are mostly in the right place, the @ character is one of the ones that aren't. If you for example try to type in _ you should get similar results. When you say that @ comes out as A do you then mean that A@@ becomes A or that it becomes AAA? I also found something interesting while looking through Unicode conversion supplied by Unicode Inc.:

0x00为NULL(仅后跟0x00直到(固定字节长度)消息的末尾,也可能最多表单进纸.但是0x00还是COMMERCIAL AT的代码当其他字符时(如果没有其他字符,则返回CARRIAGE)在0x00之后.

因此,如果您尝试仅发送 A @@ ,则最后两个@可能会被解释为填充字符,而不是@字符.无论您所在地区的运营商似乎在它们之间进行了某种转换,您是否都尝试过使用 sendDataMessage 作为原始数据字节?函数 byte [] stringToGsm7BitPacked(String data)从电话中抛出EncodeException .GsmAlphabet应该可以帮助您将字符串转换为GSM字母.

So if you tried to send only A@@ then the two last @s might be interpreted as padding characters instead of @ characters. Regardless it seems like the carriers in your area does some conversion between them, have you tried to send the characters with sendDataMessage as raw data bytes? The function byte[] stringToGsm7BitPacked(String data) throws EncodeException from telephony.GsmAlphabet should help convert your string to the GSM alphabet.

这篇关于为什么是"@"?被翻译成“¿"在Android 2.3上通过短信发送时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆