Android: проблемы с Unicode / Charset при отправке SMS (sendTextMessage) - PullRequest
9 голосов
/ 20 ноября 2010

В основном у меня есть работающее приложение, которое отправляет SMS после получения SMS.

Все отлично работает , кроме случаев, когда текст SMS для отправки имеет "специальныйchars ", то есть" é, à, í, ç "и т. д.

Я пробовал много вещей, включая преобразование кодировки, но просто не могу заставить его работать ... msgText всегда возвращается с charsetпроблемы кодирования.

Вот часть, в которую отправляется сообщение:

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;
}

Почти в отчаянии Я даже попробовал здесь решение для обмена сообщениями в Юникоде (не помогло):

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

В любом случае, вот(очищено - пакет com.THE.APPLICATION, основное действие - MAINACT) LogCat для случая сбоя (при попытке отправить сообщение после его получения):

WARN/dalvikvm(28218): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
ERROR/AndroidRuntime(28218): FATAL EXCEPTION: main
ERROR/AndroidRuntime(28218): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.provider.Telephony.SMS_RECEIVED (has extras) } in com.THE.APPLICATION.SMSReceiver@44acd880
ERROR/AndroidRuntime(28218):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:905)
ERROR/AndroidRuntime(28218):     at android.os.Handler.handleCallback(Handler.java:587)
ERROR/AndroidRuntime(28218):     at android.os.Handler.dispatchMessage(Handler.java:92)
ERROR/AndroidRuntime(28218):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(28218):     at android.app.ActivityThread.main(ActivityThread.java:4627)
ERROR/AndroidRuntime(28218):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(28218):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(28218):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
ERROR/AndroidRuntime(28218):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
ERROR/AndroidRuntime(28218):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(28218): Caused by: java.lang.NullPointerException
ERROR/AndroidRuntime(28218):     at android.os.Parcel.readException(Parcel.java:1253)
ERROR/AndroidRuntime(28218):     at android.os.Parcel.readException(Parcel.java:1235)
ERROR/AndroidRuntime(28218):     at com.android.internal.telephony.ISms$Stub$Proxy.sendText(ISms.java:369)
ERROR/AndroidRuntime(28218):     at android.telephony.SmsManager.sendTextMessage(SmsManager.java:87)
ERROR/AndroidRuntime(28218):     at com.THE.APPLICATION.MAINACT.sendMessage(MAINACT.java:214)
ERROR/AndroidRuntime(28218):     at com.THE.APPLICATION.SMSReceiver.onReceive(SMSReceiver.java:24)
ERROR/AndroidRuntime(28218):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:892)
ERROR/AndroidRuntime(28218):     ... 9 more

Пример текста сообщения для отправкис проблемами:

VERBOSE/debug_tag(28218): msgText is: possível.

Итак, читает possÃvel когда это должно быть возможно

Пожалуйста, какая-нибудь просветленная душа поможет мне.У него / нее будет особое место в моем сердце!:)

Редактировать: Если особое место в моем сердце не порезать его, я готов заплатить несколько баксов за рабочее решение ...

Ответы [ 5 ]

9 голосов
/ 29 ноября 2010

Хорошо, похоже, это было решено простым использованием sendMultipartTextMessage вместо sendTextMessage для сообщений.

Кто бы мог подумать ... это имеет смысл, потому что символы Юникода используют больше «пробела», чем «нормальных».

2 голосов
/ 01 марта 2011

Я использовал этот код для преобразования символов UTF-8 в ASCII.Тогда отправка смс работает и я могу использовать 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();
}
1 голос
/ 27 апреля 2017

У меня такая же проблема со спецсимволами.Когда я изменяю сообщение 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. У меня всегда есть специальные символы в моем приложении.

1 голос
/ 22 сентября 2015

Я использую эту командную строку:

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

и мое SMS-сообщение выглядит идеально.

0 голосов
/ 10 января 2011

Вы можете использовать только 160 символов, если это 7-битная кодировка. Если вы используете 140 символов, оно должно работать без sendMultipartTextMessage, поскольку вы используете 8-разрядные символы (UTF-8).

...