pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
+ if (pinfo != null) {
+ for (int i = 0; i < pinfo.size(); i++) {
+ String pn = pinfo.get(i).packageName;
+ if (pn.equals("com.tencent.mm")) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * 打电话
+ *
+ * Intent.ACTION_DIAL Intent.ACTION_CALL
+ *
+ * @param context
+ * @param mobile
+ */
+ public static void callUp(Context context, String mobile) {
+ Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"
+ + mobile));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ /**
+ * 获取设备ID
+ *
+ * @param context
+ * @return
+ */
+ public static String getDevId(Context context) {
+ TelephonyManager TelephonyMgr = (TelephonyManager) context
+ .getSystemService(Context.TELEPHONY_SERVICE);
+ return TelephonyMgr.getDeviceId();
+ }
+
+ /**
+ * 姓名脱敏
+ *
+ * @param fullName
+ * @return
+ */
+ public static String desensitizedName(String fullName) {
+ if (fullName == null || fullName.length() <= 1) {
+ return fullName;
+ }
+ char[] nameArr = fullName.toCharArray();
+ if (nameArr.length > 2) {
+ for (int i = 1; i < nameArr.length - 1; i++) {
+ nameArr[i] = '*';
+ }
+ } else {
+ nameArr[1] = '*';
+ }
+
+ return new String(nameArr);
+ }
+
+
+ public static String formatDateGetFull(String date) {
+ if (isEmpty(date)) {
+ return "";
+ }
+ Date d = new Date(Long.parseLong(date));
+ SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ return dateFormat1.format(d);
+ }
+
+ public static String formatDateGetCurrentTime() {
+ Date d = new Date(System.currentTimeMillis());
+ SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//.SSS
+ return dateFormat1.format(d);
+ }
+
+
+ public static String formatDateGetFull(long date) {
+ if (date == 0) {
+ return "";
+ }
+ Date d = new Date(date);
+ SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ return dateFormat1.format(d);
+ }
+
+ public static String formatDateGetDay(long date) {
+ if (date == 0) {
+ return "";
+ }
+ Date d = new Date(date);
+ SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
+ return dateFormat1.format(d);
+ }
+
+ public static boolean isEmpty(String s) {
+ if (TextUtils.isEmpty(s) || s.trim().equals("null")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * 格式化浮点型
+ *
+ * @param data
+ * @return
+ */
+ public static String formatDouble(double data) {
+ return new DecimalFormat("0.00").format(data);
+ }
+
+
+ /**
+ * 格式化分钟
+ *
+ * @param minutes
+ * @return
+ */
+ public static String formatMinutes(int minutes) {
+ int hour = minutes / 60;
+ int minute = minutes % 60;
+ if (hour > 0 && minute > 0) {
+ return hour + "小时" + minute + "分钟";
+ } else if (hour > 0) {
+ return hour + "小时";
+ } else {
+ return minute + "分钟";
+ }
+ }
+
+
+ //com.fawan.news
+ public static void goToMarket(Context context, String packageName) {
+ Uri uri = Uri.parse("market://details?id=" + packageName);
+ Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
+ try {
+ context.startActivity(goToMarket);
+ } catch (ActivityNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * true为存在,false为不存在
+ *
+ * @param context
+ * @param packageName
+ * @return
+ */
+ public static boolean isInstallApp(Context context, String packageName) {
+ try {
+ context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ return true;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * 格式化float 保留两位小数
+ *
+ * @param data
+ * @return
+ */
+ public static float formatFloat2(float data) {
+// DecimalFormat decimalFormat = new DecimalFormat("0.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
+// return decimalFormat.format(data);//返回字符串
+
+ int scale = 1;//设置位数
+ int roundingMode = 4;//表示四舍五入,可以选择其他舍值方式,例如去尾,等等.
+ BigDecimal bd = new BigDecimal((double) data);
+ bd = bd.setScale(scale, roundingMode);
+ data = bd.floatValue();
+ return data;
+ }
+
+ /**
+ * Android 6.0 之前(不包括6.0)获取mac地址
+ * 必须的权限
+ *
+ * @param context * @return
+ */
+ public static String getMacDefault(Context context) {
+ String mac = "";
+ if (context == null) {
+ return mac;
+ }
+ WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ WifiInfo info = null;
+ try {
+ info = wifi.getConnectionInfo();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (info == null) {
+ return null;
+ }
+ mac = info.getMacAddress();
+ if (!TextUtils.isEmpty(mac)) {
+ mac = mac.toUpperCase(Locale.ENGLISH);
+ }
+ return mac;
+ }
+
+ /**
+ * Android 6.0-Android 7.0 获取mac地址
+ */
+ public static String getMacAddress() {
+ String macSerial = null;
+ String str = "";
+
+ try {
+ Process pp = Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address");
+ InputStreamReader ir = new InputStreamReader(pp.getInputStream());
+ LineNumberReader input = new LineNumberReader(ir);
+
+ while (null != str) {
+ str = input.readLine();
+ if (str != null) {
+ macSerial = str.trim();//去空格
+ break;
+ }
+ }
+ } catch (IOException ex) {
+ // 赋予默认值
+ ex.printStackTrace();
+ }
+
+ return macSerial;
+ }
+
+ /**
+ * Android 7.0之后获取Mac地址
+ * 遍历循环所有的网络接口,找到接口是 wlan0
+ * 必须的权限
+ *
+ * @return
+ */
+ public static String getMacFromHardware() {
+ try {
+ ArrayList all = Collections.list(NetworkInterface.getNetworkInterfaces());
+ for (NetworkInterface nif : all) {
+ if (!nif.getName().equals("wlan0"))
+ continue;
+ byte[] macBytes = nif.getHardwareAddress();
+ if (macBytes == null) return "";
+ StringBuilder res1 = new StringBuilder();
+ for (Byte b : macBytes) {
+ res1.append(String.format("%02X:", b));
+ }
+ if (!TextUtils.isEmpty(res1)) {
+ res1.deleteCharAt(res1.length() - 1);
+ }
+ return res1.toString();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return "";
+ }
+
+ /**
+ * 获取mac地址(适配所有Android版本)
+ *
+ * @return
+ */
+ public static String getMac(Context context) {
+ String mac = "";
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ mac = getMacDefault(context);
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ mac = getMacAddress();
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ mac = getMacFromHardware();
+ }
+ return mac;
+ }
+
+ //把String转化为float
+ public static double convertToFloat(String number, double defaultValue) {
+ if (TextUtils.isEmpty(number)) {
+ return defaultValue;
+ }
+ try {
+ return Double.parseDouble(number);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+
+ }
+
+ /**
+ * 获取AndroidId
+ *
+ * @param context
+ * @return
+ */
+ public static String getAndroidId(Context context) {
+ String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ return androidId;
+ }
+
+ /**
+ * 获取设备唯一 UDID
+ *
+ * @param context
+ * @return
+ */
+ @SuppressLint("MissingPermission")
+ public static String getUDID(Context context) {
+// String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+// L.e("androidID===" + androidID);
+// return androidID;
+ String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ if (!androidID.equals("")) {
+ try {
+ if (!"9774d56d682e549c".equals(androidID)) {
+ androidID = UUID.nameUUIDFromBytes(androidID.getBytes("utf8")).toString();
+ } else {
+ @SuppressLint("MissingPermission") final String deviceId = ((TelephonyManager) context.getSystemService(TELEPHONY_SERVICE)).getDeviceId();
+ androidID = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")).toString() : UUID.randomUUID().toString();
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ return androidID;
+ }
+
+ //需要权限 android.permission.READ_PHONE_STATE
+ TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
+ String szImei = TelephonyMgr.getDeviceId();
+ if (!szImei.equals("")) {
+ return szImei;
+ }
+
+ //需要权限 android.permission.ACCESS_WIFI_STATE
+ WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
+ if (!m_szWLANMAC.equals("")) {
+ return m_szWLANMAC;
+ }
+
+ //需要权限 android.permission.BLUETOOTH
+ BluetoothAdapter m_BluetoothAdapter = null;
+ m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ String m_szBTMAC = m_BluetoothAdapter.getAddress();
+ if (!m_szBTMAC.equals("")) {
+ return m_szBTMAC;
+ }
+ return getUniquePsuedoID();
+ }
+
+ //获得 Psuedo ID
+ public static String getUniquePsuedoID() {
+ String serial = null;
+ String m_szDevIDShort = "35" +
+ Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
+ Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +
+ Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +
+ Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +
+ Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +
+ Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +
+ Build.USER.length() % 10; //13 位
+ try {
+ serial = Build.class.getField("SERIAL").get(null).toString();
+ //API>=9 使用serial号
+ return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
+ } catch (Exception exception) {
+ //serial需要一个初始化,随意值
+ serial = "serial";
+ }
+
+ //使用硬件信息拼凑出来的15位号码
+ return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
+ }
+
+ public static String getCPUSerial() {
+ String line = "";
+ String TAG = "aaa";
+ Log.e(TAG, " get_quck_Sn() ");
+ Class> c = null;
+ try {
+ c = Class.forName("android.os.SystemProperties");
+
+ Method get = c.getMethod("get", String.class);
+ line = (String) get.invoke(c, "ro.serialno");
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Log.e(TAG, " get_quck_Sn() " + line);
+ System.out.println("设备串号" + line);
+ return line;
+ }
+
+ /**
+ * 判断网络连接状态
+ *
+ * @param context
+ * @return
+ */
+ 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
+ */
+ 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
+ */
+ 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 input 原始字符串
+ * @param startIndex 起始索引(包含,从0开始)
+ * @param endIndex 结束索引(不包含)
+ * @return 子串,若输入无效或索引越界则返回空字符串
+ */
+ public static String getSubstringByIndices(String input, int startIndex, int endIndex) {
+ if (input == null) {
+ return "";
+ }
+ // 处理索引越界问题
+ int safeStart = Math.max(startIndex, 0);
+ int safeEnd = Math.min(endIndex, input.length());
+ if (safeStart > safeEnd) {
+ return "";
+ }
+ return input.substring(safeStart, safeEnd);
+ }
+
+ public static String getSubstringByIndex(String input, int startIndex, int length) {
+ if (input == null) {
+ return "";
+ }
+ // 处理索引越界问题
+ int safeStart = Math.max(startIndex, 0);
+ int safeEnd = Math.min(startIndex + length, input.length());
+ if (safeStart > safeEnd) {
+ return "";
+ }
+ return input.substring(safeStart, safeEnd);
+ }
+
+ /**
+ * 十进制转十六进制
+ *
+ * @param decimal
+ * @return
+ */
+ public static String decimalToHexWithPadding(int decimal, int padding) {
+ // 将十进制转换为十六进制,并转换为字符串
+ String hex = Integer.toHexString(decimal);
+
+ // 确保字符串长度为至少4位,不足部分前面补0
+ while (hex.length() < padding) {
+ hex = "0" + hex;
+ }
+
+ return hex.toUpperCase(); // 返回大写形式的十六进制字符串
+ }
+
+ /**
+ * 十进制转二进制,且返回的二进制为至少7位数
+ *
+ * @param decimal
+ * @return
+ */
+ public static String decimalToBinary(int decimal) {
+ // 如果输入为0,直接返回"0"
+ if (decimal == 0) {
+ return "0";
+ }
+
+ StringBuilder binary = new StringBuilder();
+
+ // 除2取余法,将余数加入二进制字符串
+ while (decimal > 0) {
+ int remainder = decimal % 2;
+ binary.insert(0, remainder);
+ decimal = decimal / 2;
+ }
+ int length = binary.length();
+ if (length < 7) {
+ int padding = 7 - length;
+ for (int i = 0; i < padding; i++) {
+ binary.insert(0, '0');
+ }
+ }
+ return binary.toString();
+ }
+
+ /**
+ * 将二进制字符串转换为十六进制字符串,每8位转换为两位十六进制,不足两位前面补零
+ *
+ * @param binaryStr 输入的二进制字符串(仅包含0和1)
+ * @return 转换后的十六进制字符串
+ * @throws IllegalArgumentException 如果输入不是有效的二进制字符串
+ */
+ public static String binaryToHex(String binaryStr) {
+ // 校验输入合法性
+ if (binaryStr == null || !binaryStr.matches("[01]+")) {
+ throw new IllegalArgumentException("Invalid binary string");
+ }
+
+ // 补前导零使长度成为8的倍数
+ int length = binaryStr.length();
+ int padding = (8 - (length % 8)) % 8; // 计算需要补零的数量
+ StringBuilder paddedBinary = new StringBuilder();
+ for (int i = 0; i < padding; i++) {
+ paddedBinary.append('0');
+ }
+ paddedBinary.append(binaryStr);
+
+ // 每8位转换为两位十六进制
+ StringBuilder hexStr = new StringBuilder();
+ for (int i = 0; i < paddedBinary.length(); i += 8) {
+ String byteStr = paddedBinary.substring(i, i + 8);
+ int decimalValue = Integer.parseInt(byteStr, 2);
+ hexStr.append(String.format("%02X", decimalValue & 0xFF));
+ }
+
+ return hexStr.toString();
+ }
+
+ /**
+ * 数据校验 异或处理
+ */
+ public static String getXor(String content) {
+ int a = 0;
+ for (int i = 0; i < content.length() / 2; i++) {
+ a = a ^ Integer.parseInt(content.substring(i * 2, (i * 2) + 2), 16);
+ }
+ String result = Integer.toHexString(a).toUpperCase();
+ if (result.length() == 1) {
+ return "0" + result;
+ } else {
+ return result;
+ }
+ }
+
+ public static double formatPersonInfo(String input, int startIndex, int length) {
+ if (input == null) {
+ return 0;
+ }
+ // 处理索引越界问题
+ int safeStart = Math.max(startIndex, 0);
+ int safeEnd = Math.min(startIndex + length, input.length());
+ if (safeStart > safeEnd) {
+ return 0;
+ }
+ String result = input.substring(safeStart, safeEnd);
+ double num = Integer.parseInt(result, 16);
+ return num;
+ }
+
+ /**
+ * 安装apk
+ *
+ * @param activity
+ * @param apkFile
+ */
+ public static void installApk(Context activity, File apkFile) {
+ //文件有所有者概念,现在是属于当前进程的,需要把这个文件暴露给系统安装程序(其他进程)去安装
+ //因此,可能会存在权限问题,需要做下面的设置
+ //如果文件是sdcard上的,就不需要这个操作了
+ try {
+ apkFile.setExecutable(true, false);
+ apkFile.setReadable(true, false);
+ apkFile.setWritable(true, false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Intent intent = new Intent();
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setAction(Intent.ACTION_VIEW);
+ Uri uri;
+
+ //TODO N FileProvider
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ uri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileProvider", apkFile);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+// intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ } else {
+ uri = Uri.fromFile(apkFile);
+ }
+
+ intent.setDataAndType(uri, "application/vnd.android.package-archive");
+ activity.startActivity(intent);
+
+ //TODO 0 INSTALL PERMISSION
+ //在AndroidManifest中加入权限即可
+ }
+
+}
diff --git a/lib_face/src/main/java/com/sw/plate/utils/Base64.java b/lib_face/src/main/java/com/sw/plate/utils/Base64.java
new file mode 100644
index 0000000..eaf28da
--- /dev/null
+++ b/lib_face/src/main/java/com/sw/plate/utils/Base64.java
@@ -0,0 +1,265 @@
+package com.sw.plate.utils;
+
+public final class Base64 {
+
+ private static final int BASELENGTH = 128;
+ private static final int LOOKUPLENGTH = 64;
+ private static final int TWENTYFOURBITGROUP = 24;
+ private static final int EIGHTBIT = 8;
+ private static final int SIXTEENBIT = 16;
+ private static final int FOURBYTE = 4;
+ private static final int SIGN = -128;
+ private static char PAD = '=';
+ private static byte[] base64Alphabet = new byte[BASELENGTH];
+ private static char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+ static {
+ for (int i = 0; i < BASELENGTH; ++i) {
+ base64Alphabet[i] = -1;
+ }
+ for (int i = 'Z'; i >= 'A'; i--) {
+ base64Alphabet[i] = (byte) (i - 'A');
+ }
+ for (int i = 'z'; i >= 'a'; i--) {
+ base64Alphabet[i] = (byte) (i - 'a' + 26);
+ }
+
+ for (int i = '9'; i >= '0'; i--) {
+ base64Alphabet[i] = (byte) (i - '0' + 52);
+ }
+
+ base64Alphabet['+'] = 62;
+ base64Alphabet['/'] = 63;
+
+ for (int i = 0; i <= 25; i++) {
+ lookUpBase64Alphabet[i] = (char) ('A' + i);
+ }
+
+ for (int i = 26, j = 0; i <= 51; i++, j++) {
+ lookUpBase64Alphabet[i] = (char) ('a' + j);
+ }
+
+ for (int i = 52, j = 0; i <= 61; i++, j++) {
+ lookUpBase64Alphabet[i] = (char) ('0' + j);
+ }
+ lookUpBase64Alphabet[62] = (char) '+';
+ lookUpBase64Alphabet[63] = (char) '/';
+
+ }
+
+ private static boolean isWhiteSpace(char octect) {
+ return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+ }
+
+ private static boolean isPad(char octect) {
+ return (octect == PAD);
+ }
+
+ private static boolean isData(char octect) {
+ return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+ }
+
+ /**
+ * Encodes hex octects into Base64
+ *
+ * @param binaryData Array containing binaryData
+ * @return Encoded Base64 array
+ */
+ public static String encode(byte[] binaryData) {
+
+ if (binaryData == null) {
+ return null;
+ }
+
+ int lengthDataBits = binaryData.length * EIGHTBIT;
+ if (lengthDataBits == 0) {
+ return "";
+ }
+
+ int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+ int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+ int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
+ : numberTriplets;
+ char encodedData[] = null;
+
+ encodedData = new char[numberQuartet * 4];
+
+ byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+ int encodedIndex = 0;
+ int dataIndex = 0;
+
+ for (int i = 0; i < numberTriplets; i++) {
+ b1 = binaryData[dataIndex++];
+ b2 = binaryData[dataIndex++];
+ b3 = binaryData[dataIndex++];
+
+ l = (byte) (b2 & 0x0f);
+ k = (byte) (b1 & 0x03);
+
+ byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+ : (byte) ((b1) >> 2 ^ 0xc0);
+ byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+ : (byte) ((b2) >> 4 ^ 0xf0);
+ byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
+ : (byte) ((b3) >> 6 ^ 0xfc);
+
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+ }
+
+ // form integral number of 6-bit groups
+ if (fewerThan24bits == EIGHTBIT) {
+ b1 = binaryData[dataIndex];
+ k = (byte) (b1 & 0x03);
+
+ byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+ : (byte) ((b1) >> 2 ^ 0xc0);
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+ encodedData[encodedIndex++] = PAD;
+ encodedData[encodedIndex++] = PAD;
+ } else if (fewerThan24bits == SIXTEENBIT) {
+ b1 = binaryData[dataIndex];
+ b2 = binaryData[dataIndex + 1];
+ l = (byte) (b2 & 0x0f);
+ k = (byte) (b1 & 0x03);
+
+ byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+ : (byte) ((b1) >> 2 ^ 0xc0);
+ byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+ : (byte) ((b2) >> 4 ^ 0xf0);
+
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+ encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+ encodedData[encodedIndex++] = PAD;
+ }
+
+ return new String(encodedData);
+ }
+
+ /**
+ * Decodes Base64 data into octects
+ *
+ * @param encoded string containing Base64 data
+ * @return Array containind decoded data.
+ */
+ public static byte[] decode(String encoded) {
+
+ if (encoded == null) {
+ return null;
+ }
+
+ char[] base64Data = encoded.toCharArray();
+ // remove white spaces
+ int len = removeWhiteSpace(base64Data);
+
+ if (len % FOURBYTE != 0) {
+ return null;// should be divisible by four
+ }
+
+ int numberQuadruple = (len / FOURBYTE);
+
+ if (numberQuadruple == 0) {
+ return new byte[0];
+ }
+
+ byte decodedData[] = null;
+ byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+ char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+ int i = 0;
+ int encodedIndex = 0;
+ int dataIndex = 0;
+ decodedData = new byte[(numberQuadruple) * 3];
+
+ for (; i < numberQuadruple - 1; i++) {
+
+ if (!isData((d1 = base64Data[dataIndex++]))
+ || !isData((d2 = base64Data[dataIndex++]))
+ || !isData((d3 = base64Data[dataIndex++]))
+ || !isData((d4 = base64Data[dataIndex++]))) {
+ return null;
+ }// if found "no data" just return null
+
+ b1 = base64Alphabet[d1];
+ b2 = base64Alphabet[d2];
+ b3 = base64Alphabet[d3];
+ b4 = base64Alphabet[d4];
+
+ decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+ decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+ decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+ }
+
+ if (!isData((d1 = base64Data[dataIndex++]))
+ || !isData((d2 = base64Data[dataIndex++]))) {
+ return null;// if found "no data" just return null
+ }
+
+ b1 = base64Alphabet[d1];
+ b2 = base64Alphabet[d2];
+
+ d3 = base64Data[dataIndex++];
+ d4 = base64Data[dataIndex++];
+ if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
+ if (isPad(d3) && isPad(d4)) {
+ if ((b2 & 0xf) != 0)// last 4 bits should be zero
+ {
+ return null;
+ }
+ byte[] tmp = new byte[i * 3 + 1];
+ System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+ tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+ return tmp;
+ } else if (!isPad(d3) && isPad(d4)) {
+ b3 = base64Alphabet[d3];
+ if ((b3 & 0x3) != 0)// last 2 bits should be zero
+ {
+ return null;
+ }
+ byte[] tmp = new byte[i * 3 + 2];
+ System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+ tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+ tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+ return tmp;
+ } else {
+ return null;
+ }
+ } else { // No PAD e.g 3cQl
+ b3 = base64Alphabet[d3];
+ b4 = base64Alphabet[d4];
+ decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+ decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+ decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+ }
+
+ return decodedData;
+ }
+
+ /**
+ * remove WhiteSpace from MIME containing encoded Base64 data.
+ *
+ * @param data the byte array of base64 data (with WS)
+ * @return the new length
+ */
+ private static int removeWhiteSpace(char[] data) {
+ if (data == null) {
+ return 0;
+ }
+
+ // count characters that's not whitespace
+ int newSize = 0;
+ int len = data.length;
+ for (int i = 0; i < len; i++) {
+ if (!isWhiteSpace(data[i])) {
+ data[newSize++] = data[i];
+ }
+ }
+ return newSize;
+ }
+}
diff --git a/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java
new file mode 100644
index 0000000..61b91ea
--- /dev/null
+++ b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java
@@ -0,0 +1,38 @@
+package com.sw.plate.utils.comn;
+
+import static com.sw.plate.utils.CabinetLockCommand.generateOpenCommand;
+
+import android.serialport.SerialPort;
+
+import com.sw.plate.utils.ToastUtils;
+
+public class SerialApi {
+ private static String path = "/dev/ttyS2";
+ private static int speed = 19200;
+ private static SerialPortManager serialPortManager;
+ private static SerialPort serialPort;
+
+ public static void init() {
+ serialPortManager = SerialPortManager.instance();
+ serialPort = serialPortManager.open(new Device(path, String.valueOf(speed)));
+ if (serialPort == null) {
+ ToastUtils.showToast("打开串口失败");
+ }
+ }
+
+ /**
+ * 开柜
+ *
+ * @param boxNumber
+ * @param callback
+ */
+ public static void openPlate(int boxNumber, SerialPortManager.SendCallback callback) {
+ if (serialPort == null) {
+ init();
+ }
+ if (serialPort == null) {
+ return;
+ }
+ serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback);
+ }
+}
diff --git a/lib_face/src/main/java/com/sw/plate/utils/comn/SerialPortManager.java b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialPortManager.java
index 9b98d01..6835200 100644
--- a/lib_face/src/main/java/com/sw/plate/utils/comn/SerialPortManager.java
+++ b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialPortManager.java
@@ -153,7 +153,7 @@ public class SerialPortManager {
/**
* 发送命令包
*/
- public void sendCommand(final String command) {
+ public void sendCommand(final String command, SendCallback callback) {
// TODO: 2018/3/22
L.e("发送命令:" + command);
@@ -168,11 +168,13 @@ public class SerialPortManager {
@Override
public void onNext(Object o) {
// LogManager.instance().post(new SendMessage(command));
+ callback.onSuccess();
}
@Override
public void onError(Throwable e) {
L.e("发送失败" + e);
+ callback.onFail(new Exception(e));
}
@Override
@@ -181,4 +183,10 @@ public class SerialPortManager {
}
});
}
+
+ public interface SendCallback {
+ void onSuccess();
+
+ void onFail(Exception e);
+ }
}
diff --git a/lib_face/src/main/res/layout/toast_bg.xml b/lib_face/src/main/res/layout/toast_bg.xml
index e3ba3f5..67e932f 100644
--- a/lib_face/src/main/res/layout/toast_bg.xml
+++ b/lib_face/src/main/res/layout/toast_bg.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
\ No newline at end of file