plus - Android: problemas de Unicode/Charset al enviar un SMS(sendTextMessage)
como activar el acceso a sms premium motorola (5)
Básicamente tengo una aplicación en funcionamiento que envía un SMS después de recibir un SMS.
Todo funciona bien , excepto cuando el texto SMS para enviar tiene "caracteres especiales", es decir, "é, à, í, ç", etc.
He intentado muchas cosas, incluida la conversión de juegos de caracteres, pero simplemente no puedo hacer que funcione ... el msgText siempre regresa con problemas de codificación del juego de caracteres.
Aquí está la parte donde 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 que probé (pero no ayudó), que apliqué 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 ayudó):
http://since2006.com/blog/android-send-unicode-message/
De todos modos, aquí está el (limpiado - el paquete es com.THE.APPLICATION, la actividad principal es MAINACT) LogCat para cuando se cuelga (cuando se trata de enviar el mensaje, después de recibir uno):
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
Muestra del texto del mensaje para enviar con problemas:
VERBOSE/debug_tag(28218): msgText is: possÃvel.
Por lo tanto, dice posible cuando debería ser posible
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 lo corta, estoy dispuesto a pagar unos pocos dólares por una solución funcional ...
Ok, parece que esto se resolvió simplemente usando sendMultipartTextMessage
lugar de sendTextMessage
para los mensajes.
Quién hubiera pensado ... tiene sentido porque los caracteres Unicode usan más "espacio" que los "normales".
Solo puedes usar 160 caracteres si se trata de codificación de 7 bits. Si usa 140 caracteres, debería funcionar sin sendMultipartTextMessage porque está utilizando caracteres de 8 bits (UTF-8).
He usado este código para convertir caracteres UTF-8 en ASCII. Luego, el envío de SMS funciona y puedo usar 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();
}
Estoy usando esta línea de comando:
Html.fromHtml(new String(myString.getBytes("UTF-8"))).toString();
y mi mensaje SMS se ve perfecto.
Tengo el mismo problema con los personajes especiales. Cuando cambio el mensaje MAX_SMS_MESSAGE_LENGTH a 70, todo funciona bien. Mira ese enlace:
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, puede insertar un controlador que verifique si el mensaje contiene algún carácter especial y luego cambie MAX_SMS_MESSAGE_LENGTH de 160 a 70. Siempre tengo caracteres especiales en mi aplicación.