Add files via upload

This commit is contained in:
DXL
2020-08-27 12:45:49 +08:00
committed by GitHub
parent 08d6761dd9
commit d3b2b8d3b2
16 changed files with 2135 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
package com.proxgrind.chameleon.utils.tools;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
/*
* 一些数组,集合操作的封装类!
* */
public class ArrayUtils {
//将字符串链表或者数列转换为一般字符串数组
public static <T> T[] list2Arr(List<T> list) {
if (list == null) return null;
if (list.size() == 0) return null;
return list.toArray((T[]) Array.newInstance(list.get(0).getClass(), list.size()));
}
//obj数组去重
public static <T> T[] unrepeat(T[] objs) {
if (objs == null) return null;
if (objs.length == 0) return null;
ArrayList<T> list = new ArrayList<>();
for (int i = 0; i < objs.length; ++i) {
if (list.indexOf(objs[i]) == -1) {
//-1证明没有找到这个元素的存在,添加进去!
list.add(objs[i]);
}
}
return list.toArray((T[]) Array.newInstance(objs[0].getClass(), list.size()));
}
/**
* 得到一个数组中的元素,如果越界则为空!
*
* @param array 需要被取出元素的数组!
* @param index 需要取出的对应数组的元素的索引!
* @return 如果不越界,则取出对应的值,否则直接返回null
*/
public static <T> T getElement(T[] array, int index) {
return index >= array.length ? null : array[index];
}
// 得到距离数组开始的有效长度!
public static <T> int getLength(T[] array, int offset) {
if (offset >= array.length) return -1;
return array.length - offset;
}
}
+99
View File
@@ -0,0 +1,99 @@
package com.proxgrind.chameleon.utils.tools;
import android.content.Context;
import android.content.res.AssetManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/*
* 针对Assets进行操作的类!
* */
public class AssetsUtil {
private Context context;
public AssetsUtil(Context context) {
this.context = context;
}
//判断assets文件是否存在!
public boolean isFileExists(String fileName) {
InputStream is = null;
boolean ret = false;
try {
is = context.getResources().getAssets().open(fileName);
ret = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
//得到assets指定目录下的所有文件!
public String[] getFiles(String root) {
String[] files = new String[0];
try {
files = context.getAssets().list(root);
} catch (IOException e) {
e.printStackTrace();
}
if (files == null || files.length == 0) return null;
return files;
}
//移动assets中的文件到指定目录
public boolean moveFile(String asFile, String targetPath) {
File file = new File(targetPath);
if (!file.exists() || !file.isFile()) {
try {
if (!file.createNewFile()) {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
boolean ret = false;
//移动默认key文件
AssetManager am = context.getResources().getAssets();
InputStream is = null;
FileOutputStream fos = null;
try {
is = am.open(asFile);
fos = new FileOutputStream(file);
int len = is.available();
for (int i = 0; i < len; ++i) {
fos.write((byte) is.read());
}
ret = true;
} catch (IOException e) {
e.printStackTrace();
try {
if (is != null) is.close();
if (fos != null) fos.close();
ret = false;
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
}
File diff suppressed because it is too large Load Diff
+77
View File
@@ -0,0 +1,77 @@
package com.proxgrind.chameleon.utils.tools;
import java.util.Timer;
import java.util.TimerTask;
/*
* 倒计时任务!
* */
public class CountDown extends TimerTask {
private int timeDelay = 1000;
private transient int countdynamic = 0;
private Progress mProgress;
private Timer timer;
public CountDown(Progress progress) {
timer = new Timer();
mProgress = progress;
}
//倒计时回调接口
public interface Progress {
boolean onProgress(int countdynamic);
}
//设置回调!
public void setProgress(Progress progress) {
mProgress = progress;
}
//设置每次的延迟
public CountDown setTimeDelay(int ms) {
timeDelay = ms;
return this;
}
//设置需要延迟多少次!
public CountDown setCountDown(int count) {
countdynamic = count;
return this;
}
//开始倒计时!
public CountDown startCountDown() {
if (countdynamic == 0) return this;
timer.schedule(this, 0, timeDelay);
return this;
}
//取消倒计时
public CountDown cancelCountDown() {
cancel();
countdynamic = 0;
return this;
}
//是否处于倒计时状态!
public boolean isRunning() {
return this.countdynamic != 0;
}
@Override
public void run() {
//判断为零,立刻回调结束
if (countdynamic == 0) {
mProgress.onProgress(0);
cancelCountDown();
} else {
//回调且判断需不需要继续下次回调!
if (!mProgress.onProgress(countdynamic)) {
cancelCountDown();
return;
}
--countdynamic;
}
}
}
+220
View File
@@ -0,0 +1,220 @@
package com.proxgrind.chameleon.utils.tools;
import android.util.Log;
import com.proxgrind.chameleon.utils.stream.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author DXL
* @Date 2019/4/12
*/
public class DiskKVUtil {
private static String LOG_TAG = "DiskKVUtil";
/**
* 封装由设置写到持久化层的实现
*
* @param key 键
* @param value 值
* @param file 最终写入的文件
*/
public static void update2Disk(String key, String value, File file) throws IOException {
//由键值对到底层持久化的实现
byte[] dataBuf = FileUtils.readBytes(file);
String[] dats = new String(dataBuf).split("\n");
//迭代判断行!
for (int i = 0; i < dats.length; i++) {
String kvLine = dats[i];
//如果是注释则跳过处理
if (kvLine.startsWith("#")) continue;
//否则判断键值对!
if (kvLine.matches(".* : .*")) {
if (kvLine.startsWith(key)) {
//判断键是否对应行开头,更新具体内容!
String newKVLine = warp2KvLine(key, value);
dats[i] = newKVLine;
}
}
}
String result = StringUtils.arr2Str(dats, "\n", true);
//重新写入到磁盘!
FileUtils.writeBytes(result.getBytes(), file, false);
}
/**
* 封装由设置写到持久化层的实现
*
* @param key 键
* @param value 值,数组形式,表示一键多值!
* @param file 最终写入的文件
*/
public static void update2Disk(String key, String[] value, File file) throws IOException {
//由键值对到底层持久化的实现
byte[] dataBuf = FileUtils.readBytes(file);
String[] dats = new String(dataBuf).split("\n");
//迭代判断行!
for (int i = 0, j = 0; i < dats.length; i++) {
String kvLine = dats[i];
//如果是注释则跳过处理
if (kvLine.startsWith("#")) continue;
//否则判断键值对!
if (kvLine.matches(".* : .*")) {
if (kvLine.startsWith(key)) {
if (j >= value.length) {
//可能会越界!
Log.d(LOG_TAG, "update2Disk 有越界风险!");
} else {
//判断键是否对应行开头,更新具体内容!
String newKVLine = warp2KvLine(key, value[j]);
j++;
dats[i] = newKVLine;
}
}
}
}
String result = StringUtils.arr2Str(dats, "\n", true);
//重新写入到磁盘!
FileUtils.writeBytes(result.getBytes(), file, false);
}
/**
* 查询键值对!
*
* @param key 键
* @param file 欲操作的文件
* @return 查询的结果集(值)!
* @throws IOException 操作出现的各种问题!
*/
public static String[] queryKVLine(String key, File file) throws IOException {
byte[] dataBuf = FileUtils.readBytes(file);
String[] dats = new String(dataBuf).split("\n");
ArrayList<String> valueList = new ArrayList<>(16);
for (String line : dats) {
//如果是注释则跳过处理
if (line.startsWith("#")) continue;
if (line.startsWith(key)) {
valueList.add(getValue(line));
}
}
return valueList.toArray(new String[0]);
}
/**
* 查询键是否存在!
*
* @param key 键
* @param file 查询的文件!
* @return 对应的键是否存在于配置文件中!
*/
public static boolean isKVExists(String key, File file) throws IOException {
byte[] dataBuf = FileUtils.readBytes(file);
String[] dats = new String(dataBuf).split("\n");
for (String line : dats) {
//如果是注释则跳过处理
if (line.startsWith("#")) continue;
if (line.startsWith(key)) {
return true;
}
}
return false;
}
/**
* @param key 键
* @param value 值
* @param file 欲操作的文件!
*/
public static void insertKV(String key, String value, File file) throws IOException {
String line = warp2KvLine(key, value) + "\n";
FileUtils.writeBytes(line.getBytes(), file, true);
}
/**
* 凡是匹配到的键信息行,全部略过,然后将区间外的行写回去!
*
* @param key 键
* @param file 操作的文件
*/
public static void deleteKV(String key, File file) throws IOException {
byte[] dataBuf = FileUtils.readBytes(file);
String[] dats = new String(dataBuf).split("\n");
ArrayList<String> valueList = new ArrayList<>(16);
for (String line : dats) {
if (!line.startsWith(key)) {
valueList.add(getValue(line));
}
}
String ret = StringUtils.arr2Str(valueList.toArray(new String[0]), "\n", true);
FileUtils.writeBytes(ret.getBytes(), file, false);
}
public static char toChar(String v, char defaultVar) {
try {
return v.toCharArray()[0];
} catch (Exception e) {
return defaultVar;
}
}
public static short toShort(String v, short defaultVar) {
try {
return Short.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
public static int toInt(String v, int defaultVar) {
try {
return Integer.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
public static long toLong(String v, long defaultVar) {
try {
return Long.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
public static float toFloat(String v, float defaultVar) {
try {
return Float.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
public static double toDouble(String v, double defaultVar) {
try {
return Double.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
public static boolean toBoolean(String v, boolean defaultVar) {
try {
return Boolean.valueOf(v);
} catch (Exception e) {
return defaultVar;
}
}
private static String getValue(String line) {
//pm3DelayTime :
return RegexGroupUtils.matcherGroup(line, ".* : (.*)", 1, 0);
}
private static String warp2KvLine(String key, String value) {
return key + " : " + value;
}
}
+41
View File
@@ -0,0 +1,41 @@
package com.proxgrind.chameleon.utils.tools;
import android.app.Activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.proxgrind.chameleon.R;
import java.util.List;
/*
* 一些碎片开发使用上的工具!
* */
public class FragmentUtils {
//隐藏所有的碎片!
public static void hides(FragmentManager manager, Fragment exclude) {
List<Fragment> fragmentList = manager.getFragments();
//迭代隐藏所有的碎片!
for (Fragment fragment : fragmentList)
//排除指定的碎片!
if (fragment != exclude)
manager.beginTransaction().hide(fragment).commitAllowingStateLoss();
}
public static void showAndAddBackStack(FragmentActivity activity, Fragment fragment) {
if (activity == null || fragment == null) return;
FragmentManager manager = activity.getSupportFragmentManager();
manager.beginTransaction()
.add(R.id.mainContainer, fragment)
.addToBackStack(fragment.getTag()).commit();
}
public static void runOnUiThread(Activity activity, Runnable runnable) {
if (activity != null)
activity.runOnUiThread(runnable);
}
}
+44
View File
@@ -0,0 +1,44 @@
package com.proxgrind.chameleon.utils.tools;
import android.nfc.Tag;
import java.util.ArrayList;
import java.util.List;
/**
* 全局的标签缓存!
*/
public class GlobalTag {
private static Tag tag = null;
private static List<OnNewTagListener> listeners = new ArrayList<>();
public static Tag getTag() {
return tag;
}
public static void setTag(Tag tag) {
GlobalTag.tag = tag;
}
public interface OnNewTagListener {
void onNewTag(Tag tag);
}
public static void addListener(OnNewTagListener listener) {
listeners.add(listener);
}
public static void removeListener(OnNewTagListener listener) {
listeners.remove(listener);
}
public static void notifyOnNewTag(Tag tag) {
//直接通知TAG的变化!
for (OnNewTagListener l : listeners) {
try {
l.onNewTag(tag);
} catch (Exception ignored) {
}
}
}
}
+261
View File
@@ -0,0 +1,261 @@
package com.proxgrind.chameleon.utils.tools;
import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class HexUtil {
private final static char[] HEX_DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
public static String dumpHexString(byte[] array) {
return dumpHexString(array, 0, array.length);
}
public static String dumpHexString(byte[] array, int offset, int length) {
StringBuilder result = new StringBuilder();
byte[] line = new byte[16];
int lineIndex = 0;
result.append("\n0x");
result.append(toHexString(offset));
for (int i = offset; i < offset + length; i++) {
if (lineIndex == 16) {
result.append(" ");
for (int j = 0; j < 16; j++) {
if (line[j] > ' ' && line[j] < '~') {
result.append(new String(line, j, 1));
} else {
result.append(".");
}
}
result.append("\n0x");
result.append(toHexString(i));
lineIndex = 0;
}
byte b = array[i];
result.append(" ");
result.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
result.append(HEX_DIGITS[b & 0x0F]);
line[lineIndex++] = b;
}
if (lineIndex != 16) {
int count = (16 - lineIndex) * 3;
count++;
for (int i = 0; i < count; i++) {
result.append(" ");
}
for (int i = 0; i < lineIndex; i++) {
if (line[i] > ' ' && line[i] < '~') {
result.append(new String(line, i, 1));
} else {
result.append(".");
}
}
}
return result.toString();
}
public static String toHexString(byte b) {
return toHexString(toByteArray(b));
}
public static String toHexString(byte[] array) {
if (array == null) return null;
return toHexString(array, 0, array.length);
}
public static String toHexString(byte[] array, int offset, int length) {
char[] buf = new char[length * 2];
int bufIndex = 0;
for (int i = offset; i < offset + length; i++) {
byte b = array[i];
buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
}
return new String(buf);
}
public static String toHexString(int i) {
return toHexString(toByteArray(i));
}
public static String toHexString(short i) {
return toHexString(toByteArray(i));
}
public static String decorateHex(String hexStr) {
StringBuilder sb = new StringBuilder();
char[] charArr = hexStr.toCharArray();
for (int i = 0; i < charArr.length; i += 2) {
sb.append("0x").append(charArr[i])
.append(charArr[i + 1]).append(" ");
}
return sb.toString();
}
public static byte[] toByteArray(byte b) {
byte[] array = new byte[1];
array[0] = b;
return array;
}
public static byte[] toByteArray(int i) {
byte[] array = new byte[4];
array[3] = (byte) (i & 0xFF);
array[2] = (byte) ((i >> 8) & 0xFF);
array[1] = (byte) ((i >> 16) & 0xFF);
array[0] = (byte) ((i >> 24) & 0xFF);
return array;
}
public static byte[] toByteArray(short i) {
byte[] array = new byte[2];
array[1] = (byte) (i & 0xFF);
array[0] = (byte) ((i >> 8) & 0xFF);
return array;
}
private static int toByte(char c) {
if (c >= '0' && c <= '9')
return (c - '0');
if (c >= 'A' && c <= 'F')
return (c - 'A' + 10);
if (c >= 'a' && c <= 'f')
return (c - 'a' + 10);
Log.d("HexUtil", "The byte char is invalid: " + c);
//throw new RuntimeException("Invalid hex char '" + c + "'");
return 0;
}
public static int toInt(byte b) {
return b & 0xFF;
}
public static int toIntFrom2Byte(byte[] b) {
return Integer.parseInt(toHexString(b), 16);
}
/**
* 拆分byte数组
*
* @param bytes 要拆分的数组
* @param size 要按几个组成一份
* @return
*/
public static byte[][] splitBytes(byte[] bytes, int size) {
double splitLength = Double.parseDouble(size + "");
int arrayLength = (int) Math.ceil(bytes.length / splitLength);
byte[][] result = new byte[arrayLength][];
int from, to;
for (int i = 0; i < arrayLength; i++) {
from = (int) (i * splitLength);
to = (int) (from + splitLength);
if (to > bytes.length)
to = bytes.length;
result[i] = Arrays.copyOfRange(bytes, from, to);
}
return result;
}
public static byte[] bytesMerge(byte[]... arrs) {
byte[] ret = new byte[byteArraysLength(arrs)];
int pos = 0;
for (byte[] tmp : arrs) {
if (tmp != null && tmp.length > 0) {
System.arraycopy(tmp, 0, ret, pos, tmp.length);
pos += tmp.length;
}
}
return ret;
}
public static int byteArraysLength(byte[]... arrs) {
int ret = 0;
for (byte[] tmp : arrs) {
if (tmp != null)
ret += tmp.length;
}
return ret;
}
public static int byteArrayToInt(byte[] b) {
return (b[3] & 0xFF) |
(b[2] & 0xFF) << 8 |
(b[1] & 0xFF) << 16 |
(b[0] & 0xFF) << 24;
}
public static int byte2Int(byte[] data, int offset) {
byte[] bs = new byte[4];
for (int i = offset, j = 0; j < bs.length; i++, j++) {
bs[j] = data[i];
}
return HexUtil.byteArrayToInt(bs);
}
public static int hexString2Int(String hexString) {
byte[] hexByte = hexStringToByteArray(hexString);
return byteArrayToInt(hexByte);
}
public static byte[] intToByteArray(int a) {
return new byte[]{
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) (a & 0xFF)
};
}
public static byte[] hexStringToByteArray(String hexString) {
if (hexString == null) return null;
if (hexString.length() == 0) return null;
int length = hexString.length();
byte[] buffer = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
buffer[i / 2] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString
.charAt(i + 1)));
}
return buffer;
}
public static byte[] getAsciiBytes(String str) {
return str.getBytes(StandardCharsets.US_ASCII);
}
//判断是否是十六进制格式的字符串
public static boolean isHexString(String str) {
if (str == null) return false;
if (str.matches("[0-9a-fA-F]+")) return true;
if (str.matches("0x[0-9a-fA-F]+")) return true;
return str.matches("0x[0-9a-fA-F] +");
}
public static boolean sequenceEqual(byte[] a, byte[] b, int len) {
if (len > a.length && len > b.length) return false;
int minLen = Math.min(a.length, b.length);
if (minLen > len) return false;
for (int i = 0; i < minLen; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
}
+33
View File
@@ -0,0 +1,33 @@
package com.proxgrind.chameleon.utils.tools;
import java.security.MessageDigest;
//MD5加密不可逆
public class MD5Utils {
/**
* 对字节内容进行加密
*
* @param source 摘要对象!
* @return 密文
*/
public static String digest(byte[] source) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
return HexUtil.toHexString(digest.digest(source));
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
}
/**
* 对字节内容进行摘要检查!
*
* @param digest 已经确定的摘要信息!
* @param source 未知的摘要对象!
* @return 摘要信息对比结果!
*/
public static boolean verify(String digest, byte[] source) {
return digest(source).equals(digest);
}
}
+105
View File
@@ -0,0 +1,105 @@
package com.proxgrind.chameleon.utils.tools;
/*
* MifareClassic标签用得到的工具!
* */
public class MifareUtils {
public static boolean validateSector(int sector) {
// Do not be too strict on upper bounds checking, since some cards
// have more addressable memory than they report. For example,
// MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in
// MIFARE Classic compatibility mode.
// Note that issuing a command to an out-of-bounds block is safe - the
// tag should report error causing IOException. This validation is a
// helper to guard against obvious programming mistakes.
int NR_TRAILERS_4k = 40;
if (sector < 0 || sector >= NR_TRAILERS_4k) {
return false;
}
return true;
}
public static boolean validateBlock(int block) {
// Just looking for obvious out of bounds...
int NR_BLOCKS_4k = 0xFF;
if (block < 0 || block >= NR_BLOCKS_4k) {
return false;
}
return true;
}
public static boolean validateValueOperand(int value) {
if (value < 0) {
return false;
}
return true;
}
public static int blockToSector(int blockIndex) {
if (!validateBlock(blockIndex)) return 0;
if (blockIndex < 32 * 4) {
return (blockIndex / 4);
} else {
return (32 + (blockIndex - 32 * 4) / 16);
}
}
public static int sectorToBlock(int sectorIndex) {
if (!validateSector(sectorIndex)) {
return -1;
}
if (sectorIndex < 32) {
return (sectorIndex * 4);
} else {
return (32 * 4 + (sectorIndex - 32) * 16);
}
}
public static boolean isFirstBlock(int uiBlock) {
// 测试我们是否处于小扇区或者大扇区?
if (uiBlock < 128)
return ((uiBlock) % 4 == 0);
else
return ((uiBlock) % 16 == 0);
}
public static boolean isTrailerBlock(int uiBlock) {
// 测试我们处于小区块还是大扇区
if (uiBlock < 128)
return ((uiBlock + 1) % 4 == 0);
else
return ((uiBlock + 1) % 16 == 0);
}
public static int getBlockCountInSector(int sectorIndex) {
if (!validateSector(sectorIndex)) return -1;
if (sectorIndex < 32) {
return 4;
} else {
return 16;
}
}
public static int get_trailer_block(int uiFirstBlock) {
// Test if we are in the small or big sectors
int trailer_block;
if (uiFirstBlock < 128) {
trailer_block = uiFirstBlock + (3 - (uiFirstBlock % 4));
} else {
trailer_block = uiFirstBlock + (15 - (uiFirstBlock % 16));
}
return trailer_block;
}
public static int getIndexOnSector(int block, int sector) {
int index = 0;
//得到当前的块在扇区中的具体索引!
for (int i = 0; i < getBlockCountInSector(sector); i++) { //得到当前扇区的块总数!
if (block == (sectorToBlock(block) + i)) break;
++index;
}
return index;
}
}
+195
View File
@@ -0,0 +1,195 @@
package com.proxgrind.chameleon.utils.tools;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Enumeration;
public class NetworkUtils {
/**
* 是否使用代理(WiFi状态下的,避免被抓包)
*/
public static boolean isWifiProxy() {
String proxyAddress;
int proxyPort;
proxyAddress = System.getProperty("http.proxyHost");
String portstr = System.getProperty("http.proxyPort");
proxyPort = Integer.parseInt((portstr != null ? portstr : "-1"));
System.out.println(proxyAddress + "~");
System.out.println("port = " + proxyPort);
return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}
/**
* 是否正在使用VPN
*/
public static boolean isVpnUsed() {
try {
Enumeration niList = NetworkInterface.getNetworkInterfaces();
if (niList != null) {
for (Object intf : Collections.list(niList)) {
NetworkInterface ni = (NetworkInterface) intf;
if (!ni.isUp() || ni.getInterfaceAddresses().size() == 0) {
continue;
}
Log.d("-----", "isVpnUsed() NetworkInterface Name: " + ni.getName());
if ("tun0".equals(ni.getName()) || "ppp0".equals(ni.getName())) {
return true; // The VPN is up
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
/**
* 网络是否连接!
*
* @param context 上下文
* @return 有网时返回true,没网时返回false
*/
public static boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
/**
* wifi是否连接
*
* @param context 上下文
* @return 是WIFI网络返回true,不是WIFI返回false
*/
public static boolean isWifiConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 移动网络是否连接
*
* @param context 上下文
* @return 是数据流量时返回true,不是返回false
*/
public static boolean isMobileConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mMobileNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobileNetworkInfo != null) {
return mMobileNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 获取当前网络连接的类型信息
*
* @param context 上下文
* @return 判断结果,
*/
public static int getConnectedType(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
return mNetworkInfo.getType();
}
}
return -1;
}
/**
* 判断主机是否存在!
*
* @param host 主机
* @param timeout 超时值!
*/
public static boolean isHostReachable(String host, int timeout) {
try {
return InetAddress.getByName(host).isReachable(timeout);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 判断主机是否可以连接!
*
* @param host 主机
* @param port 端口
* @param timeout 超时值
*/
public static boolean isHostConnectable(String host, int port, int timeout) {
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(host, port), timeout);
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
/**
* 判断主机是否可以连接!
*
* @param host 主机
* @param port 端口
*/
public static boolean isHostConnectable(String host, int port) {
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(host, port));
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
}
+31
View File
@@ -0,0 +1,31 @@
package com.proxgrind.chameleon.utils.tools;
import com.proxgrind.chameleon.utils.stream.FileUtils;
import java.io.File;
public interface Properties {
String APP_SDCARD = FileUtils.getAppFilesDir("files").getAbsolutePath();
String APP_SETTINH_DIR = "settings";
String APP_SETTINGS_NAME = "settings.ky";
// APP的配置文件保存目录!
String APP_CONF_PATH = APP_SDCARD + File.separator + APP_SETTINH_DIR;
// app的通用配置文件!
String APP_CONF_FILE = APP_CONF_PATH + File.separator + APP_SETTINGS_NAME;
// 设备的自动关闭状态设置key!
String APP_AUTO_CLOSE_KEY = "autoClose";
// 设备的自动断开时间!
String APP_AUTO_CLOSE_TIME_KEY = "autoCloseTime";
// 新手模式的标志!
String APP_NOVICE_MODE = "noviceMode";
// 绑定的mac地址
String APP_BIND_MAC = "bindMac";
// 是否启用了MAC地址绑定!
String APP_BIND_MAC_STATUS = "bindMacStatus";
// 设备备注
String APP_DEVICE_REMARKS = "device_remarks";
// UI模式
String APP_UI_MODE = "ui_mode";
// DUMP模式
String APP_DUMP_MODE = "dump_mode";
}
+51
View File
@@ -0,0 +1,51 @@
package com.proxgrind.chameleon.utils.tools;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* TODO 正则组匹配工具类
* 根据给出的组标签反选或者正选内容!
* */
public class RegexGroupUtils {
/*public static void main(String args[]) {
String c = "UID : 8b 36 8b eb";
String s = matcherGroup(c, ".*UID : (.{11}).*", 1, 0);
System.out.println("最终测试组匹配截取: " + s);
}*/
/**
* @param content 被匹配的内容!
* @param regex 匹配规则
* @return 匹配的组!
* @Method 匹配组多个,根据组得到内容结果!
*/
public static String[] matcherGroups(String content, String regex, int group) {
//准备格式匹配对象!
Pattern p = Pattern.compile(regex);
//准备匹配器对象!
Matcher m = p.matcher(content);
//结果集!
ArrayList<String> ret = new ArrayList<>();
//迭代查组
while (m.find()) {
ret.add(m.group(group));
}
return ret.toArray(new String[0]);
}
/*
* Method 匹配一个组
* @Param content 被匹配的内容!
* @Param regex 被匹配的正则!
* @Param index 组索引,位于字符串中的第一次pos
* @Return 返回指定索引的组内容!
* */
public static String matcherGroup(String content, String regex, int group, int index) {
String[] res = matcherGroups(content, regex, group);
if (index >= res.length || index < 0) return null;
return res[index];
}
}
+69
View File
@@ -0,0 +1,69 @@
package com.proxgrind.chameleon.utils.tools;
public class StringUtils {
//字符串数组转字符串,可选择性的添加分隔符!
public static String arr2Str(String[] arr, String split, boolean addSplitInEnd) {
StringBuilder sb = new StringBuilder();
//进行迭代添加!
for (int i = 0; i < arr.length; ++i) {
//判断是否是在尾部
if (i == arr.length - 1 && !addSplitInEnd) {
//不添加换行符!
sb.append(arr[i]);
} else {
sb.append(arr[i]).append(split);
}
}
return sb.toString();
}
//是否是空串
public static boolean isEmpty(String str) {
return str.isEmpty() || str.equals(" ") || str.matches("\\s*");
}
//是否是十六进制字符串
public static boolean isHexStr(String str) {
return str.matches("[0-9a-fA-F]+");
}
//是否是数字
public static boolean isNumStr(String str) {
return str.matches("[0-9]+");
}
//是否是字母
public static boolean isLetter(String str) {
return str.matches("[A-Fa-f]+");
}
//是否是纯空格
public static boolean isSpaces(String str) {
return str.matches(" +");
}
//删除所有的空格和转为大写!
public static String trimO2Upper(String content) {
return content.replaceAll(" ", "").toUpperCase();
}
//删除所有的空格和转为小写!
public static String trimO2Lower(String content) {
return content.replaceAll(" ", "").toLowerCase();
}
//删除所有的空格和转为大写!
public static void trimO2Upper(String[] datas) {
for (int i = 0; i < datas.length; i++) {
datas[i] = trimO2Upper(datas[i]);
}
}
//删除所有的空格和转为小写!
public static void trimO2Lower(String[] datas) {
for (int i = 0; i < datas.length; i++) {
datas[i] = trimO2Lower(datas[i]);
}
}
}
+44
View File
@@ -0,0 +1,44 @@
package com.proxgrind.chameleon.utils.tools;
import android.content.Context;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.TextAppearanceSpan;
/*
* 设置文本的样式!
* */
public class TextStyleUtils {
/*
* 合并多个富文本对象到构造器里!
* */
public static SpannableStringBuilder merge(SpannableString... text) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
for (SpannableString ss : text) {
ssb.append(ss);
}
return ssb;
}
/*
* 设置字体前景色!
* */
public static SpannableString getColorString(String str, int color) {
SpannableString ret = new SpannableString(str);
ret.setSpan(new ForegroundColorSpan(color), 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return ret;
}
/*
* 设置背景样式!
* */
public static SpannableString getStyleString(Context context, String str, int style) {
// TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)
SpannableString ret = new SpannableString(str);
ret.setSpan(new TextAppearanceSpan(context, style), 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return ret;
}
}
+53
View File
@@ -0,0 +1,53 @@
package com.proxgrind.chameleon.utils.tools;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ScrollView;
public class ViewUtils {
//加载layout文件并且返回view引用
public static View inflate(Context context, int layID) {
View v = LayoutInflater.from(context).inflate(layID, null);
return v;
}
public static void measureUnspecified(View view) {
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
}
// ScrollView自动滑动到底部!
public static void fullScroll(ScrollView scrollView) {
scrollView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
scrollView.post(new Runnable() {
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});
}
//给编辑器请求焦点和虚拟键盘
public static void requestFocusAndShowInputMethod(EditText edt) {
if (edt == null) return;
edt.post(new Runnable() {
@Override
public void run() {
edt.setFocusable(true);
edt.setFocusableInTouchMode(true);
edt.requestFocus();
InputMethodManager imm = (InputMethodManager) edt.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_NOT_ALWAYS);
}
});
}
}