2010-11-20 7 views
8

Về cơ bản tôi có một ứng dụng làm việc gửi một tin nhắn SMS sau khi nhận được một tin nhắn SMS.Android: Unicode/Charset vấn đề khi gửi một tin nhắn SMS (sendTextMessage)

Tất cả mọi thứ hoạt động tốt, trừ khi văn bản SMS để gửi có "ký tự đặc biệt", tức là "é, à, í, ç", vv

Tôi đã thử nhiều thứ trong đó có charset chuyển đổi nhưng tôi chỉ đơn giản là không thể làm cho nó hoạt động ... msgText luôn luôn trở lại với các vấn đề mã hóa charset.

Đây là một phần trong đó thông điệp được gửi:

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

Dưới đây là các chức năng chuyển đổi charset tôi đã cố gắng (nhưng không hiệu quả), mà tôi áp dụng trên 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; 
}

gần tuyệt vọng Tôi thậm chí đã thử giải pháp cho nhắn tin unicode ở đây (cũng không hữu ích):

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

Dù sao, đây là (dọn dẹp - gói là com.THE.APPLICATION, hoạt động chính là MAINACT) LogCat khi nó bị treo (khi cố gắng gửi tin nhắn, sau khi nhận được một):

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 

Sample các tin nhắn văn bản để gửi các vấn đề:

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

Vì vậy, nó đọcpossÃvel khi nó nên đượcpossível

Xin vui lòng một số linh hồn giác ngộ giúp tôi. Anh ấy/cô ấy sẽ có một vị trí đặc biệt trong trái tim tôi! :)

Edit: Nếu vị trí đặc biệt trong trái tim tôi không cắt nó, tôi sẵn sàng trả một vài Bucks cho một giải pháp làm việc ...

Trả lời

8

Ok, điều này dường như đã được giải quyết bằng cách chỉ cần sử dụng sendMultipartTextMessage thay vì sendTextMessage cho thư.

Ai có thể nghĩ ... nó có ý nghĩa bởi vì các ký tự unicode sử dụng nhiều "không gian" hơn so với "bình thường".

0

Bạn chỉ có thể sử dụng 160 ký tự nếu mã hóa 7 bit. Nếu bạn sử dụng 140 ký tự, nó sẽ hoạt động mà không cần sendMultipartTextMessage vì bạn đang sử dụng các ký tự 8 bit (UTF-8).

+1

Làm cho tinh thần, phải không? Nhưng nó không hoạt động nếu không có sendMultipartTextMessage với các ký tự 8 bit (rõ ràng là nó hoạt động cho các ký tự 7 bit không có nó). Tôi cảm thấy có điều gì đó không thực sự đúng trong đó. –

2

Tôi đã sử dụng mã này để chuyển đổi các ký tự UTF-8 thành ASCII. Sau đó gửi công trình SMS và tôi có thể sử dụng 160 ký tự:

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

cảm ơn bài đăng rất hữu ích –

1

Tôi đang sử dụng dòng lệnh này:

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

và tin nhắn SMS của tôi trông hoàn hảo.

+0

Xin chào, Christian. Tôi đã không mã hóa cho Android nguyên bản trong một vài năm, nhưng có vẻ như đó là một giải pháp sạch hơn nhiều mà có thể không tồn tại vào thời điểm đó. –

0

Tôi có cùng sự cố với các ký tự đặc biệt.Khi tôi thay đổi tin nhắn MAX_SMS_MESSAGE_LENGTH thành 70 mọi thứ hoạt động tốt. Nhìn vào liên kết:

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

Đây là mã của tôi:

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

Tất nhiên bạn có thể chèn một bộ điều khiển sẽ kiểm tra xem thông điệp có chứa một số ký tự đặc biệt và sau đó thay đổi MAX_SMS_MESSAGE_LENGTH từ 160 đến 70. Tôi luôn có những nhân vật đặc biệt trong ứng dụng của mình.