Android - 确定短信文本限制
Android - Determine SMS Text Limit
我正在开发具有共享(通过短信)功能的营销应用程序。
我需要确定短信第一部分允许的最大字符数。通常限制为 160 个字符。
当我输入内容时,例如"ABC",变成:
3 / 160
但是当我添加♥
字符时,它应该变成:
4 / 70
,而不是 4 / 160
这不仅适用于特殊字符,也适用于汉字。如何实现?
编辑:
下面是我目前的代码:
mSMS = (EditText) findViewById(R.id.SMS);
mSMS.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void afterTextChanged(Editable editable) {
String SMSText = mSMS.getText().toString();
String SMSLimit = "160";
SmsManager manager = SmsManager.getDefault();
ArrayList<String> messageParts = manager.divideMessage(SMSText);
if(messageParts.size() > 1){
if(messageParts.get(0).length() <= 70)
SMSLimit = "70";
} mCounter.setText(String.valueOf(SMSText.length()) + " / " + SMSLimit);
}
});
但这是错误,因为它只有在达到短信限制时才有效。我希望它在输入特殊字符时工作。
因为♥不是标准的ASCII字符,是Unicode!,每个Unicode字符占2个字节,而每个ASCII字符占1个字节。
standard ASCII
也许你应该像这样修改你的代码?
我遇到了同样的情况,就这样解决了。 :) 希望对您有所帮助。
boolean isASCII(String str){
for(int i=0;i<str.length();i++){
if(str.charAt(i) >= 128)
return false;
}
return true;
}
@Override
public void afterTextChanged(Editable editable) {
String SMSText = mSMS.getText().toString();
String SMSLimit = "160";
SmsManager manager = SmsManager.getDefault();
ArrayList<String> messageParts = manager.divideMessage(SMSText);
if(messageParts.size() > 1){
String smsStr = messageParts.get(0);
if(!isASCII(smsStr)) SMSLimit = "70";
}
mCounter.setText(String.valueOf(SMSText.length()) + " / " + SMSLimit);
}
更新
第二个版本是
private static CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
boolean isASCII(String str){
return encoder.canEncode(str);
}
我认为这也会遍历整个字符串,正如您提到的那样,它很慢。
我认为如果你想要更快的性能,你需要覆盖 beforeTextChanged
和 onTextChanged
并获取用户添加或删除的字符。
如果用户删除所有 unicode
个字符,您可以假设您的字符串是 ASCII
,因此不需要在每次更改时遍历相同的字符串,只需要查看 added/deleted 个字符,即优化。
我正在开发具有共享(通过短信)功能的营销应用程序。 我需要确定短信第一部分允许的最大字符数。通常限制为 160 个字符。
当我输入内容时,例如"ABC",变成:
3 / 160
但是当我添加♥
字符时,它应该变成:
4 / 70
,而不是 4 / 160
这不仅适用于特殊字符,也适用于汉字。如何实现?
编辑:
下面是我目前的代码:
mSMS = (EditText) findViewById(R.id.SMS);
mSMS.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void afterTextChanged(Editable editable) {
String SMSText = mSMS.getText().toString();
String SMSLimit = "160";
SmsManager manager = SmsManager.getDefault();
ArrayList<String> messageParts = manager.divideMessage(SMSText);
if(messageParts.size() > 1){
if(messageParts.get(0).length() <= 70)
SMSLimit = "70";
} mCounter.setText(String.valueOf(SMSText.length()) + " / " + SMSLimit);
}
});
但这是错误,因为它只有在达到短信限制时才有效。我希望它在输入特殊字符时工作。
因为♥不是标准的ASCII字符,是Unicode!,每个Unicode字符占2个字节,而每个ASCII字符占1个字节。 standard ASCII
也许你应该像这样修改你的代码?
我遇到了同样的情况,就这样解决了。 :) 希望对您有所帮助。
boolean isASCII(String str){
for(int i=0;i<str.length();i++){
if(str.charAt(i) >= 128)
return false;
}
return true;
}
@Override
public void afterTextChanged(Editable editable) {
String SMSText = mSMS.getText().toString();
String SMSLimit = "160";
SmsManager manager = SmsManager.getDefault();
ArrayList<String> messageParts = manager.divideMessage(SMSText);
if(messageParts.size() > 1){
String smsStr = messageParts.get(0);
if(!isASCII(smsStr)) SMSLimit = "70";
}
mCounter.setText(String.valueOf(SMSText.length()) + " / " + SMSLimit);
}
更新
第二个版本是
private static CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
boolean isASCII(String str){
return encoder.canEncode(str);
}
我认为这也会遍历整个字符串,正如您提到的那样,它很慢。
我认为如果你想要更快的性能,你需要覆盖 beforeTextChanged
和 onTextChanged
并获取用户添加或删除的字符。
如果用户删除所有 unicode
个字符,您可以假设您的字符串是 ASCII
,因此不需要在每次更改时遍历相同的字符串,只需要查看 added/deleted 个字符,即优化。