From ce46dd9e401d7f2936db08bcea201bbd1da8e0a2 Mon Sep 17 00:00:00 2001
From: weimingfei <fei_gaming@sina.com>
Date: 星期三, 10 十二月 2025 13:39:44 +0800
Subject: [PATCH] 指纹钥匙柜

---
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDB.java                      |   28 
 keyCabinet-android/app/src/main/res/layout/chose_fun_activity.xml                                      |  127 +
 keyCabinet-android/app/src/main/jniLibs/x86/libserial_port.so                                          |    0 
 keyCabinet-android/app/src/main/res/layout/chose_activation_activity.xml                               |   66 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SerialPortModel.java             |   10 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunVM.java               |   20 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDao.java                     |   50 
 keyCabinet-android/app/src/main/java/android_serialport_api/SerialHelper.java                          |  227 ++
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java             |  547 +++++
 keyCabinet-android/app/build.gradle                                                                    |    4 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwLrRcvAdapter.java   |   44 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRVM.java                   |   29 
 keyCabinet-android/app/src/main/java/android_serialport_api/ComBean.java                               |   24 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDo.java                      |   79 
 keyCabinet-android/app/src/main/res/layout/zwlist_rcv_item.xml                                         |   76 
 keyCabinet-android/app/src/main/res/layout/zwlr_activity.xml                                           |  375 ++++
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListVM.java                 |   27 
 keyCabinet-android/app/src/main/res/layout/zwlist_activity.xml                                         |  110 +
 keyCabinet-android/app/src/main/res/layout/item_usb_device.xml                                         |   52 
 keyCabinet-android/app/src/main/res/layout/zwlr_rcv_item.xml                                           |   43 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/DaoManager.java                         |    4 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java      |    3 
 keyCabinet-android/app/src/main/res/layout/offline_activation_activity.xml                             |  263 ++
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java                  |   17 
 keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenguanli.png                                  |    0 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/FingerPrintVo.java                     |   56 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginVM.java            |    2 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListActivity.java           |  150 +
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/RefreshFingerEvent.java               |    4 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/PhotoUtils.java                       |    9 
 keyCabinet-android/build.gradle                                                                        |    1 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunActivity.java         |   49 
 keyCabinet-android/app/src/main/res/layout/manage_cabinet_activity.xml                                 |   56 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/UsbController.java                |  451 ++++
 keyCabinet-android/app/src/main/jniLibs/arm64-v8a/libserial_port.so                                    |    0 
 keyCabinet-android/app/src/main/jniLibs/armeabi-v7a/libserial_port.so                                  |    0 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java                     |   38 
 keyCabinet-android/app/src/main/java/android_serialport_api/SerialPortFinder.java                      |  122 +
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/DevComm.java                      | 1812 +++++++++++++++++++
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java                   |  271 ++
 keyCabinet-android/app/src/main/res/mipmap-xxhdpi/design_ic_ar.png                                     |    0 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java                   |    2 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/LoginBean.java                         |    2 
 keyCabinet-android/app/src/main/jniLibs/armeabi/libserial_port.so                                      |    0 
 keyCabinet-android/app/src/main/jniLibs/mips64/libserial_port.so                                       |    0 
 keyCabinet-android/app/src/main/jniLibs/x86_64/libserial_port.so                                       |    0 
 keyCabinet-android/app/src/main/jniLibs/mips/libserial_port.so                                         |    0 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java                         |    8 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/IUsbConnState.java                |   12 
 keyCabinet-android/app/src/main/java/android_serialport_api/SerialPort.java                            |   89 
 keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwListRcvAdapter.java |   49 
 keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_delete.png                                        |    0 
 keyCabinet-android/app/src/main/AndroidManifest.xml                                                    |   49 
 keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_guigeguanli.png                                   |    0 
 keyCabinet-android/app/src/main/res/drawable/shape_f8_r15_bg.xml                                       |    7 
 keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java                     |    2 
 56 files changed, 5,380 insertions(+), 86 deletions(-)

diff --git a/keyCabinet-android/app/build.gradle b/keyCabinet-android/app/build.gradle
index ddeec78..a5c5f36 100644
--- a/keyCabinet-android/app/build.gradle
+++ b/keyCabinet-android/app/build.gradle
@@ -125,8 +125,6 @@
     //implementation 'com.github.Shouheng88:compressor:latest-version'
     //鍘嬬缉鍥剧墖
     implementation "id.zelory:compressor:1.0.3"
-    //涓插彛
-    implementation 'com.licheedev:android-serialport:2.1.3'
 
     //浜岀淮鐮佺敓鎴�
     implementation 'com.journeyapps:zxing-android-embedded:3.4.0'
@@ -135,4 +133,6 @@
     implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19'
     //杞挱鍥�
     implementation 'com.bigkoo:convenientbanner:2.0.5'
+    //澶村儚
+    implementation 'de.hdodenhof:circleimageview:3.1.0'
 }
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/AndroidManifest.xml b/keyCabinet-android/app/src/main/AndroidManifest.xml
index 4658735..ee474d0 100644
--- a/keyCabinet-android/app/src/main/AndroidManifest.xml
+++ b/keyCabinet-android/app/src/main/AndroidManifest.xml
@@ -15,6 +15,16 @@
         android:usesCleartextTraffic="true"
         tools:replace="android:allowBackup">
         <activity
+            android:name=".ui.keyCabinet.ChoseFunActivity"
+            android:exported="false" />
+        <activity
+            android:name=".ui.keyCabinet.ZWLRActivity"
+            android:exported="false" />
+        <activity
+            android:name=".ui.keyCabinet.ZWListActivity"
+            android:exported="true" >
+        </activity>
+        <activity
             android:name=".ui.face.ChoseActivationActivity"
             android:exported="false" />
         <activity
@@ -69,16 +79,9 @@
         <meta-data
             android:name="com.google.android.gms.vision.DEPENDENCIES"
             android:value="face" />
-
-        <provider
-            android:name="androidx.core.content.FileProvider"
-            android:authorities="com.doumee.keyCabinet.fileProvider"
-            android:exported="false"
-            android:grantUriPermissions="true">
-            <meta-data
-                android:name="android.support.FILE_PROVIDER_PATHS"
-                android:resource="@xml/provider_paths" />
-        </provider>
+        <meta-data
+            android:name="android:requestLegacyExternalStorage"
+            android:value="true" />
         <!--
 <receiver
             android:name="com.doumee.keyCabinet.ui.service.BootCompleteReceiver"
@@ -95,17 +98,29 @@
 <service android:name="com.doumee.keyCabinet.ui.service.HeartbeatService" />
         <service android:name="com.doumee.keyCabinet.ui.service.FaceUpdateService" />
         -->
-        <meta-data
-            android:name="android:requestLegacyExternalStorage"
-            android:value="true" />
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="com.doumee.keyCabinet.fileProvider"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/provider_paths" />
+        </provider>
         <uses-library
             android:name="org.apache.http.legacy"
             android:required="false" />
     </application>
-    <uses-feature android:name="android.hardware.usb.host" />
+    <uses-feature android:name="android.hardware.usb.host"
+        android:sharedUserId="android.uid.system"/>
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.READ_OWNER_DATA" />
+    <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
     <uses-feature android:name="android.hardware.nfc" />
     <uses-permission android:name="android.permission.ACCESS_SURERUSER" />
-    <uses-permission android:name="android.permission.USB_PERMISSION" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
@@ -116,7 +131,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission
         android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
@@ -134,7 +149,7 @@
     <uses-permission
         android:name="android.permission.WRITE_SETTINGS"
         tools:ignore="ProtectedPermissions" />
-    <uses-permission android:name="android.permission.ACCESS_USB_PERMISSION"/>
+    <uses-permission android:name="android.permission.ACCESS_USB_PERMISSION" />
 
     <uses-permission android:name="android.permission.NFC" />
 
diff --git a/keyCabinet-android/app/src/main/java/android_serialport_api/ComBean.java b/keyCabinet-android/app/src/main/java/android_serialport_api/ComBean.java
new file mode 100644
index 0000000..0a6d9c1
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/android_serialport_api/ComBean.java
@@ -0,0 +1,24 @@
+package android_serialport_api;
+
+import java.text.SimpleDateFormat;
+
+/**
+ * @author benjaminwan
+ */
+public class ComBean {
+		public byte[] bRec=null;
+		public String sRecTime="";
+		public String sComPort="";
+		public int nSize = 0;
+		public ComBean(String sPort,byte[] buffer,int size){
+			sComPort=sPort;
+			bRec=new byte[size];
+			for (int i = 0; i < size; i++)
+			{
+				bRec[i]=buffer[i];
+			}
+			nSize = size;
+			SimpleDateFormat sDateFormat = new SimpleDateFormat("hh:mm:ss");       
+			sRecTime = sDateFormat.format(new java.util.Date()); 
+		}
+}
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/android_serialport_api/SerialHelper.java b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialHelper.java
new file mode 100644
index 0000000..f91de72
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialHelper.java
@@ -0,0 +1,227 @@
+package android_serialport_api;
+
+import com.doumee.keyCabinet.utils.usb.DevComm;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidParameterException;
+
+
+public abstract class SerialHelper{
+	private SerialPort mSerialPort;
+	private OutputStream mOutputStream;
+	private InputStream mInputStream;
+	private ReadThread mReadThread;
+	private SendThread mSendThread;
+	private String sPort="/dev/s3c2410_serial0";
+	private int iBaudRate=9600;
+	private boolean _isOpen=false;
+	private byte[] _bLoopData=new byte[]{0x30};
+	private int iDelay=500;
+	//----------------------------------------------------
+	public SerialHelper(String sPort,int iBaudRate){
+		this.sPort = sPort;
+		this.iBaudRate=iBaudRate;
+	}
+	public SerialHelper(){
+		this("/dev/s3c2410_serial0",9600);
+	}
+	public SerialHelper(String sPort){
+		this(sPort,9600);
+	}
+	public SerialHelper(String sPort,String sBaudRate){
+		this(sPort,Integer.parseInt(sBaudRate));
+	}
+	//----------------------------------------------------
+	public void open() throws SecurityException, IOException,InvalidParameterException{
+		mSerialPort =  new SerialPort(new File(sPort), iBaudRate, 0);
+		mOutputStream = mSerialPort.getOutputStream();
+		mInputStream = mSerialPort.getInputStream();
+		mReadThread = new ReadThread();
+		mReadThread.start();
+		mSendThread = new SendThread();
+		mSendThread.setSuspendFlag();
+		mSendThread.start();
+		_isOpen=true;
+	}
+	//----------------------------------------------------
+	public void close(){
+		if (mReadThread != null)
+			mReadThread.interrupt();
+		if (mSerialPort != null) {
+			mSerialPort.close();
+			mSerialPort = null;
+		}
+		_isOpen=false;
+	}
+	//----------------------------------------------------
+	public void send(byte[] bOutArray, int nSize){
+		try
+		{
+			mOutputStream.write(bOutArray, 0, nSize);
+		} catch (IOException e)
+		{
+			e.printStackTrace();
+		}
+	}
+	//----------------------------------------------------
+	public void sendTxt(String sTxt){
+		byte[] bOutArray =sTxt.getBytes();
+		send(bOutArray, sTxt.length());
+	}
+	//----------------------------------------------------
+	private class ReadThread extends Thread {
+		@Override
+		public void run() {
+			super.run();
+			while(!isInterrupted()) {
+				try
+				{
+					if (mInputStream == null) return;
+					byte[] buffer=new byte[DevComm.MAX_DATA_LEN];
+					int size = mInputStream.read(buffer);
+					if (size > 0){
+						ComBean ComRecData = new ComBean(sPort,buffer,size);
+						onDataReceived(ComRecData);
+					}
+					try
+					{
+						Thread.sleep(50);
+					} catch (InterruptedException e)
+					{
+						e.printStackTrace();
+					}
+				} catch (Throwable e)
+				{
+					e.printStackTrace();
+					return;
+				}
+			}
+		}
+	}
+	//----------------------------------------------------
+	private class SendThread extends Thread{
+		public boolean suspendFlag = true;
+		@Override
+		public void run() {
+			super.run();
+			while(!isInterrupted()) {
+				synchronized (this)
+				{
+					while (suspendFlag)
+					{
+						try
+						{
+							wait();
+						} catch (InterruptedException e)
+						{
+							e.printStackTrace();
+						}
+					}
+				}
+				send(getbLoopData(), 1);
+				try
+				{
+					Thread.sleep(iDelay);
+				} catch (InterruptedException e)
+				{
+					e.printStackTrace();
+				}
+			}
+		}
+
+		public void setSuspendFlag() {
+		this.suspendFlag = true;
+		}
+
+		public synchronized void setResume() {
+		this.suspendFlag = false;
+		notify();
+		}
+	}
+	//----------------------------------------------------
+	public int getBaudRate()
+	{
+		return iBaudRate;
+	}
+	public boolean setBaudRate(int iBaud)
+	{
+		if (_isOpen)
+		{
+			return false;
+		} else
+		{
+			iBaudRate = iBaud;
+			return true;
+		}
+	}
+	public boolean setBaudRate(String sBaud)
+	{
+		int iBaud = Integer.parseInt(sBaud);
+		return setBaudRate(iBaud);
+	}
+	//----------------------------------------------------
+	public String getPort()
+	{
+		return sPort;
+	}
+	public boolean setPort(String sPort)
+	{
+		if (_isOpen)
+		{
+			return false;
+		} else
+		{
+			this.sPort = sPort;
+			return true;
+		}
+	}
+	//----------------------------------------------------
+	public boolean isOpen()
+	{
+		return _isOpen;
+	}
+	//----------------------------------------------------
+	public byte[] getbLoopData()
+	{
+		return _bLoopData;
+	}
+	//----------------------------------------------------
+	public void setbLoopData(byte[] bLoopData)
+	{
+		this._bLoopData = bLoopData;
+	}
+	//----------------------------------------------------
+	public void setTxtLoopData(String sTxt){
+		this._bLoopData = sTxt.getBytes();
+	}
+	//----------------------------------------------------
+	public int getiDelay()
+	{
+		return iDelay;
+	}
+	//----------------------------------------------------
+	public void setiDelay(int iDelay)
+	{
+		this.iDelay = iDelay;
+	}
+	//----------------------------------------------------
+	public void startSend()
+	{
+		if (mSendThread != null)
+		{
+			mSendThread.setResume();
+		}
+	}
+	//----------------------------------------------------
+	public void stopSend()
+	{
+		if (mSendThread != null)
+		{
+			mSendThread.setSuspendFlag();
+		}
+	}
+	//----------------------------------------------------
+	protected abstract void onDataReceived(ComBean ComRecData);
+}
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPort.java b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPort.java
new file mode 100644
index 0000000..e156cff
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPort.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 Cedric Priscal
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+package android_serialport_api;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class SerialPort {
+
+	private static final String TAG = "SerialPort";
+
+	/*
+	 * Do not remove or rename the field mFd: it is used by native method close();
+	 */
+	private FileDescriptor mFd;
+	private FileInputStream mFileInputStream;
+	private FileOutputStream mFileOutputStream;
+
+	public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
+
+		/* Check access permission */
+		if (!device.canRead() || !device.canWrite()) {
+			try {
+				/* Missing read/write permission, trying to chmod the file */
+				Process su;
+				su = Runtime.getRuntime().exec("/system/bin/su");
+				String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
+						+ "exit\n";
+				su.getOutputStream().write(cmd.getBytes());
+				if ((su.waitFor() != 0) || !device.canRead()
+						|| !device.canWrite()) {
+					throw new SecurityException();
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new SecurityException();
+			}
+		}
+
+		mFd = open(device.getAbsolutePath(), baudrate, flags);
+		if (mFd == null) {
+			Log.e(TAG, "native open returns null");
+			throw new IOException();
+		}
+		mFileInputStream = new FileInputStream(mFd);
+		mFileOutputStream = new FileOutputStream(mFd);
+	}
+
+	// Getters and setters
+	public InputStream getInputStream() {
+		return mFileInputStream;
+	}
+
+	public OutputStream getOutputStream() {
+		return mFileOutputStream;
+	}
+
+	// JNI
+	private native static FileDescriptor open(String path, int baudrate, int flags);
+	public native void close();
+	static {
+		try {
+			System.loadLibrary("serial_port");
+		} catch (UnsatisfiedLinkError err) {
+			err.printStackTrace();
+		}
+	}
+}
diff --git a/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPortFinder.java b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPortFinder.java
new file mode 100644
index 0000000..292aca3
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/android_serialport_api/SerialPortFinder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2009 Cedric Priscal
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+package android_serialport_api;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class SerialPortFinder {
+
+	public class Driver {
+		public Driver(String name, String root) {
+			mDriverName = name;
+			mDeviceRoot = root;
+		}
+		private String mDriverName;
+		private String mDeviceRoot;
+		Vector<File> mDevices = null;
+		public Vector<File> getDevices() {
+			if (mDevices == null) {
+				mDevices = new Vector<File>();
+				File dev = new File("/dev");
+				File[] files = dev.listFiles();
+				int i;
+				for (i=0; i<files.length; i++) {
+					if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {
+						Log.d(TAG, "Found new device: " + files[i]);
+						mDevices.add(files[i]);
+					}
+				}
+			}
+			return mDevices;
+		}
+		public String getName() {
+			return mDriverName;
+		}
+	}
+
+	private static final String TAG = "SerialPort";
+
+	private Vector<Driver> mDrivers = null;
+
+	Vector<Driver> getDrivers() throws IOException {
+		if (mDrivers == null) {
+			mDrivers = new Vector<Driver>();
+			LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));
+			String l;
+			while((l = r.readLine()) != null) {
+				// Issue 3:
+				// Since driver name may contain spaces, we do not extract driver name with split()
+				String drivername = l.substring(0, 0x15).trim();
+				String[] w = l.split(" +");
+				if ((w.length >= 5) && (w[w.length-1].equals("serial"))) {
+					Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length-4]);
+					mDrivers.add(new Driver(drivername, w[w.length-4]));
+				}
+			}
+			r.close();
+		}
+		return mDrivers;
+	}
+
+	public String[] getAllDevices() {
+		Vector<String> devices = new Vector<String>();
+		// Parse each driver
+		Iterator<Driver> itdriv;
+		try {
+			itdriv = getDrivers().iterator();
+			while(itdriv.hasNext()) {
+				Driver driver = itdriv.next();
+				Iterator<File> itdev = driver.getDevices().iterator();
+				while(itdev.hasNext()) {
+					String device = itdev.next().getName();
+					String value = String.format("%s (%s)", device, driver.getName());
+					devices.add(value);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return devices.toArray(new String[devices.size()]);
+	}
+
+	public String[] getAllDevicesPath() {
+		Vector<String> devices = new Vector<String>();
+		// Parse each driver
+		Iterator<Driver> itdriv;
+		try {
+			itdriv = getDrivers().iterator();
+			while(itdriv.hasNext()) {
+				Driver driver = itdriv.next();
+				Iterator<File> itdev = driver.getDevices().iterator();
+				while(itdev.hasNext()) {
+					String device = itdev.next().getAbsolutePath();
+					devices.add(device);
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return devices.toArray(new String[devices.size()]);
+	}
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/FingerPrintVo.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/FingerPrintVo.java
new file mode 100644
index 0000000..f11d3dd
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/FingerPrintVo.java
@@ -0,0 +1,56 @@
+package com.doumee.keyCabinet.bean;
+
+import androidx.room.ColumnInfo;
+
+public class FingerPrintVo {
+    //鐢ㄦ埛id
+    private int memberId;;
+    //鍚嶇О
+    private String memberName;
+    //澶村儚
+    private String face;
+    //0:绠$悊鍛橈紝1锛氬徃鏈�
+    private String groupId;
+    //鏁伴噺
+    private int count;
+
+    public int getMemberId() {
+        return memberId;
+    }
+
+    public void setMemberId(int memberId) {
+        this.memberId = memberId;
+    }
+
+    public String getMemberName() {
+        return memberName;
+    }
+
+    public void setMemberName(String memberName) {
+        this.memberName = memberName;
+    }
+
+    public String getFace() {
+        return face;
+    }
+
+    public void setFace(String face) {
+        this.face = face;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/LoginBean.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/LoginBean.java
index 8563de9..b79b249 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/LoginBean.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/LoginBean.java
@@ -5,7 +5,7 @@
     private Integer autoMemberId;
     private Integer memberId;
 
-    //鐢ㄦ埛楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱
+    //鐢ㄦ埛楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱 2鎸囩汗
     private int authType;
 
     //0锛氬彇锛�1锛氳繕
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/DaoManager.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/DaoManager.java
index 5d19688..b19c33a 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/DaoManager.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/DaoManager.java
@@ -8,4 +8,8 @@
     public static CabinetGridDao getCabinetGridDao(){
         return CabinetGridDB.getInstance(MApplication.mContext).cabinetGridDao();
     }
+
+    public static FingerPrintDao getFingerPrintDao(){
+        return FingerPrintDB.getInstance(MApplication.mContext).fingerPrintDao();
+    }
 }
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDB.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDB.java
new file mode 100644
index 0000000..9154ec3
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDB.java
@@ -0,0 +1,28 @@
+package com.doumee.keyCabinet.dao;
+
+import android.content.Context;
+
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+
+@Database(entities = {FingerPrintDo.class}, version = 1,exportSchema = false)
+public abstract class FingerPrintDB extends RoomDatabase {
+    public abstract FingerPrintDao fingerPrintDao();
+    private static FingerPrintDB INSTANCE;
+    private static final Object sLock = new Object();
+
+    public static FingerPrintDB getInstance(Context context) {
+        synchronized (sLock) {
+            if (INSTANCE == null) {
+                INSTANCE =
+                        Room.databaseBuilder(context.getApplicationContext(), FingerPrintDB.class, "FingerPrint.db")
+                                .allowMainThreadQueries()//Room涓嶅厑璁稿湪涓荤嚎绋嬩腑璁块棶鏁版嵁搴�
+                                //.addMigrations(MIGRATION_1_2)//鏁版嵁搴撹縼绉�
+                                //.addMigrations(MIGRATION_1_2,MIGRATION_2_4,MIGRATION_1_4)//鏁版嵁搴撹縼绉� ,鍙互鐢�1_4,蹇�熻縼绉�
+                                .build();
+            }
+            return INSTANCE;
+        }
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDao.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDao.java
new file mode 100644
index 0000000..8d253b9
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDao.java
@@ -0,0 +1,50 @@
+package com.doumee.keyCabinet.dao;
+
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.Query;
+import androidx.room.Transaction;
+import androidx.room.Update;
+
+import java.util.List;
+
+@Dao
+public interface FingerPrintDao {
+
+    @Transaction
+    @Query("SELECT * FROM finger_print")
+    List<FingerPrintDo> loadAll();
+
+    @Transaction
+    @Query("SELECT * FROM finger_print WHERE id = :id")
+    FingerPrintDo getFingerById(int id);
+
+    @Transaction
+    @Query("SELECT * FROM finger_print WHERE member_id = :memberId")
+    List<FingerPrintDo> getFingerByMemberId(int memberId);
+
+    @Transaction
+    @Query("SELECT * FROM finger_print WHERE finger_id = :fingerId")
+    FingerPrintDo getByFingerId(int fingerId);
+
+    @Transaction
+    @Insert
+    void insert(FingerPrintDo data);
+
+    @Transaction
+    @Insert
+    void insertAll(FingerPrintDo... datas);
+
+    @Transaction
+    @Insert
+    void insert(List<FingerPrintDo> studentLists);
+
+    @Transaction
+    @Update
+    void update(FingerPrintDo... datas);
+
+    @Transaction
+    @Delete
+    void delete(FingerPrintDo... datas);
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDo.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDo.java
new file mode 100644
index 0000000..86bc320
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/dao/FingerPrintDo.java
@@ -0,0 +1,79 @@
+package com.doumee.keyCabinet.dao;
+
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity(tableName = "finger_print")
+public class FingerPrintDo {
+    @PrimaryKey(autoGenerate = true)
+    private int id;
+
+    @ColumnInfo(name = "member_id",typeAffinity = ColumnInfo.INTEGER)
+    //鐢ㄦ埛id
+    private int memberId;;
+
+    @ColumnInfo(name = "member_name",typeAffinity = ColumnInfo.TEXT)
+    //鍚嶇О
+    private String memberName;
+
+    @ColumnInfo(name = "face",typeAffinity = ColumnInfo.TEXT)
+    //澶村儚
+    private String face;
+
+    @ColumnInfo(name = "group_id",typeAffinity = ColumnInfo.TEXT)
+    //0:绠$悊鍛橈紝1锛氬徃鏈�
+    private String groupId;
+
+    @ColumnInfo(name = "finger_id",typeAffinity = ColumnInfo.INTEGER)
+    //鎸囩汗妯℃澘id
+    private int fingerId;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getMemberId() {
+        return memberId;
+    }
+
+    public void setMemberId(int memberId) {
+        this.memberId = memberId;
+    }
+
+    public String getMemberName() {
+        return memberName;
+    }
+
+    public void setMemberName(String memberName) {
+        this.memberName = memberName;
+    }
+
+    public String getFace() {
+        return face;
+    }
+
+    public void setFace(String face) {
+        this.face = face;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    public int getFingerId() {
+        return fingerId;
+    }
+
+    public void setFingerId(int fingerId) {
+        this.fingerId = fingerId;
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/RefreshFingerEvent.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/RefreshFingerEvent.java
new file mode 100644
index 0000000..61948dd
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/RefreshFingerEvent.java
@@ -0,0 +1,4 @@
+package com.doumee.keyCabinet.event;
+
+public class RefreshFingerEvent {
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java
index 94257da..99bf869 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java
@@ -9,6 +9,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemClock;
 import android.text.Editable;
 import android.text.SpannableString;
 import android.text.Spanned;
@@ -25,22 +26,28 @@
 import com.doumee.keyCabinet.MApplication;
 import com.doumee.keyCabinet.R;
 import com.doumee.keyCabinet.base.MyBaseActivity;
+import com.doumee.keyCabinet.dao.DaoManager;
+import com.doumee.keyCabinet.dao.FingerPrintDo;
 import com.doumee.keyCabinet.databinding.FaceActivityBinding;
 import com.doumee.keyCabinet.event.FaceStatusChangeEvent;
 import com.doumee.keyCabinet.event.HttpEvent;
 import com.doumee.keyCabinet.event.JiujinBeginEvent;
 import com.doumee.keyCabinet.event.JiujinResultEvent;
+import com.doumee.keyCabinet.event.RefreshFingerEvent;
 import com.doumee.keyCabinet.event.TimeClockEvent;
 import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity;
 import com.doumee.keyCabinet.utils.BraceletLogUtils;
 import com.doumee.keyCabinet.utils.face.FaceUtils;
 import com.doumee.keyCabinet.utils.face.model.SingleBaseConfig;
+import com.doumee.keyCabinet.utils.usb.DevComm;
+import com.doumee.keyCabinet.utils.usb.IUsbConnState;
 import com.doumee.lib_coremodel.bean.event.ActionEventData;
 import com.doumee.lib_coremodel.util.SpUtil;
 import com.doumee.lib_coremodel.util.StringUtil;
 import com.doumee.lib_coremodel.view.ToastView;
 import com.example.datalibrary.callback.CameraDataCallback;
 import com.example.datalibrary.callback.FaceDetectCallBack;
+import com.example.datalibrary.db.DBManager;
 import com.example.datalibrary.gatecamera.CameraPreviewManager;
 import com.example.datalibrary.gl.view.GlMantleSurfacView;
 import com.example.datalibrary.manager.FaceSDKManager;
@@ -112,6 +119,7 @@
     @Override
     public void initData(@Nullable Bundle savedInstanceState) {
         //getPermission();
+        initDev();
     }
 
     @Override
@@ -146,6 +154,7 @@
                 getDB().clZw.setVisibility(View.GONE);
                 getDB().clFace.setVisibility(View.VISIBLE);
                 setFaceModel(0);
+                setFingerStatus(1);
                 break;
             case 10:
                 //鍙�-绠$悊鍛樻寚绾归獙璇�
@@ -154,6 +163,7 @@
                 getDB().clFace.setVisibility(View.GONE);
                 getDB().clZw.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(0);
                 break;
             case 1:
                 //鍙�-绠$悊鍛樺埛鍗¢獙璇�
@@ -163,6 +173,7 @@
                 getDB().clZw.setVisibility(View.GONE);
                 getDB().clCard.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(1);
                 break;
             case 5:
                 //鍙�-鍙告満楠岃瘉鏂瑰紡閫夋嫨椤�
@@ -183,6 +194,7 @@
                 getDB().clSjXuan.setVisibility(View.GONE);
                 getDB().clFace.setVisibility(View.VISIBLE);
                 setFaceModel(1);
+                setFingerStatus(1);
                 break;
             case 11:
                 //鍙�-鍙告満鎸囩汗楠岃瘉
@@ -192,6 +204,7 @@
                 getDB().clSjXuan.setVisibility(View.GONE);
                 getDB().clZw.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(0);
                 break;
             case 3:
                 //鍙�-鍙告満鍒峰崱楠岃瘉
@@ -203,6 +216,7 @@
                 getDB().clSjXuan.setVisibility(View.GONE);
                 getDB().clCard.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(1);
                 break;
             case 4:
                 //鍙�-鍙告満閰掔簿妫�娴�
@@ -238,14 +252,16 @@
                 getDB().clZw.setVisibility(View.GONE);
                 getDB().clFace.setVisibility(View.VISIBLE);
                 setFaceModel(1);
+                setFingerStatus(1);
                 break;
             case 12:
-                //杩�-鍙告満浜鸿劯楠岃瘉
+                //杩�-鍙告満鎸囩汗楠岃瘉
                 getDB().tvTitle.setText("鍙告満韬唤楠岃瘉");
                 getDB().clCard.setVisibility(View.GONE);
                 getDB().clFace.setVisibility(View.GONE);
                 getDB().clZw.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(0);
                 break;
             case 8:
                 //杩�-鍙告満鍒峰崱楠岃瘉
@@ -255,6 +271,7 @@
                 getDB().clFace.setVisibility(View.GONE);
                 getDB().clCard.setVisibility(View.VISIBLE);
                 setFaceModel(2);
+                setFingerStatus(1);
                 break;
             case 9:
                 //鍙�-鍙告満閰掔簿妫�娴嬪け璐�
@@ -281,6 +298,16 @@
         }
     }
 
+    private void setFingerStatus(int fs){
+        if(fs==0){
+            //寮�濮嬫娴�
+            identify();
+        }else {
+            //鍏抽棴妫�娴�
+            mBCancel = true;
+        }
+    }
+
     private Bitmap bitmap;
     private byte[] secondFeature = new byte[512];
     @Override
@@ -300,8 +327,12 @@
                 }
                 break;
             case 9:
-                //绠$悊鍛樻寚绾归獙璇�
-                statusFsm(10);
+                //鎸囩汗楠岃瘉
+                if(status==0) {
+                    statusFsm(10);
+                }else {
+                    statusFsm(12);
+                }
                 break;
             case 10:
                 //鍙告満鎸囩汗楠岃瘉
@@ -641,6 +672,10 @@
         faceDetectCallBack = null;
         glMantleSurfacView = null;
         FaceSDKManager.getInstance().destroy();
+        mBCancel = true;
+        if(mDevComm!=null){
+            mDevComm.CloseComm();
+        }
     }
 
     private int resultCount = 0;
@@ -785,4 +820,234 @@
         }
     }
 
+    /**------------------------鎸囩汗妯″潡--------------------------*/
+
+    private void getUserIdByFingerId(int fingerId){
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                FingerPrintDo printDo = DaoManager.getFingerPrintDao().getByFingerId(fingerId);
+                if(printDo!=null){
+                    if(status==10){
+                        //鍙�-绠$悊鍛樻寚绾归獙璇�
+                        MApplication.getLoginBean().setAutoMemberId(printDo.getMemberId());
+                        EventBus.getDefault().post(new FaceStatusChangeEvent(5));
+                    }else if(status==11){
+                        //鍙�-鍙告満鎸囩汗楠岃瘉
+                        MApplication.getLoginBean().setMemberId(printDo.getMemberId());
+                        MApplication.getLoginBean().setAuthType(2);
+                        if(MApplication.getConfigBean()!=null&&MApplication.getConfigBean().getAlcoholStatus()==1) {
+                            //闈為厭绮炬娴�
+                            startActivity(KeyCabinetActivity.class);
+                            finish();
+                        }else {
+                            //閰掔簿妫�娴�
+                            EventBus.getDefault().post(new FaceStatusChangeEvent(4));
+                        }
+                    }else if(status==12){
+                        //杩�-鍙告満
+                        MApplication.getLoginBean().setMemberId(printDo.getMemberId());
+                        MApplication.getLoginBean().setAuthType(2);
+                        startActivity(KeyCabinetActivity.class);
+                        finish();
+                    }
+                }else {
+                    //鎵句笉鍒帮紝鍒犻櫎鎸囩汗
+                    if(deleteID(fingerId)) {
+                        //缁х画鏌ユ寚绾�
+                        identify();
+                    }else {
+                        showToast("鏈煡璇㈠埌鐢ㄦ埛");
+                    }
+                }
+            }
+        });
+    }
+
+    private static DevComm mDevComm;
+    //鏄惁缁撴潫褰曞叆
+    private boolean mBCancel = true;
+    private byte[] m_binImage = new byte[1024 * 100];
+    private final IUsbConnState m_IConnectionHandler = new IUsbConnState() {
+        @Override
+        public void onUsbConnected() {
+            //String[] w_strInfo = new String[1];
+            /*if (mDevComm.Run_TestConnection() == DevComm.ERR_SUCCESS) {
+                if (mDevComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) {
+
+                    getVM().addInfo("杩炴帴usb鎴愬姛");
+                }else {
+                    getVM().addInfo("杩炴帴璁惧澶辫触1锛�" + mDevComm.Run_GetDeviceInfo(w_strInfo));
+                }
+            } else {
+                getVM().addInfo("杩炴帴璁惧澶辫触2锛�" + mDevComm.Run_TestConnection());
+            }*/
+        }
+
+        @Override
+        public void onUsbPermissionDenied() {
+            Toast.makeText(mContext, "鏃犺澶囨潈闄�", Toast.LENGTH_SHORT).show();
+        }
+
+        @Override
+        public void onDeviceNotFound() {
+            Toast.makeText(mContext, "鏈彂鐜版寚绾硅澶�", Toast.LENGTH_SHORT).show();
+        }
+    };
+
+    private void initDev(){
+        mDevComm = new DevComm(this, m_IConnectionHandler);
+        openDevice();
+    }
+    /**
+     * 寮�鍚澶�
+     */
+    private void openDevice() {
+        String[] w_strInfo = new String[1];
+
+        if (mDevComm != null) {
+            if (!mDevComm.IsInit()) {
+                if (mDevComm.OpenComm("USB", 19200) == false) {
+                    EventBus.getDefault().post(new HttpEvent("鍒濆鍖栬澶囧け璐�"));
+                    return;
+                }
+            }
+            if (mDevComm.Run_TestConnection() == DevComm.ERR_SUCCESS) {
+                if (mDevComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) {
+                    EventBus.getDefault().post(new HttpEvent("寮�鍚澶囨垚鍔�"));
+                } else {
+                    EventBus.getDefault().post(new HttpEvent("杩炴帴璁惧澶辫触3," + mDevComm.Run_GetDeviceInfo(w_strInfo)));
+                }
+            } else {
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        EventBus.getDefault().post(new HttpEvent("杩炴帴璁惧澶辫触4,"+mDevComm.Run_TestConnection()));
+                    }
+                });
+                mDevComm.CloseComm();
+            }
+        }
+    }
+
+    private void identify() {
+        if (!mDevComm.IsInit())
+            return;
+
+        mBCancel = false;
+        new Thread(new Runnable() {
+            int w_nRet;
+            int[] w_nID = new int[1];
+            int[] w_nLearned = new int[1];
+            int[] w_nWidth = new int[1];
+            int[] w_nHeight = new int[1];
+
+            @Override
+            public void run() {
+
+                while (true) {
+                    if(mBCancel){
+                        //鍋滄
+                        return;
+                    }
+                    if (capturing() < 0)
+                        return;
+                    //鏉惧紑鎵嬫寚
+
+                    // Up Cpatured Image
+                    if (mDevComm.m_nConnected == 2) {
+                        w_nRet = mDevComm.Run_UpImage(0, m_binImage, w_nWidth, w_nHeight);
+
+                        if (w_nRet != DevComm.ERR_SUCCESS) {
+                            showToast(DevComm.GetErrorMsg(w_nRet));
+                            return;
+                        }
+                    }
+
+                    // Create template
+                    w_nRet = mDevComm.Run_Generate(0);
+
+                    if (w_nRet != DevComm.ERR_SUCCESS) {
+                        if (w_nRet == DevComm.ERR_CONNECTION) {
+                            showToast(DevComm.GetErrorMsg(w_nRet));
+                            return;
+                        } else {
+                            SystemClock.sleep(1000);
+                            continue;
+                        }
+                    }
+
+                    // Identify
+                    w_nRet = mDevComm.Run_Search(0, 1, 500, w_nID, w_nLearned);
+                    if(mBCancel){
+                        //鍋滄
+                        return;
+                    }
+                    if (w_nRet == DevComm.ERR_SUCCESS) {
+                        //鎵惧埌浜�
+                        //showToast("鎵惧埌浜嗭紝"+w_nID[0]);
+                        getUserIdByFingerId(w_nID[0]);
+                        break;
+                        //m_strPost = String.format("Result : Success\r\nTemplate No : %d, Learn Result : %d\r\nMatch Time : %dms", w_nID[0], w_nLearned[0], m_nPassedTime);
+                    } else {
+                        //娌℃壘鍒�
+                        //showToast("娌℃壘鍒�");
+                        /*m_strPost = String.format("\r\nMatch Time : %dms", m_nPassedTime);
+                        m_strPost = GetErrorMsg(w_nRet) + m_strPost;*/
+                    }
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * 鑾峰彇鎸囩汗
+     * @return
+     */
+    private int capturing() {
+        int w_nRet;
+        while (true) {
+            if(isFinishing()){
+                break;
+            }
+            w_nRet = mDevComm.Run_GetImage();
+
+            if (w_nRet == DevComm.ERR_CONNECTION) {
+                showToast("閫氫俊閿欒!");
+                return -1;
+            } else if (w_nRet == DevComm.ERR_SUCCESS) {
+                break;
+            }
+            if (mBCancel) {
+                return -1;
+            }
+        }
+        return 0;
+    }
+
+    private boolean deleteID(int fingerId) {
+        int m_nUserID = fingerId;
+        int w_nRet;
+
+        if (!mDevComm.IsInit())
+            return false;
+
+        w_nRet = mDevComm.Run_DelChar(m_nUserID, m_nUserID);
+        if (w_nRet != DevComm.ERR_SUCCESS&&w_nRet!=DevComm.ERR_TMPL_EMPTY) {
+            //鍒犻櫎澶辫触
+            return false;
+        }
+        return true;
+    }
+
+    private void showToast(String msg){
+        if(!isFinishing()){
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
+                }
+            });
+        }
+    }
 }
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunActivity.java
new file mode 100644
index 0000000..054ffd2
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunActivity.java
@@ -0,0 +1,49 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+
+import com.doumee.keyCabinet.R;
+import com.doumee.keyCabinet.base.MyBaseActivity;
+import com.doumee.keyCabinet.databinding.ChoseFunActivityBinding;
+import com.doumee.lib_coremodel.bean.event.ActionEventData;
+
+import dagger.hilt.android.AndroidEntryPoint;
+
+@AndroidEntryPoint
+public class ChoseFunActivity extends MyBaseActivity<ChoseFunVM, ChoseFunActivityBinding> {
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.chose_fun_activity;
+    }
+
+    @Override
+    public void initView(@Nullable Bundle savedInstanceState) {
+        isAddCountTimer = false;
+        normalConfig();
+        getDB().setModel(getVM());
+    }
+
+    @Override
+    public void initData(@Nullable Bundle savedInstanceState) {
+
+    }
+
+    @Override
+    protected void doRegister(int type, ActionEventData data) {
+        switch (type){
+            case 1:
+                finish();
+                break;
+            case 2:
+                startActivity(ManageCabinetActivity.class);
+                break;
+            case 3:
+                startActivity(ZWListActivity.class);
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunVM.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunVM.java
new file mode 100644
index 0000000..ac631c6
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChoseFunVM.java
@@ -0,0 +1,20 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.hilt.lifecycle.ViewModelInject;
+
+import com.doumee.lib_coremodel.base.BaseModel;
+import com.doumee.lib_coremodel.base.DataViewModel;
+
+public class ChoseFunVM extends DataViewModel {
+    @ViewModelInject
+    public ChoseFunVM(@NonNull Application application, BaseModel model) {
+        super(application, model);
+    }
+    @Override
+    protected void clickByTypeCommand(int type) {
+        doAction(type);
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java
index 0297682..0532abf 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java
@@ -87,10 +87,11 @@
                 getDB().clProgress.setVisibility(View.GONE);
                 tipDownCount = 60;
                 isShowTip = true;
+                getDB().tvTip1.setText(data.getData().get("obj").toString());
                 getDB().clTip.setVisibility(View.VISIBLE);
                 break;
             case 5:
-                startActivity(ManageCabinetActivity.class);
+                startActivity(ChoseFunActivity.class);
                 finish();
                 break;
             case 6:
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginVM.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginVM.java
index 6ed3624..d066893 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginVM.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginVM.java
@@ -44,7 +44,7 @@
                             MApplication.getLoginBean().setAuthType(2);
                             doAction(5);
                         }else {
-                            doAction(4);
+                            doAction(4,response.getMessage());
                         }
                     }
 
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java
new file mode 100644
index 0000000..4ff16ae
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java
@@ -0,0 +1,547 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.TextAppearanceSpan;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.bumptech.glide.Glide;
+import com.doumee.keyCabinet.MApplication;
+import com.doumee.keyCabinet.R;
+import com.doumee.keyCabinet.base.MyBaseActivity;
+import com.doumee.keyCabinet.dao.DaoManager;
+import com.doumee.keyCabinet.dao.FingerPrintDo;
+import com.doumee.keyCabinet.databinding.ZwlrActivityBinding;
+import com.doumee.keyCabinet.event.HttpEvent;
+import com.doumee.keyCabinet.event.RefreshFingerEvent;
+import com.doumee.keyCabinet.event.TimeClockEvent;
+import com.doumee.keyCabinet.ui.keyCabinet.adapter.ZwListRcvAdapter;
+import com.doumee.keyCabinet.ui.keyCabinet.adapter.ZwLrRcvAdapter;
+import com.doumee.keyCabinet.utils.PhotoUtils;
+import com.doumee.keyCabinet.utils.usb.DevComm;
+import com.doumee.keyCabinet.utils.usb.IUsbConnState;
+import com.doumee.lib_coremodel.bean.event.ActionEventData;
+import com.doumee.lib_coremodel.http.utils.FrescoUtils;
+import com.doumee.lib_coremodel.util.RecyclerHelp;
+import com.example.datalibrary.model.User;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.util.List;
+
+import dagger.hilt.android.AndroidEntryPoint;
+
+@AndroidEntryPoint
+public class ZWLRActivity extends MyBaseActivity<ZWLRVM, ZwlrActivityBinding> {
+    private ZwLrRcvAdapter adapter;
+    private int userId;
+    private String userName;
+    private String userPic;
+    private String groupId;
+    private FingerPrintDo delFinger;
+    private Handler handler = new Handler(){
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what){
+                case 0:
+                    getDB().clOk.setVisibility(View.GONE);
+                    break;
+            }
+        }
+    };
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.zwlr_activity;
+    }
+
+    @Override
+    public void initView(@Nullable Bundle savedInstanceState) {
+        isAddCountTimer = false;
+        normalConfig();
+        getDB().setModel(getVM());
+        adapter = new ZwLrRcvAdapter(this, R.layout.zwlr_rcv_item, new ZwLrRcvAdapter.OnItemClick() {
+            @Override
+            public void onItemDelete(FingerPrintDo item) {
+                if(delFinger==null){
+                    delFinger = item;
+                    deleteID(item.getFingerId());
+                }
+            }
+        });
+        RecyclerHelp.bindVL(this,getDB().recyclerView,0,false);
+        getDB().recyclerView.setAdapter(adapter);
+        userName = getStringFormBundle("userName");
+        groupId = getStringFormBundle("groupId");
+        userId = getIntFormBundle("userId");
+        if(userId==0){
+            Toast.makeText(mContext, "鐢ㄦ埛id閿欒", Toast.LENGTH_SHORT).show();
+            finish();
+            return;
+        }
+        userPic = getStringFormBundle("userPic");
+        getDB().tvName.setText(userName);
+        //PhotoUtils.datasToBitmap(this,userPic,getDB().sim);
+        FrescoUtils.displayImageFresco(userPic,getDB().sim);
+        getDB().tvJg2.setText(getErrPhoneText(), TextView.BufferType.SPANNABLE);
+    }
+
+    @Override
+    public void initData(@Nullable Bundle savedInstanceState) {
+        getDatas();
+        initDev();
+    }
+
+    private void getDatas(){
+        List<FingerPrintDo> printDos = DaoManager.getFingerPrintDao().getFingerByMemberId(userId);
+        if(printDos.size()>0) {
+            adapter.refreshData(printDos);
+            getVM().emptyVisibility.set(View.GONE);
+            if(printDos.size()>=3){
+                getDB().tvAdd.setVisibility(View.GONE);
+            }else {
+                getDB().tvAdd.setVisibility(View.VISIBLE);
+            }
+        }else {
+            getDB().tvAdd.setVisibility(View.VISIBLE);
+            getVM().emptyVisibility.set(View.VISIBLE);
+        }
+    }
+
+    @Override
+    protected void doRegister(int type, ActionEventData data) {
+        switch (type){
+            case 1:
+                //鏂板鎸囩汗
+                getDB().clTip.setVisibility(View.GONE);
+                getDB().clZw.setVisibility(View.VISIBLE);
+                getDB().tvZwTip.setText("璇峰皢鎵嬫寚鏀剧疆鍦ㄦ寚绾归噰闆嗗櫒涓婅繘琛屽綍鍏�");
+                tipDownCount = 60;
+                isShowTip = true;
+                enrollBtn();
+                break;
+            case 5:
+                getDB().nsv.setVisibility(getDB().nsv.getVisibility()==View.VISIBLE?View.GONE:View.VISIBLE);
+                break;
+            case 55:
+                getVM().infoObs.set("");
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void showFingerTip(String tip){
+        if(!isFinishing()){
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    if(TextUtils.isEmpty(tip)){
+                        getDB().tvZwTip.setText("璇峰皢鎵嬫寚鏀剧疆鍦ㄦ寚绾归噰闆嗗櫒涓婅繘琛屽綍鍏�");
+                    }else {
+                        getDB().tvZwTip.setText(tip);
+                    }
+                }
+            });
+        }
+    }
+
+    private void showErrTip(String tip){
+        if(!isFinishing()){
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    //鏄剧ず鎻愮ず
+                    getDB().clTip.setVisibility(View.VISIBLE);
+                    getDB().clZw.setVisibility(View.GONE);
+                    if(TextUtils.isEmpty(tip)){
+                        getDB().tvJg1.setText("鎸囩汗褰曞叆澶辫触锛岃閲嶆柊褰曞叆");
+                    }else {
+                        getDB().tvJg1.setText(tip);
+                    }
+                    tipDownCount = 30;
+                    isShowTip = true;
+                }
+            });
+        }
+    }
+
+    private void lrcg(int fingerId){
+        if(!isFinishing()){
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    getVM().addInfo("褰曞叆鎸囩汗锛歩d="+fingerId);
+                    //鎴愬姛
+                    getDB().clTip.setVisibility(View.GONE);
+                    getDB().clZw.setVisibility(View.GONE);
+                    getDB().clOk.setVisibility(View.VISIBLE);
+                    handler.sendEmptyMessageDelayed(0,1000);
+                    //鏂板鎸囩汗璁板綍
+                    FingerPrintDo addDo = new FingerPrintDo();
+                    addDo.setMemberId(userId);
+                    addDo.setMemberName(userName);
+                    addDo.setGroupId(groupId);
+                    addDo.setFingerId(fingerId);
+                    addDo.setFace(userPic);
+                    DaoManager.getFingerPrintDao().insert(addDo);
+                    getDatas();
+                    EventBus.getDefault().post(new RefreshFingerEvent());
+                }
+            });
+        }
+    }
+
+    private void showToast(String msg){
+        if(!isFinishing()){
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
+                }
+            });
+        }
+    }
+
+
+    private SpannableString getErrPhoneText(){
+        String phone = MApplication.getConfigBean().getLinkPhone();
+        if(phone==null){
+            String text = "濡傛湁闂璇疯仈绯荤鐞嗗憳";
+            SpannableString styledText = new SpannableString(text);
+            styledText.setSpan(new TextAppearanceSpan(this, R.style.style_tip3), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            return styledText;
+        }
+        String text = "濡傛湁闂璇疯仈绯荤鐞嗗憳"+phone;
+        SpannableString styledText = new SpannableString(text);
+        styledText.setSpan(new TextAppearanceSpan(this, R.style.style_tip3), 0, text.length()-phone.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        styledText.setSpan(new TextAppearanceSpan(this,R.style.style_tip1), text.length()-phone.length()+1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        return styledText;
+    }
+
+    private int tipDownCount = 60;
+    private boolean isShowTip;
+    @Subscribe
+    public void TimeClockEvent(TimeClockEvent e){
+        if(isShowTip){
+            getDB().tvDjs.setVisibility(View.VISIBLE);
+            getDB().tvTitle.setVisibility(View.GONE);
+            if(tipDownCount==0){
+                isShowTip = false;
+                getDB().tvDjs.setVisibility(View.GONE);
+                finish();
+            }else {
+                tipDownCount--;
+                getDB().tvDjs.setText(tipDownCount+"s");
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        handler.removeCallbacksAndMessages(null);
+        handler = null;
+        mBCancel = true;
+        if(mDevComm!=null){
+            mDevComm.CloseComm();
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void HttpEvent(HttpEvent e){
+        if(!isFinishing()){
+            getVM().addInfo(e.getMsg());
+        }
+    }
+    private static DevComm mDevComm;
+    //鏈�澶ф寚绾规暟
+    private int maxFpCount = 500;
+    //鏄惁缁撴潫褰曞叆
+    private boolean mBCancel = true;
+    private byte[] m_binImage = new byte[1024 * 100];
+    private byte[] m_bmpImage = new byte[1024 * 100];
+    private int m_nParam, m_nImgWidth, m_nImgHeight;
+
+    private final IUsbConnState m_IConnectionHandler = new IUsbConnState() {
+        @Override
+        public void onUsbConnected() {
+            String[] w_strInfo = new String[1];
+            if (mDevComm.Run_TestConnection() == DevComm.ERR_SUCCESS) {
+                if (mDevComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) {
+                    getVM().addInfo("杩炴帴usb鎴愬姛");
+                }else {
+                    getVM().addInfo("杩炴帴璁惧澶辫触1锛�" + mDevComm.Run_GetDeviceInfo(w_strInfo));
+                }
+            } else {
+                getVM().addInfo("杩炴帴璁惧澶辫触2锛�" + mDevComm.Run_TestConnection());
+            }
+        }
+
+        @Override
+        public void onUsbPermissionDenied() {
+            Toast.makeText(mContext, "鏃犺澶囨潈闄�", Toast.LENGTH_SHORT).show();
+        }
+
+        @Override
+        public void onDeviceNotFound() {
+            Toast.makeText(mContext, "鏈彂鐜拌澶�", Toast.LENGTH_SHORT).show();
+        }
+    };
+
+    private void initDev(){
+        mDevComm = new DevComm(this, m_IConnectionHandler);
+        openDevice();
+    }
+
+    /**
+     * 寮�鍚澶�
+     */
+    private void openDevice() {
+        String[] w_strInfo = new String[1];
+
+        if (mDevComm != null) {
+            if (!mDevComm.IsInit()) {
+                if (mDevComm.OpenComm("USB", 19200) == false) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            getVM().addInfo("鍒濆鍖栬澶囧け璐�");
+                        }
+                    });
+                    return;
+                }
+            }
+            if (mDevComm.Run_TestConnection() == DevComm.ERR_SUCCESS) {
+                if (mDevComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            getVM().addInfo("寮�鍚澶囨垚鍔�");
+                        }
+                    });
+                } else {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            getVM().addInfo("杩炴帴璁惧澶辫触3," + mDevComm.Run_GetDeviceInfo(w_strInfo));
+                        }
+                    });
+                }
+            } else {
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        getVM().addInfo("杩炴帴璁惧澶辫触4,"+mDevComm.Run_TestConnection());
+                    }
+                });
+                mDevComm.CloseComm();
+            }
+        }
+    }
+
+
+    /**
+     * 褰曞叆鎸囩汗
+     */
+    private void enrollBtn() {
+        int w_nRet;
+        int[] w_nState = new int[1];
+
+        if (!mDevComm.IsInit())
+            return;
+        int m_nUserID = getEmptyID();
+        EventBus.getDefault().post(new HttpEvent("userId="+m_nUserID));
+        if (m_nUserID > (maxFpCount) || m_nUserID < 1) {
+            Toast.makeText(mContext, "宸茶揪鍒版渶澶ф寚绾规暟", Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+        // Check if fp is exist
+        w_nRet = mDevComm.Run_GetStatus(m_nUserID, w_nState);
+
+        if (w_nRet != DevComm.ERR_SUCCESS) {
+            Toast.makeText(mContext, DevComm.GetErrorMsg(w_nRet), Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+        if (w_nState[0] == DevComm.GD_TEMPLATE_NOT_EMPTY) {
+            Toast.makeText(mContext, "妯℃澘宸插瓨鍦�", Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+        mDevComm.Run_SLEDControl(1);
+        mBCancel = false;
+        new Thread(new Runnable() {
+            int w_nRet, w_nUserID, w_nEnrollStep = 0, w_nGenCount = 3;
+            int[] w_nDupID = new int[1];
+            int[] w_nWidth = new int[1];
+            int[] w_nHeight = new int[1];
+
+            @Override
+            public void run() {
+
+                w_nUserID = m_nUserID;
+
+                while (w_nEnrollStep < w_nGenCount) {
+                    if(w_nEnrollStep==1) {
+                        showFingerTip("璇风浜屾灏嗘墜鎸囨斁缃湪鎸囩汗閲囬泦鍣ㄤ笂杩涜褰曞叆");
+                    }else if(w_nEnrollStep==2) {
+                        showFingerTip("璇风涓夋灏嗘墜鎸囨斁缃湪鎸囩汗閲囬泦鍣ㄤ笂杩涜褰曞叆");
+                    }
+                    EventBus.getDefault().post(new HttpEvent(String.format("杈撳叆鎵嬫寚 #%d!", w_nEnrollStep + 1)));
+                    // 鑾峰彇鎸囩汗
+                    if (capturing() < 0)
+                        return;
+                    EventBus.getDefault().post(new HttpEvent("鏉惧紑浣犵殑鎵嬫寚"));
+                    showFingerTip("璇锋澗寮�浣犵殑鎵嬫寚");
+                    // Up Cpatured Image
+                    if (mDevComm.m_nConnected == 2) {
+                        w_nRet = mDevComm.Run_UpImage(0, m_binImage, w_nWidth, w_nHeight);
+
+                        if (w_nRet != DevComm.ERR_SUCCESS) {
+                            EventBus.getDefault().post(new HttpEvent(DevComm.GetErrorMsg(w_nRet)));
+                            return;
+                        }
+
+                        // Draw image
+                        m_nImgWidth = w_nWidth[0];
+                        m_nImgHeight = w_nHeight[0];
+                    }
+
+                    //鐢熸垚鎸囩汗
+                    w_nRet = mDevComm.Run_Generate(w_nEnrollStep);
+
+                    if (w_nRet != DevComm.ERR_SUCCESS) {
+                        if (w_nRet == DevComm.ERR_BAD_QUALITY) {
+                            EventBus.getDefault().post(new HttpEvent("璐ㄩ噺涓嶄匠銆傝閲嶈瘯"));
+                            showErrTip("璐ㄩ噺涓嶄匠銆傝閲嶈瘯");
+                            continue;
+                        } else {
+                            EventBus.getDefault().post(new HttpEvent(DevComm.GetErrorMsg(w_nRet)));
+                            showErrTip(DevComm.GetErrorMsg(w_nRet));
+                            return;
+                        }
+                    }
+                    w_nEnrollStep++;
+                }
+
+                // 鍚堟垚鎸囩汗
+                if (w_nGenCount != 1) {
+                    //. Merge Template
+                    w_nRet = mDevComm.Run_Merge(0, w_nGenCount);
+
+                    if (w_nRet != DevComm.ERR_SUCCESS) {
+                        EventBus.getDefault().post(new HttpEvent(DevComm.GetErrorMsg(w_nRet)));
+                        showErrTip(DevComm.GetErrorMsg(w_nRet));
+                        return;
+                    }
+                }
+
+                //. Store template
+                w_nRet = mDevComm.Run_StoreChar(w_nUserID, 0, w_nDupID);
+
+                if (w_nRet != DevComm.ERR_SUCCESS) {
+                    if (w_nRet == DevComm.ERR_DUPLICATION_ID) {
+                        showErrTip("鎸囩汗宸插綍鍏�,涓嶈兘閲嶅褰曞叆");
+                    }else{
+                        showErrTip("");
+                        runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                Toast.makeText(ZWLRActivity.this, DevComm.GetErrorMsg(w_nRet), Toast.LENGTH_SHORT).show();
+                            }
+                        });
+                    }
+                } else{
+                    lrcg(w_nUserID);
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * 鑾峰彇绌烘寚绾筰d
+     * @return
+     */
+    private int getEmptyID() {
+        int w_nRet;
+        int[] w_nEmptyID = new int[1];
+
+        if (!mDevComm.IsInit())
+            return -1;
+
+        w_nRet = mDevComm.Run_GetEmptyID(1, maxFpCount, w_nEmptyID);
+
+        if (w_nRet != DevComm.ERR_SUCCESS) {
+            Toast.makeText(mContext, DevComm.GetErrorMsg(w_nRet), Toast.LENGTH_SHORT).show();
+            return -1;
+        }
+        return w_nEmptyID[0];
+    }
+
+    /**
+     * 鑾峰彇鎸囩汗
+     * @return
+     */
+    private int capturing() {
+        int w_nRet;
+        while (true) {
+            if(isFinishing()){
+               break;
+            }
+            w_nRet = mDevComm.Run_GetImage();
+
+            if (w_nRet == DevComm.ERR_CONNECTION) {
+                showErrTip("閫氫俊閿欒!");
+                return -1;
+            } else if (w_nRet == DevComm.ERR_SUCCESS)
+                break;
+
+            if (mBCancel) {
+                return -1;
+            }
+        }
+        return 0;
+    }
+
+    private void deleteID(int fingerId) {
+        int m_nUserID = fingerId;
+        int w_nRet;
+
+        if (!mDevComm.IsInit())
+            return;
+
+        w_nRet = mDevComm.Run_DelChar(m_nUserID, m_nUserID);
+
+        if (w_nRet != DevComm.ERR_SUCCESS&&w_nRet!=DevComm.ERR_TMPL_EMPTY) {
+            //妯℃澘涓嶅瓨鍦ㄧ殑涔熺畻鍒犻櫎
+            delFinger = null;
+            showToast(DevComm.GetErrorMsg(w_nRet));
+            return;
+        }
+        showToast("鍒犻櫎鎴愬姛");
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                DaoManager.getFingerPrintDao().delete(delFinger);
+                delFinger = null;
+                getDatas();
+                EventBus.getDefault().post(new RefreshFingerEvent());
+            }
+        });
+    }
+
+
+}
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRVM.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRVM.java
new file mode 100644
index 0000000..85532f6
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRVM.java
@@ -0,0 +1,29 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.databinding.ObservableField;
+import androidx.hilt.lifecycle.ViewModelInject;
+
+import com.doumee.lib_coremodel.base.BaseModel;
+import com.doumee.lib_coremodel.base.DataViewModel;
+
+public class ZWLRVM extends DataViewModel {
+    public ObservableField<String> infoObs = new ObservableField<>("");
+
+    @ViewModelInject
+    public ZWLRVM(@NonNull Application application, BaseModel model) {
+        super(application, model);
+    }
+
+    @Override
+    protected void clickByTypeCommand(int type) {
+        doAction(type);
+    }
+
+    public void addInfo(String s) {
+        String x = infoObs.get();
+        infoObs.set(s+"\n"+x);
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListActivity.java
new file mode 100644
index 0000000..2219028
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListActivity.java
@@ -0,0 +1,150 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import androidx.annotation.Nullable;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Toast;
+
+import com.doumee.keyCabinet.R;
+import com.doumee.keyCabinet.base.MyBaseActivity;
+import com.doumee.keyCabinet.bean.FingerPrintVo;
+import com.doumee.keyCabinet.dao.DaoManager;
+import com.doumee.keyCabinet.dao.FingerPrintDo;
+import com.doumee.keyCabinet.databinding.ZwlistActivityBinding;
+import com.doumee.keyCabinet.event.HttpEvent;
+import com.doumee.keyCabinet.event.RefreshFingerEvent;
+import com.doumee.keyCabinet.ui.keyCabinet.adapter.ZwListRcvAdapter;
+import com.doumee.keyCabinet.utils.usb.DevComm;
+import com.doumee.keyCabinet.utils.usb.IUsbConnState;
+import com.doumee.lib_coremodel.bean.event.ActionEventData;
+import com.doumee.lib_coremodel.util.RecyclerHelp;
+import com.example.datalibrary.api.FaceApi;
+import com.example.datalibrary.model.User;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import dagger.hilt.android.AndroidEntryPoint;
+
+@AndroidEntryPoint
+public class ZWListActivity extends MyBaseActivity<ZWListVM, ZwlistActivityBinding> {
+    private ZwListRcvAdapter adapter;
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.zwlist_activity;
+    }
+
+    @Override
+    public void initView(@Nullable Bundle savedInstanceState) {
+        isAddCountTimer = false;
+        normalConfig();
+        getDB().setModel(getVM());
+        adapter = new ZwListRcvAdapter(this, R.layout.zwlist_rcv_item);
+        RecyclerHelp.bindVL(this,getDB().recyclerView,30,false);
+        getDB().recyclerView.setAdapter(adapter);
+    }
+
+    @Override
+    public void initData(@Nullable Bundle savedInstanceState) {
+        getDatas();
+    }
+
+    private void getDatas(){
+        List<User> users = FaceApi.getInstance().getAllUserList();
+        List<FingerPrintDo> printDos = DaoManager.getFingerPrintDao().loadAll();
+        HashMap<String,User> mMap = new HashMap<>();
+        if(users!=null&&users.size()>0) {
+            for(User u:users){
+                mMap.put(u.getUserId(),u);
+            }
+        }
+        LinkedHashMap<String,FingerPrintVo> pMap = new LinkedHashMap<>();
+        List<FingerPrintDo> updateList = new ArrayList<>();
+        for(FingerPrintDo d:printDos){
+            FingerPrintVo vo = null;
+            if(pMap.containsKey(d.getMemberId()+"")){
+                vo = pMap.get(d.getMemberId()+"");
+            }else {
+                vo = new FingerPrintVo();
+                pMap.put(d.getMemberId()+"",vo);
+            }
+            vo.setMemberName(d.getMemberName());
+            vo.setMemberId(d.getMemberId());
+            vo.setFace(d.getFace());
+            vo.setGroupId(d.getGroupId());
+            vo.setCount(vo.getCount()+1);
+            if(mMap.containsKey(d.getMemberId()+"")){
+                //鏇存柊淇℃伅
+                User user = mMap.get(d.getMemberId()+"");
+                d.setFace(user.getImageName());
+                d.setMemberName(user.getUserName());
+                updateList.add(d);
+            }
+        }
+        HashMap<String,Integer> numMap = new HashMap<>();
+        for(String key:pMap.keySet()){
+            numMap.put(key,pMap.get(key).getCount());
+        }
+        List<FingerPrintVo> vos = new ArrayList<>();
+        if(users!=null&&users.size()>0) {
+            for(User u:users){
+                FingerPrintVo vo = new FingerPrintVo();
+                vo.setMemberId(Integer.parseInt(u.getUserId()));
+                vo.setMemberName(u.getUserName());
+                vo.setFace(u.getImageName());
+                vo.setGroupId(u.getGroupId());
+                if(numMap.containsKey(u.getUserId())){
+                    vo.setCount(numMap.get(u.getUserId()));
+                    pMap.remove(u.getUserId());
+                }
+                vos.add(vo);
+            }
+        }
+        if(pMap.size()>0){
+            for(String key:pMap.keySet()){
+                vos.add(pMap.get(key));
+            }
+        }
+        if(vos.size()>0) {
+            adapter.refreshData(vos);
+            getVM().emptyVisibility.set(View.GONE);
+        }else {
+            getVM().emptyVisibility.set(View.VISIBLE);
+        }
+        if(updateList.size()>0){
+            DaoManager.getFingerPrintDao().update(updateList.toArray(new FingerPrintDo[updateList.size()]));
+        }
+    }
+
+    @Override
+    protected void doRegister(int type, ActionEventData data) {
+        switch (type){
+            default:
+                break;
+        }
+    }
+
+    @Subscribe
+    public void RefreshFingerEvent(RefreshFingerEvent e){
+        if(!isFinishing()){
+            getDatas();
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+    }
+
+}
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListVM.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListVM.java
new file mode 100644
index 0000000..af7bcf5
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWListVM.java
@@ -0,0 +1,27 @@
+package com.doumee.keyCabinet.ui.keyCabinet;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.databinding.ObservableField;
+import androidx.hilt.lifecycle.ViewModelInject;
+
+import com.doumee.lib_coremodel.base.BaseModel;
+import com.doumee.lib_coremodel.base.DataViewModel;
+
+public class ZWListVM extends DataViewModel {
+
+
+
+    @ViewModelInject
+    public ZWListVM(@NonNull Application application, BaseModel model) {
+        super(application, model);
+    }
+
+    @Override
+    protected void clickByTypeCommand(int type) {
+        doAction(type);
+    }
+
+
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwListRcvAdapter.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwListRcvAdapter.java
new file mode 100644
index 0000000..8b774e8
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwListRcvAdapter.java
@@ -0,0 +1,49 @@
+package com.doumee.keyCabinet.ui.keyCabinet.adapter;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+
+import com.doumee.keyCabinet.bean.FingerPrintVo;
+import com.doumee.keyCabinet.bean.KeyCabinetBean;
+import com.doumee.keyCabinet.databinding.CabinetRcvItemBinding;
+import com.doumee.keyCabinet.databinding.ZwlistRcvItemBinding;
+import com.doumee.keyCabinet.ui.keyCabinet.ZWLRActivity;
+import com.doumee.keyCabinet.utils.PhotoUtils;
+import com.doumee.lib_coremodel.http.utils.FrescoUtils;
+import com.doumee.lib_coremodel.view.recyclerview.adapter.BindingAdapter;
+import com.doumee.lib_coremodel.view.recyclerview.adapter.BindingHolder;
+import com.example.datalibrary.model.User;
+
+public class ZwListRcvAdapter extends BindingAdapter<FingerPrintVo, ZwlistRcvItemBinding> {
+
+    public ZwListRcvAdapter(Context context, int layoutId) {
+        super(context, layoutId);
+    }
+
+    @Override
+    public void bindViewDatas(BindingHolder<ZwlistRcvItemBinding> holder, FingerPrintVo item, int position) {
+        holder.getBinding().setData(item);
+        //PhotoUtils.datasToBitmap(getContext(),item.getFace(),holder.getBinding().sim);
+        FrescoUtils.displayImageFresco(item.getFace(),holder.getBinding().sim);
+        holder.getBinding().tvGw.setText("0".equals(item.getGroupId())?"鏍¢獙浜�":"鍙告満");
+        holder.getBinding().tvNum.setText("宸查噰闆嗘寚绾癸細"+item.getCount());
+        holder.getBinding().clRoot.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Bundle bundle = new Bundle();
+                bundle.putString("userName",item.getMemberName());
+                bundle.putInt("userId",item.getMemberId());
+                bundle.putString("userPic",item.getFace());
+                bundle.putString("groupId",item.getGroupId());
+                Intent intent = new Intent(getContext(),ZWLRActivity.class);
+                intent.putExtras(bundle);
+                getContext().startActivity(intent);
+            }
+        });
+    }
+
+
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwLrRcvAdapter.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwLrRcvAdapter.java
new file mode 100644
index 0000000..0edc295
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/adapter/ZwLrRcvAdapter.java
@@ -0,0 +1,44 @@
+package com.doumee.keyCabinet.ui.keyCabinet.adapter;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+import com.doumee.keyCabinet.bean.KeyCabinetBean;
+import com.doumee.keyCabinet.dao.FingerPrintDo;
+import com.doumee.keyCabinet.databinding.ZwlistRcvItemBinding;
+import com.doumee.keyCabinet.databinding.ZwlrRcvItemBinding;
+import com.doumee.keyCabinet.ui.keyCabinet.ZWLRActivity;
+import com.doumee.keyCabinet.utils.PhotoUtils;
+import com.doumee.lib_coremodel.view.recyclerview.adapter.BindingAdapter;
+import com.doumee.lib_coremodel.view.recyclerview.adapter.BindingHolder;
+import com.example.datalibrary.model.User;
+
+public class ZwLrRcvAdapter extends BindingAdapter<FingerPrintDo, ZwlrRcvItemBinding> {
+    public static interface OnItemClick{
+        void onItemDelete(FingerPrintDo item);
+    }
+    private OnItemClick onItemClick;
+
+    public ZwLrRcvAdapter(Context context, int layoutId,OnItemClick onItemClick) {
+        super(context, layoutId);
+        this.onItemClick = onItemClick;
+    }
+
+    @Override
+    public void bindViewDatas(BindingHolder<ZwlrRcvItemBinding> holder, FingerPrintDo item, int position) {
+        holder.getBinding().setData(item);
+        holder.getBinding().tvPos.setText("鎸囩汗"+(position+1));
+        holder.getBinding().imgClose.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if(onItemClick!=null){
+                    onItemClick.onItemDelete(item);
+                }
+            }
+        });
+    }
+
+
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
index 52a2407..6543879 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
@@ -14,7 +14,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.serialport.SerialPortFinder;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -75,6 +74,7 @@
 import com.doumee.keyCabinet.ui.keyCabinet.ChangeUrlActivity;
 import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity;
 import com.doumee.keyCabinet.ui.keyCabinet.ManageLoginActivity;
+import com.doumee.keyCabinet.ui.keyCabinet.ZWListActivity;
 import com.doumee.keyCabinet.ui.service.FaceUpdateService;
 import com.doumee.keyCabinet.ui.service.HeartbeatService;
 import com.doumee.keyCabinet.ui.face.AddFaceActivity;
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java
index 39ca636..fe0d656 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java
@@ -249,7 +249,6 @@
 
     public void getFaceDatas() {
         //showLoading(true);
-        addInfo("鏌ヨ浜鸿劯鏁版嵁======銆嬭皟鐢ㄦ帴鍙�");
         getRetrofitService(Apis.class).allFaceList( LMobileInfo.getDeviceUniqueId())
                 .compose(RxUtils.schedulersTransformer())
                 .subscribe(new SimpleObserver<BaseResponse<CabinetFaceBean>>(rxJavaGcManager) {
@@ -344,13 +343,12 @@
         param.setCabinetId(MApplication.getConfigBean().getId());
         param.setMemberId(loginBean.getMemberId());
         param.setGridId(gridDo.getGridId());
-        EventBus.getDefault().post(new HttpEvent("===>瓒呮椂鏈叧闂�-璇锋眰"));
         getRetrofitService(Apis.class).timeOutUnCloseAlarm(ParamsUtil.encodeRequestBody(param))
                 .compose(RxUtils.schedulersTransformer())
                 .subscribe(new SimpleObserver<BaseResponse>(rxJavaGcManager) {
                     @Override
                     public void onNext(@NonNull BaseResponse response) {
-                        toast("===>瓒呮椂鏈叧闂�-杩斿洖");
+                        //toast("===>瓒呮椂鏈叧闂�-杩斿洖");
                     }
 
                     @Override
@@ -373,13 +371,13 @@
         param.setMemberId(loginBean.getMemberId());
         param.setGridId(gridDo.getGridId());
         param.setKeyStatus(!TextUtils.isEmpty(gridDo.getCurKeyCode())?1:2);
-        EventBus.getDefault().post(new HttpEvent("===>棣栭〉鍏抽棴鏌滄牸-璇锋眰"));
+        //EventBus.getDefault().post(new HttpEvent("===>棣栭〉鍏抽棴鏌滄牸-璇锋眰"));
         getRetrofitService(Apis.class).closeGrid(ParamsUtil.encodeRequestBody(param))
                 .compose(RxUtils.schedulersTransformer())
                 .subscribe(new SimpleObserver<BaseResponse>(rxJavaGcManager) {
                     @Override
                     public void onNext(@NonNull BaseResponse response) {
-                        EventBus.getDefault().post(new HttpEvent("===>棣栭〉鍏抽棴鏌滄牸-杩斿洖"));
+                        //EventBus.getDefault().post(new HttpEvent("===>棣栭〉鍏抽棴鏌滄牸-杩斿洖"));
                     }
 
                     @Override
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java
index dbe30e2..e6fd8d6 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java
@@ -89,6 +89,26 @@
 	@Override
 	public void uncaughtException(Thread thread, Throwable ex) {
 		try {
+			long current = System.currentTimeMillis();
+			String time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
+			try {
+				ByteArrayOutputStream out = new ByteArrayOutputStream();
+				PrintStream print = new PrintStream(out);
+				//瀵煎嚭鍙戠敓寮傚父鐨勬椂闂�
+				print.println(time2);
+				//瀵煎嚭鎵嬫満淇℃伅
+				dumpPhoneInfo(print);
+				print.println();
+				ex.printStackTrace(print);
+				SpUtil.saveString(FILE_NAME+time2,new String(out.toByteArray()));
+
+				print.close();
+			} catch (Exception e) {
+				e.printStackTrace();
+				System.out.println("閿欒鏃ュ織2"+e.getMessage());
+				//LogUtils.e(TAG, "dump crash info failed");
+			}
+
 			//瀵煎嚭寮傚父淇℃伅鍒癝D鍗′腑
 			McSystemUi mcSystemUi = McSystemUi.getInstance(mContext);
 			MCUtils.show(mcSystemUi);
@@ -126,25 +146,7 @@
 				// 濡傛灉鐢ㄦ埛娌℃湁澶勭悊鍒欒绯荤粺榛樿鐨勫紓甯稿鐞嗗櫒鏉ュ鐞�
 				mDefaultHandler.uncaughtException(thread, ex);
 			}
-			long current = System.currentTimeMillis();
-			String time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
-			try {
-				ByteArrayOutputStream out = new ByteArrayOutputStream();
-				PrintStream print = new PrintStream(out);
-				//瀵煎嚭鍙戠敓寮傚父鐨勬椂闂�
-				print.println(time2);
-				//瀵煎嚭鎵嬫満淇℃伅
-				dumpPhoneInfo(print);
-				print.println();
-				ex.printStackTrace(print);
-				SpUtil.saveString(FILE_NAME+time2,new String(out.toByteArray()));
 
-				print.close();
-			} catch (Exception e) {
-				e.printStackTrace();
-				System.out.println("閿欒鏃ュ織2"+e.getMessage());
-				//LogUtils.e(TAG, "dump crash info failed");
-			}
 		}catch (Exception e){
 			e.printStackTrace();
 		}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/PhotoUtils.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/PhotoUtils.java
index 0c5c69c..e700d74 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/PhotoUtils.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/PhotoUtils.java
@@ -1,9 +1,12 @@
 package com.doumee.keyCabinet.utils;
 
 import android.app.Activity;
+import android.content.Context;
 import android.graphics.Color;
+import android.widget.ImageView;
 import android.widget.Toast;
 
+import com.bumptech.glide.Glide;
 import com.doumee.keyCabinet.R;
 import com.doumee.keyCabinet.utils.update.PermissionUtils;
 import com.doumee.keyCabinet.utils.update.PermissiondDialog;
@@ -129,4 +132,10 @@
         // 璺宠浆鍒板浘鐗囬�夋嫨鍣�
         ISNav.getInstance().toCameraActivity(source, config, REQUEST_LIST_CODE);
     }
+
+    public static void datasToBitmap(Context context, String path, ImageView img){
+        Glide.with(context)
+                .load(path)
+                .into(img);
+    }
 }
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SerialPortModel.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SerialPortModel.java
index f79b81a..4535510 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SerialPortModel.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SerialPortModel.java
@@ -1,6 +1,5 @@
 package com.doumee.keyCabinet.utils.i485;
 
-import android.serialport.SerialPort;
 import android.util.Log;
 
 import java.io.File;
@@ -11,6 +10,8 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+
+import android_serialport_api.SerialPort;
 
 public class SerialPortModel {
 
@@ -46,12 +47,7 @@
     public boolean open() {
         try {
             File device = new File(serialPortPath);
-            serialPort = SerialPort
-                    .newBuilder(device, baudrate)
-                    .dataBits(dataBits)
-                    .stopBits(stopBits)
-                    .parity(parity)
-                    .build();
+            serialPort = new SerialPort(device, baudrate, 0);
             scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
             singleThreadExecutor = Executors.newSingleThreadExecutor();
         } catch (IOException e) {
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java
index 11f64e6..3d06572 100644
--- a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java
@@ -1,24 +1,19 @@
 package com.doumee.keyCabinet.utils.i485;
 
 import android.content.Context;
-import android.hardware.usb.UsbConstants;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbInterface;
-import android.hardware.usb.UsbManager;
-import android.serialport.SerialPortFinder;
-
 import java.util.ArrayList;
 import java.util.List;
+
+import android_serialport_api.SerialPortFinder;
 
 public class SportUtils {
     public static List<String> getSerialPortPaths(Context context) {
         // 鑾峰彇鎵�鏈変覆鍙h澶囪矾寰�
-        String[] devices = new SerialPortFinder().getAllDevicesPath();
+        SerialPortFinder mSerialPortFinder = new SerialPortFinder();
+        String[] entryValues = mSerialPortFinder.getAllDevicesPath();
         List<String> serialPaths = new ArrayList<>();
-        if(devices!=null){
-            for(String key:devices){
-                serialPaths.add(key);
-            }
+        for (int i = 0; i < entryValues.length; i++) {
+            serialPaths.add(entryValues[i]);
         }
         return serialPaths;
     }
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/DevComm.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/DevComm.java
new file mode 100644
index 0000000..de65fb7
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/DevComm.java
@@ -0,0 +1,1812 @@
+package com.doumee.keyCabinet.utils.usb;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.SystemClock;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import android_serialport_api.ComBean;
+import android_serialport_api.SerialHelper;
+
+/**
+ * Created by KMS on 2016/8/23.
+ */
+public class DevComm {
+    public	static final int MAX_DATA_LEN              = 498;
+    public static final int IMAGE_DATA_UNIT           = 496;
+    public	static final int ID_NOTE_SIZE                = 64;
+    public	static final int MODULE_SN_LEN               = 16;
+
+    private static final int SCSI_TIMEOUT              = 5000; //ms
+    private static final int COMM_SLEEP_TIME           = 40;	//ms
+
+    private static final int CMD_PACKET_LEN			= 26;
+    private static final int RCM_PACKET_LEN			= 26;
+    private static final int RCM_DATA_OFFSET		= 10;
+
+    /***************************************************************************/
+    /***************************************************************************/
+    private static final int CMD_PREFIX_CODE		= 0xAA55;
+    private static final int CMD_DATA_PREFIX_CODE	= 0xA55A;
+    private static final int RCM_PREFIX_CODE		= 0x55AA;
+    private static final int RCM_DATA_PREFIX_CODE	= 0x5AA5;
+
+    /***************************************************************************
+     * System Code (0x0000 ~ 0x001F, 0x0000 : Reserved)
+     ***************************************************************************/
+    private static final short CMD_TEST_CONNECTION		= 0x0001;
+    private static final short CMD_SET_PARAM			= 0x0002;
+    private static final short CMD_GET_PARAM			= 0x0003;
+    private static final short CMD_GET_DEVICE_INFO		= 0x0004;
+    private static final short CMD_ENTER_ISPMODE		= 0x0005;
+    private static final short CMD_SET_ID_NOTE			= 0x0006;
+    private static final short CMD_GET_ID_NOTE			= 0x0007;
+    private static final short CMD_SET_MODULE_SN		= 0x0008;
+    private static final short CMD_GET_MODULE_SN		= 0x0009;
+
+    /***************************************************************************
+     * Sensor Code (0x0020 ~ 0x003F)
+     ***************************************************************************/
+    private static final short CMD_GET_IMAGE			= 0x0020;
+    private static final short CMD_FINGER_DETECT		= 0x0021;
+    private static final short CMD_UP_IMAGE				= 0x0022;
+    private static final short CMD_DOWN_IMAGE			= 0x0023;
+    private static final short CMD_SLED_CTRL			= 0x0024;
+
+    /***************************************************************************
+     * Template Code (0x0040 ~ 0x005F)
+     ***************************************************************************/
+    private static final short CMD_STORE_CHAR			= 0x0040;
+    private static final short CMD_LOAD_CHAR			= 0x0041;
+    private static final short CMD_UP_CHAR				= 0x0042;
+    private static final short CMD_DOWN_CHAR			= 0x0043;
+    private static final short CMD_DEL_CHAR				= 0x0044;
+    private static final short CMD_GET_EMPTY_ID			= 0x0045;
+    private static final short CMD_GET_STATUS			= 0x0046;
+    private static final short CMD_GET_BROKEN_ID		= 0x0047;
+    private static final short CMD_GET_ENROLL_COUNT		= 0x0048;
+
+    /***************************************************************************
+     * FingerPrint Alagorithm Code (0x0060 ~ 0x007F)
+     ***************************************************************************/
+    private static final short CMD_GENERATE				= 0x0060;
+    private static final short CMD_MERGE				= 0x0061;
+    private static final short CMD_MATCH				= 0x0062;
+    private static final short CMD_SEARCH				= 0x0063;
+    private static final short CMD_VERIFY				= 0x0064;
+
+    /***************************************************************************
+     * Unknown Command
+     ***************************************************************************/
+    private static final short RCM_INCORRECT_COMMAND	= 0x00FF;
+
+    /***************************************************************************
+     * Error Code
+     ***************************************************************************/
+    public static final int ERR_SUCCESS				= 0;
+    public static final int ERR_FAIL				= 1;
+    public static final int ERR_CONNECTION			= 2;
+    public static final int ERR_VERIFY				= 0x10;
+    public static final int ERR_IDENTIFY			= 0x11;
+    public static final int ERR_TMPL_EMPTY			= 0x12;
+    public static final int ERR_TMPL_NOT_EMPTY		= 0x13;
+    public static final int ERR_ALL_TMPL_EMPTY		= 0x14;
+    public static final int ERR_EMPTY_ID_NOEXIST	= 0x15;
+    public static final int ERR_BROKEN_ID_NOEXIST	= 0x16;
+    public static final int ERR_INVALID_TMPL_DATA	= 0x17;
+    public static final int ERR_DUPLICATION_ID		= 0x18;
+    public static final int ERR_BAD_QUALITY			= 0x19;
+    public static final int ERR_MERGE_FAIL			= 0x1A;
+    public static final int ERR_NOT_AUTHORIZED		= 0x1B;
+    public static final int ERR_MEMORY				= 0x1C;
+    public static final int ERR_INVALID_TMPL_NO		= 0x1D;
+    public static final int ERR_INVALID_PARAM		= 0x22;
+    public static final int ERR_GEN_COUNT			= 0x25;
+    public static final int ERR_INVALID_BUFFER_ID	= 0x26;
+    public static final int ERR_INVALID_OPERATION_MODE	= 0x27;
+    public static final int ERR_FP_NOT_DETECTED		= 0x28;
+
+    /***************************************************************************
+     * Parameter Index
+     ***************************************************************************/
+    public static final int DP_DEVICE_ID				= 0;
+    public static final int DP_SECURITY_LEVEL			= 1;
+    public static final int DP_DUP_CHECK				= 2;
+    public static final int DP_BAUDRATE					= 3;
+    public static final int DP_AUTO_LEARN				= 4;
+
+    /***************************************************************************
+     * Device ID, Security Level
+     ***************************************************************************/
+    public static final int MIN_DEVICE_ID				= 1;
+    public static final int MAX_DEVICE_ID				= 255;
+    public static final int MIN_SECURITY_LEVEL			= 1;
+    public static final int MAX_SECURITY_LEVEL			= 5;
+
+    public static final int GD_TEMPLATE_NOT_EMPTY	= 0x01;
+    public static final int GD_TEMPLATE_EMPTY		= 0x00;
+
+    //--------------- For Usb Communication ------------//
+    public int		m_nPacketSize;
+    public byte		m_bySrcDeviceID = 1, m_byDstDeviceID = 1;
+    public byte[]	m_abyPacket = new byte[64 * 1024];
+    public byte[]	m_abyPacket2 = new byte[64 * 1024];
+    //--------------------------------------------------//
+
+    private final Context mApplicationContext;
+    private Activity m_parentAcitivity;
+    private static final int VID = 0x2009;
+    private static final int PID = 0x7638;
+
+    private UsbController   m_usbBase;
+
+    // Serial Port
+    private DispQueueThread DispQueue;
+    private SerialControl m_SerialPort;
+
+    // uart variables
+    public byte[] m_pWriteBuffer;
+    public byte[] m_pReadBuffer;
+    public byte[] m_pUARTReadBuf;
+    public int m_nUARTReadLen;
+    public boolean m_bBufferHandle = false;
+
+    // Connection
+    public byte m_nConnected;	// 0 : Not Connected, 1 : ttyUART, 2 : USB
+
+    public DevComm(Activity parentActivity, IUsbConnState usbConnState){
+        m_parentAcitivity = parentActivity;
+        mApplicationContext = parentActivity.getApplicationContext();
+
+        // usb init
+        m_usbBase = new UsbController(parentActivity, usbConnState, VID, PID);
+
+        // init variables
+        m_nConnected = 0;
+        m_nUARTReadLen = 0;
+        m_pWriteBuffer = new byte[DevComm.MAX_DATA_LEN];
+        m_pReadBuffer = new byte[DevComm.MAX_DATA_LEN];
+        m_pUARTReadBuf = new byte[DevComm.MAX_DATA_LEN];
+
+        // uart thread initialize
+        DispQueue = new DispQueueThread();
+        DispQueue.start();
+        m_SerialPort = new SerialControl();
+    }
+
+    public boolean IsInit(){
+        if (m_nConnected == 0)
+            return false;
+        else if (m_nConnected == 1)
+            return true;
+        else if (m_nConnected == 2)
+            return m_usbBase.IsInit();
+
+        return false;
+    }
+
+    public boolean  OpenComm(String p_szDevice, int p_nBaudrate){
+        if (m_nConnected != 0)
+            return false;
+
+        if (p_szDevice == "USB")  // usb mode
+        {
+            if (!m_usbBase.IsInit())
+                m_usbBase.init();
+            if (!m_usbBase.IsInit())
+                return false;
+            m_nConnected = 2;
+        }
+        else  // tty uart mode
+        {
+            m_SerialPort.setPort(p_szDevice);
+            m_SerialPort.setBaudRate(p_nBaudrate);
+            try
+            {
+                m_SerialPort.open();
+            } catch (SecurityException e) {
+                Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show();
+                return false;
+            } catch (IOException e) {
+                Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show();
+                return false;
+            } catch (InvalidParameterException e) {
+                Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show();
+                return false;
+            }
+            m_nConnected = 1;
+        }
+
+        return true;
+    }
+
+    public boolean  CloseComm(){
+        if (m_nConnected == 0) {
+            return false;
+        }
+        else if (m_nConnected == 1) {  // tty uart mode
+            m_SerialPort.stopSend();
+            m_SerialPort.close();
+        }
+        else {  // usb mode
+            m_usbBase.uninit();
+        }
+
+        m_nConnected = 0;
+        return true;
+    }
+
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_TestConnection()
+    {
+        boolean	w_bRet;
+
+        InitCmdPacket(CMD_TEST_CONNECTION, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, (short)0);
+
+        w_bRet = Send_Command(CMD_TEST_CONNECTION);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_SetParam(int p_nParamIndex, int p_nParamValue)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[5];
+
+        w_abyData[0] = (byte)p_nParamIndex;
+
+        //memcpy(&w_abyData[1], &p_nParamValue, 4);
+        w_abyData[1] = (byte)(p_nParamValue & 0x000000ff);
+        w_abyData[2] = (byte)((p_nParamValue & 0x0000ff00) >> 8);
+        w_abyData[3] = (byte)((p_nParamValue & 0x00ff0000) >> 16);
+        w_abyData[4] = (byte)((p_nParamValue & 0xff000000) >> 24);
+
+        InitCmdPacket(CMD_SET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)5);
+
+        w_bRet = Send_Command(CMD_SET_PARAM);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_GetParam(int p_nParamIndex, int[] p_pnParamValue)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[1];
+
+        w_abyData[0] = (byte)p_nParamIndex;
+
+        InitCmdPacket(CMD_GET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)1);
+
+        w_bRet = Send_Command(CMD_GET_PARAM);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //memcpy(p_pnParamValue, g_pRcmPacket->m_abyData, 4);
+        p_pnParamValue[0] = (int)(  (int)((m_abyPacket[RCM_DATA_OFFSET+3] << 24) & 0xFF000000)	|
+                (int)((m_abyPacket[RCM_DATA_OFFSET+2] << 16) & 0x00FF0000)	|
+                (int)((m_abyPacket[RCM_DATA_OFFSET+1] << 8) & 0x0000FF00)	|
+                (int)(m_abyPacket[RCM_DATA_OFFSET+0] & 0x000000FF));
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int Run_GetDeviceInfo(String[] p_szDevInfo)
+    {
+        int		w_nDevInfoLen;
+        boolean	w_bRet;
+        String  w_strTmp;
+        byte[] w_szDevInfo;
+
+        InitCmdPacket(CMD_GET_DEVICE_INFO, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0);
+
+        w_bRet = Send_Command(CMD_GET_DEVICE_INFO);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        w_nDevInfoLen = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+
+        w_bRet = Receive_DataPacket(CMD_GET_DEVICE_INFO);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if ( GetRetCode() != ERR_SUCCESS )
+            return GetRetCode();
+
+        //memcpy(p_szDevInfo, g_pRcmPacket->m_abyData, w_wDevInfoLen);
+        w_szDevInfo = new byte[w_nDevInfoLen];
+        System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, w_szDevInfo, 0, w_nDevInfoLen);
+        w_strTmp = new String(w_szDevInfo);
+        p_szDevInfo[0] = w_strTmp;
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_SetIDNote(int p_nTmplNo, String p_pstrNote)
+    {
+        boolean	w_bRet = false;
+        byte[]	w_abyData = new byte[ID_NOTE_SIZE+2];
+        byte[]	w_abyData2 = new byte[2];
+        byte[]	w_abyNoteBuf = p_pstrNote.getBytes();
+
+        //. Assemble command packet
+        w_abyData2[0] = LOBYTE((short)(ID_NOTE_SIZE + 2));
+        w_abyData2[1] = HIBYTE((short)(ID_NOTE_SIZE + 2));
+
+        InitCmdPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_SET_ID_NOTE);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if( GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //. Assemble data packet
+        memset(w_abyData, (byte)0, ID_NOTE_SIZE+2);
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+        System.arraycopy(w_abyNoteBuf, 0, w_abyData, 2, w_abyNoteBuf.length);
+
+        InitCmdDataPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, ID_NOTE_SIZE+2);
+
+        //. Send data packet to target
+        w_bRet = Send_DataPacket(CMD_SET_ID_NOTE);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_GetIDNote(int p_nTmplNo, String[] p_pstrNote)
+    {
+        boolean		w_bRet = false;
+        byte[]		w_abyData = new byte[2];
+        String		w_strTmp;
+
+        //. Assemble command packet
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+        InitCmdPacket(CMD_GET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_GET_ID_NOTE);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        w_bRet = Receive_DataPacket(CMD_GET_ID_NOTE);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //memset(m_abyPacket2, (byte)0, ID_NOTE_SIZE+1);
+        memset(m_abyPacket2, (byte)0, 512);
+        System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, ID_NOTE_SIZE);
+
+        w_strTmp = new String(m_abyPacket2);
+        p_pstrNote[0] = w_strTmp;
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_SetModuleSN(String p_pstrModuleSN)
+    {
+        boolean	w_bRet = false;
+        byte[]	w_abyData = p_pstrModuleSN.getBytes();
+        byte[]	w_abyModuleSN = new byte[MODULE_SN_LEN];
+        byte[]	w_abyData2 = new byte[2];
+
+        memset(w_abyModuleSN, (byte)0, MODULE_SN_LEN);
+        System.arraycopy(w_abyData, 0, w_abyModuleSN, 0, w_abyData.length);
+
+        //. Assemble command packet
+        w_abyData2[0] = LOBYTE((short)(MODULE_SN_LEN));
+        w_abyData2[1] = HIBYTE((short)(MODULE_SN_LEN));
+
+        InitCmdPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_SET_MODULE_SN);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if( GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //. Assemble data packet
+        InitCmdDataPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyModuleSN, MODULE_SN_LEN);
+
+        //. Send data packet to target
+        w_bRet = Send_DataPacket(CMD_SET_MODULE_SN);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_GetModuleSN(String[] p_pstrModuleSN)
+    {
+        boolean		w_bRet = false;
+        String		w_strTmp;
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_GET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_GET_MODULE_SN);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        w_bRet = Receive_DataPacket(CMD_GET_MODULE_SN);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //memset(m_abyPacket2, (byte)0, MODULE_SN_LEN+1);
+        memset(m_abyPacket2, (byte)0, 512);
+        System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, MODULE_SN_LEN);
+
+        w_strTmp = new String(m_abyPacket2);
+        p_pstrModuleSN[0] = w_strTmp;
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_GetImage()
+    {
+        boolean	w_bRet;
+
+        InitCmdPacket(CMD_GET_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0);
+
+        w_bRet = Send_Command(CMD_GET_IMAGE);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_FingerDetect(int[] p_pnDetectResult)
+    {
+        boolean	w_bRet;
+
+        InitCmdPacket(CMD_FINGER_DETECT, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0);
+
+        w_bRet = Send_Command(CMD_FINGER_DETECT);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        p_pnDetectResult[0] = m_abyPacket[RCM_DATA_OFFSET];
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_UpImage(int p_nType, byte[] p_pFpData, int[] p_pnImgWidth, int[] p_pnImgHeight)
+    {
+        int		i, n, r, w, h, size;
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[1];
+
+        w_abyData[0] = (byte)p_nType;
+
+        InitCmdPacket(CMD_UP_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 1);
+
+        w_bRet = Send_Command(CMD_UP_IMAGE);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        w = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+        h = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]);
+
+        size = w * h;
+        n = size / IMAGE_DATA_UNIT;
+        r = size % IMAGE_DATA_UNIT;
+
+        if (m_nConnected == 1) {
+            for (i=0; i<n; i++)
+            {
+                w_bRet = Receive_DataPacket(CMD_UP_IMAGE);
+                if(w_bRet == false)
+                    return ERR_CONNECTION;
+
+                if (GetRetCode() != ERR_SUCCESS)
+                    return GetRetCode();
+
+                System.arraycopy(m_abyPacket, RCM_DATA_OFFSET + 2, p_pFpData, i * IMAGE_DATA_UNIT, IMAGE_DATA_UNIT);
+            }
+
+            if (r > 0)
+            {
+                w_bRet = Receive_DataPacket(CMD_UP_IMAGE);
+                if(w_bRet == false)
+                    return ERR_CONNECTION;
+
+                if (GetRetCode() != ERR_SUCCESS)
+                    return GetRetCode();
+
+                System.arraycopy(m_abyPacket, RCM_DATA_OFFSET + 2, p_pFpData, i * IMAGE_DATA_UNIT, r);
+            }
+        }
+        else if (m_nConnected == 2) {
+            w_bRet = USB_ReceiveImage(p_pFpData, w * h);
+            if (w_bRet == false)
+                return ERR_CONNECTION;
+        }
+        else {
+            return ERR_CONNECTION;
+        }
+
+        p_pnImgWidth[0] = w;
+        p_pnImgHeight[0] = h;
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    int	Run_DownImage(byte[] p_pData, int p_nWidth, int p_nHeight)
+    {
+    	/*
+    	int		i, n, r, w, h;
+    	boolean	w_bRet;
+    	BYTE	w_abyData[840];
+
+    	w = p_nWidth;
+    	h = p_nHeight;
+
+    	w_abyData[0] = LOBYTE(p_nWidth);
+    	w_abyData[1] = HIBYTE(p_nWidth);
+    	w_abyData[2] = LOBYTE(p_nHeight);
+    	w_abyData[3] = HIBYTE(p_nHeight);
+
+    	//. Assemble command packet
+    	InitCmdPacket(CMD_DOWN_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+    	Send_Command(CMD_DOWN_IMAGE, w_bRet, m_bySrcDeviceID, m_byDstDeviceID);
+
+    	if(!w_bRet)
+    		return ERR_CONNECTION;
+
+    	if (GetRetCode() != ERR_SUCCESS)
+    		return GetRetCode();
+
+    	n = (w*h)/DOWN_IMAGE_DATA_UINT;
+    	r = (w*h)%DOWN_IMAGE_DATA_UINT;
+
+		w_bRet = USB_DownImage(m_hUsbHandle, p_pData, p_nWidth*p_nHeight);
+
+		if(w_bRet == false)
+			return ERR_CONNECTION;
+		*/
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_SLEDControl(int p_nState)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[2];
+
+        w_abyData[0] = LOBYTE((short)p_nState);
+        w_abyData[1] = HIBYTE((short)p_nState);
+
+        InitCmdPacket(CMD_SLED_CTRL, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2);
+
+        w_bRet = Send_Command(CMD_SLED_CTRL);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_StoreChar(int p_nTmplNo, int p_nRamBufferID, int[] p_pnDupTmplNo)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[3] = HIBYTE((short)p_nRamBufferID);
+
+        InitCmdPacket(CMD_STORE_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_STORE_CHAR);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+        {
+            if (GetRetCode() == ERR_DUPLICATION_ID)
+                p_pnDupTmplNo[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+
+            return GetRetCode();
+        }
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_LoadChar(int p_nTmplNo, int p_nRamBufferID)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[3] = HIBYTE((short)p_nRamBufferID);
+
+        InitCmdPacket(CMD_LOAD_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_LOAD_CHAR);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_UpChar(int p_nRamBufferID, byte[] p_pbyTemplate)
+    {
+        boolean		w_bRet = false;
+        byte[]		w_abyData = new byte[2];
+
+        //. Assemble command packet
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID);
+        InitCmdPacket(CMD_UP_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_UP_CHAR);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        w_bRet = Receive_DataPacket(CMD_UP_CHAR);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        //memcpy(p_pbyTemplate, &g_pRcmPacket->m_abyData[0], GD_RECORD_SIZE);
+        System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, 0, MAX_DATA_LEN);
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_DownChar(int p_nRamBufferID, byte[] p_pbyTemplate)
+    {
+        boolean	w_bRet = false;
+        byte[]	w_abyData = new byte[MAX_DATA_LEN+2];
+        byte[]	w_abyData2 = new byte[2];
+
+        //. Assemble command packet
+        w_abyData2[0] = LOBYTE((short)(MAX_DATA_LEN + 2));
+        w_abyData2[1] = HIBYTE((short)(MAX_DATA_LEN + 2));
+
+        InitCmdPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_DOWN_CHAR);
+
+        if(w_bRet == false)
+            return ERR_CONNECTION;
+
+        if( GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        SystemClock.sleep(10);
+
+        //. Assemble data packet
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID);
+        //memcpy(&w_abyData[2], p_pbyTemplate, GD_RECORD_SIZE);
+        System.arraycopy(p_pbyTemplate, 0, w_abyData, 2, MAX_DATA_LEN);
+
+        InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, MAX_DATA_LEN+2);
+
+        //. Send data packet to target
+        w_bRet = Send_DataPacket(CMD_DOWN_CHAR);
+
+        if (w_bRet == false)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int Run_DelChar(int p_nSTmplNo, int p_nETmplNo)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nSTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nSTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nETmplNo);
+        w_abyData[3] = HIBYTE((short)p_nETmplNo);
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_DEL_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_DEL_CHAR);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_GetEmptyID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEmptyID)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData =  new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nSTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nSTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nETmplNo);
+        w_abyData[3] = HIBYTE((short)p_nETmplNo);
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_GET_EMPTY_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_GET_EMPTY_ID);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        if ( GetRetCode() != ERR_SUCCESS )
+            return GetRetCode();
+
+        p_pnEmptyID[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_GetStatus(int p_nTmplNo, int[] p_pnStatus)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[2];
+
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+
+        InitCmdPacket(CMD_GET_STATUS, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2);
+
+        w_bRet = Send_Command(CMD_GET_STATUS);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        if ( GetRetCode() != ERR_SUCCESS )
+            return GetRetCode();
+
+        p_pnStatus[0] = m_abyPacket[RCM_DATA_OFFSET+0];
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_GetBrokenID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnCount, int[] p_pnFirstID)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nSTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nSTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nETmplNo);
+        w_abyData[3] = HIBYTE((short)p_nETmplNo);
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_GET_BROKEN_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_GET_BROKEN_ID);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        if (GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        p_pnCount[0]		= MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+        p_pnFirstID[0]		= MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]);
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_GetEnrollCount(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEnrollCount)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nSTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nSTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nETmplNo);
+        w_abyData[3] = HIBYTE((short)p_nETmplNo);
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_GET_ENROLL_COUNT, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_GET_ENROLL_COUNT);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if(GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        p_pnEnrollCount[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+
+        return ERR_SUCCESS;
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_Generate(int p_nRamBufferID)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[2];
+
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID);
+
+        InitCmdPacket(CMD_GENERATE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_GENERATE);
+
+        if(!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_Merge(int p_nRamBufferID, int p_nMergeCount)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[3];
+
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID);
+        w_abyData[2] = (byte)p_nMergeCount;
+
+        InitCmdPacket(CMD_MERGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 3);
+
+        w_bRet = Send_Command(CMD_MERGE);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_Match(int p_nRamBufferID0, int p_nRamBufferID1)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID0);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID0);
+        w_abyData[2] = LOBYTE((short)p_nRamBufferID1);
+        w_abyData[3] = HIBYTE((short)p_nRamBufferID1);
+
+        InitCmdPacket(CMD_MATCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_MATCH);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_Search(int p_nRamBufferID, int p_nStartID, int p_nSearchCount, int[] p_pnTmplNo, int[] p_pnLearnResult)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[6];
+
+        w_abyData[0] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[1] = HIBYTE((short)p_nRamBufferID);
+        w_abyData[2] = LOBYTE((short)p_nStartID);
+        w_abyData[3] = HIBYTE((short)p_nStartID);
+        w_abyData[4] = LOBYTE((short)p_nSearchCount);
+        w_abyData[5] = HIBYTE((short)p_nSearchCount);
+
+        InitCmdPacket(CMD_SEARCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 6);
+
+        //. Send command packet to target
+        w_bRet = Send_Command(CMD_SEARCH);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        if(GetRetCode() != ERR_SUCCESS)
+            return GetRetCode();
+
+        p_pnTmplNo[0]		= MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+0], m_abyPacket[RCM_DATA_OFFSET+1]);
+        p_pnLearnResult[0]	= m_abyPacket[RCM_DATA_OFFSET+2];
+
+        return GetRetCode();
+    }
+    /************************************************************************/
+    /************************************************************************/
+    public int	Run_Verify(int p_nTmplNo, int p_nRamBufferID, int[] p_pnLearnResult)
+    {
+        boolean	w_bRet;
+        byte[]	w_abyData = new byte[4];
+
+        w_abyData[0] = LOBYTE((short)p_nTmplNo);
+        w_abyData[1] = HIBYTE((short)p_nTmplNo);
+        w_abyData[2] = LOBYTE((short)p_nRamBufferID);
+        w_abyData[3] = HIBYTE((short)p_nRamBufferID);
+
+        //. Assemble command packet
+        InitCmdPacket(CMD_VERIFY, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4);
+
+        w_bRet = Send_Command(CMD_VERIFY);
+
+        if (!w_bRet)
+            return ERR_CONNECTION;
+
+        p_pnLearnResult[0] = m_abyPacket[RCM_DATA_OFFSET+2];
+
+        return GetRetCode();
+    }
+
+    public  boolean GetDeviceInformation(String[] deviceInfo)
+    {
+        int[]  w_nRecvLen = new int[1];
+        byte[] w_abyPCCmd = new byte[6];
+        byte[] w_abyData = new byte[32];
+
+        String  w_strTmp;
+        boolean w_bRet;
+
+        Arrays.fill(w_abyPCCmd, (byte) 0);
+
+        w_abyPCCmd[2] = 0x04;
+
+        w_bRet = SendPackage(w_abyPCCmd, w_abyData);
+
+        //Toast.makeText(mApplicationContext, "GetDeviceInformation, SendPackage ret = " + w_bRet, Toast.LENGTH_SHORT).show();
+
+        if (!w_bRet)
+        {
+            return  false;
+        }
+
+        w_bRet = RecvPackage(w_abyData, w_nRecvLen);
+
+        //Toast.makeText(mApplicationContext, "GetDeviceInformation, RecvPackage : " + w_bRet, Toast.LENGTH_SHORT).show();
+
+        if (!w_bRet)
+        {
+            return  false;
+        }
+
+        w_strTmp = new String(w_abyData);
+        deviceInfo[0] = w_strTmp;
+
+        //Toast.makeText(mApplicationContext, "GetDeviceInformation, Recv Data : " + w_strTmp, Toast.LENGTH_SHORT).show();
+
+        return true;
+    }
+
+
+
+    private  boolean SendPackage(byte[] pPCCmd, byte[] pData)
+    {
+        int    nDataLen;
+
+        pPCCmd[0] = (byte)0xEF;
+        pPCCmd[1] = 0x01;
+
+        nDataLen = (int)((int)((pPCCmd[5] << 8) & 0x0000FF00) | (int)(pPCCmd[4] & 0x000000FF));
+
+        return m_usbBase.UsbSCSIWrite(pPCCmd, 6, pData, nDataLen, 5000);
+    }
+
+    private  boolean RecvPackage(byte[] pData, int[] pLevRen)
+    {
+        int    w_nLen;
+        byte[] w_abyPCCmd = new byte[6];
+        byte[] w_abyRespond = new byte[4];
+        boolean w_bRet;
+
+        w_abyPCCmd[0] = (byte)0xEF;
+        w_abyPCCmd[1] = 0x02;
+        w_abyPCCmd[2] = 0;
+        w_abyPCCmd[3] = 0;
+        w_abyPCCmd[4] = 0;
+        w_abyPCCmd[5] = 0;
+
+        // receive status
+        w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, w_abyRespond, 4, 5000);
+
+        if (!w_bRet)
+            return false;
+
+        // receive data
+        //w_nLen = (int)((w_abyRespond[3] << 8) | w_abyRespond[2]);
+        w_nLen = (int)((int)((w_abyRespond[3] << 8) & 0x0000FF00) | (int)(w_abyRespond[2] & 0x000000FF));
+
+        if (w_nLen > 0)
+        {
+            //w_nTime = SystemClock.elapsedRealtime();
+
+            w_abyPCCmd[1] = 0x03;
+            w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, pData, w_nLen, 5000);
+
+            //w_nTime = SystemClock.elapsedRealtime() - w_nTime;
+
+            if (!w_bRet)
+                return false;
+
+            pLevRen[0] = w_nLen;
+        }
+
+        return  true;
+    }
+
+    /***************************************************************************
+     * Get Return Code
+     ***************************************************************************/
+    private short GetRetCode()
+    {
+        return (short)((int)((m_abyPacket[9] << 8) & 0x0000FF00) | (int)(m_abyPacket[8] & 0x000000FF));
+    }
+
+    /***************************************************************************
+     * Get Data Length
+     ***************************************************************************/
+    private short GetDataLen()
+    {
+        return (short)(((m_abyPacket[7] << 8) & 0x0000FF00) | (m_abyPacket[6] & 0x000000FF));
+    }
+
+    /***************************************************************************
+     * Set Data Length
+     ***************************************************************************/
+    private void SetDataLen(short p_wDataLen)
+    {
+        m_abyPacket[6] = (byte)(p_wDataLen & 0xFF);
+        m_abyPacket[7] = (byte)(((p_wDataLen & 0xFF00) >> 8) & 0xFF);
+    }
+
+    /***************************************************************************
+     * Set Command Data
+     ***************************************************************************/
+    private void SetCmdData(short p_wData, boolean p_bFirst)
+    {
+        if (p_bFirst)
+        {
+            m_abyPacket[8] = (byte)(p_wData & 0xFF);
+            m_abyPacket[9] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF);
+        }
+        else
+        {
+            m_abyPacket[10] = (byte)(p_wData & 0xFF);
+            m_abyPacket[11] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF);
+        }
+    }
+
+    /***************************************************************************
+     * Get Command Data
+     ***************************************************************************/
+    private short GetCmdData(boolean p_bFirst)
+    {
+        if (p_bFirst)
+        {
+            return (short)(((m_abyPacket[9] << 8) & 0x0000FF00) | (m_abyPacket[8] & 0x000000FF));
+        }
+        else
+        {
+            return (short)(((m_abyPacket[11] << 8) & 0x0000FF00) | (m_abyPacket[10] & 0x000000FF));
+        }
+    }
+
+    /***************************************************************************
+     * Get 2bytes packet checksum(pDataPkt[0] + pDataPkt[1] + ....)
+     ***************************************************************************/
+    private short CalcChkSumOfPkt(byte[] pDataPkt, int nSize)
+    {
+        int     i, nChkSum = 0;
+
+        for(i=0;i<nSize;i++)
+        {
+            if ((int)pDataPkt[i] < 0)
+                nChkSum = nChkSum + ((int)pDataPkt[i] + 256);
+            else
+                nChkSum = nChkSum + pDataPkt[i];
+        }
+
+        return (short)nChkSum;
+    }
+
+    /***************************************************************************
+     * Make Command Packet
+     ***************************************************************************/
+    void InitCmdPacket(short wCMDCode, byte bySrcDeviceID, byte byDstDeviceID, byte[] pbyData, int nDataLen)
+    {
+        short	w_wCheckSum;
+
+        memset(m_abyPacket, (byte)0, CMD_PACKET_LEN);
+
+        //g_pCmdPacket->m_wPrefix = CMD_PREFIX_CODE;
+        m_abyPacket[0] = (byte)(CMD_PREFIX_CODE & 0xFF);
+        m_abyPacket[1] = (byte)((CMD_PREFIX_CODE >> 8) & 0xFF);
+
+        //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID;
+        m_abyPacket[2] = bySrcDeviceID;
+
+        //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID;
+        m_abyPacket[3] = byDstDeviceID;
+
+        //g_pCmdPacket->m_wCMDCode = p_wCMDCode;
+        m_abyPacket[4] = (byte)(wCMDCode & 0xFF);
+        m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF);
+
+        //g_pCmdPacket->m_wDataLen = p_wDataLen;
+        m_abyPacket[6] = (byte)(nDataLen & 0xFF);
+        m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF);
+
+        if (nDataLen > 0)
+            //memcpy(g_pCmdPacket->m_abyData, p_pbyData, wDataLen);
+            System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen);
+
+        w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, CMD_PACKET_LEN-2);
+
+        //g_pCmdPacket->m_wCheckSum = w_wCheckSum;
+        m_abyPacket[24] = (byte)(w_wCheckSum & 0xFF);
+        m_abyPacket[25] = (byte)((w_wCheckSum >> 8) & 0xFF);
+
+        m_nPacketSize = CMD_PACKET_LEN;
+    }
+    /***************************************************************************
+     * Make Data Packet
+     ***************************************************************************/
+    void	InitCmdDataPacket(short wCMDCode, byte bySrcDeviceID, byte byDstDeviceID, byte[] pbyData, int nDataLen)
+    {
+        short	w_wCheckSum;
+
+        //g_pCmdPacket->m_wPrefix = CMD_DATA_PREFIX_CODE;
+        m_abyPacket[0] = (byte)(CMD_DATA_PREFIX_CODE & 0xFF);
+        m_abyPacket[1] = (byte)((CMD_DATA_PREFIX_CODE >> 8) & 0xFF);
+
+        //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID;
+        m_abyPacket[2] = bySrcDeviceID;
+
+        //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID;
+        m_abyPacket[3] = byDstDeviceID;
+
+        //g_pCmdPacket->m_wCMDCode = p_wCMDCode;
+        m_abyPacket[4] = (byte)(wCMDCode & 0xFF);
+        m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF);
+
+        //g_pCmdPacket->m_wDataLen = p_wDataLen;
+        m_abyPacket[6] = (byte)(nDataLen & 0xFF);
+        m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF);
+
+        //memcpy(&g_pCmdPacket->m_abyData[0], p_pbyData, p_wDataLen);
+        System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen);
+
+        //. Set checksum
+        w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, nDataLen + 8);
+
+        m_abyPacket[nDataLen+8] = (byte)(w_wCheckSum & 0xFF);
+        m_abyPacket[nDataLen+9] = (byte)((w_wCheckSum >> 8) & 0xFF);
+
+        m_nPacketSize = nDataLen + 10;
+    }
+    /***************************************************************************
+     * Check Packet
+     ***************************************************************************/
+    boolean CheckReceive( byte[] pbyPacket, int nPacketLen, short wPrefix, short wCMDCode )
+    {
+        short			w_wCalcCheckSum, w_wCheckSum, w_wTmp;
+
+        //. Check prefix code
+        w_wTmp = (short)((int)((pbyPacket[1] << 8) & 0x0000FF00) | (int)(pbyPacket[0] & 0x000000FF));
+
+        if (wPrefix != w_wTmp)
+        {
+            return false;
+        }
+
+        //. Check checksum
+        w_wCheckSum = (short)((int)((pbyPacket[nPacketLen-1] << 8) & 0x0000FF00) | (int)(pbyPacket[nPacketLen-2] & 0x000000FF));
+
+        w_wCalcCheckSum = CalcChkSumOfPkt(pbyPacket, nPacketLen-2);
+
+        if (w_wCheckSum != w_wCalcCheckSum)
+        {
+            return false;
+        }
+
+        //. Check Command Code
+        w_wTmp = (short)((int)((pbyPacket[5] << 8) & 0x0000FF00) | (int)(pbyPacket[4] & 0x000000FF));
+        if (wCMDCode != w_wTmp)
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    //--------------------------- Send, Receive Communication Packet Functions ---------------------//
+    public boolean Send_Command(short p_wCmd)
+    {
+        if (m_nConnected == 1)
+            return UART_SendCommand(p_wCmd);
+        else if (m_nConnected == 2)
+            return USB_SendPacket(p_wCmd);
+        else
+            return false;
+    }
+
+    public boolean Send_DataPacket(short p_wCmd)
+    {
+        if (m_nConnected == 1)
+            return UART_SendDataPacket(p_wCmd);
+        else if (m_nConnected == 2)
+            return USB_SendDataPacket(p_wCmd);
+        else
+            return false;
+    }
+
+    public boolean Receive_DataPacket(short p_wCmd)
+    {
+        if (m_nConnected == 1)
+            return UART_ReceiveDataPacket(p_wCmd);
+        else if (m_nConnected == 2)
+            return USB_ReceiveDataPacket(p_wCmd);
+        else
+            return false;
+    }
+
+    //-------------------------------- USB Communication Functions --------------------------------//
+    private  boolean USB_SendPacket(short wCMD)
+    {
+        byte[]	btCDB = new byte[8];
+        boolean	w_bRet;
+
+        Arrays.fill(btCDB, (byte)0);
+
+        btCDB[0] = (byte)0xEF; btCDB[1] = 0x11; btCDB[4] = (byte)m_nPacketSize;
+
+        w_bRet = m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT);
+
+        if (!w_bRet)
+        {
+            return false;
+        }
+
+        return USB_ReceiveAck( wCMD );
+    }
+
+    private boolean USB_ReceiveAck(short wCMD)
+    {
+        int		c, w_nLen, w_nReadCount = 0;
+        byte[]	btCDB = new byte[8];
+        byte[]	w_abyWaitPacket = new byte[CMD_PACKET_LEN];
+
+        Arrays.fill(btCDB, (byte)0);
+
+        //w_nReadCount = GetReadWaitTime(p_byCMD);
+
+        c = 0;
+        Arrays.fill(w_abyWaitPacket, (byte)0xAF);
+
+        do
+        {
+            Arrays.fill(m_abyPacket, (byte)0);
+
+            btCDB[0] = (byte)0xEF; btCDB[1] = (byte)0x12;
+
+            w_nLen = RCM_PACKET_LEN;
+
+            if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT))
+            {
+                return false;
+            }
+
+            SystemClock.sleep(COMM_SLEEP_TIME);
+
+            c++;
+
+            //if ( c > w_nReadCount)
+            //{
+            //	return false;
+            //}
+        } while ( memcmp(m_abyPacket, w_abyWaitPacket, CMD_PACKET_LEN) == true );
+
+        m_nPacketSize = w_nLen;
+
+        if (!CheckReceive(m_abyPacket, m_nPacketSize, (short)RCM_PREFIX_CODE, wCMD )) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean USB_ReceiveDataAck(short wCMD)
+    {
+        byte[]	btCDB = new byte[8];
+        byte[]	w_WaitPacket = new byte[10];
+        int		w_nLen;
+
+        memset(btCDB, (byte)0, 8);
+        memset(w_WaitPacket, (byte)0xAF, 10);
+
+        do
+        {
+            btCDB[0] = (byte)0xEF; btCDB[1] = 0x15;
+            w_nLen = 8;
+
+            if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT))
+            {
+                return false;
+            }
+
+            SystemClock.sleep(COMM_SLEEP_TIME);
+
+        }while(memcmp(m_abyPacket, w_WaitPacket, 8) == true);
+
+        //w_nLen = g_pRcmPacket->m_wDataLen + 2;
+        w_nLen = (short)((int)((m_abyPacket[7] << 8) & 0x0000FF00) | (int)(m_abyPacket[6] & 0x000000FF)) + 2;
+
+        if (USB_ReceiveRawData(m_abyPacket2, w_nLen) == false)
+        {
+            return false;
+        }
+
+        System.arraycopy(m_abyPacket2, 0, m_abyPacket, 8, w_nLen);
+
+        m_nPacketSize = 8 + w_nLen;
+
+        if (!CheckReceive(m_abyPacket, m_nPacketSize, (short)RCM_DATA_PREFIX_CODE, wCMD ))
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    boolean USB_SendDataPacket(short wCMD)
+    {
+        byte[]	btCDB = new byte[8];
+
+        memset(btCDB, (byte)0, 8);
+
+        btCDB[0] = (byte)0xEF; btCDB[1] = 0x13;
+
+        btCDB[4] = (byte)(m_nPacketSize & 0xFF);
+        btCDB[5] = (byte)((m_nPacketSize >> 8) & 0xFF);
+
+        if (!m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT ) )
+            return false;
+
+        return USB_ReceiveDataAck(wCMD);
+    }
+
+    boolean USB_ReceiveDataPacket(short wCMD)
+    {
+        return USB_ReceiveDataAck(wCMD);
+    }
+
+    boolean USB_ReceiveRawData(byte[] pBuffer, int nDataLen)
+    {
+        byte[] btCDB = new byte[8];
+
+        memset(btCDB, (byte)0, 8);
+
+        btCDB[0] = (byte)0xEF; btCDB[1] = 0x14;
+
+        if (!m_usbBase.UsbSCSIRead(btCDB, 8, pBuffer, nDataLen, SCSI_TIMEOUT ) )
+            return false;
+
+        return true;
+    }
+
+    boolean USB_ReceiveImage(byte[] p_pBuffer, int nDataLen )
+    {
+        byte[]	btCDB = new byte[8];
+        byte[]	w_WaitPacket = new byte[8];
+
+        memset( btCDB, (byte)0, 8 );
+        memset( w_WaitPacket, (byte)0xAF, 8 );
+
+        if (nDataLen < 1024*64)
+        {
+            btCDB[0] = (byte)0xEF; btCDB[1] = 0x16;
+
+            if (!m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen, SCSI_TIMEOUT ))
+                return false;
+        }
+        else if (nDataLen == 256*288)
+        {
+            btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x00;
+
+            if (!m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen/2, SCSI_TIMEOUT))
+                return false;
+
+            btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x01;
+
+            if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket2, nDataLen/2, SCSI_TIMEOUT ))
+                return false;
+
+            System.arraycopy(m_abyPacket2, 0, p_pBuffer, nDataLen/2, nDataLen/2);
+        }
+
+        return true;
+    }
+
+    //-------------------------------- UART Communication Functions --------------------------------//
+    public boolean UART_SendCommand(short p_wCmd)
+    {
+        int	w_nResult = 0;
+
+        if (m_nConnected == 1)
+        {
+            byte[] w_pData = new byte[m_nPacketSize];
+            System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize);
+            m_SerialPort.send(w_pData, m_nPacketSize);
+        }
+
+        return UART_ReceiveAck(p_wCmd);
+    }
+
+    public boolean UART_ReceiveAck(short p_wCmd)
+    {
+        if (!UART_ReadDataN(m_abyPacket, 0, CMD_PACKET_LEN))
+            return false;
+
+        if (!CheckReceive(m_abyPacket, CMD_PACKET_LEN, (short)RCM_PREFIX_CODE, p_wCmd))
+            return false;
+
+        return true;
+    }
+
+    public boolean UART_ReceiveDataAck(short p_wCmd)
+    {
+        if (!UART_ReadDataN(m_abyPacket, 0, 8))
+            return false;
+
+        if (!UART_ReadDataN(m_abyPacket, 8, GetDataLen() + 2))
+            return false;
+
+        return CheckReceive(m_abyPacket, GetDataLen() + 10, (short)RCM_DATA_PREFIX_CODE, p_wCmd);
+    }
+
+    public boolean UART_SendDataPacket(short p_wCmd)
+    {
+        int		w_nSendCnt = 0;
+
+        if (m_nConnected == 1)
+        {
+            byte[] w_pData = new byte[m_nPacketSize];
+            System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize);
+            m_SerialPort.send(w_pData, m_nPacketSize);
+        }
+
+        return UART_ReceiveDataAck(p_wCmd);
+    }
+    /***************************************************************************/
+    /***************************************************************************/
+    public boolean UART_ReceiveDataPacket(short p_wCmd)
+    {
+        return UART_ReceiveDataAck(p_wCmd);
+    }
+    /***************************************************************************/
+    /***************************************************************************/
+    public boolean UART_ReceiveData(short p_wCmd, int p_nDataLen, byte[] p_pBuffer)
+    {
+        int		w_nReceivedCnt;
+        int		w_wPacketDataLen = 0;
+
+        for (w_nReceivedCnt = 0; w_nReceivedCnt < p_nDataLen; w_nReceivedCnt += w_wPacketDataLen)
+        {
+            w_wPacketDataLen = p_nDataLen - w_nReceivedCnt;
+            if (w_wPacketDataLen > MAX_DATA_LEN) w_wPacketDataLen = MAX_DATA_LEN;
+            if (UART_ReceiveDataPacket(p_wCmd) == false)
+                return false;
+            System.arraycopy(m_abyPacket, 8, p_pBuffer, w_nReceivedCnt, GetDataLen() + 4);
+        }
+        return true;
+    }
+    /***************************************************************************/
+    /***************************************************************************/
+    boolean UART_ReadDataN(byte[] p_pData, int p_nStart, int p_nLen)
+    {
+//    	int		w_nAckCnt = 0;
+        int		w_nRecvLen, w_nTotalRecvLen;
+        int 	w_nTmpLen;
+        long	w_nTime;
+        int     i;
+
+        w_nRecvLen = p_nLen;
+        w_nTotalRecvLen = 0;
+
+        w_nTime = System.currentTimeMillis();
+
+        while(w_nTotalRecvLen < p_nLen )
+        {
+            if (System.currentTimeMillis() - w_nTime > 10000)
+            {
+                m_nUARTReadLen = 0;
+                return false;
+            }
+
+            i = 0;
+            while (m_bBufferHandle)
+            {
+                i++;
+                if (i < 10000)
+                    break;
+            }
+
+            m_bBufferHandle = true;
+
+            if (m_nUARTReadLen <= 0) {
+                m_bBufferHandle = false;
+                continue;
+            }
+
+            if (p_nLen - w_nTotalRecvLen < m_nUARTReadLen)
+            {
+                w_nTmpLen = p_nLen - w_nTotalRecvLen;
+                System.arraycopy(m_pUARTReadBuf, 0, p_pData, p_nStart + w_nTotalRecvLen, w_nTmpLen);
+                w_nRecvLen = w_nRecvLen - w_nTmpLen;
+                w_nTotalRecvLen = w_nTotalRecvLen + w_nTmpLen;
+                m_nUARTReadLen = m_nUARTReadLen - w_nTmpLen;
+                System.arraycopy(m_pUARTReadBuf, w_nTmpLen, m_abyPacket2, 0, m_nUARTReadLen);
+                System.arraycopy(m_abyPacket2, 0, m_pUARTReadBuf, 0, m_nUARTReadLen);
+            }
+            else
+            {
+                System.arraycopy(m_pUARTReadBuf, 0, p_pData, p_nStart + w_nTotalRecvLen, m_nUARTReadLen);
+                w_nRecvLen = w_nRecvLen - m_nUARTReadLen;
+                w_nTotalRecvLen = w_nTotalRecvLen + m_nUARTReadLen;
+                m_nUARTReadLen = 0;
+            }
+
+            m_bBufferHandle = false;
+        }
+
+        return true;
+    }
+
+    private boolean memcmp(byte[] p1, byte[] p2, int nLen)
+    {
+        int		i;
+
+        for (i=0; i<nLen; i++)
+        {
+            if (p1[i] != p2[i])
+                return false;
+        }
+
+        return true;
+    }
+
+    private void memset(byte[] p1, byte nValue, int nLen)
+    {
+        Arrays.fill(p1, 0, nLen, nValue);
+    }
+
+    private void memcpy(byte[] p1, byte nValue, int nLen)
+    {
+        Arrays.fill(p1, 0, nLen, nValue);
+    }
+
+    private short MAKEWORD(byte low, byte high)
+    {
+        short s;
+        s = (short)((int)((high << 8) & 0x0000FF00) | (int)(low & 0x000000FF));
+        return s;
+    }
+
+    private byte LOBYTE(short s)
+    {
+        return (byte)(s & 0xFF);
+    }
+
+    private byte HIBYTE(short s)
+    {
+        return (byte)((s >> 8) & 0xFF);
+    }
+
+
+    // uart control classes ======================================================
+    private class SerialControl extends SerialHelper{
+
+        public SerialControl(){
+        }
+
+        @Override
+        protected void onDataReceived(final ComBean ComRecData)
+        {
+            DispQueue.AddQueue(ComRecData);
+        }
+    }
+
+    private class DispQueueThread extends Thread{
+        private Queue<ComBean> QueueList = new LinkedList<ComBean>();
+        @Override
+        public void run() {
+            super.run();
+            while(!isInterrupted()) {
+                int i;
+                while(true)
+                {
+                    final ComBean ComData;
+                    if ((ComData=QueueList.poll())==null)
+                        break;
+
+                    i = 0;
+                    while (m_bBufferHandle)
+                    {
+                        i++;
+                        if (i > 10000)
+                            break;
+                    }
+                    m_bBufferHandle = true;
+                    System.arraycopy(ComData.bRec, 0, m_pUARTReadBuf, m_nUARTReadLen, ComData.nSize);
+                    m_nUARTReadLen = m_nUARTReadLen + ComData.nSize;
+                    m_bBufferHandle = false;
+//		        	break;
+                }
+            }
+        }
+
+        public synchronized void AddQueue(ComBean ComData){
+            QueueList.add(ComData);
+        }
+    }
+    // ! uart control classes ====================================================
+
+    public static String GetErrorMsg(int nErrorCode) {
+        String str = new String("");
+
+        switch (nErrorCode) {
+            case DevComm.ERR_SUCCESS:
+                str = "鎴愬姛";
+                break;
+            case DevComm.ERR_VERIFY:
+                str = "楠岃瘉涓嶉�氳繃";
+                break;
+            case DevComm.ERR_IDENTIFY:
+                str = "璇嗗埆涓嶅悎鏍煎搧";
+                break;
+            case DevComm.ERR_EMPTY_ID_NOEXIST:
+                str = "绌烘ā鏉夸笉瀛樺湪";
+                break;
+            case DevComm.ERR_BROKEN_ID_NOEXIST:
+                str = "妯℃澘涓嶅瓨鍦�";
+                break;
+            case DevComm.ERR_TMPL_NOT_EMPTY:
+                str = "姝D鐨勬ā鏉垮凡瀛樺湪";
+                break;
+            case DevComm.ERR_TMPL_EMPTY:
+                str = "姝ゆā鏉垮凡绌�";
+                break;
+            case DevComm.ERR_INVALID_TMPL_NO:
+                str = "鏃犳晥妯℃澘缂栧彿";
+                break;
+            case DevComm.ERR_ALL_TMPL_EMPTY:
+                str = "鎵�鏈夋ā鏉块兘鏄┖鐨�";
+                break;
+            case DevComm.ERR_INVALID_TMPL_DATA:
+                str = "鏃犳晥妯℃澘鏁版嵁";
+                break;
+            case DevComm.ERR_DUPLICATION_ID:
+                str = "閲嶅鐨処D";
+                break;
+            case DevComm.ERR_BAD_QUALITY:
+                str = "鍔h川鍥惧儚";
+                break;
+            case DevComm.ERR_MERGE_FAIL:
+                str = "鍚堝苟澶辫触";
+                break;
+            case DevComm.ERR_NOT_AUTHORIZED:
+                str = "璁惧鏈巿鏉�";
+                break;
+            case DevComm.ERR_MEMORY:
+                str = "鍐呭瓨閿欒";
+                break;
+            case DevComm.ERR_INVALID_PARAM:
+                str = "鏃犳晥鍙傛暟";
+                break;
+            case DevComm.ERR_GEN_COUNT:
+                str = "鐢熸垚璁℃暟鏃犳晥";
+                break;
+            case DevComm.ERR_INVALID_BUFFER_ID:
+                str = "RAM缂撳啿鍖篒D鏃犳晥";
+                break;
+            case DevComm.ERR_INVALID_OPERATION_MODE:
+                str = "鎿嶄綔妯″紡鏃犳晥";
+                break;
+            case DevComm.ERR_FP_NOT_DETECTED:
+                str = "鏈娴嬪埌鎵嬫寚";
+                break;
+            default:
+                str = String.format("澶辫触, 閿欒鐮�=%d", nErrorCode);
+                break;
+        }
+
+        return str;
+    }
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/IUsbConnState.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/IUsbConnState.java
new file mode 100644
index 0000000..38b98fb
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/IUsbConnState.java
@@ -0,0 +1,12 @@
+package com.doumee.keyCabinet.utils.usb;
+
+/**
+ * Created by KMS on 2016/8/23.
+ */
+public interface IUsbConnState {
+    void onUsbConnected();
+
+    void onUsbPermissionDenied();
+
+    void onDeviceNotFound();
+}
diff --git a/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/UsbController.java b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/UsbController.java
new file mode 100644
index 0000000..8e3d4a6
--- /dev/null
+++ b/keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/usb/UsbController.java
@@ -0,0 +1,451 @@
+package com.doumee.keyCabinet.utils.usb;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Created by KMS on 2016/8/23.
+ */
+public class UsbController {
+    private final Context mApplicationContext;
+    private final UsbManager mUsbManager;
+    private final int VID;
+    private final int PID;
+    private int m_nEPInSize, m_nEPOutSize;
+
+    private byte[] m_abyTransferBuf;
+    private boolean m_bInit = false;
+    private UsbDeviceConnection m_usbConn = null;
+    private UsbInterface m_usbIf = null;
+    private UsbEndpoint m_epIN = null;
+    private UsbEndpoint m_epOUT = null;
+    private final IUsbConnState mConnectionHandler;
+
+    protected static final String ACTION_USB_PERMISSION = "ch.serverbox.android.USB";
+
+    /**
+     * Activity is needed for onResult
+     *
+     * @param parentActivity
+     */
+    public UsbController(Activity parentActivity, IUsbConnState connectionHandler, int vid, int pid){
+        mConnectionHandler = connectionHandler;
+        mApplicationContext = parentActivity.getApplicationContext();
+        mUsbManager = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE);
+        VID = vid;
+        PID = pid;
+        m_abyTransferBuf = new byte[512];
+        //init();
+    }
+
+    public void init(){
+        enumerate(new IPermissionListener() {
+            @Override
+            public void onPermissionDenied(UsbDevice d) {
+                UsbManager usbman = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE);
+                PendingIntent pi = PendingIntent.getBroadcast(mApplicationContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
+                mApplicationContext.registerReceiver(mPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));
+                usbman.requestPermission(d, pi);
+            }
+        });
+    }
+
+    public void uninit(){
+        if (m_usbConn != null)
+        {
+            m_usbConn.releaseInterface(m_usbIf);
+            m_usbConn.close();
+            m_usbConn = null;
+            m_bInit = false;
+        }
+
+        //stop();
+    }
+
+    public void stop()
+    {
+        try{
+            mApplicationContext.unregisterReceiver(mPermissionReceiver);
+        }catch(IllegalArgumentException e){};//bravo
+    }
+
+    public boolean IsInit(){
+        return m_bInit;
+    }
+
+    private void enumerate(IPermissionListener listener) {
+        boolean bFound = false;
+        l("enumerating");
+        HashMap<String, UsbDevice> devlist = mUsbManager.getDeviceList();
+        Iterator<UsbDevice> deviter = devlist.values().iterator();
+
+        while (deviter.hasNext()) {
+            UsbDevice d = deviter.next();
+            l("Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId()));
+
+            Toast.makeText(mApplicationContext, "Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId()), Toast.LENGTH_SHORT).show();
+
+            if (d.getVendorId() == VID && d.getProductId() == PID) {
+                bFound = true;
+                l("Device under: " + d.getDeviceName());
+                if (!mUsbManager.hasPermission(d))
+                {
+                    Toast.makeText(mApplicationContext, "enumerate, hasPermission return false" , Toast.LENGTH_SHORT).show();
+                    listener.onPermissionDenied(d);
+                }
+                else{
+                    Toast.makeText(mApplicationContext, "enumerate, GetConnInerface start" , Toast.LENGTH_SHORT).show();
+                    //startHandler(d);
+                    GetConnInerface(d);
+                    //TestComm(d);
+                    return;
+                }
+                break;
+            }
+        }
+        if (bFound == false)
+        {
+            Toast.makeText(mApplicationContext, "no more devices found" , Toast.LENGTH_SHORT).show();
+            mConnectionHandler.onDeviceNotFound();
+        }
+    }
+
+    private class PermissionReceiver extends BroadcastReceiver {
+        private final IPermissionListener mPermissionListener;
+
+        public PermissionReceiver(IPermissionListener permissionListener) {
+            mPermissionListener = permissionListener;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mApplicationContext.unregisterReceiver(this);
+            if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
+                if (!intent.getBooleanExtra(
+                        UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+                    mPermissionListener.onPermissionDenied((UsbDevice) intent
+                            .getParcelableExtra(UsbManager.EXTRA_DEVICE));
+
+                    mConnectionHandler.onUsbPermissionDenied();
+                } else {
+                    l("Permission granted");
+                    UsbDevice dev = (UsbDevice) intent
+                            .getParcelableExtra(UsbManager.EXTRA_DEVICE);
+                    if (dev != null) {
+                        if (dev.getVendorId() == VID
+                                && dev.getProductId() == PID) {
+                            //startHandler(dev);// has new thread
+                            GetConnInerface(dev);
+                            //TestComm(dev);
+                        }
+                    } else {
+                        mConnectionHandler.onDeviceNotFound();
+                    }
+                }
+            }
+        }
+    }
+
+    private void GetConnInerface(UsbDevice dev){
+        int n;
+
+        m_usbConn = mUsbManager.openDevice(dev);
+
+        n = dev.getInterfaceCount();
+
+        if (n <= 0)
+            return;
+        if(m_usbConn==null){
+            return;
+        }
+        if (!m_usbConn.claimInterface(dev.getInterface(0), true)) {
+            return;
+        }
+
+        m_usbIf = dev.getInterface(0);
+
+        n = m_usbIf.getEndpointCount();
+
+        if (n < 2)
+            return;
+
+        for (int i = 0; i < n; i++) {
+            if (m_usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
+                if (m_usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN)
+                    m_epIN = m_usbIf.getEndpoint(i);
+                else
+                    m_epOUT = m_usbIf.getEndpoint(i);
+            }
+        }
+
+        m_nEPInSize = m_epIN.getMaxPacketSize();
+        m_nEPOutSize = m_epOUT.getMaxPacketSize();
+
+        m_bInit = true;
+
+        //m_epOUT.getMaxPacketSize();
+
+        //Toast.makeText(mApplicationContext, "GetConnInerface OK, Out Max Size="+m_nEPOutSize+" In Max Size=" + m_nEPInSize, Toast.LENGTH_SHORT).show();
+        mConnectionHandler.onUsbConnected();
+    }
+
+    public boolean OperationInternal(byte[] pData, int nDataLen, int nTimeOut, boolean bRead)
+    {
+        byte[] w_abyTmp = new byte[31];
+        byte[] w_abyCSW = new byte[13];
+        boolean w_bRet;
+
+        Arrays.fill(w_abyTmp, (byte)0);
+        w_abyTmp[0] = 0x55;
+        w_abyTmp[1] = 0x53;
+        w_abyTmp[2] = 0x42;
+        w_abyTmp[3] = 0x43;
+        w_abyTmp[4] = 0x28;
+        w_abyTmp[5] = 0x2b;
+        w_abyTmp[6] = 0x18;
+        w_abyTmp[7] = (byte)0x89;
+        w_abyTmp[8] = (byte)(nDataLen & 0xFF);
+        w_abyTmp[9] = (byte)((nDataLen >> 8)& 0xFF);
+        w_abyTmp[10] = (byte)((nDataLen >> 16)& 0xFF);
+        w_abyTmp[11] = (byte)((nDataLen >> 24)& 0xFF);
+
+        if(bRead)
+            w_abyTmp[12] = (byte)0x80;
+        else
+            w_abyTmp[12] = 0x00;    //cCBWFlags
+
+        w_abyTmp[13] = 0x00;    //cCBWlun
+        w_abyTmp[14] = 0x0a;    //cCBWCBLength
+
+        w_abyTmp[15] = (byte)0xef;
+        if (bRead)
+            w_abyTmp[16] = (byte)0xff;
+        else
+            w_abyTmp[16] = (byte)0xfe;
+
+        // send 31bytes
+        w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut);
+
+        if (!w_bRet)
+            return false;
+
+        // read or write real data
+        if (bRead)
+            w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut);
+        else
+            w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut);
+
+        if (!w_bRet)
+            return false;
+
+        // receive csw
+        w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut);
+
+        return w_bRet;
+    }
+
+    public boolean UsbSCSIWrite(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut)
+    {
+        byte[] w_abyTmp = new byte[31];
+        byte[] w_abyCSW = new byte[13];
+        boolean w_bRet;
+
+        //Arrays.fill(w_abyTmp, (byte)0);
+        w_abyTmp[0] = 0x55;
+        w_abyTmp[1] = 0x53;
+        w_abyTmp[2] = 0x42;
+        w_abyTmp[3] = 0x43;
+        w_abyTmp[4] = 0x28;
+        w_abyTmp[5] = 0x2b;
+        w_abyTmp[6] = 0x18;
+        w_abyTmp[7] = (byte)0x89;
+        w_abyTmp[8] = 0x00;
+        w_abyTmp[9] = 0x00;
+        w_abyTmp[10] = 0x00;
+        w_abyTmp[11] = 0x00;
+        w_abyTmp[12] = 0x00;    //cCBWFlags
+        w_abyTmp[13] = 0x00;    //cCBWlun
+        w_abyTmp[14] = 0x0a;    //cCBWCBLength
+
+        System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen);
+        //System.arraycopy(pData, 0, w_abyTmp, 31, nDataLen);
+
+        w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut);
+
+        if (!w_bRet)
+            return false;
+
+        w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut);
+
+        if (!w_bRet)
+            return false;
+
+        // receive csw
+        w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut);
+
+        return w_bRet;
+    }
+
+    public boolean UsbSCSIRead(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut)
+    {
+        long    w_nTime;
+        byte[] w_abyTmp = new byte[31];
+        byte[] w_abyCSW = new byte[13];
+        boolean w_bRet;
+
+        //Arrays.fill(w_abyTmp, (byte)0);
+        w_abyTmp[0] = 0x55;
+        w_abyTmp[1] = 0x53;
+        w_abyTmp[2] = 0x42;
+        w_abyTmp[3] = 0x43;
+        w_abyTmp[4] = 0x28;
+        w_abyTmp[5] = 0x2b;
+        w_abyTmp[6] = 0x18;
+        w_abyTmp[7] = (byte)0x89;
+        w_abyTmp[8] = 0x00;
+        w_abyTmp[9] = 0x00;
+        w_abyTmp[10] = 0x00;
+        w_abyTmp[11] = 0x00;
+        w_abyTmp[12] = (byte)0x80;    //cCBWFlags
+        w_abyTmp[13] = 0x00;    //cCBWlun
+        w_abyTmp[14] = 0x0a;    //cCBWCBLength
+
+        System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen);
+
+        w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut);
+
+        if (!w_bRet)
+            return false;
+
+        w_nTime = SystemClock.elapsedRealtime();
+
+        w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut);
+
+        w_nTime = SystemClock.elapsedRealtime() - w_nTime;
+
+        //Toast.makeText(mApplicationContext, "UsbSCSIRead, UsbBulkReceive Time : " + w_nTime , Toast.LENGTH_SHORT).show();
+
+        if (!w_bRet)
+            return false;
+
+        // receive csw
+        w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut);
+
+        return w_bRet;
+    }
+
+    private boolean UsbBulkSend(byte[] pBuf, int nLen, int nTimeOut)
+    {
+        int i, n, r, w_nRet;
+        //byte[] w_abyTmp = new byte[m_nEPOutSize];
+
+        n = nLen / m_nEPOutSize;
+        r = nLen % m_nEPOutSize;
+
+        for(i=0; i<n; i++)
+        {
+            System.arraycopy(pBuf, i*m_nEPOutSize, m_abyTransferBuf, 0, m_nEPOutSize);
+            if(m_usbConn==null){
+                return false;
+            }
+            w_nRet = m_usbConn.bulkTransfer(m_epOUT, m_abyTransferBuf, m_nEPOutSize, nTimeOut);
+
+            if (w_nRet != m_nEPOutSize)
+                return false;
+        }
+
+        if (r > 0)
+        {
+            System.arraycopy(pBuf, i*m_nEPOutSize, m_abyTransferBuf, 0, r);
+            if(m_usbConn==null){
+                return false;
+            }
+            w_nRet = m_usbConn.bulkTransfer(m_epOUT, m_abyTransferBuf, r, nTimeOut);
+
+            if (w_nRet != r)
+                return false;
+        }
+
+        return true;
+    }
+
+    private boolean UsbBulkReceive(byte[] pBuf, int nLen, int nTimeOut)
+    {
+        int i, n, r, w_nRet;
+        //byte[] w_abyTmp = new byte[m_nEPInSize];
+
+        //w_nRet = m_usbConn.bulkTransfer(m_epIN, pBuf, nLen, nTimeOut);
+
+        //if (w_nRet != nLen)
+        //    return false;
+
+        n = nLen / m_nEPInSize;
+        r = nLen % m_nEPInSize;
+
+        //Toast.makeText(mApplicationContext, "UsbBulkReceive, Buf Len = " + pBuf.length, Toast.LENGTH_SHORT).show();
+
+        for(i=0; i<n; i++)
+        {
+            if(m_usbConn==null){
+                return false;
+            }
+            w_nRet = m_usbConn.bulkTransfer(m_epIN, m_abyTransferBuf, m_nEPInSize, nTimeOut);
+
+            if (w_nRet != m_nEPInSize)
+                return false;
+
+            System.arraycopy(m_abyTransferBuf, 0, pBuf, i*m_nEPInSize, m_nEPInSize);
+        }
+
+        if (r > 0)
+        {
+            if(m_usbConn==null){
+                return false;
+            }
+            w_nRet = m_usbConn.bulkTransfer(m_epIN, m_abyTransferBuf, r, nTimeOut);
+
+            if (w_nRet != r)
+                return false;
+
+            System.arraycopy(m_abyTransferBuf, 0, pBuf, i*m_nEPInSize, r);
+        }
+
+        return true;
+    }
+
+    // END MAIN LOOP
+    private BroadcastReceiver mPermissionReceiver = new PermissionReceiver(
+            new IPermissionListener() {
+                @Override
+                public void onPermissionDenied(UsbDevice d) {
+                    l("Permission denied on " + d.getDeviceId());
+                }
+            });
+
+    private static interface IPermissionListener {
+        void onPermissionDenied(UsbDevice d);
+    }
+
+    public final static String TAG = "USBController";
+
+    private void l(Object msg) {
+        Log.d(TAG, ">==< " + msg.toString() + " >==<");
+    }
+}
diff --git a/keyCabinet-android/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/arm64-v8a/libserial_port.so
new file mode 100644
index 0000000..d1ae2f7
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/arm64-v8a/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/armeabi-v7a/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/armeabi-v7a/libserial_port.so
new file mode 100644
index 0000000..4faa9a7
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/armeabi-v7a/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/armeabi/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/armeabi/libserial_port.so
new file mode 100644
index 0000000..252e703
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/armeabi/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/mips/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/mips/libserial_port.so
new file mode 100644
index 0000000..7b1b9e9
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/mips/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/mips64/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/mips64/libserial_port.so
new file mode 100644
index 0000000..aea7352
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/mips64/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/x86/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/x86/libserial_port.so
new file mode 100644
index 0000000..51f5f4c
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/x86/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/jniLibs/x86_64/libserial_port.so b/keyCabinet-android/app/src/main/jniLibs/x86_64/libserial_port.so
new file mode 100644
index 0000000..a454958
--- /dev/null
+++ b/keyCabinet-android/app/src/main/jniLibs/x86_64/libserial_port.so
Binary files differ
diff --git a/keyCabinet-android/app/src/main/res/drawable/shape_f8_r15_bg.xml b/keyCabinet-android/app/src/main/res/drawable/shape_f8_r15_bg.xml
new file mode 100644
index 0000000..802163f
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/drawable/shape_f8_r15_bg.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle"
+    >
+    <solid android:color="#fff8f8f8" />
+    <corners android:radius="15dp" />
+</shape>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/chose_activation_activity.xml b/keyCabinet-android/app/src/main/res/layout/chose_activation_activity.xml
new file mode 100644
index 0000000..ef78ae5
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/chose_activation_activity.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout >
+    <data>
+        <import type="com.doumee.lib_coremodel.base.BaseViewModel"/>
+        <import type="android.view.View"/>
+        <variable
+            name="model"
+            type="com.doumee.keyCabinet.ui.face.ChoseActivationVM" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.face.ChoseActivationActivity">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="閫夋嫨婵�娲绘柟寮�"
+            android:textColor="#ff111111"
+            android:textSize="33sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="30dp"/>
+
+        <TextView
+            android:id="@+id/tv_zx"
+            android:layout_width="match_parent"
+            android:layout_height="75dp"
+            android:text="鍦ㄧ嚎婵�娲�"
+            android:textColor="@color/white"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            android:gravity="center"
+            android:background="@drawable/shape_mb_bt_ok"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:commandType="@{1}"
+            app:onClickCommand="@{model.myTypeCommand}"
+            android:layout_marginBottom="30dp"/>
+
+        <TextView
+            android:id="@+id/tv_km"
+            android:layout_width="match_parent"
+            android:layout_height="75dp"
+            android:text="绂荤嚎婵�娲�"
+            android:textColor="@color/white"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            android:gravity="center"
+            android:background="@drawable/shape_mb_bt_ok"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            app:layout_constraintTop_toBottomOf="@+id/tv_zx"
+            android:layout_marginTop="60dp"
+            app:commandType="@{2}"
+            app:onClickCommand="@{model.myTypeCommand}"
+            android:layout_marginBottom="30dp"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/chose_fun_activity.xml b/keyCabinet-android/app/src/main/res/layout/chose_fun_activity.xml
new file mode 100644
index 0000000..b2e6919
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/chose_fun_activity.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout >
+    <data>
+        <import type="com.doumee.lib_coremodel.base.BaseViewModel"/>
+        <variable
+            name="model"
+            type="com.doumee.keyCabinet.ui.keyCabinet.ChoseFunVM" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.keyCabinet.ChoseFunActivity">
+
+        <TextView
+            android:id="@+id/tv_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="棣栭〉"
+            android:textColor="#ff111111"
+            android:textSize="33sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="30dp"/>
+
+        <View
+            android:id="@+id/bg_qu"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:background="@drawable/shape_main_qu"
+            app:layout_constraintTop_toTopOf="@+id/img_qu"
+            android:layout_marginTop="-36dp"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toLeftOf="@+id/bg_huan"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            app:layout_constraintBottom_toBottomOf="@+id/tv5"
+            android:layout_marginBottom="-36dp"
+            app:commandType="@{2}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+        <ImageView
+            android:id="@+id/img_qu"
+            android:layout_width="140dp"
+            android:layout_height="140dp"
+            android:src="@mipmap/ic_guigeguanli"
+            app:layout_constraintTop_toBottomOf="@+id/tv_title"
+            android:layout_marginTop="120dp"
+            app:layout_constraintStart_toStartOf="@+id/bg_qu"
+            app:layout_constraintEnd_toEndOf="@+id/bg_qu"/>
+
+        <TextView
+            android:id="@+id/tv5"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="鏌滄牸绠$悊"
+            android:textColor="#222222"
+            android:textSize="27sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toBottomOf="@+id/img_qu"
+            android:layout_marginTop="12dp"
+            app:layout_constraintStart_toStartOf="@+id/img_qu"
+            app:layout_constraintEnd_toEndOf="@+id/img_qu"/>
+
+        <View
+            android:id="@+id/bg_huan"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:background="@drawable/shape_main_huan"
+            app:layout_constraintTop_toTopOf="@+id/img_huan"
+            android:layout_marginTop="-36dp"
+            app:layout_constraintLeft_toRightOf="@+id/bg_qu"
+            app:layout_constraintRight_toRightOf="parent"
+            android:layout_marginRight="30dp"
+            app:layout_constraintBottom_toBottomOf="@+id/tv6"
+            android:layout_marginBottom="-36dp"
+            app:commandType="@{3}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+        <ImageView
+            android:id="@+id/img_huan"
+            android:layout_width="140dp"
+            android:layout_height="140dp"
+            android:src="@mipmap/ic_zhiwenguanli"
+            app:layout_constraintTop_toTopOf="@+id/img_qu"
+            app:layout_constraintStart_toStartOf="@+id/bg_huan"
+            app:layout_constraintEnd_toEndOf="@+id/bg_huan"/>
+
+        <TextView
+            android:id="@+id/tv6"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="鎸囩汗绠$悊"
+            android:textColor="#222222"
+            android:textSize="27sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toBottomOf="@+id/img_huan"
+            android:layout_marginTop="12dp"
+            app:layout_constraintStart_toStartOf="@+id/img_huan"
+            app:layout_constraintEnd_toEndOf="@+id/img_huan"/>
+
+        <TextView
+            android:id="@+id/tv_all_open"
+            android:layout_width="match_parent"
+            android:layout_height="75dp"
+            android:text="閫�鍑虹櫥褰�"
+            android:textStyle="bold"
+            android:gravity="center"
+            android:textColor="#ff279baa"
+            android:textSize="24sp"
+            android:paddingLeft="30dp"
+            android:paddingRight="30dp"
+            android:background="@drawable/shape_mb_bg01"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_marginBottom="30dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:commandType="@{1}"
+            app:onClickCommand="@{model.myTypeCommand}"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/item_usb_device.xml b/keyCabinet-android/app/src/main/res/layout/item_usb_device.xml
new file mode 100644
index 0000000..499ba9f
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/item_usb_device.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/cl_root"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="24dp"
+        android:background="@drawable/shape_f8_r15_bg">
+
+        <TextView
+            android:id="@+id/device_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="1111"
+            android:textColor="#ff333333"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:layout_marginLeft="22dp"/>
+
+        <TextView
+            android:id="@+id/device_info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="222"
+            android:textColor="#ff279baa"
+            android:textSize="21sp"
+            app:layout_constraintTop_toBottomOf="@+id/device_name"
+            app:layout_constraintStart_toStartOf="@+id/device_name"/>
+
+        <Button
+            android:id="@+id/permission_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="鑾峰彇鏉冮檺"
+            android:textColor="#ff666666"
+            android:textSize="21sp"
+            app:layout_constraintTop_toBottomOf="@+id/device_info"
+            app:layout_constraintStart_toStartOf="parent"
+            android:layout_marginRight="16dp"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="@color/line"
+            app:layout_constraintTop_toBottomOf="@+id/permission_button"
+            android:layout_marginTop="24dp"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
diff --git a/keyCabinet-android/app/src/main/res/layout/manage_cabinet_activity.xml b/keyCabinet-android/app/src/main/res/layout/manage_cabinet_activity.xml
index e2655a4..f1ed265 100644
--- a/keyCabinet-android/app/src/main/res/layout/manage_cabinet_activity.xml
+++ b/keyCabinet-android/app/src/main/res/layout/manage_cabinet_activity.xml
@@ -28,6 +28,42 @@
             app:layout_constraintEnd_toEndOf="parent"
             android:layout_marginTop="30dp"/>
 
+        <View
+            android:id="@+id/viewBack"
+            android:layout_width="0dp"
+            android:layout_height="60dp"
+            app:layout_constraintTop_toTopOf="parent"
+            android:layout_marginTop="22dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="@+id/tv_back"
+            android:layout_marginRight="-22dp"
+            android:background="@drawable/shape_r20_back"
+            app:commandType="@{1}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+        <ImageView
+            android:id="@+id/im_back"
+            android:layout_width="14dp"
+            android:layout_height="22dp"
+            android:src="@mipmap/ic_back"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintStart_toStartOf="@+id/viewBack"
+            android:layout_marginLeft="22dp"/>
+
+        <TextView
+            android:id="@+id/tv_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="杩斿洖"
+            android:textStyle="bold"
+            android:textColor="#ffffffff"
+            android:textSize="26sp"
+            android:layout_marginLeft="6dp"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintLeft_toRightOf="@+id/im_back"/>
+
         <TextView
             android:id="@+id/tv1"
             android:layout_width="wrap_content"
@@ -37,7 +73,7 @@
             android:textSize="22sp"
             app:layout_constraintTop_toTopOf="@+id/tv_title"
             app:layout_constraintBottom_toBottomOf="@+id/tv_title"
-            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
             android:layout_marginLeft="30dp"/>
 
         <TextView
@@ -49,24 +85,6 @@
             android:textSize="22sp"
             app:layout_constraintTop_toTopOf="@+id/tv1"
             app:layout_constraintStart_toEndOf="@+id/tv1"/>
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="閫�鍑虹櫥褰�"
-            android:textColor="#ff279baa"
-            android:textSize="22sp"
-            app:layout_constraintEnd_toEndOf="parent"
-            android:paddingTop="7dp"
-            android:paddingBottom="7dp"
-            android:paddingLeft="15dp"
-            android:paddingRight="15dp"
-            android:background="@drawable/shape_r45_tc_bg"
-            app:layout_constraintTop_toTopOf="@+id/tv_title"
-            app:layout_constraintBottom_toBottomOf="@+id/tv_title"
-            app:commandType="@{1}"
-            app:onClickCommand="@{model.myTypeCommand}"
-            android:layout_marginRight="30dp"/>
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/cl_1"
diff --git a/keyCabinet-android/app/src/main/res/layout/offline_activation_activity.xml b/keyCabinet-android/app/src/main/res/layout/offline_activation_activity.xml
new file mode 100644
index 0000000..30da852
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/offline_activation_activity.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout >
+    <data>
+        <import type="com.doumee.lib_coremodel.base.BaseViewModel"/>
+        <import type="android.view.View"/>
+        <variable
+            name="model"
+            type="com.doumee.keyCabinet.ui.face.OfflineActivationVM" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.face.OfflineActivationActivity">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <!--绂荤嚎婵�娲�-->
+            <RelativeLayout
+                android:layout_marginTop="@dimen/start_15"
+                android:id="@+id/accredit_offRl"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <LinearLayout
+                    android:id="@+id/accredit_Ll"
+                    android:layout_marginRight="49.3dp"
+                    android:layout_marginLeft="49.3dp"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_centerHorizontal="true"
+                    android:background="@drawable/bg_round_import"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:textSize="20sp"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="20dp"
+                        android:layout_marginTop="@dimen/start_15"
+                        android:text="@string/off_technological_process"
+                        android:textColor="#999999" />
+
+                    <RelativeLayout
+                        android:layout_marginTop="@dimen/start_15"
+                        android:orientation="horizontal"
+                        android:layout_marginRight="20dp"
+                        android:layout_marginLeft="20dp"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            android:id="@+id/activity_hintOne"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="涓�"
+                            android:textColor="#ffffff"
+                            android:textSize="20sp" />
+
+                        <TextView
+                            android:layout_marginLeft="5dp"
+                            android:layout_toRightOf="@+id/activity_hintOne"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="@string/off_technological_process_one"
+                            android:textColor="#ffffff"
+                            android:textSize="18sp" />
+                    </RelativeLayout>
+                    <RelativeLayout
+                        android:layout_marginTop="@dimen/start_10"
+                        android:orientation="horizontal"
+                        android:layout_marginRight="20dp"
+                        android:layout_marginLeft="20dp"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            android:id="@+id/activity_hintTwo"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="浜�"
+                            android:textColor="#ffffff"
+                            android:textSize="20sp" />
+
+                        <TextView
+                            android:layout_marginLeft="5dp"
+                            android:layout_toRightOf="@+id/activity_hintTwo"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="@string/off_technological_process_two"
+                            android:textColor="#ffffff"
+                            android:textSize="18sp" />
+                    </RelativeLayout>
+                    <RelativeLayout
+                        android:layout_marginTop="@dimen/start_10"
+                        android:orientation="horizontal"
+                        android:layout_marginRight="20dp"
+                        android:layout_marginLeft="20dp"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            android:id="@+id/activity_hintThree"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="涓�"
+                            android:textColor="#ffffff"
+                            android:textSize="20sp" />
+
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginLeft="5dp"
+                            android:layout_toRightOf="@+id/activity_hintThree"
+                            android:text="@string/off_technological_process_three"
+                            android:textColor="#ffffff"
+                            android:textSize="18sp" />
+                    </RelativeLayout>
+                    <RelativeLayout
+                        android:layout_marginTop="@dimen/start_10"
+                        android:orientation="horizontal"
+                        android:layout_marginRight="20dp"
+                        android:layout_marginLeft="20dp"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            android:id="@+id/activity_hintFour"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="鍥�"
+                            android:textColor="#ffffff"
+                            android:textSize="20sp" />
+
+                        <TextView
+                            android:layout_marginLeft="5dp"
+                            android:layout_toRightOf="@+id/activity_hintFour"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="@string/off_technological_process_four"
+                            android:textColor="#ffffff"
+                            android:textSize="18sp" />
+                    </RelativeLayout>
+                    <RelativeLayout
+                        android:layout_marginTop="@dimen/start_10"
+                        android:orientation="horizontal"
+                        android:layout_marginRight="20dp"
+                        android:layout_marginLeft="20dp"
+                        android:layout_marginBottom="@dimen/start_15"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            android:id="@+id/activity_hintFive"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="浜�"
+                            android:textColor="#ffffff"
+                            android:textSize="20sp" />
+
+                        <TextView
+                            android:layout_marginLeft="5dp"
+                            android:layout_toRightOf="@+id/activity_hintFive"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="@string/off_technological_process_five"
+                            android:textColor="#ffffff"
+                            android:textSize="18sp" />
+                    </RelativeLayout>
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/accredit_setTv"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/accredit_Ll"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginTop="30dp"
+                    android:text="@string/off_local_hardware"
+                    android:textColor="#666666"
+                    android:textSize="20sp" />
+
+                <TextView
+                    android:textSize="20sp"
+                    android:id="@+id/accredit_deviceTv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/accredit_setTv"
+                    android:layout_marginTop="20dp"
+                    android:gravity="center"
+                    android:textColor="@color/black" />
+
+                <View
+                    android:id="@+id/aaccredit_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:layout_below="@+id/accredit_deviceTv"
+                    android:layout_marginLeft="50dp"
+                    android:layout_marginTop="10dp"
+                    android:layout_marginRight="50dp"
+                    android:background="#222222" />
+
+                <TextView
+                    android:layout_marginLeft="49.3dp"
+                    android:layout_marginRight="49.3dp"
+                    android:textSize="@dimen/bottom_font"
+                    android:id="@+id/accredit_hintTv"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/aaccredit_view"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginTop="@dimen/activition_14"
+                    android:textColor="#F34B56" />
+
+                <Button
+                    android:padding="13dp"
+                    android:id="@+id/accredit_offBtn"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/accredit_hintTv"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginLeft="@dimen/activition_49"
+                    android:layout_marginTop="13dp"
+                    android:layout_marginRight="@dimen/activition_49"
+                    android:background="@mipmap/btn_less_normal"
+                    android:text="@string/accredit_off"
+                    android:textColor="@color/white"
+                    android:textSize="@dimen/activition_18_sp" />
+
+                <Button
+                    android:padding="13dp"
+                    android:id="@+id/btn_down"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@+id/accredit_offBtn"
+                    android:layout_centerHorizontal="true"
+                    android:layout_marginLeft="@dimen/activition_49"
+                    android:layout_marginTop="13dp"
+                    android:layout_marginRight="@dimen/activition_49"
+                    android:background="@mipmap/btn_less_normal"
+                    android:text="涓嬭浇婵�娲绘枃浠�"
+                    android:textColor="@color/white"
+                    android:textSize="@dimen/activition_18_sp"/>
+            </RelativeLayout>
+        </ScrollView>
+
+        <TextView
+            android:id="@+id/tv_id"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="NO锛�"
+            android:textColor="#ffaaaaaa"
+            android:textSize="18sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:layout_marginLeft="30dp"
+            android:layout_marginBottom="22dp"
+            />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/zwlist_activity.xml b/keyCabinet-android/app/src/main/res/layout/zwlist_activity.xml
new file mode 100644
index 0000000..e8ec4c2
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/zwlist_activity.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout >
+    <data>
+        <import type="com.doumee.lib_coremodel.base.BaseViewModel"/>
+        <variable
+            name="model"
+            type="com.doumee.keyCabinet.ui.keyCabinet.ZWListVM" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.keyCabinet.ZWListActivity"
+        android:background="@color/white">
+
+
+        <View
+            android:id="@+id/viewBack"
+            android:layout_width="0dp"
+            android:layout_height="60dp"
+            app:layout_constraintTop_toTopOf="parent"
+            android:layout_marginTop="22dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="@+id/tv_back"
+            android:layout_marginRight="-22dp"
+            android:background="@drawable/shape_r20_back"
+            app:onClickCommand="@{model.backOnClickCommand}"/>
+
+        <ImageView
+            android:id="@+id/im_back"
+            android:layout_width="14dp"
+            android:layout_height="22dp"
+            android:src="@mipmap/ic_back"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintStart_toStartOf="@+id/viewBack"
+            android:layout_marginLeft="22dp"/>
+
+        <TextView
+            android:id="@+id/tv_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="杩斿洖"
+            android:textStyle="bold"
+            android:textColor="#ffffffff"
+            android:textSize="26sp"
+            android:layout_marginLeft="6dp"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintLeft_toRightOf="@+id/im_back"/>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="鎸囩汗绠$悊"
+            android:textColor="#ff111111"
+            android:textSize="33sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_marginTop="14dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"/>
+
+        <ImageView
+            android:id="@+id/im_empty"
+            android:layout_width="300dp"
+            android:layout_height="300dp"
+            android:src="@mipmap/default_nodata"
+            app:layout_constraintTop_toTopOf="@+id/recycler_view"
+            app:layout_constraintBottom_toBottomOf="@+id/recycler_view"
+            app:layout_constraintStart_toStartOf="@+id/recycler_view"
+            app:layout_constraintEnd_toEndOf="@+id/recycler_view"
+            android:visibility="@{model.emptyVisibility}"/>
+
+        <LinearLayout
+            android:id="@+id/deviceListLayout"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_marginTop="14dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            android:orientation="vertical"
+            android:visibility="visible"/>
+
+        <Button
+            android:id="@+id/bt_con"
+            android:layout_width="200dp"
+            android:layout_height="70dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:text="姣旇緝"
+            android:textSize="30sp"
+            app:commandType="@{5}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/zwlist_rcv_item.xml b/keyCabinet-android/app/src/main/res/layout/zwlist_rcv_item.xml
new file mode 100644
index 0000000..42bfb52
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/zwlist_rcv_item.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:app="http://schemas.android.com/apk/res-auto">
+    <data>
+        <variable
+            name="data"
+            type="com.doumee.keyCabinet.bean.FingerPrintVo" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/cl_root"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="24dp"
+        >
+
+        <com.facebook.drawee.view.SimpleDraweeView
+            android:id="@+id/sim"
+            android:layout_width="75dp"
+            android:layout_height="75dp"
+            app:roundAsCircle="true"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            style="@style/sim_head"
+            />
+
+        <TextView
+            android:id="@+id/tv_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@{data.memberName}"
+            android:textColor="#ff333333"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="@+id/sim"
+            app:layout_constraintStart_toEndOf="@+id/sim"
+            android:layout_marginLeft="22dp"/>
+
+        <TextView
+            android:id="@+id/tv_gw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text=""
+            android:textColor="#ff279baa"
+            android:textSize="21sp"
+            app:layout_constraintBottom_toBottomOf="@+id/sim"
+            app:layout_constraintStart_toStartOf="@+id/tv_name"/>
+
+        <TextView
+            android:id="@+id/tv_num"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="宸查噰闆嗘寚绾癸細0"
+            android:textColor="#ff666666"
+            android:textSize="21sp"
+            app:layout_constraintTop_toTopOf="@+id/sim"
+            app:layout_constraintBottom_toBottomOf="@+id/sim"
+            app:layout_constraintEnd_toStartOf="@+id/img1"
+            android:layout_marginRight="16dp"/>
+
+        <ImageView
+            android:id="@+id/img1"
+            android:layout_width="15dp"
+            android:layout_height="27dp"
+            android:src="@mipmap/design_ic_ar"
+            app:layout_constraintTop_toTopOf="@+id/sim"
+            app:layout_constraintBottom_toBottomOf="@+id/sim"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="@color/line"
+            app:layout_constraintTop_toBottomOf="@+id/sim"
+            android:layout_marginTop="24dp"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/keyCabinet-android/app/src/main/res/layout/zwlr_activity.xml b/keyCabinet-android/app/src/main/res/layout/zwlr_activity.xml
new file mode 100644
index 0000000..96afbc5
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/zwlr_activity.xml
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout >
+    <data>
+        <import type="com.doumee.lib_coremodel.base.BaseViewModel"/>
+        <variable
+            name="model"
+            type="com.doumee.keyCabinet.ui.keyCabinet.ZWLRVM" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.keyCabinet.ZWLRActivity"
+        android:background="@color/white">
+
+
+        <View
+            android:id="@+id/viewBack"
+            android:layout_width="0dp"
+            android:layout_height="60dp"
+            app:layout_constraintTop_toTopOf="parent"
+            android:layout_marginTop="22dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="@+id/tv_back"
+            android:layout_marginRight="-22dp"
+            android:background="@drawable/shape_r20_back"
+            app:onClickCommand="@{model.backOnClickCommand}"/>
+
+        <ImageView
+            android:id="@+id/im_back"
+            android:layout_width="14dp"
+            android:layout_height="22dp"
+            android:src="@mipmap/ic_back"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintStart_toStartOf="@+id/viewBack"
+            android:layout_marginLeft="22dp"/>
+
+        <TextView
+            android:id="@+id/tv_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="杩斿洖"
+            android:textStyle="bold"
+            android:textColor="#ffffffff"
+            android:textSize="26sp"
+            android:layout_marginLeft="6dp"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintLeft_toRightOf="@+id/im_back"/>
+
+        <TextView
+            android:id="@+id/tv_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="鎸囩汗绠$悊"
+            android:textColor="#ff111111"
+            android:textSize="33sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/viewBack"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <TextView
+            android:id="@+id/tv_djs"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="59s"
+            android:textColor="#ff279baa"
+            android:textSize="24sp"
+            app:layout_constraintTop_toTopOf="parent"
+            android:layout_marginTop="33dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginRight="30dp"
+            android:visibility="gone"/>
+
+        <View
+            android:id="@+id/hbg"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:background="@drawable/shape_f8_r15_bg"
+            app:layout_constraintTop_toBottomOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="@+id/sim"
+            android:layout_marginBottom="-22dp"
+            android:layout_marginTop="30dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"/>
+
+        <com.facebook.drawee.view.SimpleDraweeView
+            android:id="@+id/sim"
+            android:layout_width="84dp"
+            android:layout_height="84dp"
+            app:roundAsCircle="true"
+            app:layout_constraintStart_toStartOf="@+id/hbg"
+            app:layout_constraintTop_toTopOf="@+id/hbg"
+            style="@style/sim_head"
+            android:layout_marginLeft="22dp"
+            android:layout_marginTop="22dp"
+            />
+
+        <TextView
+            android:id="@+id/tv_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text=""
+            android:textColor="#ff333333"
+            android:textSize="27sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="@+id/sim"
+            app:layout_constraintBottom_toBottomOf="@+id/sim"
+            app:layout_constraintStart_toEndOf="@+id/sim"
+            android:layout_marginLeft="18dp"/>
+
+        <TextView
+            android:id="@+id/tv1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="宸叉湁鎸囩汗"
+            android:textColor="#ff111111"
+            android:textSize="27sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toBottomOf="@+id/hbg"
+            android:layout_marginTop="30dp"
+            app:layout_constraintStart_toStartOf="parent"
+            android:layout_marginLeft="30dp"/>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@+id/tv1"
+            app:layout_constraintBottom_toTopOf="@+id/tv_add"
+            android:layout_marginTop="8dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"
+            android:layout_marginBottom="30dp"/>
+
+        <ImageView
+            android:id="@+id/im_empty"
+            android:layout_width="300dp"
+            android:layout_height="300dp"
+            android:src="@mipmap/default_nodata"
+            app:layout_constraintTop_toTopOf="@+id/recycler_view"
+            app:layout_constraintBottom_toBottomOf="@+id/recycler_view"
+            app:layout_constraintStart_toStartOf="@+id/recycler_view"
+            app:layout_constraintEnd_toEndOf="@+id/recycler_view"
+            android:visibility="@{model.emptyVisibility}"/>
+
+        <TextView
+            android:id="@+id/tv_add"
+            android:layout_width="match_parent"
+            android:layout_height="75dp"
+            android:text="鏂板鎸囩汗"
+            android:textColor="@color/white"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            android:gravity="center"
+            android:background="@drawable/shape_r25_blue_bg"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:commandType="@{1}"
+            app:onClickCommand="@{model.myTypeCommand}"
+            android:layout_marginBottom="30dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginRight="30dp"/>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_zw"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:layout_marginTop="30dp"
+            android:background="@color/white"
+            android:visibility="gone">
+
+            <TextView
+                android:id="@+id/tv_lr"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="鎸囩汗褰曞叆"
+                android:textColor="#ff111111"
+                android:textSize="33sp"
+                android:textStyle="bold"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+
+            <View
+                android:id="@+id/v_c_zw"
+                android:layout_width="340dp"
+                android:layout_height="340dp"
+                android:background="@mipmap/ic_zhiwenyanzheng"
+                app:layout_constraintTop_toBottomOf="@+id/tv_lr"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_marginTop="39dp"
+                />
+
+            <TextView
+                android:id="@+id/tv_zw_tip"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:text="璇峰皢鎵嬫寚鏀剧疆鍦ㄦ寚绾归噰闆嗗櫒涓婅繘琛屽綍鍏�"
+                android:textColor="#ff666666"
+                android:textSize="24sp"
+                android:gravity="center"
+                app:layout_constraintTop_toBottomOf="@+id/v_c_zw"
+                android:layout_marginTop="39dp"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_tip"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@+id/viewBack"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_marginTop="30dp"
+            android:background="@color/white"
+            android:visibility="gone">
+
+            <ImageView
+                android:id="@+id/img_jg1"
+                android:layout_width="150dp"
+                android:layout_height="150dp"
+                app:layout_constraintTop_toTopOf="parent"
+                android:layout_marginTop="60dp"
+                android:src="@mipmap/ic_jjfail"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <TextView
+                android:id="@+id/tv_jg1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="鎸囩汗褰曞叆澶辫触锛岃閲嶆柊褰曞叆"
+                android:textColor="#ff111111"
+                android:textSize="33sp"
+                android:gravity="center"
+                android:textStyle="bold"
+                app:layout_constraintTop_toBottomOf="@+id/img_jg1"
+                android:layout_marginTop="36dp"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <TextView
+                android:id="@+id/tv_jg2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="濡傛湁闂璇疯仈绯荤鐞嗗憳"
+                android:textColor="#ff666666"
+                android:textSize="24sp"
+                app:layout_constraintTop_toBottomOf="@+id/tv_jg1"
+                android:layout_marginTop="22dp"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="75dp"
+                android:text="閲嶆柊褰曞叆"
+                android:textColor="@color/white"
+                android:textSize="24sp"
+                android:textStyle="bold"
+                android:gravity="center"
+                android:background="@drawable/shape_r25_blue_bg"
+                android:layout_marginLeft="30dp"
+                android:layout_marginRight="30dp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:commandType="@{1}"
+                app:onClickCommand="@{model.myTypeCommand}"
+                android:layout_marginBottom="30dp"/>
+
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_Ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="@drawable/shape_jiujin_ok"
+            android:paddingLeft="40dp"
+            android:paddingRight="40dp"
+            android:paddingTop="50dp"
+            android:paddingBottom="50dp"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:visibility="gone">
+
+            <ImageView
+                android:id="@+id/img_jiu"
+                android:layout_width="45dp"
+                android:layout_height="45dp"
+                android:src="@mipmap/ic_pass"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="褰曞叆鎴愬姛"
+                android:textColor="#ffffffff"
+                android:textSize="33sp"
+                app:layout_constraintTop_toBottomOf="@+id/img_jiu"
+                android:layout_marginTop="10dp"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.core.widget.NestedScrollView
+            android:id="@+id/nsv"
+            android:layout_width="match_parent"
+            android:layout_height="700dp"
+            app:layout_constraintTop_toTopOf="parent"
+            android:background="@color/white"
+            android:visibility="gone">
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    app:layout_constraintTop_toTopOf="parent"
+                    android:text="@{model.infoObs}"
+                    android:textColor="@color/black"
+                    android:textSize="20sp">
+
+                </TextView>
+
+
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+        </androidx.core.widget.NestedScrollView>
+
+        <TextView
+            android:id="@+id/tv11"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="娓呯┖"
+            android:textColor="#ff279baa"
+            android:textSize="20sp"
+            android:textStyle="bold"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:commandType="@{55}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+        <Button
+            android:id="@+id/bt_con"
+            android:layout_width="100dp"
+            android:layout_height="70dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:text="鏃ュ織"
+            android:textSize="30sp"
+            app:commandType="@{5}"
+            app:onClickCommand="@{model.myTypeCommand}"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/keyCabinet-android/app/src/main/res/layout/zwlr_rcv_item.xml b/keyCabinet-android/app/src/main/res/layout/zwlr_rcv_item.xml
new file mode 100644
index 0000000..4b6fb93
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/layout/zwlr_rcv_item.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:app="http://schemas.android.com/apk/res-auto">
+    <data>
+        <variable
+            name="data"
+            type="com.doumee.keyCabinet.dao.FingerPrintDo" />
+    </data>
+    <androidx.constraintlayout.widget.ConstraintLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/cl_root"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
+        <TextView
+            android:id="@+id/tv_pos"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text=""
+            android:textColor="#ff333333"
+            android:textSize="27sp"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:layout_marginTop="22dp"
+            />
+        
+        <ImageView
+            android:id="@+id/img_close"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:src="@mipmap/ic_delete"/>
+        
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="@color/line"
+            app:layout_constraintTop_toBottomOf="@+id/tv_pos"
+            android:layout_marginTop="22dp"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/design_ic_ar.png b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/design_ic_ar.png
new file mode 100644
index 0000000..842ff77
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/design_ic_ar.png
Binary files differ
diff --git a/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_delete.png b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_delete.png
new file mode 100644
index 0000000..73ea0ba
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_delete.png
Binary files differ
diff --git a/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_guigeguanli.png b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_guigeguanli.png
new file mode 100644
index 0000000..3698a13
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_guigeguanli.png
Binary files differ
diff --git a/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenguanli.png b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenguanli.png
new file mode 100644
index 0000000..4d751c1
--- /dev/null
+++ b/keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenguanli.png
Binary files differ
diff --git a/keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java b/keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java
index 8d799f8..59b3a17 100644
--- a/keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java
+++ b/keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java
@@ -1,5 +1,7 @@
 package com.doumee.ticketmachine;
 
+import android.text.TextUtils;
+
 import com.doumee.keyCabinet.MApplication;
 import com.doumee.keyCabinet.utils.CircularQueue;
 import com.doumee.keyCabinet.utils.i485.SportUtils;
diff --git a/keyCabinet-android/build.gradle b/keyCabinet-android/build.gradle
index 08079a6..944862a 100644
--- a/keyCabinet-android/build.gradle
+++ b/keyCabinet-android/build.gradle
@@ -10,6 +10,7 @@
         maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
         maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
         maven { url 'https://dl.bintray.com/hpdx/maven/' }
+        maven { url "https://jitpack.io" }
         google()
         jcenter()
     }

--
Gitblit v1.9.3