weimingfei
11 小时以前 8ff90d87687b6d38158809aae776b6c709d7b60a
指纹钥匙柜
已添加10个文件
已修改34个文件
1545 ■■■■ 文件已修改
keyCabinet-android/app/build.gradle 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/libs/enjoySDK.aar 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/AndroidManifest.xml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/DevConfigBean.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/KeyCabinetBean.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/KeyResultEvent.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/Apis.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/BatchOpenGridAdminParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/OpenGridDriverParam.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/SyncGridDataParam.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/ChoseActivationActivity.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/ChoseActivationVM.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/OfflineActivationActivity.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/OfflineActivationVM.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/UserManagerActivity.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/guide/TestActivity.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChangeUrlActivity.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/KeyCabinetActivity.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/KeyCabinetVM.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageCabinetActivity.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageCabinetVM.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java 164 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/BraceletLogUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/MCUtils.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/update/FileUtil.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/layout/change_url_activity.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/layout/face_activity.xml 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/layout/key_cabinet_activity.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/layout/main_activity.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwen.png 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenluru.png 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenyanzheng.png 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/res/values/strings.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/datalibrary/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/facelibrary/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/lib_opensource/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/settinglibrary/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/versions.gradle 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/build.gradle
@@ -10,8 +10,8 @@
        applicationId "com.doumee.keyCabinet"
        minSdkVersion build_versions.min_sdk
        targetSdkVersion build_versions.target_sdk
        versionCode 2
        versionName "1.0.1"
        versionCode 5
        versionName "1.0.5"
        //支持vectorDrawables矢量图
        vectorDrawables.useSupportLibrary = true
@@ -108,7 +108,6 @@
    implementation project(path: ':settinglibrary')
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation files('libs\\simple-xml-2.7.1.jar')
    implementation files('libs\\API-20250310.jar')
    testImplementation deps.test.junit
    androidTestImplementation deps.test.ext_junit
    androidTestImplementation deps.test.test_espresso
keyCabinet-android/app/libs/enjoySDK.aar
Binary files differ
keyCabinet-android/app/src/main/AndroidManifest.xml
@@ -10,11 +10,16 @@
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="${network_security_config}"
        android:requestLegacyExternalStorage="true"
        android:supportsRtl="true"
        android:theme="@style/CustomAppTheme"
        android:usesCleartextTraffic="true"
        tools:replace="android:allowBackup">
        <activity
            android:name=".ui.face.ChoseActivationActivity"
            android:exported="false" />
        <activity
            android:name=".ui.face.OfflineActivationActivity"
            android:exported="false" />
        <activity
            android:name=".ui.keyCabinet.ChangeUrlActivity"
            android:exported="false" />
@@ -27,31 +32,30 @@
        <activity
            android:name=".ui.keyCabinet.KeyCabinetActivity"
            android:exported="false" />
        <activity android:name=".ui.guide.TestActivity">
        </activity>
        <activity android:name=".ui.guide.TestActivity" />
        <activity
            android:name="com.doumee.keyCabinet.ui.face.ErrActivity"
            android:name=".ui.face.ErrActivity"
            android:exported="false" />
        <activity
            android:name="com.doumee.keyCabinet.ui.face.UserManagerActivity"
            android:name=".ui.face.UserManagerActivity"
            android:exported="false" />
        <activity
            android:name="com.doumee.keyCabinet.ui.face.AddFaceActivity"
            android:name=".ui.face.AddFaceActivity"
            android:exported="false" />
        <activity
            android:name="com.doumee.keyCabinet.ui.face.ActivationActivity"
            android:name=".ui.face.ActivationActivity"
            android:exported="false" />
        <activity
            android:name="com.doumee.keyCabinet.ui.face.FaceActivity"
            android:name=".ui.face.FaceActivity"
            android:exported="false"
            android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>
        <activity
            android:name="com.doumee.keyCabinet.ui.main.MainActivity"
            android:name=".ui.main.MainActivity"
            android:exported="true"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
@@ -75,8 +79,8 @@
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
        <!--<receiver
        <!--
<receiver
            android:name="com.doumee.keyCabinet.ui.service.BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">
@@ -85,22 +89,25 @@
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>-->
        <!--<service android:name="com.doumee.keyCabinet.ui.service.HeartbeatService" />
        <service android:name="com.doumee.keyCabinet.ui.service.FaceUpdateService" />-->
        </receiver>
        -->
        <!--
<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" />
        <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.nfc" />
    <uses-permission android:name="android.permission.ACCESS_SURERUSER" />
    <uses-permission android:name="android.permission.USB_PERMISSION"/>
    <uses-feature android:name="android.hardware.usb.host"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.nfc" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -109,7 +116,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_PRIVILEGED_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"
@@ -120,7 +127,6 @@
    <uses-permission
        android:name="android.permission.INTERACT_ACROSS_USERS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission
        android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
@@ -128,6 +134,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.NFC" />
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/DevConfigBean.java
@@ -14,12 +14,16 @@
    private String devId;
    //是否双重验证 0否 1是
    private int doubleAuth;
    //酒精检测开启:0=开启;1=关闭
    private int  alcoholStatus;
    //主键
    private Integer id;
    //备注
    private String info;
    //设备名称
    private String name;
    //人脸识别离线激活文件下载地址
    private String activateFileUrl;
    private CabinetConfigDataBean cabinetConfigDataVO;
    private List<ManageKeyCabinetBean> cabinetGridInfoVOList;
@@ -103,4 +107,20 @@
    public void setCabinetConfigDataVO(CabinetConfigDataBean cabinetConfigDataVO) {
        this.cabinetConfigDataVO = cabinetConfigDataVO;
    }
    public String getActivateFileUrl() {
        return activateFileUrl;
    }
    public void setActivateFileUrl(String activateFileUrl) {
        this.activateFileUrl = activateFileUrl;
    }
    public int getAlcoholStatus() {
        return alcoholStatus;
    }
    public void setAlcoholStatus(int alcoholStatus) {
        this.alcoholStatus = alcoholStatus;
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/bean/KeyCabinetBean.java
@@ -41,6 +41,10 @@
    private Integer status;
    //运行状态 0正常 1故障
    private Integer workingStatus;
    //派车申请单主键
    private Integer carUseBookId;
    //取钥匙方式:0=随车;1=派车单;2=保洁打扫
    private Integer getKeyWay;
    private ObservableField<Boolean> isSelected = new ObservableField<>(false);
    private ObservableField<Integer> text1Color = new ObservableField<>(0xff111111);
@@ -185,4 +189,20 @@
    public ObservableField<Integer> getText2Color() {
        return text2Color;
    }
    public Integer getCarUseBookId() {
        return carUseBookId;
    }
    public void setCarUseBookId(Integer carUseBookId) {
        this.carUseBookId = carUseBookId;
    }
    public Integer getGetKeyWay() {
        return getKeyWay;
    }
    public void setGetKeyWay(Integer getKeyWay) {
        this.getKeyWay = getKeyWay;
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/event/KeyResultEvent.java
@@ -4,5 +4,19 @@
 * é’¥åŒ™ç›‘听返回
 */
public class KeyResultEvent {
    //1:1号板,2:2号板,3:两块板
    private String type;
    public KeyResultEvent(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/Apis.java
@@ -23,7 +23,7 @@
public interface Apis {
    //测试服
    //String HTTP = "http://192.168.1.45:10010/";
    String HTTP = "http://192.168.0.212/system_gateway/";
    String HTTP = "http://10.49.152.112/system_gateway/";
    String HEAT_HTTP = "do?c=220301";
    /**
     * æŸ¥è¯¢ç‰ˆæœ¬ä¿¡æ¯
@@ -44,6 +44,12 @@
     */
    @GET("visitsAdmin/cloudService/web/cabinet/updateRunStatusById")
    Observable<BaseResponse> heart(@Query("id")Integer id);
    /**
     * åŒæ­¥æŸœæ ¼å®žé™…钥匙数据
     */
    @POST("visitsAdmin/cloudService/web/cabinet/syncGridData")
    Observable<BaseResponse> syncGridData(@Body RequestBody requestBody);
    /**
     * ä¸Šä¼ æŠ¥é”™ä¿¡æ¯
@@ -128,6 +134,5 @@
     */
    @POST("loginCabinet")
    Observable<BaseResponse<String>> loginCabinet(@Body RequestBody requestBody);
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/BatchOpenGridAdminParam.java
@@ -7,6 +7,8 @@
    private Integer cabinetId;
    //柜格主键列表
    private List<Integer> gridIdList;
    //开启方式:0=系统开启;1=手动开启
    private int openType;
    public Integer getCabinetId() {
        return cabinetId;
@@ -23,4 +25,12 @@
    public void setGridIdList(List<Integer> gridIdList) {
        this.gridIdList = gridIdList;
    }
    public int getOpenType() {
        return openType;
    }
    public void setOpenType(int openType) {
        this.openType = openType;
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/OpenGridDriverParam.java
@@ -12,6 +12,13 @@
    private int cabinetId;
    //柜格主键
    private int gridId;
    //开启方式:0=系统开启;1=手动开启
    private int openType;
    //派车申请单主键
    private Integer carUseBookId;
    //取钥匙方式:0=随车;1=派车单;2=保洁打扫
    private Integer openWay;
    public int getAuthType() {
        return authType;
@@ -44,4 +51,28 @@
    public void setGridId(int gridId) {
        this.gridId = gridId;
    }
    public int getOpenType() {
        return openType;
    }
    public void setOpenType(int openType) {
        this.openType = openType;
    }
    public Integer getCarUseBookId() {
        return carUseBookId;
    }
    public void setCarUseBookId(Integer carUseBookId) {
        this.carUseBookId = carUseBookId;
    }
    public Integer getOpenWay() {
        return openWay;
    }
    public void setOpenWay(Integer openWay) {
        this.openWay = openWay;
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/http/param/SyncGridDataParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.doumee.keyCabinet.http.param;
import java.io.Serializable;
import java.util.List;
//同步柜格实际钥匙数据
public class SyncGridDataParam implements Serializable {
    //钥匙柜编号
    private String code;
    private List<GridDTO> gridDTOList;
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public List<GridDTO> getGridDTOList() {
        return gridDTOList;
    }
    public void setGridDTOList(List<GridDTO> gridDTOList) {
        this.gridDTOList = gridDTOList;
    }
    public static class GridDTO{
        //实际钥匙编码
        private String actualLable;
        //板号
        private String boardCode;
        //通道号
        private String channelCode;
        public String getActualLable() {
            return actualLable;
        }
        public void setActualLable(String actualLable) {
            this.actualLable = actualLable;
        }
        public String getBoardCode() {
            return boardCode;
        }
        public void setBoardCode(String boardCode) {
            this.boardCode = boardCode;
        }
        public String getChannelCode() {
            return channelCode;
        }
        public void setChannelCode(String channelCode) {
            this.channelCode = channelCode;
        }
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/ChoseActivationActivity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.doumee.keyCabinet.ui.face;
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.ChoseActivationActivityBinding;
import com.doumee.keyCabinet.utils.MCUtils;
import com.doumee.lib_coremodel.bean.event.ActionEventData;
import com.mc.enjoysdk.McSystemUi;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class ChoseActivationActivity extends MyBaseActivity<ChoseActivationVM, ChoseActivationActivityBinding> {
    @Override
    public int getLayoutId() {
        return R.layout.chose_activation_activity;
    }
    @Override
    public void initView(@Nullable Bundle savedInstanceState) {
        isToGuild = false;
        normalConfig();
        getDB().setModel(getVM());
        McSystemUi mcSystemUi = McSystemUi.getInstance(this);
        MCUtils.show(mcSystemUi);
    }
    @Override
    public void initData(@Nullable Bundle savedInstanceState) {
    }
    @Override
    protected void doRegister(int type, ActionEventData data) {
        switch (type){
            case 1:
                startActivity(ActivationActivity.class);
                finish();
                break;
            case 2:
                startActivity(OfflineActivationActivity.class);
                finish();
                break;
            default:
                break;
        }
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/ChoseActivationVM.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.doumee.keyCabinet.ui.face;
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 ChoseActivationVM extends DataViewModel {
    @ViewModelInject
    public ChoseActivationVM(@NonNull Application application, BaseModel model) {
        super(application, model);
    }
    @Override
    protected void clickByTypeCommand(int type) {
        doAction(type);
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java
@@ -121,6 +121,12 @@
    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);
@@ -137,14 +143,24 @@
                //取-管理员人脸验证
                getDB().tvTitle.setText("管理员身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.VISIBLE);
                setFaceModel(0);
                break;
            case 10:
                //取-管理员指纹验证
                getDB().tvTitle.setText("管理员身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.VISIBLE);
                setFaceModel(2);
                break;
            case 1:
                //取-管理员刷卡验证
                getDB().etEwm.setText("");
                getDB().tvTitle.setText("管理员身份验证");
                getDB().clFace.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clCard.setVisibility(View.VISIBLE);
                setFaceModel(2);
                break;
@@ -152,6 +168,7 @@
                //取-司机验证方式选择页
                getDB().tvTitle.setText("司机身份验证");
                getDB().clFace.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clCard.setVisibility(View.GONE);
                getDB().clTip1.setVisibility(View.GONE);
                getDB().clSjXuan.setVisibility(View.VISIBLE);
@@ -162,9 +179,19 @@
                //取-司机人脸验证
                getDB().tvTitle.setText("司机身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clSjXuan.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.VISIBLE);
                setFaceModel(1);
                break;
            case 11:
                //取-司机指纹验证
                getDB().tvTitle.setText("司机身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.GONE);
                getDB().clSjXuan.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.VISIBLE);
                setFaceModel(2);
                break;
            case 3:
                //取-司机刷卡验证
@@ -172,6 +199,7 @@
                getDB().etEwm.requestFocus();
                getDB().tvTitle.setText("司机身份验证");
                getDB().clFace.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clSjXuan.setVisibility(View.GONE);
                getDB().clCard.setVisibility(View.VISIBLE);
                setFaceModel(2);
@@ -181,6 +209,7 @@
                getDB().tvTitle.setText("酒精检测");
                getDB().clFace.setVisibility(View.GONE);
                getDB().clCard.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clSjXuan.setVisibility(View.GONE);
                getDB().clTip1.setVisibility(View.GONE);
                getDB().clJiu.setVisibility(View.VISIBLE);
@@ -206,8 +235,17 @@
                //还-司机人脸验证
                getDB().tvTitle.setText("司机身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.VISIBLE);
                setFaceModel(1);
                break;
            case 12:
                //还-司机人脸验证
                getDB().tvTitle.setText("司机身份验证");
                getDB().clCard.setVisibility(View.GONE);
                getDB().clFace.setVisibility(View.GONE);
                getDB().clZw.setVisibility(View.VISIBLE);
                setFaceModel(2);
                break;
            case 8:
                //还-司机刷卡验证
@@ -249,15 +287,37 @@
    protected void doRegister(int type, ActionEventData data) {
        switch (type){
            case 1:
                //切换到刷卡
                if(flag==0){
                    if(status==0){
                    //切换到管理员刷卡
                    if(status==0||status==10){
                        statusFsm(1);
                    }else if(status==2){
                    }else if(status==2||status==11){
                        statusFsm(3);
                    }
                }else {
                    //还-司机刷卡验证
                    statusFsm(8);
                }
                break;
            case 9:
                //管理员指纹验证
                statusFsm(10);
                break;
            case 10:
                //司机指纹验证
                statusFsm(11);
                break;
            case 11:
                //刷卡-->指纹验证
                if(flag==0){
                    if(status==1){
                        statusFsm(10);
                    }else {
                        statusFsm(11);
                    }
                }else {
                    //还-司机指纹
                    statusFsm(12);
                }
                break;
            case 2:
@@ -271,9 +331,9 @@
            case 4:
                //切换到人脸
                if(flag==0){
                    if(status==1){
                    if(status==1||status==10){
                        statusFsm(0);
                    }else if(status==3){
                    }else if(status==3||status==11){
                        statusFsm(2);
                    }
                }else {
@@ -291,7 +351,14 @@
                //司机ic卡成功
                if(flag==0) {
                    //取
                    if(MApplication.getConfigBean()!=null&&MApplication.getConfigBean().getAlcoholStatus()==1) {
                        //非酒精检测
                        startActivity(KeyCabinetActivity.class);
                        finish();
                    }else {
                        //酒精检测
                    statusFsm(4);
                    }
                }else {
                    //还
                    startActivity(KeyCabinetActivity.class);
@@ -306,6 +373,7 @@
                getDB().message.requestLayout();
                EventBus.getDefault().post(new HttpEvent("ic卡+++++++"+data.getData().get("type").toString()));
                break;
            default:
                break;
        }
@@ -503,6 +571,7 @@
                    if(new BigDecimal(MApplication.getConfigBean().getCabinetConfigDataVO().getConcentration())
                            .compareTo(resultEvent.getConcentration())>=0){
                        //酒精通过
                        getVM().alcoholTestAlarm(resultEvent.getConcentration().toString());
                        getDB().clJiujinOk.setVisibility(View.VISIBLE);
                        handler.sendEmptyMessageDelayed(4,1000);
                    }else {
@@ -645,7 +714,15 @@
                            MApplication.getLoginBean().setMemberId(Integer.parseInt(user.getUserId()));
                            MApplication.getLoginBean().setAuthType(0);
                            //handler.sendEmptyMessageDelayed(8,0);
                            //Toast.makeText(mContext, "是否酒精检测:"+MApplication.getConfigBean().getAlcoholStatus(), Toast.LENGTH_SHORT).show();
                            if(MApplication.getConfigBean()!=null&&MApplication.getConfigBean().getAlcoholStatus()==1) {
                                //非酒精检测
                                startActivity(KeyCabinetActivity.class);
                                finish();
                            }else {
                                //酒精检测
                            EventBus.getDefault().post(new FaceStatusChangeEvent(4));
                            }
                        }else if(status==7){
                            //还-司机
                            MApplication.getLoginBean().setMemberId(Integer.parseInt(user.getUserId()));
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/OfflineActivationActivity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
package com.doumee.keyCabinet.ui.face;
import androidx.annotation.Nullable;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import com.baidu.idl.main.facesdk.FaceAuth;
import com.baidu.idl.main.facesdk.callback.Callback;
import com.doumee.keyCabinet.MApplication;
import com.doumee.keyCabinet.R;
import com.doumee.keyCabinet.base.MyBaseActivity;
import com.doumee.keyCabinet.databinding.OfflineActivationActivityBinding;
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.utils.LMobileInfo;
import com.doumee.keyCabinet.utils.update.FileUtil;
import com.doumee.lib_coremodel.view.ToastView;
import com.example.datalibrary.utils.FileUtils;
import com.example.datalibrary.utils.ToastUtils;
import org.greenrobot.eventbus.Subscribe;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class OfflineActivationActivity extends MyBaseActivity<OfflineActivationVM, OfflineActivationActivityBinding> implements View.OnClickListener {
    private FaceAuth faceAuth;
    private boolean isDownLoad;
    String filePath = Environment.getExternalStorageDirectory().getPath()+"/License.zip";
    @Override
    public int getLayoutId() {
        return R.layout.offline_activation_activity;
    }
    @Override
    public void initView(@Nullable Bundle savedInstanceState) {
        isToGuild = false;
        normalConfig();
        getDB().setModel(getVM());
    }
    @Override
    public void initData(@Nullable Bundle savedInstanceState) {
        getDB().tvId.setText("NO:"+ LMobileInfo.getDeviceUniqueId());
        // å¤åˆ¶æŒ‰é’®
        faceAuth = new FaceAuth();
        String a = faceAuth.getDeviceId(this);
        getDB().accreditDeviceTv.setText(a);
        // é•¿æŒ‰ç‚¹å‡»å¤åˆ¶
        getDB().accreditDeviceTv.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                ClipboardManager clipboardManager = (ClipboardManager)
                        getSystemService(Context.CLIPBOARD_SERVICE);
                clipboardManager.setText(getDB().accreditDeviceTv.getText());
                ToastUtils.toast(OfflineActivationActivity.this, "deviceID å¤åˆ¶æˆåŠŸ");
                return false;
            }
        });
        getDB().accreditOffBtn.setOnClickListener(this);
        getDB().btnDown.setOnClickListener(this);
        setupDownloadManager();
        setupDownloadReceiver();
    }
    @Subscribe
    public void TimeClockEvent(TimeClockEvent e){
        if(!isFinishing()){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateDownStatus();
                }
            });
        }
    }
    private void updateDownStatus(){
        if(isDownLoad){
            return;
        }
        //先校验是否有下载路径
        if(!TextUtils.isEmpty(MApplication.getConfigBean().getActivateFileUrl())){
            if(FileUtil.FileIsExist(filePath)) {
                //文件存在
                getDB().btnDown.setText("重新下载激活文件");
                getDB().btnDown.setClickable(true);
                getDB().btnDown.setBackgroundResource(R.mipmap.btn_main_normal);
                getDB().accreditOffBtn.setClickable(true);
                getDB().accreditOffBtn.setBackgroundResource(R.mipmap.btn_main_normal);
            }else {
                getDB().btnDown.setText("下载激活文件");
                getDB().btnDown.setClickable(true);
                getDB().btnDown.setBackgroundResource(R.mipmap.btn_main_normal);
                getDB().accreditOffBtn.setClickable(false);
                getDB().accreditOffBtn.setBackgroundResource(R.mipmap.btn_less_normal);
            }
        }else {
            //删除激活文件
            FileUtils.deleteFile(filePath);
            getDB().btnDown.setText("待后台上传激活文件");
            getDB().btnDown.setClickable(false);
            getDB().btnDown.setBackgroundResource(R.mipmap.btn_less_normal);
            getDB().accreditOffBtn.setClickable(false);
            getDB().accreditOffBtn.setBackgroundResource(R.mipmap.btn_less_normal);
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_down:
                //下载按钮
                if(isDownLoad){
                    ToastView.show(MApplication.mContext,"下载中...");
                    return;
                }
                if(!TextUtils.isEmpty(MApplication.getConfigBean().getActivateFileUrl())){
                    isDownLoad = true;
                    startDownload(MApplication.getConfigBean().getActivateFileUrl());
                }
                break;
            // ç¦»çº¿æ¿€æ´»
            case R.id.accredit_offBtn:
                faceAuth.initLicenseOffLine(this, new Callback() {
                    @Override
                    public void onResponse(final int code, final String response) {
                        if (code == 0) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // æŽˆæƒæˆåŠŸè·³è½¬åŠŸèƒ½å…¥å£é¡µé¢
                                    getDB().accreditHintTv.setText("");
                                    finish();
                                }
                            });
                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (code == 7) {
                                        getDB().accreditHintTv.setText("激活失败,设备硬件指纹与License.zip不符");
                                    } else if (code == 11) {
                                        getDB().accreditHintTv.setText("激活失败,License.zip文件对应的序列号不在有效期范围内");
                                    } else if (code == -1) {
                                        getDB().accreditHintTv.setText("未检测到License.zip文件");
                                    } else if (code == 14) {
                                        getDB().accreditHintTv.setText("激活失败,License.zip文件对应的序列号不在有效期范围内");
                                    } else if (code == 4) {
                                        getDB().accreditHintTv.setText("激活失败,设备硬件指纹与License.zip不符");
                                    } else {
                                        getDB().accreditHintTv.setText(code);
                                    }
                                }
                            });
                        }
                    }
                });
                break;
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (downloadReceiver != null) {
            unregisterReceiver(downloadReceiver);
        }
    }
    private BroadcastReceiver downloadReceiver;
    private DownloadManager downloadManager;
    private long downloadId;
    private void setupDownloadManager() {
        downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    }
    private void startDownload(String url) {
        try {
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
            // è®¾ç½®ä¸‹è½½å‚æ•°
            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
            request.setTitle("文件下载");
            request.setDescription("正在下载文件...");
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir("", "License.zip");
            // å¼€å§‹ä¸‹è½½
            downloadId = downloadManager.enqueue(request);
            Toast.makeText(mContext, "下载已开始", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            isDownLoad = false;
            Toast.makeText(this, "下载失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
    private void setupDownloadReceiver() {
        downloadReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive (Context context, Intent intent){
                long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                if (id == downloadId) {
                    isDownLoad = false;
                    Toast.makeText(context, "文件下载完成", Toast.LENGTH_LONG).show();
                }
            }
        };
        registerReceiver(downloadReceiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/OfflineActivationVM.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.doumee.keyCabinet.ui.face;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.hilt.lifecycle.ViewModelInject;
import com.android.internal.logging.AndroidConfig;
import com.doumee.lib_coremodel.base.BaseModel;
import com.doumee.lib_coremodel.base.DataViewModel;
public class OfflineActivationVM extends DataViewModel {
    @ViewModelInject
    public OfflineActivationVM(@NonNull Application application, BaseModel model) {
        super(application, model);
    }
    @Override
    protected void clickByTypeCommand(int type) {
        doAction(type);
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/UserManagerActivity.java
@@ -30,6 +30,7 @@
import com.doumee.keyCabinet.R;
import com.doumee.keyCabinet.base.MyBaseActivity;
import com.doumee.keyCabinet.databinding.UserManagerActivityBinding;
import com.doumee.keyCabinet.event.HttpEvent;
import com.doumee.keyCabinet.ui.face.adapter.FaceUserAdapter;
import com.doumee.keyCabinet.ui.view.TipDialog;
import com.doumee.keyCabinet.utils.face.model.SingleBaseConfig;
@@ -41,6 +42,8 @@
import com.example.datalibrary.model.KeyboardsUtils;
import com.example.datalibrary.model.User;
import com.example.datalibrary.utils.DensityUtils;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
@@ -428,6 +431,12 @@
        }
        if (mSelectCount != 0) {
            isDBLoad = false;
            String info = "数量:"+mUserInfoList.size();
            for(User u:mUserInfoList){
                String key = u.getUserName()+"-"+u.getGroupId();
                info+="\n"+key+" :"+u.isChecked()+";";
            }
            EventBus.getDefault().post(new HttpEvent(info));
            UserInfoManager.getInstance().deleteUserListInfo(mUserInfoList,
                    mEditTitleSearch.getText().toString() , mUserListListener,
                    loadListener);
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/guide/TestActivity.java
@@ -8,7 +8,6 @@
import com.doumee.keyCabinet.R;
import com.doumee.keyCabinet.base.MyBaseActivity;
import com.doumee.keyCabinet.databinding.ActivityTestBinding;
import com.innohi.YNHAPI;
import dagger.hilt.android.AndroidEntryPoint;
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ChangeUrlActivity.java
@@ -46,6 +46,7 @@
    public void initData(@Nullable Bundle savedInstanceState) {
        getDB().etUrl.setText(SpUtil.getString("base_url", Apis.HTTP));
        getDB().etTime.setText(SpUtil.getInt("loop_time",60)+"");
        getDB().etXj.setText(SpUtil.getString("rbgCameraId","0"));
    }
    @Override
@@ -72,11 +73,18 @@
                    ToastView.show(MApplication.mContext,"接口调用间隔错误");
                    return;
                }
                String xj = getDB().etXj.getText().toString();
                if(!"0".equals(xj)&&!"1".equals(xj)){
                    ToastView.show(MApplication.mContext,"摄像头编号错误");
                    return;
                }
                String oldCameraId = SpUtil.getString("rbgCameraId","0");
                SpUtil.saveString("rbgCameraId",xj);
                String oldUrl = SpUtil.getString("base_url", Apis.HTTP);
                SpUtil.saveString("base_url",url);
                SpUtil.saveInt("loop_time",time);
                ToastView.show(MApplication.mContext,"保存成功");
                if(!oldUrl.equals(url)){
                if(!oldUrl.equals(url)||!oldCameraId.equals(xj)){
                    //接口不同,重新启动
                    restartApp();
                }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/KeyCabinetActivity.java
@@ -167,6 +167,7 @@
                //开启柜门
                getVM().openGridDriver(selectBean);
                downTime = 60;
                getDB().tvTitle.setVisibility(View.GONE);
                break;
            case 2:
                //getDB().clTip1.setVisibility(View.GONE);
@@ -281,6 +282,12 @@
    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_tip2), 0, text.length()-phone.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -473,6 +480,17 @@
                if(handler.hasMessages(0)){
                    handler.removeMessages(0);
                }
                if("1".equals(e.getType())){
                    //1号板
                    if(!"1".equals(selectBean.getBoardCode())){
                        return;
                    }
                }else if("2".equals(e.getType())){
                    //2号板
                    if(!"2".equals(selectBean.getBoardCode())){
                        return;
                    }
                }
                String key = SportUtils.intToHex(Integer.parseInt(selectBean.getBoardCode()))
                        +SportUtils.intToHex(Integer.parseInt(selectBean.getChannelCode()));
                if(flag==0) {
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/KeyCabinetVM.java
@@ -100,17 +100,20 @@
        OpenGridDriverParam param = new OpenGridDriverParam();
        param.setCabinetId(selectBean.getCabinetId());
        param.setGridId(selectBean.getId());
        param.setOpenWay(selectBean.getGetKeyWay());
        param.setCarUseBookId(selectBean.getCarUseBookId());
        param.setMemberId(MApplication.getLoginBean().getMemberId());
        param.setAuthType(MApplication.getLoginBean().getAuthType());
        showLoading(true);
        EventBus.getDefault().post(new HttpEvent("===>司机开门-请求"));
        getRetrofitService(Apis.class).openGridDriver(ParamsUtil.encodeRequestBody(param))
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new SimpleObserver<BaseResponse>(rxJavaGcManager) {
                    @Override
                    public void onNext(@NonNull BaseResponse response) {
                        EventBus.getDefault().post(new HttpEvent("===>司机开门-返回"));
                        if(200==response.getCode()){
                            //开门
                            EventBus.getDefault().post(new HttpEvent("开门接口成功"));
                            doAction(2);
                        }else {
                            toast(response.getMessage());
@@ -141,12 +144,13 @@
        param.setMemberId(loginBean.getMemberId());
        param.setGridId(gridDo.getGridId());
        param.setKeyStatus(!TextUtils.isEmpty(gridDo.getCurKeyCode())?1:2);
        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
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageCabinetActivity.java
@@ -37,12 +37,13 @@
import com.doumee.keyCabinet.event.OpenGridOneResultEvent;
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.ui.keyCabinet.adapter.ManageCabinetRcvAdapter;
import com.doumee.keyCabinet.utils.MCUtils;
import com.doumee.keyCabinet.utils.i485.SportUtils;
import com.doumee.lib_coremodel.bean.event.ActionEventData;
import com.doumee.lib_coremodel.util.RecyclerHelp;
import com.doumee.lib_coremodel.util.StringUtil;
import com.example.datalibrary.db.DBManager;
import com.innohi.YNHAPI;
import com.mc.enjoysdk.McSystemUi;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -110,8 +111,8 @@
            @Override
            public boolean onLongClick(View v) {
                //可以下拉
                YNHAPI mAPI = YNHAPI.getInstance();
                mAPI.setNavigationBarVisibility(YNHAPI.NavigationBarVisibility.VISIBLE);
                McSystemUi mcSystemUi = McSystemUi.getInstance(ManageCabinetActivity.this);
                MCUtils.show(mcSystemUi);
                return true;
            }
        });
@@ -673,11 +674,28 @@
                if(!isFail){
                    if(copyMap.containsKey(gridDo.getGridKey())){
                        //关门成功
                        boolean isSend = false;
                        String bh = gridDo.getGridKey().substring(0,2);
                        if("1".equals(e.getType())){
                            //1号板
                            if("01".equals(bh)){
                                isSend = true;
                            }
                        }else if("2".equals(e.getType())){
                            //2号板
                            if("02".equals(bh)){
                                isSend = true;
                            }
                        }else {
                            isSend = true;
                        }
                        if(isSend) {
                        EventBus.getDefault().post(new HttpEvent(StringUtil.DateToStrSS(new Date())+"门关闭成功***************************>目标:"+gridDo.getKeyCode()+",当前:"+gridDo.getCurKeyCode()));
                        getVM().closeGrid(gridDo);
                    }
                }
            }
            }
            if(sb.length()>0){
                showKeyErrTip(sb.toString());
            }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageCabinetVM.java
@@ -289,7 +289,7 @@
        param.setMemberId(loginBean.getMemberId());
        param.setGridId(gridDo.getGridId());
        param.setKeyStatus(!TextUtils.isEmpty(gridDo.getCurKeyCode())?1:2);
        toast(gridDo.getGridKey()+"关闭,当前钥匙号:"+gridDo.getCurKeyCode());
        //toast(gridDo.getGridKey()+"关闭,当前钥匙号:"+gridDo.getCurKeyCode());
        getRetrofitService(Apis.class).closeGrid(ParamsUtil.encodeRequestBody(param))
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new SimpleObserver<BaseResponse>(rxJavaGcManager) {
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ManageLoginActivity.java
@@ -17,8 +17,9 @@
import com.doumee.keyCabinet.databinding.ManageLoginActivityBinding;
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.utils.LMobileInfo;
import com.doumee.keyCabinet.utils.MCUtils;
import com.doumee.lib_coremodel.bean.event.ActionEventData;
import com.innohi.YNHAPI;
import com.mc.enjoysdk.McSystemUi;
import org.greenrobot.eventbus.Subscribe;
@@ -51,8 +52,8 @@
            public boolean onLongClick(View v) {
                if(MApplication.getConfigBean().getId()==null){
                    //可以下拉
                    YNHAPI mAPI = YNHAPI.getInstance();
                    mAPI.setNavigationBarVisibility(YNHAPI.NavigationBarVisibility.VISIBLE);
                    McSystemUi mcSystemUi = McSystemUi.getInstance(ManageLoginActivity.this);
                    MCUtils.show(mcSystemUi);
                    return true;
                }
                return false;
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
@@ -14,6 +14,7 @@
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;
@@ -69,6 +70,7 @@
import com.doumee.keyCabinet.event.OpenGridOneResultEvent;
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.ui.face.ActivationActivity;
import com.doumee.keyCabinet.ui.face.ChoseActivationActivity;
import com.doumee.keyCabinet.ui.face.FaceActivity;
import com.doumee.keyCabinet.ui.keyCabinet.ChangeUrlActivity;
import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity;
@@ -84,6 +86,7 @@
import com.doumee.keyCabinet.utils.CircularQueue;
import com.doumee.keyCabinet.utils.CrashHandler;
import com.doumee.keyCabinet.utils.LMobileInfo;
import com.doumee.keyCabinet.utils.MCUtils;
import com.doumee.keyCabinet.utils.TimeUtils;
import com.doumee.keyCabinet.utils.face.FaceSDKManager;
import com.doumee.keyCabinet.utils.face.FaceUtils;
@@ -107,13 +110,16 @@
import com.doumee.lib_coremodel.util.StringUtil;
import com.doumee.lib_coremodel.view.ToastView;
import com.example.datalibrary.api.FaceApi;
import com.example.datalibrary.db.DBManager;
import com.example.datalibrary.listener.DBLoadListener;
import com.example.datalibrary.listener.SdkInitListener;
import com.example.datalibrary.model.ImportFeatureResult;
import com.example.datalibrary.model.User;
import com.example.datalibrary.utils.ToastUtils;
import com.example.datalibrary.view.PreviewTexture;
import com.innohi.YNHAPI;
import com.mc.enjoysdk.McHome;
import com.mc.enjoysdk.McSystemUi;
import com.mc.enjoysdk.transform.McSystemUiFlag;
import com.yanzhenjie.permission.runtime.Permission;
import org.greenrobot.eventbus.EventBus;
@@ -160,6 +166,8 @@
    private int downCount = 0;
    private Long lastDownTime;
    private Long showTime;
    private McSystemUi mcSystemUi;
    private McHome mcHome;
    private Handler handler = new Handler(){
        @Override
@@ -219,6 +227,8 @@
        startService(intent2);*/
        getPermission();
        Timber.tag("====>").d(LMobileInfo.getDeviceUniqueId());
        mcSystemUi = McSystemUi.getInstance(this);
        mcHome = McHome.getInstance(this);
    }
    private void initM(){
@@ -253,6 +263,7 @@
            @Override
            public void onChanged(List<FaceUserBean> beans) {
                //更新人脸数据
                getVM().addInfo("更新人脸数据======》beans = "+beans);
                if(beans!=null&&beans.size()>0){
                    initModel(beans);
                }
@@ -324,8 +335,10 @@
                }else {
                    getDB().nsv.setVisibility(View.VISIBLE);
                }
                YNHAPI mAPI = YNHAPI.getInstance();
                mAPI.setNavigationBarVisibility(YNHAPI.NavigationBarVisibility.VISIBLE);
                //显示状态栏
                mcSystemUi.temporarilySwitchStatusBar(true);
                //显示导航栏
                mcSystemUi.temporarilySwitchNavigation(true);
            }
        });
        upErrInfo();
@@ -340,6 +353,7 @@
                    }
                    setJiuConfig();
                    initPort();
                    EventBus.getDefault().post(new GetFacesEvent());
                }
            }
        });
@@ -458,6 +472,12 @@
    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);
@@ -470,9 +490,9 @@
    protected void onResume() {
        super.onResume();
        isShowing = true;
        YNHAPI mAPI = YNHAPI.getInstance();
        mAPI.setNavigationBarVisibility(YNHAPI.NavigationBarVisibility.ALWAYS_INVISIBLE);
        mAPI.setBootLaunchApk("com.doumee.keyCabinet", true);
        getVM().setSubmit(true);
        MCUtils.hind(mcSystemUi);
        mcHome.setHomePackage("com.doumee.keyCabinet");
        showTime = System.currentTimeMillis();
        if(!isFaceOk) {
            initLicense();
@@ -512,7 +532,10 @@
        if (future != null && !future.isDone()) {
            future.cancel(true);
        }
        if(isFaceOk) {
            //激活了才处理
        FaceApi.getInstance().cleanRecords();
        }
        handler.removeCallbacksAndMessages(null);
        handler = null;
        faceHandler.removeCallbacksAndMessages(null);
@@ -543,7 +566,9 @@
    @Subscribe
    public void GetFacesEvent(GetFacesEvent event){
        getVM().addInfo("查询人脸数据======》");
        if(!isFinishing()&&!isUpdatingFace){
            getVM().addInfo("查询人脸数据======》isDBLoad = "+isDBLoad);
            if(isDBLoad){
                isNeedUpdateFace = false;
                //查询人脸
@@ -577,7 +602,7 @@
                        /*
                         *要执行的操作*/
                        startActivity(new Intent(mContext, ActivationActivity.class));
                        startActivity(new Intent(mContext, ChoseActivationActivity.class));
                    }
                };
                Timer timer = new Timer();
@@ -639,10 +664,10 @@
                            @Override
                            public void run() {
                                FaceApi.getInstance().setUsers(users);
                                isDBLoad = true;
                                initFaceSDKManager(null);
                                if (successCount > 5000 || successCount == 0) {
                                    getDB().progressGroup.setVisibility(View.GONE);
                                    isDBLoad = true;
                                    isFaceOk = true;
                                }
                            }
@@ -688,8 +713,10 @@
    private void initModel(List<FaceUserBean> userBeans) {
        if (com.example.datalibrary.manager.FaceSDKManager.initStatus == com.example.datalibrary.manager.FaceSDKManager.SDK_MODEL_LOAD_SUCCESS) {
            getVM().addInfo("更新人脸===》开始更新");
            waitUpdate(userBeans);
        }else {
            getVM().addInfo("更新人脸===》初始化");
            initFaceSDKManager(userBeans);
        }
    }
@@ -745,6 +772,7 @@
        super.onPause();
        showTime = null;
        isShowing = false;
        getVM().setSubmit(false);
    }
    private int finishCount;
@@ -778,11 +806,9 @@
        }
    };
    private void waitUpdate(List<FaceUserBean> userBeans){
        if(isUpdatingFace){
            //正在更新
            waitBeans.addAll(userBeans);
        }else {
    private UserInfoManager.UserInfoListener mUserListListener = new UserInfoManager.UserInfoListener(){
        @Override
        public void userListQuerySuccess(String userName, List<User> listUserInfo) {
            selectBeans.clear();
            selectBeans.addAll(waitBeans);
            waitBeans.clear();
@@ -800,25 +826,37 @@
            //删除不存在用户
            List<User> users = FaceApi.getInstance().getAllUserList();
            List<User> dels = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            for(User u:users){
                String key = u.getUserId()+"_"+u.getGroupId();
                if(!uMap.containsKey(key)){
                    u.setChecked(true);
                    dels.add(u);
                    if(sb.length()>0){
                        sb.append(",");
                    }
                    sb.append(u.getUserName());
                }
            }
            getVM().addInfo("更新人脸》》》》》》》》》》》》》》》》》》");
            if(dels.size()>0){
                UserInfoManager.getInstance().deleteUserListInfo(dels,
                        "", new UserInfoManager.UserInfoListener() {
                getVM().addInfo("准备删除用户:"+sb.toString());
                UserInfoManager.getInstance().deleteUserListInfo(users,
                        "1", new UserInfoManager.UserInfoListener() {
                            @Override
                            public void userListDeleteSuccess() {
                                // ç”¨æˆ·åˆ—表删除成功
                                faceHandler.sendEmptyMessage(0);
                                getVM().addInfo("删除用户成功:");
                            }
                            @Override
                            public void userListDeleteFailure(String message) {
                                // ç”¨æˆ·åˆ—表删除失败
                                faceHandler.sendEmptyMessage(0);
                                getVM().addInfo("删除用户失败:"+message);
                                getVM().addInfo("删除用户列表:"+sb.toString());
                            }
                        },
                        new DBLoadListener() {
@@ -846,11 +884,41 @@
                faceHandler.sendEmptyMessage(0);
            }
        }
        @Override
        public void userListQueryFailure(String message) {
        }
        @Override
        public void userListDeleteSuccess() {
        }
        @Override
        public void userListDeleteFailure(String message) {
        }
    };
    private List<FaceUserBean> userBeans = new ArrayList<>();
    private void waitUpdate(List<FaceUserBean> userBeans){
        if(isUpdatingFace){
            //正在更新
            waitBeans.addAll(userBeans);
            getVM().addInfo("正在更新、等待 ã€Šã€Šã€Šã€Šã€Šã€Šã€Šã€Š");
        }else {
            getVM().addInfo("初始化人脸库 ã€Šã€Šã€Šã€Šã€Šã€Šã€Šã€Š");
            com.example.datalibrary.manager.FaceSDKManager.getInstance().initDataBases(MainActivity.this);
            this.userBeans.clear();
            this.userBeans.addAll(userBeans);
            UserInfoManager.getInstance().getUserListInfo(null, mUserListListener);
        }
    }
    private int repeatCount = 0;
    private void updateFace(FaceUserBean bean){
        Timber.d("==UpdatingFace==>完成数量 "+finishCount);
        //getVM().addInfo("==UpdatingFace==>完成数量 " + finishCount);
        if (TextUtils.isEmpty(bean.getFaceImg())||bean.getFaceImg().endsWith("null")) {
            finishCount++;
            faceHandler.sendEmptyMessage(0);
@@ -959,12 +1027,14 @@
            isSave = FaceApi.getInstance().registerUserIntoDBmanager(newDo.getGroupId(),
                    newDo.getUserId(), newDo.getUserName(), newDo.getImageName(), newDo.getUserInfo(), newDo.getFeature());
            //System.out.println("==isOk==>保存成功");
            //getVM().addInfo("新增人脸==》"+newDo.getUserName()+"   ç»“果:"+isSave);
        } else {
            //更新
            user.setUserName(newDo.getUserName());
            user.setImageName(newDo.getImageName());
            user.setFeature(newDo.getFeature());
            isSave = FaceApi.getInstance().userUpdateOnly(user);
            //getVM().addInfo("更新人脸==》"+newDo.getUserName()+"   ç»“果:"+isSave);
            //System.out.println("==isOk==>更新成功");
        }
@@ -1088,7 +1158,7 @@
        SingleBaseConfig.getBaseConfig().setRBGCameraId(index);
        SingleBaseConfig.getBaseConfig().setRgbRevert(true);
        SingleBaseConfig.getBaseConfig().setRgbDetectDirection(90);
        SingleBaseConfig.getBaseConfig().setRgbVideoDirection(270);
        SingleBaseConfig.getBaseConfig().setRgbVideoDirection(90);
        GateConfigUtils.modityJson();
        RegisterConfigUtils.modityJson();
    }
@@ -1178,7 +1248,6 @@
                getVM().devLogin();
                getPermission();
                getVM().devHeart();
                EventBus.getDefault().post(new GetFacesEvent());
            }else {
                loopDownCount--;
            }
@@ -1546,7 +1615,7 @@
        }
        getVM().updateGrids(updateList);
        EventBus.getDefault().post(new KeyResultEvent());
        EventBus.getDefault().post(new KeyResultEvent(bh+""));
    }
    private SerialPortModel jiuPort;
@@ -1610,20 +1679,28 @@
                return;
            }
            runOnUiThread(() -> {
                getVM().addInfo("获取到门数据:" + SportUtils.bytesToHexSimple(bytes));
                getVM().addInfo("获取到数据:" + SportUtils.bytesToHexSimple(bytes));
            });
            String data = SportUtils.bytesToHexSimple(bytes);
            if(startIndex==1){
                if(data.toLowerCase().startsWith("80")){
                gridPath = path;
                getVM().addInfo("设置门串口路径:" + path);
                    getVM().addInfo("设置门串口路径:=====XXXXX===>" + path);
                SpUtil.saveString("port_grid",path);
                }
            }else if(startIndex==2){
                if(data.toLowerCase().startsWith("cc")){
                keyPath = path;
                getVM().addInfo("设置钥匙串口路径:" + path);
                    getVM().addInfo("设置钥匙串口路径:====XXXX====>" + path);
                SpUtil.saveString("port_key",path);
                }
            }else if(startIndex==3){
                String data2 = new String(bytes);
                if(data2.toLowerCase().startsWith("mic")) {
                jiuPath = path;
                getVM().addInfo("设置酒精串口路径:" + path);
                    getVM().addInfo("设置酒精串口路径:====XXXX====>" + path);
                SpUtil.saveString("port_jiu",path);
                }
            }
        }
    };
@@ -1642,8 +1719,8 @@
            switch (msg.what){
                case 0:
                    if(index>=1&&!checkEnd()){
                        path = ports.get(index);
                        index--;
                        path = ports.get(index);
                        portHandler.sendEmptyMessage(4);
                    }else if(checkEnd()){
                        initPort();
@@ -1747,9 +1824,11 @@
    private boolean isInitPort;
    //初始化串口
    private void initPort(){
        //SpUtil.setString("port_grid","/dev/ttyS7");
        //SpUtil.setString("port_key","/dev/ttyS1");
        //SpUtil.setString("port_jiu","/dev/ttyS2");
        try {
            /*SpUtil.setString("port_grid","/dev/ttyS0");
            SpUtil.setString("port_key","/dev/ttyS4");
            SpUtil.setString("port_jiu","/dev/ttyS9");*/
        gridPath = SpUtil.getString("port_grid");
        getVM().addInfo("门串口链接:"+gridPath);
        keyPath = SpUtil.getString("port_key");
@@ -1828,9 +1907,14 @@
                getVM().addInfo("串口列表:"+ports.size());
            }
            if(ports.size()>0){
                index = ports.size()-1;
                    index = ports.size();
                portHandler.sendEmptyMessage(0);
            }
            }
        }catch (RuntimeException e){
            Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
        }catch (Exception e){
            Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
@@ -1948,17 +2032,17 @@
    private boolean checkEnd(){
        if(TextUtils.isEmpty(gridPath)){
            getVM().addInfo("门错误");
            getVM().addInfo("门错误<<<<<<<<<<<<<<<<<<<");
            startIndex=0;
            return false;
        }
        if(TextUtils.isEmpty(keyPath)){
            getVM().addInfo("钥匙错误");
            getVM().addInfo("钥匙错误<<<<<<<<<<<<<<<<<<<");
            startIndex=1;
            return false;
        }
        if(TextUtils.isEmpty(jiuPath)){
            getVM().addInfo("酒精错误");
            getVM().addInfo("酒精错误<<<<<<<<<<<<<<<<<<<");
            startIndex=2;
            return false;
        }
@@ -2034,7 +2118,6 @@
            if(handler.hasMessages(2)){
                handler.removeMessages(2);
            }
            HashMap<String,String> copyMap = new HashMap<>();
            copyMap.putAll(closeMap);
            closeMap.clear();
@@ -2071,11 +2154,28 @@
                    }
                    if(!isFail){
                        //关门成功
                        boolean isSend = false;
                        String bh = gridDo.getGridKey().substring(0,2);
                        if("1".equals(e.getType())){
                            //1号板
                            if("01".equals(bh)){
                                isSend = true;
                            }
                        }else if("2".equals(e.getType())){
                            //2号板
                            if("02".equals(bh)){
                                isSend = true;
                            }
                        }else {
                            isSend = true;
                        }
                        if(isSend) {
                        EventBus.getDefault().post(new HttpEvent(StringUtil.DateToStrSS(new Date())+"门关闭成功***************************>目标:"+gridDo.getKeyCode()+",当前:"+gridDo.getCurKeyCode()));
                        getVM().closeGrid(gridDo);
                    }
                }
            }
            }
            if(sb.length()>0){
                ToastView.show(MApplication.mContext, sb.toString() + "钥匙存放位置错误");
            }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainVM.java
@@ -13,30 +13,24 @@
import com.doumee.keyCabinet.bean.CabinetFaceBean;
import com.doumee.keyCabinet.bean.DevConfigBean;
import com.doumee.keyCabinet.bean.FaceUserBean;
import com.doumee.keyCabinet.bean.KeyCabinetBean;
import com.doumee.keyCabinet.bean.LoginBean;
import com.doumee.keyCabinet.bean.ManageKeyCabinetBean;
import com.doumee.keyCabinet.dao.CabinetGridDo;
import com.doumee.keyCabinet.dao.DaoManager;
import com.doumee.keyCabinet.event.DevConfigEvent;
import com.doumee.keyCabinet.event.HttpEvent;
import com.doumee.keyCabinet.http.Apis;
import com.doumee.keyCabinet.http.param.BaseResponse;
import com.doumee.keyCabinet.http.param.CloseGridParam;
import com.doumee.keyCabinet.http.param.DevErrInfoParam;
import com.doumee.keyCabinet.http.param.DevLoginParam;
import com.doumee.keyCabinet.http.param.FaceUserParam;
import com.doumee.keyCabinet.http.param.RequestBaseObject;
import com.doumee.keyCabinet.http.param.SyncGridDataParam;
import com.doumee.keyCabinet.http.param.TimeOutUnCloseAlarmParam;
import com.doumee.keyCabinet.utils.BraceletLogUtils;
import com.doumee.keyCabinet.utils.LMobileInfo;
import com.doumee.keyCabinet.utils.LanguageUtil;
import com.doumee.keyCabinet.utils.ParamsUtil;
import com.doumee.keyCabinet.utils.i485.SportUtils;
import com.doumee.lib_coremodel.base.BaseModel;
import com.doumee.lib_coremodel.base.DataViewModel;
import com.doumee.lib_coremodel.http.rxJava.SimpleObserver;
import com.doumee.lib_coremodel.http.utils.GsonTools;
import com.doumee.lib_coremodel.http.utils.RxUtils;
import com.doumee.lib_coremodel.util.SpUtil;
import com.doumee.lib_coremodel.util.StringUtil;
@@ -48,9 +42,6 @@
import java.util.HashMap;
import java.util.List;
import okhttp3.Headers;
import retrofit2.Response;
public class MainVM extends DataViewModel {
    public ObservableField<String> dayObs = new ObservableField<>("");
    public ObservableField<String> timeObs = new ObservableField<>("");
@@ -58,6 +49,12 @@
    private MutableLiveData<List<FaceUserBean>> faceLD = new MutableLiveData<>();
    private MutableLiveData<DevConfigBean> confidLD = new MutableLiveData<>();
    private boolean isSubmit = false;
    public void setSubmit(boolean submit) {
        isSubmit = submit;
    }
    @ViewModelInject
    public MainVM(@NonNull Application application, BaseModel model) {
@@ -80,6 +77,7 @@
                        if(200==response.getCode()){
                            if(response.getData()!=null){
                                MApplication.saveConfigBean(response.getData());
                                EventBus.getDefault().post(new HttpEvent("酒精检测开关:"+response.getData().getAlcoholStatus()));
                                confidLD.setValue(response.getData());
                                if(response.getData().getCabinetGridInfoVOList()!=null){
                                    updateDao(response.getData().getCabinetGridInfoVOList());
@@ -114,6 +112,7 @@
        }
        List<CabinetGridDo> addList = new ArrayList<>();
        List<CabinetGridDo> updateList = new ArrayList<>();
        List<SyncGridDataParam.GridDTO> errList = new ArrayList<>();
        for(ManageKeyCabinetBean bean:beans){
            String key = SportUtils.intToHex(Integer.parseInt(bean.getBoardCode()))+SportUtils.intToHex(Integer.parseInt(bean.getChannelCode()));
            if(oldMap.containsKey(key)){
@@ -129,6 +128,13 @@
                gridDo.setWorkingStatus(bean.getWorkingStatus());
                updateList.add(gridDo);
                oldMap.remove(key);
                if(isSubmit&&!isCheck(gridDo.getKeyCode(),gridDo.getCurKeyCode())){
                    SyncGridDataParam.GridDTO errDo = new SyncGridDataParam.GridDTO();
                    errDo.setActualLable(gridDo.getCurKeyCode());
                    errDo.setBoardCode(bean.getBoardCode());
                    errDo.setChannelCode(bean.getChannelCode());
                    errList.add(errDo);
                }
            }else {
                //新增
                CabinetGridDo gridDo = new CabinetGridDo();
@@ -165,6 +171,20 @@
            }
            DaoManager.getCabinetGridDao().update(upList);
        }
        if(errList.size()>0){
            syncGridData(errList);
        }
    }
    private boolean isCheck(String v1,String v2){
        if(TextUtils.isEmpty(v1)&&TextUtils.isEmpty(v2)){
            return true;
        }else if(TextUtils.isEmpty(v1)&&!TextUtils.isEmpty(v2)){
            return false;
        }else if(!TextUtils.isEmpty(v1)&&TextUtils.isEmpty(v2)){
            return false;
        }
        return v1.equals(v2);
    }
    public void devHeart(){
@@ -191,12 +211,45 @@
                });
    }
    public void syncGridData(List<SyncGridDataParam.GridDTO> errList){
        SyncGridDataParam param = new SyncGridDataParam();
        param.setCode(LMobileInfo.getDeviceUniqueId());
        param.setGridDTOList(errList);
        StringBuilder sb = new StringBuilder();
        for(SyncGridDataParam.GridDTO d:errList){
            if(sb.length()>0){
                sb.append(",");
            }
            sb.append(d.getBoardCode()+"_"+d.getChannelCode()+":"+d.getActualLable());
        }
        EventBus.getDefault().post(new HttpEvent("上报错误钥匙信息===》"+sb.toString()));
        getRetrofitService(Apis.class).syncGridData(ParamsUtil.encodeRequestBody(param))
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new SimpleObserver<BaseResponse>(rxJavaGcManager) {
                    @Override
                    public void onNext(@NonNull BaseResponse response) {
                    }
                    @Override
                    public void onError(@NonNull Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    public MutableLiveData<List<FaceUserBean>> getFaceLD() {
        return faceLD;
    }
    public void getFaceDatas() {
        //showLoading(true);
        addInfo("查询人脸数据======》调用接口");
        getRetrofitService(Apis.class).allFaceList( LMobileInfo.getDeviceUniqueId())
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new SimpleObserver<BaseResponse<CabinetFaceBean>>(rxJavaGcManager) {
@@ -291,12 +344,13 @@
        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
@@ -319,12 +373,13 @@
        param.setMemberId(loginBean.getMemberId());
        param.setGridId(gridDo.getGridId());
        param.setKeyStatus(!TextUtils.isEmpty(gridDo.getCurKeyCode())?1:2);
        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("===>首页关闭柜格-返回"));
                    }
                    @Override
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/BraceletLogUtils.java
@@ -14,14 +14,14 @@
    public static Long lastTime = 0L;
    public static void saveLog(String msg){
        String time = TimeUtils.getNowDate();
        /*String time = TimeUtils.getNowDate();
        String text = SpUtil.getString(LOG_KEY);
        if(TextUtils.isEmpty(text)){
            text = "";
        }
        text+= time + ":"+msg+"    #";
        COUNT++;
        SpUtil.saveString(LOG_KEY,text);
        SpUtil.saveString(LOG_KEY,text);*/
    }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/CrashHandler.java
@@ -11,10 +11,12 @@
import android.os.Environment;
import android.os.Looper;
import com.doumee.keyCabinet.MApplication;
import com.doumee.keyCabinet.ui.guide.GuideActivity;
import com.doumee.keyCabinet.ui.main.MainActivity;
import com.doumee.keyCabinet.utils.update.FileUtil;
import com.doumee.lib_coremodel.util.SpUtil;
import com.innohi.YNHAPI;
import com.mc.enjoysdk.McSystemUi;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
@@ -28,6 +30,7 @@
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
@@ -40,7 +43,7 @@
 */
public class CrashHandler implements UncaughtExceptionHandler {
    private static final String TAG = "CrashHandler";
    private static String PATH = Environment.getExternalStorageDirectory().getPath() + "/log/";
    private static String PATH =  "/log/";
    public static final String FILE_NAME = "crash";
    //log文件的后缀名
    private static final String FILE_NAME_SUFFIX = ".txt";
@@ -87,9 +90,8 @@
    public void uncaughtException(Thread thread, Throwable ex) {
        try {
            //导出异常信息到SD卡中
            YNHAPI mAPI = YNHAPI.getInstance();
            mAPI.setNavigationBarVisibility(YNHAPI.NavigationBarVisibility.VISIBLE);
            dumpExceptionToSDCard(ex);
            McSystemUi mcSystemUi = McSystemUi.getInstance(mContext);
            MCUtils.show(mcSystemUi);
            long time = SpUtil.getLong("err_app");
            SpUtil.saveLong("err_app",System.currentTimeMillis());
            if(System.currentTimeMillis()-time>60000){
@@ -111,10 +113,6 @@
            }
            //这里可以通过网络上传异常信息到服务器,便于开发人员分析日志从而解决bug
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("错误日志1"+e.getMessage());
        }
        //打印出当前调用栈信息
        ex.printStackTrace();
        //如果系统提供了默认的异常处理器,则交给系统去结束我们的程序,否则就由我们自己结束自己
@@ -127,34 +125,28 @@
        if (!handleException(ex) && mDefaultHandler != null) {
            // å¦‚果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            /*try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Log.e(TAG, "error : ", e);
            }*/
            /*System.out.println("重启应用");
            // åˆ›å»ºä¸€ä¸ªæ–°çš„启动意图
            Intent intent = new Intent(mContext, GuideActivity.class);
            // è®¾ç½®FLAG_ACTIVITY_CLEAR_TASK标志位
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            // ä½¿ç”¨PendingIntent包装启动意图
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
            // èŽ·å–AlarmManager实例
            AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
            // åœ¨500毫秒后触发重启操作
            alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 10, pendingIntent);
            }
            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()));
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);*/
            /*// æœªæ•获异常写文件
            writeCrashInfoToFile(ex);
            // é€€å‡ºæ•´ä¸ªåº”用
            if (mDefaultHandler != null) {
                mDefaultHandler.uncaughtException(thread, ex);
            } else {
                System.exit(0);
            }*/
                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();
        }
    }
@@ -200,6 +192,8 @@
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            System.out.println("错误日志3"+e.getMessage());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
@@ -244,7 +238,6 @@
                        Build.BRAND,
                        // android SDK版本
                        Build.VERSION.RELEASE);
        //sp.setString(Constants.SP_CRASH_EXCEPTION, errorLog);
        return null;
    }
@@ -272,7 +265,8 @@
            dumpPhoneInfo(print);
            print.println();
            ex.printStackTrace(print);
            //SpUtil.saveString(FILE_NAME+time,new String(out.toByteArray()));
            SpUtil.saveString(FILE_NAME+time,new String(out.toByteArray()));
            print.close();
        } catch (Exception e) {
            e.printStackTrace();
@@ -280,7 +274,7 @@
            //LogUtils.e(TAG, "dump crash info failed");
        }
        //以当前时间创建log文件
        File file = new File(PATH , FILE_NAME + time + FILE_NAME_SUFFIX);
        File file = new File(FileUtil.getFile(mContext)+PATH , FILE_NAME + time + FILE_NAME_SUFFIX);
        try {
            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            //导出发生异常的时间
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/MCUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.doumee.keyCabinet.utils;
import com.mc.enjoysdk.McSystemUi;
import com.mc.enjoysdk.transform.McSystemUiFlag;
public class MCUtils {
    public static void hind(McSystemUi mcSystemUi){
        mcSystemUi.temporarilySwitchStatusBar(false);
        mcSystemUi.temporarilySwitchNavigation(false);
        /*//隐藏状态栏信息
        mcSystemUi.disableStatusBarItem(McSystemUiFlag.DISABLE_SYSTEM_INFO);
        //禁止状态栏弹出
        mcSystemUi.disableStatusBarItem(McSystemUiFlag.DISABLE_NOTIFICATION_ALERTS);
        //禁止状态栏下拉
        mcSystemUi.disableStatusBarItem(McSystemUiFlag.DISABLE_EXPAND);*/
    }
    public static void show(McSystemUi mcSystemUi){
        //mcSystemUi.disableStatusBarItem(McSystemUiFlag.DISABLE_NONE);
        mcSystemUi.temporarilySwitchStatusBar(true);
        mcSystemUi.temporarilySwitchNavigation(true);
    }
}
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/i485/SportUtils.java
@@ -5,34 +5,20 @@
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;
public class SportUtils {
    public static List<String> getSerialPortPaths(Context context) {
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        List<UsbDevice> devices = new ArrayList<>(usbManager.getDeviceList().values());
        // èŽ·å–æ‰€æœ‰ä¸²å£è®¾å¤‡è·¯å¾„
        String[] devices = new SerialPortFinder().getAllDevicesPath();
        List<String> serialPaths = new ArrayList<>();
        for (UsbDevice device : devices) {
            for (int i = 0; i < device.getInterfaceCount(); i++) {
                UsbInterface intf = device.getInterface(i);
                if (intf.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
                    serialPaths.add(device.getDeviceName());
                    break;
        if(devices!=null){
            for(String key:devices){
                serialPaths.add(key);
                }
            }
        }
        if(serialPaths.size()==0){
            serialPaths.add("/dev/ttyS0");
            serialPaths.add("/dev/ttyS1");
            serialPaths.add("/dev/ttyS2");
            serialPaths.add("/dev/ttyS3");
            serialPaths.add("/dev/ttyS4");
            serialPaths.add("/dev/ttyS5");
            serialPaths.add("/dev/ttyS6");
            serialPaths.add("/dev/ttyS7");
        }
        return serialPaths;
    }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/utils/update/FileUtil.java
@@ -10,6 +10,9 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.DecimalFormat;
@@ -236,4 +239,60 @@
        }
        return file;
    }
    public static interface DownLoadCallBack{
        void sucess();
        void err(String e);
    }
    public static void downLoadFile(String filePath,String url,DownLoadCallBack callBack){
        try {
            URL u = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setConnectTimeout(10000);
            int responeCode = conn.getResponseCode();
            InputStream is;
            if (responeCode == 200) {
                is = conn.getInputStream();
            } else {
                //连接失败
                if(callBack!=null){
                    callBack.err("下载地址错误");
                }
                return;
            }
            int fileSize = conn.getContentLength();
            if (fileSize < 1 || is == null) {
                //文件大小不对
                if(callBack!=null){
                    callBack.err("文件大小不对");
                }
                return;
            } else {
                //下载
                if (FileUtil.deleteFile(filePath)) {// åˆ é™¤åŽŸæ¥çš„å®‰è£…æ–‡ä»¶å†ä¸‹è½½
                    FileOutputStream fos = new FileOutputStream(filePath);
                    byte[] bytes = new byte[1024];
                    int len = -1;
                    while ((len = is.read(bytes)) != -1) {
                        fos.write(bytes, 0, len);
                        fos.flush();
                    }
                    //下载完成
                    if(callBack!=null){
                        callBack.sucess();
                    }
                    is.close();
                    fos.close();
                }
            }
        } catch (Exception e) {
            //下载报错
            if(callBack!=null){
                callBack.err(e.getMessage());
            }
            e.printStackTrace();
        }
    }
}
keyCabinet-android/app/src/main/res/layout/change_url_activity.xml
@@ -60,6 +60,17 @@
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>
       <androidx.core.widget.NestedScrollView
           android:layout_width="match_parent"
           android:layout_height="0dp"
           app:layout_constraintTop_toBottomOf="@+id/viewBack"
           app:layout_constraintBottom_toTopOf="@+id/tv_bc"
           android:fillViewport="true">
           <androidx.constraintlayout.widget.ConstraintLayout
               android:layout_width="match_parent"
               android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv2"
            android:layout_width="wrap_content"
@@ -68,7 +79,7 @@
            android:textColor="#ff111111"
            android:textSize="27sp"
            android:textStyle="bold"
            app:layout_constraintTop_toBottomOf="@+id/viewBack"
                   app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginTop="30dp"
            android:layout_marginLeft="30dp"/>
@@ -187,6 +198,52 @@
            android:lines="1"/>
        <TextView
                   android:id="@+id/tv5"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:text="选择摄像头(0或1)"
                   android:textColor="#ff111111"
                   android:textSize="27sp"
                   android:textStyle="bold"
                   app:layout_constraintTop_toBottomOf="@+id/v_3"
                   app:layout_constraintStart_toStartOf="parent"
                   android:layout_marginTop="30dp"
                   android:layout_marginLeft="30dp"/>
               <View
                   android:id="@+id/v_4"
                   android:layout_width="match_parent"
                   android:layout_height="75dp"
                   app:layout_constraintTop_toBottomOf="@+id/tv5"
                   android:layout_marginTop="18dp"
                   android:background="@drawable/shape_et_bg"
                   android:layout_marginLeft="30dp"
                   android:layout_marginRight="30dp"/>
               <EditText
                   android:id="@+id/et_xj"
                   android:layout_width="0dp"
                   android:layout_height="75dp"
                   android:background="@null"
                   android:text=""
                   android:textColor="#111111"
                   android:hint="请输入摄像头编号(0或1)"
                   android:textColorHint="#999999"
                   android:textSize="24sp"
                   android:inputType="number"
                   app:layout_constraintTop_toTopOf="@+id/v_4"
                   app:layout_constraintStart_toStartOf="@+id/v_4"
                   app:layout_constraintEnd_toEndOf="@+id/v_4"
                   android:layout_marginLeft="18dp"
                   android:layout_marginRight="18dp"
                   android:gravity="center_vertical"
                   android:lines="1"/>
           </androidx.constraintlayout.widget.ConstraintLayout>
       </androidx.core.widget.NestedScrollView>
        <TextView
            android:id="@+id/tv_bc"
            android:layout_width="match_parent"
            android:layout_height="75dp"
keyCabinet-android/app/src/main/res/layout/face_activity.xml
@@ -220,13 +220,57 @@
            </androidx.constraintlayout.widget.ConstraintLayout>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:id="@+id/cl_zw_gl"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                android:background="@drawable/shape_r30_face_bg"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toLeftOf="@+id/cl_sk_gl"
                app:commandType="@{9}"
                app:onClickCommand="@{model.myTypeCommand}"
                >
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    >
                    <ImageView
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:src="@mipmap/ic_zhiwen"
                        android:layout_gravity="center_vertical"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="指纹验证"
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_sk_gl"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                android:background="@drawable/shape_r30_face_bg"
                app:layout_constraintLeft_toRightOf="@+id/cl_zw_gl"
                app:layout_constraintRight_toRightOf="parent"
                app:commandType="@{1}"
                app:onClickCommand="@{model.myTypeCommand}"
                >
@@ -252,14 +296,15 @@
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="7dp"/>
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.constraintlayout.widget.ConstraintLayout>
        <!--人脸验证-->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_fail"
            android:layout_width="wrap_content"
@@ -308,6 +353,7 @@
        </androidx.constraintlayout.widget.ConstraintLayout>
        <!-- å¸æœºé€‰éªŒè¯æ–¹å¼ -->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_sj_xuan"
            android:layout_width="match_parent"
@@ -424,18 +470,68 @@
                android:layout_marginBottom="30dp"
                android:visibility="visible">
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/cl_zw_sj"
                    android:layout_width="0dp"
                    android:layout_height="75dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:background="@drawable/shape_r30_face_bg"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toLeftOf="@+id/ll_01"
                    android:layout_marginRight="20dp"
                    app:commandType="@{10}"
                    app:onClickCommand="@{model.myTypeCommand}"
                    >
                <LinearLayout
                    android:id="@+id/ll_01"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                        android:layout_height="wrap_content"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        >
                        <ImageView
                            android:layout_width="28dp"
                            android:layout_height="28dp"
                            android:src="@mipmap/ic_zhiwen"
                            android:layout_gravity="center_vertical"/>
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="指纹"
                            android:textColor="#ff279baa"
                            android:textSize="24sp"
                            android:textStyle="bold"
                            android:layout_marginLeft="12dp"/>
                    </LinearLayout>
                </androidx.constraintlayout.widget.ConstraintLayout>
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/ll_01"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toRightOf="@+id/cl_zw_sj"
                    app:layout_constraintRight_toLeftOf="@+id/ll_02"
                    android:background="@drawable/shape_r30_face_bg"
                    android:paddingLeft="30dp"
                    android:paddingRight="30dp"
                    app:commandType="@{2}"
                    app:onClickCommand="@{model.myTypeCommand}">
                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        app:layout_constraintTop_toTopOf="parent"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        >
                    <ImageView
                        android:layout_width="28dp"
@@ -445,14 +541,15 @@
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="刷卡验证"
                            android:text="刷卡"
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:layout_marginLeft="7dp"
                        android:textStyle="bold"
                        android:layout_gravity="center_vertical"/>
                            android:layout_marginLeft="12dp"/>
                </LinearLayout>
                </androidx.constraintlayout.widget.ConstraintLayout>
                <LinearLayout
                    android:id="@+id/ll_02"
@@ -484,7 +581,125 @@
        </androidx.constraintlayout.widget.ConstraintLayout>
        <!--指纹验证-->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_zw"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="@+id/camera_textureview"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:background="@color/white"
            android:visibility="gone">
            <View
                android:id="@+id/v_c_zw"
                android:layout_width="340dp"
                android:layout_height="340dp"
                android:background="@mipmap/ic_zhiwenyanzheng"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                />
            <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="42dp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"/>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_sk_zw"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                android:background="@drawable/shape_r30_face_bg"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toLeftOf="@+id/cl_rl_zw"
                app:commandType="@{1}"
                app:onClickCommand="@{model.myTypeCommand}"
                >
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    >
                    <ImageView
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:src="@mipmap/ic_shuaka"
                        android:layout_gravity="center_vertical"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="刷卡验证"
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_rl_zw"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                app:layout_constraintLeft_toRightOf="@+id/cl_sk_zw"
                app:layout_constraintRight_toRightOf="parent"
                android:background="@drawable/shape_r30_face_bg"
                app:commandType="@{4}"
                app:onClickCommand="@{model.myTypeCommand}"
                >
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    >
                    <ImageView
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:src="@mipmap/ic_renlian"
                        android:layout_gravity="center_vertical"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="人脸验证"
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.constraintlayout.widget.ConstraintLayout>
        <!--刷卡验证-->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_card"
            android:layout_width="match_parent"
@@ -520,12 +735,55 @@
                app:layout_constraintEnd_toEndOf="parent"/>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:id="@+id/cl_zw_sk"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                android:background="@drawable/shape_r30_face_bg"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toLeftOf="@+id/cl_rl_sk"
                app:commandType="@{11}"
                app:onClickCommand="@{model.myTypeCommand}"
                >
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    >
                    <ImageView
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:src="@mipmap/ic_zhiwen"
                        android:layout_gravity="center_vertical"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="指纹验证"
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_rl_sk"
                android:layout_width="0dp"
                android:layout_height="75dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="30dp"
                app:layout_constraintLeft_toRightOf="@+id/cl_zw_sk"
                app:layout_constraintRight_toRightOf="parent"
                android:background="@drawable/shape_r30_face_bg"
                app:commandType="@{4}"
                app:onClickCommand="@{model.myTypeCommand}"
@@ -552,13 +810,14 @@
                        android:textColor="#ff279baa"
                        android:textSize="24sp"
                        android:textStyle="bold"
                        android:layout_marginLeft="7dp"/>
                        android:layout_marginLeft="12dp"/>
                </LinearLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.constraintlayout.widget.ConstraintLayout>
        <!--酒精检测-->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_jiu"
            android:layout_width="match_parent"
keyCabinet-android/app/src/main/res/layout/key_cabinet_activity.xml
@@ -61,6 +61,19 @@
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginRight="30dp"/>
        <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"/>
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_km"
            android:layout_width="match_parent"
keyCabinet-android/app/src/main/res/layout/main_activity.xml
@@ -14,13 +14,14 @@
        android:layout_height="match_parent"
        tools:context=".ui.main.MainActivity"
        >
        <TextureView
            android:id="@+id/checkNirTexture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:alpha="0"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/img1"
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwen.png
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenluru.png
keyCabinet-android/app/src/main/res/mipmap-xxhdpi/ic_zhiwenyanzheng.png
keyCabinet-android/app/src/main/res/values/strings.xml
@@ -73,6 +73,13 @@
    <string name="on_number">请输入16位序列号</string>
    <string name="accredit_use">应用激活</string>
    <string name="filter_vcode">0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
    <string name="accredit_off">离线激活</string>
    <string name="off_technological_process">离线激活流程: </string>
    <string name="off_technological_process_three">在百度智能云平台输入设备硬件指纹并获取离线激活文件(License.zip)</string>
    <string name="off_technological_process_four">将离线激活文件拷贝至内置SD卡根目录下</string>
    <string name="off_technological_process_five">在SDK界面中触发离线激活</string>
    <string name="off_local_hardware">本机硬件指纹</string>
    <string name="off_problem">激活遇到问题?</string>
    <string name="home_face">人脸导入</string>
    <string name="home_faceLibrary">人脸库管理</string>
    <string name="home_camra">切换摄像头</string>
keyCabinet-android/app/src/test/java/com/doumee/ticketmachine/ExampleUnitTest.java
@@ -15,14 +15,9 @@
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() {
        CircularQueue queue = new CircularQueue();
        for(int i=0;i<3;i++){
            queue.enqueue(i+"");
        }
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
       String code = "EF 01 FF FF FF FF 01 00 03 1D 00";
       String x = SportUtils.getBCC(code);
       System.out.println(x);
    }
keyCabinet-android/datalibrary/build.gradle
@@ -3,12 +3,12 @@
}
android {
    compileSdkVersion 29
    compileSdkVersion 28
    buildToolsVersion "29.0.3"
    defaultConfig {
        minSdkVersion 22
        targetSdkVersion 29
        targetSdkVersion 28
        versionCode 5
        versionName "5.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
keyCabinet-android/facelibrary/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'
android {
    compileSdkVersion 29
    compileSdkVersion 28
//    buildToolsVersion '26.0.2'
    publishNonDefault true
    defaultConfig {
        minSdkVersion 22
        targetSdkVersion 29
        targetSdkVersion 28
        versionCode 5
        versionName "5.0"
keyCabinet-android/lib_opensource/build.gradle
@@ -53,12 +53,12 @@
    annotationProcessor deps.lifecycle.compiler
    //work
    api(deps.work.work_runtime){
    /*api(deps.work.work_runtime){
        exclude group:"com.google.guava",module:"listenablefuture"
    }
    api (deps.work.work_rxjava2){
        exclude group:"com.google.guava",module:"listenablefuture"
    }
    }*/
    //导航 nav
    api deps.nav.navigation_runtime
keyCabinet-android/settinglibrary/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'
android {
    compileSdkVersion 29
    compileSdkVersion 28
    buildToolsVersion "29.0.3"
    defaultConfig {
        minSdkVersion 22
        targetSdkVersion 29
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
keyCabinet-android/versions.gradle
@@ -1,8 +1,8 @@
def build_versions = [:]
build_versions.min_sdk = 22
build_versions.target_sdk = 30
build_versions.compile_sdk = 30
build_versions.target_sdk = 28
build_versions.compile_sdk = 28
build_versions.build_tools = "30.0.2"
ext.build_versions = build_versions
@@ -64,11 +64,6 @@
jetpack.datastore_preferences_rxjava2 = "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
deps.jetpack = jetpack
//workManager
def work = [:]
work.work_runtime = "androidx.work:work-runtime:2.6.0"
work.work_rxjava2 = "androidx.work:work-rxjava2:2.6.0"
deps.work = work
def nav=[:]
nav.navigation_runtime = "androidx.navigation:navigation-runtime:2.3.5"