Monday, January 30, 2017

Limit EditText's length in Byte

When writing text using EditText on Android, you may need to limit the length in bytes. SMS, and MMS transmission will be typical examples. If we send messages only in English, there will be no problem, but in Hangul, it is expressed as 2 ~ 3 Bytes. The device I am currently dealing with is 3Byte, so I do not know why, but for stability. However, if you read the Byte using CharSet, you can express it in 2bytes.

1.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#e6e6e6"
    android:orientation="vertical" >
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#fff"
        android:inputType="text"/>
</LinearLayout>

2.MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.widget.EditText;

import java.io.UnsupportedEncodingException;

public class MainActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText editText = (EditText) findViewById(R.id.editText);
        InputFilter[] byteFilter = new InputFilter[]{new ByteLengthFilter(10, "KSC5601")};
        editText.setFilters(byteFilter);
    }

    class ByteLengthFilter implements InputFilter {
        private String mCharset;
        protected int mMaxByte;
        public ByteLengthFilter(int maxbyte, String charset) {
            this.mMaxByte = maxbyte;
            this.mCharset = charset;
        }

        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            String expected = new String();
            expected += dest.subSequence(0, dstart);
            expected += source.subSequence(start, end);
            expected += dest.subSequence(dend, dest.length());
            int keep = calculateMaxLength(expected) - (dest.length() - (dend - dstart));
            if(keep < 0) {
                keep = 0;
            }
            int Rekeep = plusMaxLength(dest.toString(), source.toString(), start);

            if (keep <= 0 && Rekeep <= 0) {
                return "";

            }
            else if (keep >= end - start) {
                return null;
            }
            else {
                if( dest.length() == 0 && Rekeep <= 0 ) {
                    return source.subSequence(start, start + keep);
                }
                else if(Rekeep <= 0) {
                    return source.subSequence(start, start + (source.length()-1));
                }
                else {
                    return source.subSequence(start, start + Rekeep);
                }
            }
        }
        protected int plusMaxLength( String expected, String source, int start ) {
            int keep = source.length();
            int maxByte = mMaxByte - getByteLength(expected.toString());

            while (getByteLength(source.subSequence(start, start + keep).toString()) > maxByte) {
                keep--;
            };
            return keep;
        }

        protected int calculateMaxLength(String expected) {
            int expectedByte = getByteLength(expected);
            if (expectedByte == 0) {
                return 0;
            }
            return mMaxByte - (getByteLength(expected) - expected.length());
        }
        private int getByteLength(String str) {
            try {
                return str.getBytes(mCharset).length;
            } catch (UnsupportedEncodingException e) {

            }
            return 0;
        }
    }
}


EmoticonEmoticon