2010-11-20 31 views
8

Básicamente tengo una aplicación que envía un SMS después de recibir un SMS.Android: problemas de Unicode/Charset al enviar un SMS (sendTextMessage)

Todo funciona bien, excepto cuando el texto SMS para enviar tiene "caracteres especiales", es decir, "E, A, I, C", etc.

He intentado muchas cosas, incluyendo juego de caracteres conversión pero simplemente no puedo hacer que funcione ... el msgText siempre regresa con problemas de codificación de conjunto de caracteres.

Aquí está la parte en la que se envía el mensaje:

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

Aquí está la función de conversión de juego de caracteres Probé (pero no sirvió de nada), que he aplicado en 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; 
}

Cerca de la desesperación Incluso probé la solución para mensajes Unicode aquí (tampoco me ayudó):

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

De todos modos, aquí está el (limpiado - paquete es com.THE.APPLICATION, la actividad principal es MAINACT) LogCat para cuando se rompe (cuando se trata de enviar el mensaje, después de recibir una):

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 [email protected] 
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 

Muestra del texto del mensaje a enviar con problemas:

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

Así, se lee possÃvel cuando debería ser possível

Por favor, algún alma iluminada me ayude. ¡Él/Ella tendrá un lugar especial en mi corazón! :)

Editar: Si el lugar especial en mi corazón no es suficiente, yo estoy dispuesto a pagar un poco de dinero para una solución de trabajo ...

Respuesta

8

Ok, esto parece haber sido resuelto por simplemente usando sendMultipartTextMessage en lugar de sendTextMessage para los mensajes.

Quién hubiera pensado ... tiene sentido porque los caracteres Unicode usan más "espacio" que los "normales".

0

Solo puede usar 160 caracteres si se trata de una codificación de 7 bits. Si usa 140 caracteres, debería funcionar sin sendMultipartTextMessage porque está utilizando caracteres de 8 bits (UTF-8).

+1

Tiene sentido, ¿no? Pero no funciona sin sendMultipartTextMessage con caracteres de 8 bits (obviamente funciona para caracteres de 7 bits sin él). Siento que algo no está del todo bien allí. –

2

He usado este código para convertir caracteres UTF-8 en ASCII. A continuación, el envío de SMS de obras y puedo utilizar 160 caracteres:

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(); 
} 
+0

gracias muy buena publicación útil –

1

que estoy usando esta línea de comandos:

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

y mi mensaje SMS se ve perfecto.

+0

Hola, Christian. No he codificado para Android de forma nativa en algunos años, pero parece que es una solución mucho más limpia que tal vez no existía en ese momento. –

0

Tengo el mismo problema con los caracteres especiales.Cuando cambio el mensaje MAX_SMS_MESSAGE_LENGTH a 70, todo funciona bien. Mira que enlazan:

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

Este es mi código:

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

Por supuesto se puede insertar un controlador que comprobar si el mensaje contiene algún carácter especial y luego cambiar MAX_SMS_MESSAGE_LENGTH de 160 a 70. Siempre tengo caracteres especiales en mi aplicación.

Cuestiones relacionadas