1.单例最佳写法
2. 判断系统语言是否是简体中文
@NonNull
public static Locale getLocale() {
Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//语言列表最小size=1
locale = LocaleList.getDefault().get(0);
} else {
locale = Locale.getDefault();
}
return locale;
}
public static boolean isZhHans() {
boolean isZhHans = false;
Locale locale = getLocale();
final String ZH = "zh";
//中文简体
final String CN_HANS = "zh-Hans";
//中文繁体
final String CN_HANT = "zh-Hant";
//如果是中文
if (locale.getLanguage().equals(ZH)) {
//locale.toLanguageTag()
//中国 zh-Hans-CN
//台湾 zh-Hans-TW
//澳门 zh-Hans-MO
//香港 zh-Hans-HK
if (locale.toLanguageTag().contains(CN_HANS)) {
//中文简体
PrintLog.d("中文简体");
isZhHans = true;
} else if (locale.toLanguageTag().contains(CN_HANT)) {
//中文繁体
PrintLog.d("中文繁体");
} else {
switch (locale.getCountry()) {
case "CN":
//中文简体
PrintLog.d("中文简体");
isZhHans = true;
break;
default:
PrintLog.d("中文繁体");
break;
}
}
} else {
PrintLog.d("不是中文");
}
return isZhHans;
}
3.网上流传的AndroidQ判断公有目录文件是否存在,此方法耗时操作,不要在循环中使用,容易导致ANR。
/**
* 判断公有目录文件是否存在,自Android Q开始,公有目录File API都失效,不能直接通过new File(path).exists();判断公有目录文件是否存在,正确方式如下:
*
* @param context
* @param path
* @return
*/
public static boolean isAndroidQFileExists(Context context, String path) {
if (context == null) {
return false;
}
AssetFileDescriptor afd = null;
ContentResolver cr = context.getContentResolver();
try {
Uri uri = Uri.parse(path);
afd = cr.openAssetFileDescriptor(Uri.parse(path), "r");
if (afd == null) {
return false;
} else {
try {
afd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
return false;
} finally {
try {
if (afd != null) {
afd.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
4.过滤字符串里的\n \r 和空格的InputFilter
/**
* 过滤字符串里的\n \r 和空格
*/
public class CharFilter implements InputFilter {
private final char[] filterChars;
public static CharFilter newlineCharFilter() {
return new CharFilter(new char[]{'\n'});
}
public static CharFilter whitespaceCharFilter() {
return new CharFilter(new char[]{' '});
}
public static CharFilter returnCharFilter() {
return new CharFilter(new char[]{'\r'});
}
public static CharFilter wnrCharFilter() {
return new CharFilter(new char[]{' ', '\n', '\r'});
}
private CharFilter(char[] filterChars) {
this.filterChars = filterChars == null ? new char[0] : filterChars;
}
/**
* @param source 输入的文字
* @param start 输入-0,删除-0
* @param end 输入-文字的长度,删除-0
* @param dest 原先显示的内容
* @param dstart 输入-原光标位置,删除-光标删除结束位置
* @param dend 输入-原光标位置,删除-光标删除开始位置
* @return null表示原始输入,""表示不接受输入,其他字符串表示变化值
*/
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (needFilter(source)) {
SpannableStringBuilder builder = new SpannableStringBuilder();
int abStart = start;
for (int i = start; i < end; i++) {
if (isFilterChar(source.charAt(i))) {
if (i != abStart) {
builder.append(source.subSequence(abStart, i));
}
abStart = i + 1;
}
}
if (abStart < end) {
builder.append(source.subSequence(abStart, end));
}
return builder;
}
return null;
}
private boolean needFilter(CharSequence source) {
String s = source.toString();
for (char filterChar : filterChars) {
if (s.indexOf(filterChar) >= 0) {
return true;
}
}
return false;
}
private boolean isFilterChar(char c) {
for (char filterChar : filterChars) {
if (filterChar == c) {
return true;
}
}
return false;
}
}
5.volatile使用场景