Harry
Harry

Reputation: 578

Android - Determine SMS Text Limit

I'm working on a marketing app with sharing (by SMS) feature. I need to determine the maximum allowed characters for THE FIRST PART of SMS. Normally the limit is 160 characters.

When I type something, e.g. "ABC", it becomes:

3 / 160

But when I add character, it should become:

4 / 70 , instead of 4 / 160

And this works not only for special characters, but also Chinese character as well. How to achieve this?

EDIT:

Below is my code so far:

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

But this is WRONG, because it only works when the SMS limit is reached. I want it to be working when the special character is inputted.

Upvotes: 5

Views: 1334

Answers (2)

Ioane Sharvadze
Ioane Sharvadze

Reputation: 2148

Maybe you should modify your code like this?

I had same situation , and solved like this. :) hope it helps.

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

UPDATE

Second version is

private static CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();

boolean isASCII(String str){
   return encoder.canEncode(str);
}

I think this also traverses whole string and as you mentioned it's slow.

I think if you want faster performance you need to override beforeTextChanged and onTextChanged and get what characters are added or deleted by user. If user deletes all unicode characters you can assume that your string is ASCII, so won't need to traverse same string on every change, just you need to look at added/deleted characters, that's optimization.

Upvotes: 8

Sajad Garshasbi
Sajad Garshasbi

Reputation: 508

because ♥ is not standard ASCII character and is Unicode!, and each Unicode character is 2 byte, but each ASCII character is 1 byte. standard ASCII

Upvotes: 2

Related Questions