【问题标题】:Android: Unicode/Charset problems when sending an SMS (sendTextMessage)Android:发送 SMS (sendTextMessage) 时出现 Unicode/Charset 问题
【发布时间】:2010-11-20 15:28:31
【问题描述】:

基本上我有一个在收到短信后发送短信的工作应用程序。

一切正常,除了短信发送有“特殊字符”,即“é,à,í,ç”等。

我尝试了很多方法,包括字符集转换,但我根本无法让它工作...... msgText 总是返回字符集编码问题。

这是发送消息的部分:

if (msgText.length() > 160) {
    ArrayList msgTexts = sm.divideMessage(msgText);
    sm.sendMultipartTextMessage(PhoneNumber, null, msgTexts, null, null);
} else {
    try {
        sm.sendTextMessage(PhoneNumber, null, msgText, null, null);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }
}

这是我在 msgText 上尝试过的字符集转换函数(但没有帮助):

public static String formatCharset(String txtInicial) {
    //-- Please notice this is just for reference, I tried every charset from/to conversion possibility. Even stupid ones and nothing helped.

    /*try {//-- Seems simpler, it should do the same as below, but didn't help
        msgText = new String(msgText.getBytes("UTF-8"), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
    }*/

    Charset charsetOrigem = Charset.forName("UTF-8");
    CharsetEncoder encoderOrigem = charsetOrigem.newEncoder();
    Charset charsetDestino = Charset.forName("ISO-8859-1");
    CharsetDecoder decoderDestino = charsetDestino.newDecoder();

    String txtFinal = "";

    try {
        ByteBuffer bbuf = encoderOrigem.encode(CharBuffer.wrap( txtInicial ));
        CharBuffer cbuf = decoderDestino.decode(bbuf);
        txtFinal = cbuf.toString();
    } catch (CharacterCodingException e) {
        e.printStackTrace();
    }

    if (txtFinal.length() == 0) txtFinal = txtInicial;

    return txtFinal;
}

几乎绝望,我什至在这里尝试了 unicode 消息传递的解决方案(也没有帮助):

http://since2006.com/blog/android-send-unicode-message/

无论如何,这是(清理 - 包是 com.THE.APPLICATION,主要活动是 MAINACT)LogCat 崩溃时(尝试发送消息时,收到消息后):

WARN/dalvikvm(28218): threadid=1: 线程以未捕获的异常退出 (group=0x4001d7f0)
错误/AndroidRuntime(28218):致命异常:主要
ERROR/AndroidRuntime(28218): java.lang.RuntimeException: 在 com.THE.APPLICATION.SMSReceiver@44acd880 中接收广播 Intent { act=android.provider.Telephony.SMS_RECEIVED (has extras) } 时出错
错误/AndroidRuntime(28218):在 android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:905)
错误/AndroidRuntime(28218):在 android.os.Handler.handleCallback(Handler.java:587)
错误/AndroidRuntime(28218):在 android.os.Handler.dispatchMessage(Handler.java:92)
错误/AndroidRuntime(28218):在 android.os.Looper.loop(Looper.java:123)
错误/AndroidRuntime(28218):在 android.app.ActivityThread.main(ActivityThread.java:4627)
错误/AndroidRuntime(28218):在 java.lang.reflect.Method.invokeNative(本机方法)
错误/AndroidRuntime(28218):在 java.lang.reflect.Method.invoke(Method.java:521)
错误/AndroidRuntime(28218):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
错误/AndroidRuntime(28218):在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
错误/AndroidRuntime(28218):在 dalvik.system.NativeStart.main(本机方法)
错误/AndroidRuntime(28218):由:java.lang.NullPointerException 引起
错误/AndroidRuntime(28218):在 android.os.Parcel.readException(Parcel.java:1253)
错误/AndroidRuntime(28218):在 android.os.Parcel.readException(Parcel.java:1235)
错误/AndroidRuntime(28218):在 com.android.internal.telephony.ISms$Stub$Proxy.sendText(ISms.java:369)
错误/AndroidRuntime(28218):在 android.telephony.SmsManager.sendTextMessage(SmsManager.java:87)
错误/AndroidRuntime(28218):在 com.THE.APPLICATION.MAINACT.sendMessage(MAINACT.java:214)
错误/AndroidRuntime(28218):在 com.THE.APPLICATION.SMSReceiver.onReceive(SMSReceiver.java:24)
错误/AndroidRuntime(28218):在 android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:892)
错误/AndroidRuntime(28218): ... 9 更多

发送有问题的消息文本示例:

VERBOSE/debug_tag(28218): msgText 是:possÃvel。

所以,它读取 possÃvel什么时候应该 possível

请一些开明的灵魂帮助我。他/她将在我心中占有特殊的位置! :)

编辑:如果我心中的特殊位置没有削减它,我愿意花几块钱买一个可行的解决方案......

【问题讨论】:

    标签: android sms special-characters character-encoding


    【解决方案1】:

    好的,这似乎已经通过简单地使用sendMultipartTextMessage 而不是sendTextMessage 来解决消息。

    谁会想到...这有点道理,因为 unicode 字符比“普通”字符使用更多的“空格”。

    【讨论】:

    • 当我这样发送时,'?'正在显示每个 unicode 字符。我错过了什么吗?
    【解决方案2】:

    我已使用此代码将 UTF-8 字符转换为 ASCII。然后发送 SMS 工作,我可以使用 160 个字符:

    private static final String PLAIN_ASCII = "AaEeIiOoUu" // grave
            + "AaEeIiOoUuYy" // acute
            + "AaEeIiOoUuYy" // circumflex
            + "AaOoNn" // tilde
            + "AaEeIiOoUuYy" // umlaut
            + "Aa" // ring
            + "Cc" // cedilla
            + "OoUu" // double acute
    ;
    
    private static final String UNICODE = "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9"
            + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD"
            + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177"
            + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1"
            + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF"
            + "\u00C5\u00E5" + "\u00C7\u00E7" + "\u0150\u0151\u0170\u0171";
    
    // remove accentued from a string and replace with ascii equivalent
    public static String convertNonAscii(String s) {
        if (s == null)
            return null;
        StringBuilder sb = new StringBuilder();
        int n = s.length();
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            int pos = UNICODE.indexOf(c);
            if (pos > -1) {
                sb.append(PLAIN_ASCII.charAt(pos));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
    

    【讨论】:

      【解决方案3】:

      我正在使用这个命令行:

      Html.fromHtml(new String(myString.getBytes("UTF-8"))).toString();
      

      我的短信看起来很完美。

      【讨论】:

      • 嗨,克里斯蒂安。我已经好几年没有原生地为 Android 编写代码了,但它似乎是一个更简洁的解决方案,当时可能不存在。
      【解决方案4】:

      如果是 7 位编码,您只能使用 160 个字符。如果您使用 140 个字符,它应该在没有 sendMultipartTextMessage 的情况下工作,因为您使用的是 8 位字符 (UTF-8)。

      【讨论】:

      • 有道理,对吧?但是如果没有带有 8 位字符的 sendMultipartTextMessage 则它不起作用(显然它适用于没有它的 7 位字符)。我觉得里面有些东西不太对劲。
      【解决方案5】:

      我对特殊字符也有同样的问题。当我将消息 MAX_SMS_MESSAGE_LENGTH 更改为 70 时,一切正常。看那个链接:

      https://forums.macrumors.com/threads/special-characters-in-sms-turn-them-shorter-70-characters-old-issue-never-solved.1030577/

      这是我的代码:

          public static void sendSMS(String phoneNumber, String message, Context context) {
      
          String SENT = "SMS_SENT";
          int MAX_SMS_MESSAGE_LENGTH = 70;
      
          SmsManager smsManager = SmsManager.getDefault();
          PendingIntent sentPI;
          sentPI = PendingIntent.getBroadcast(context, 0,new Intent(SENT), 0);
      
          try {
              if(message.length() > MAX_SMS_MESSAGE_LENGTH) {
                  ArrayList<String> messageList = SmsManager.getDefault().divideMessage(message);
                  smsManager.sendMultipartTextMessage(phoneNumber, null, messageList, null, null);
              } else {
                  smsManager.sendTextMessage(phoneNumber, null, message, sentPI, null);
              }
          } catch (Exception e) {
              Log.e("SmsProvider", "" + e);
          }
      }
      

      当然,您可以插入一个控制器来检查消息是否包含一些特殊字符,然后将 MAX_SMS_MESSAGE_LENGTH 从 160 更改为 70。我的应用程序中总是有特殊字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        • 2011-07-24
        • 2017-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多