Edittext入力のバイト長を制限
デバイスの名前を変更する場合、デバイスの名前に対する記憶空間は一般的に何バイトであり、何ワードではなく、utf-8の符号化が一般的である.では、utf-8の符号化は1~6バイトの不等長であり、30バイトを超えるテキストを30バイト以内に変換するにはどうすればいいのでしょうか.
Javaでutf-8テキストを取得するバイト長は、以下のように簡単です.
しかし、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符号化との対応関係から、バイト長を制限するプログラムを作成することができる.
1つのcharは2ビットしかないため、utf-8フォーマットの3バイトしか表示できないが、ここではこのように処理する.またutf-8バイトの長さは1-6ビットと前述したが,ここでは3ビット以内で表される文字しか計算されておらず,依然として厳密ではない.次号ではより完璧な計算方式を示し,まず6ビットの表現を実現するために参考にすることができる.
Edittext入力を制限するコードを添付します.
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;
}
}