Edittext入力のバイト長を制限


デバイスの名前を変更する場合、デバイスの名前に対する記憶空間は一般的に何バイトであり、何ワードではなく、utf-8の符号化が一般的である.では、utf-8の符号化は1~6バイトの不等長であり、30バイトを超えるテキストを30バイト以内に変換するにはどうすればいいのでしょうか.
Javaでutf-8テキストを取得するバイト長は、以下のように簡単です.
text.getBytes("utf-8").length

しかし、30バイトを超える文字列を30バイトに切り取ると文字化けしてしまう.文字列の長さが31バイト、文字列の最後が漢字である場合、漢字は一般的に3バイトを占有し、すなわち[29,30,31]バイト目が漢字を表し、30に切り取ると最後の漢字は[29,30]の2桁しか残って表示されず、このときに先に文字化けが発生する.文字を削除し、文字の文字化けしを防ぐ方法です.第1歩は、まず文字列をchar配列に変換し、charはJavaの中で2バイトを占有し、unicode符号化を採用する.第2ステップでは、各charのunicodeをutf-8符号化の長さに変換し、charの総長を計算する
   |  Unicode           |  UTF-8      
 n |  (    )            | (   )  
---+-----------------------+------------------------------------------------------  
 1 | 0000 0000 - 0000 007F |                                              0xxxxxxx  
 2 | 0000 0080 - 0000 07FF |                                     110xxxxx 10xxxxxx  
 3 | 0000 0800 - 0000 FFFF |                            1110xxxx 10xxxxxx 10xxxxxx  
 4 | 0001 0000 - 0010 FFFF |                   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  
 5 | 0020 0000 - 03FF FFFF |          111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
 6 | 0400 0000 - 7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  

上記のUnicode符号とUTF-8符号化との対応関係から、バイト長を制限するプログラムを作成することができる.
 
public static String getWholeText(String text, int byteCount){
    try {
        if (text != null && text.getBytes("utf-8").length > byteCount) {
            char[] tempChars = text.toCharArray();
            int sumByte = 0;
            int charIndex = 0;
            for (int i = 0, len = tempChars.length; i < len; i++) {
                char itemChar = tempChars[i];
                //   Unicode ,         
                if (itemChar >= 0x0000 && itemChar <= 0x007F) {
                    sumByte += 1;
                } else if (itemChar >= 0x0080 && itemChar <= 0x07FF) {
                    sumByte += 2;
                } else {
                    sumByte += 3;
                }
                if (sumByte > byteCount) {
                    charIndex = i;
                    break;
                }
            }
            return String.valueOf(tempChars, 0, charIndex);
        }
    } catch (UnsupportedEncodingException e) {
    }
    return text;
}

1つのcharは2ビットしかないため、utf-8フォーマットの3バイトしか表示できないが、ここではこのように処理する.またutf-8バイトの長さは1-6ビットと前述したが,ここでは3ビット以内で表される文字しか計算されておらず,依然として厳密ではない.次号ではより完璧な計算方式を示し,まず6ビットの表現を実現するために参考にすることができる.
Edittext入力を制限するコードを添付します.
public class MaxLimitTextWatcher implements TextWatcher {

	private int mMaxBytes;
	private EditText mEditText;
	
	public MaxLimitTextWatcher(EditText editText, int maxBytes) {
		mEditText = editText;
		mMaxBytes = maxBytes;
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		Editable editable = mEditText.getText();  
        int len = editable.toString().getBytes().length;  
          
        if(len > mMaxBytes)  
        {
            int selEndIndex = Selection.getSelectionEnd(editable);  
            String str = editable.toString();  
            //        
            String newStr = getWholeText(str, mMaxBytes);
            mEditText.setText(newStr);  
            editable = mEditText.getText();  
              
            //         
            int newLen = editable.length();
            //              
            if(selEndIndex > newLen)  
            {
                selEndIndex = editable.length();  
            }
            //            
            Selection.setSelection(editable, selEndIndex);  
        }
	}

	@Override
	public void afterTextChanged(Editable s) {
		
	}
	
	public static String getWholeText(String text, int byteCount){
	    try {
	        if (text != null && text.getBytes("utf-8").length > byteCount) {
	            char[] tempChars = text.toCharArray();
	            int sumByte = 0;
	            int charIndex = 0;
	            for (int i = 0, len = tempChars.length; i < len; i++) {
	                char itemChar = tempChars[i];
	                //   Unicode ,         
	                if (itemChar >= 0x0000 && itemChar <= 0x007F) {
	                    sumByte += 1;
	                } else if (itemChar >= 0x0080 && itemChar <= 0x07FF) {
	                    sumByte += 2;
	                } else {
	                    sumByte += 3;
	                }
	                if (sumByte > byteCount) {
	                    charIndex = i;
	                    break;
	                }
	            }
	            return String.valueOf(tempChars, 0, charIndex);
	        }
	    } catch (UnsupportedEncodingException e) {
	    }
	    return text;
	}

}