rk
3 天以前 4a8ff39b0fab0627ef8f7459587d514cc01c3676
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1186 @@
package com.doumee.keyCabinet.ui.main;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import com.alibaba.fastjson.JSON;
import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon;
import com.bigkoo.convenientbanner.holder.CBViewHolderCreator;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.doumee.keyCabinet.BuildConfig;
import com.doumee.keyCabinet.base.BannerPicResponsePara;
import com.doumee.keyCabinet.bean.FaceUserBean;
import com.doumee.keyCabinet.bean.LoginBean;
import com.doumee.keyCabinet.databinding.MainActivityBinding;
import com.doumee.keyCabinet.event.GetFacesEvent;
import com.doumee.keyCabinet.event.HeartEvent;
import com.doumee.keyCabinet.event.KeyDoorEvent;
import com.doumee.keyCabinet.event.KeyResultEvent;
import com.doumee.keyCabinet.event.KeyStatusListener;
import com.doumee.keyCabinet.event.OpenGridEvent;
import com.doumee.keyCabinet.event.ReLoginEvent;
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.ui.face.ActivationActivity;
import com.doumee.keyCabinet.ui.face.FaceActivity;
import com.doumee.keyCabinet.ui.guide.GuideActivity;
import com.doumee.keyCabinet.ui.keyCabinet.ChangeUrlActivity;
import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity;
import com.doumee.keyCabinet.ui.keyCabinet.ManageLoginActivity;
import com.doumee.keyCabinet.ui.service.FaceUpdateService;
import com.doumee.keyCabinet.ui.service.HeartbeatService;
import com.doumee.keyCabinet.ui.face.AddFaceActivity;
import com.doumee.keyCabinet.ui.face.ErrActivity;
import com.doumee.keyCabinet.ui.face.UserInfoManager;
import com.doumee.keyCabinet.ui.face.UserManagerActivity;
import com.doumee.keyCabinet.ui.view.BannerViewImageHolder;
import com.doumee.keyCabinet.utils.BraceletLogUtils;
import com.doumee.keyCabinet.utils.CrashHandler;
import com.doumee.keyCabinet.utils.LMobileInfo;
import com.doumee.keyCabinet.utils.TimeUtils;
import com.doumee.keyCabinet.utils.face.FaceSDKManager;
import com.doumee.keyCabinet.utils.face.FaceUtils;
import com.doumee.keyCabinet.utils.face.GateConfigUtils;
import com.doumee.keyCabinet.utils.face.ImportFileManager;
import com.doumee.keyCabinet.utils.face.RegisterConfigUtils;
import com.doumee.keyCabinet.utils.face.model.SingleBaseConfig;
import com.doumee.keyCabinet.utils.i485.SerialPortModel;
import com.doumee.keyCabinet.utils.i485.SerialPortReadObserver;
import com.doumee.keyCabinet.utils.i485.SportUtils;
import com.doumee.keyCabinet.utils.update.PermissionUtils;
import com.doumee.keyCabinet.utils.update.PermissiondDialog;
import com.doumee.keyCabinet.utils.update.UpdateUtil;
import com.doumee.lib_coremodel.bean.event.ActionEventData;
import com.doumee.keyCabinet.MApplication;
import com.doumee.keyCabinet.R;
import com.doumee.keyCabinet.base.MyBaseActivity;
import com.doumee.keyCabinet.bean.MemberBean;
import com.doumee.keyCabinet.utils.AdListResponseParam;
import com.doumee.lib_coremodel.http.utils.GsonTools;
import com.doumee.lib_coremodel.util.SpUtil;
import com.doumee.lib_coremodel.util.StringUtil;
import com.example.datalibrary.api.FaceApi;
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.view.PreviewTexture;
import com.yanzhenjie.permission.runtime.Permission;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Logger;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import dagger.hilt.android.AndroidEntryPoint;
import timber.log.Timber;
import static android.Manifest.permission.RECEIVE_BOOT_COMPLETED;
@AndroidEntryPoint
public class MainActivity extends MyBaseActivity<MainVM, MainActivityBinding> {
    private List<AdListResponseParam> lbs = new ArrayList<>();
    //是否已激活
    public static boolean isFaceOk = false;
    private boolean isActivation = false;
    private boolean isDBLoad;
    private PopupWindow popupWindow;
    private Future future;
    //相机相关
    private Camera[] mCamera;
    private PreviewTexture[] previewTextures;
    private static final int PREFER_WIDTH = 640;
    private static final int PREFER_HEIGHT = 480;
    //是否有要更新人脸
    private boolean isNeedUpdateFace;
    //是否正在更新中
    private boolean isUpdatingFace;
    private boolean isUpdateVersion;
    private int downCount = 0;
    private Long lastDownTime;
    private Long showTime;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            if(!isFinishing()){
                switch (msg.what) {
                    case 0:
                    //initM();
                    TimeUtils.updateTimeUi(getVM().dayObs, getVM().timeObs);
                    handler.sendEmptyMessageDelayed(0, 1000);
                    EventBus.getDefault().post(new TimeClockEvent());
                    /*if (isDBLoad && isNeedUpdateFace && !isUpdatingFace) {
                        isNeedUpdateFace = false;
                        getVM().getFaceLD();
                    }
                    getVM().upBraceletLog();*/
                    case 2:
                        getVM().resetReq();
                        break;
                }
            }
        }
    };
    @Override
    public int getLayoutId() {
        return R.layout.main_activity;
    }
    @Override
    public void initView(@Nullable Bundle savedInstanceState) {
        isAddCountTimer = false;
        SpUtil.initWH(this);
        normalConfig();
        getDB().setModel(getVM());
        //initRGBCheck();
        handler.sendEmptyMessageDelayed(0, 1000);
        //启动心跳
        Intent intent = new Intent(MainActivity.this, HeartbeatService.class);
        startService(intent);
        //启动更新人脸
        Intent intent2 = new Intent(MainActivity.this, FaceUpdateService.class);
        startService(intent2);
        getPermission();
        Timber.tag("====>").d(LMobileInfo.getDeviceUniqueId());
        initPort();
    }
    private void initM(){
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(memoryInfo);
        long totalMemory = memoryInfo.totalMem/(1024*1024);
        long availableMemory = memoryInfo.availMem/(1024*1024);
        long usedMemory = totalMemory - availableMemory;
        //getDB().tvM.setText("总内存:"+totalMemory+",使用内存:"+usedMemory+",可用内存:"+availableMemory);
        if((availableMemory<400&&showTime!=null&&(System.currentTimeMillis()-showTime>5000))||
                ("02:00:00".equals(StringUtil.getHM()))){
            //可用内存小于400M,或者每天凌晨2点,重启app
            restartApp();
        }
    }
    private void upErrInfo(){
        List<SpUtil.SPBean> datas = SpUtil.getMatchingStrings(CrashHandler.FILE_NAME);
        for(SpUtil.SPBean data : datas){
            getVM().upErrInfo(data);
        }
    }
    @Override
    public void initData(@Nullable Bundle savedInstanceState) {
        //handler.sendEmptyMessageDelayed(0,1000);
        getDB().tvId.setText("NO:"+LMobileInfo.getDeviceUniqueId());
        getDB().tvVersion.setText("V"+BuildConfig.VERSION_NAME);
        getVM().getFaceLD().observe(this, new Observer<List<FaceUserBean>>() {
            @Override
            public void onChanged(List<FaceUserBean> beans) {
                //更新人脸数据
                if(beans!=null&&beans.size()>0){
                    initModel(beans);
                }
            }
        });
        getDB().img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(lastDownTime!=null){
                    if(System.currentTimeMillis()-lastDownTime>1000){
                        downCount=0;
                    }
                }
                lastDownTime = System.currentTimeMillis();
                Timber.d("downCount="+downCount);
                downCount++;
                if(downCount>4) {
                    downCount=0;
                    lastDownTime=null;
                    initPopupWindow();
                }
            }
        });
        getDB().tv1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //管理员登录
                if(lastDownTime1!=null){
                    if(System.currentTimeMillis()-lastDownTime1>1000){
                        downCount1=0;
                    }
                }
                lastDownTime1 = System.currentTimeMillis();
                downCount1++;
                System.out.println();
                Timber.tag("==>").d(""+downCount1);
                if(downCount1>4) {
                    downCount1=0;
                    lastDownTime1=null;
                    startActivity(ManageLoginActivity.class);
                }
            }
        });
        getDB().tvId.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //更改url
                if(lastDownTime2!=null){
                    if(System.currentTimeMillis()-lastDownTime2>1000){
                        downCount2=0;
                    }
                }
                lastDownTime2 = System.currentTimeMillis();
                downCount2++;
                if(downCount2>4) {
                    downCount2=0;
                    lastDownTime2=null;
                    startActivity(ChangeUrlActivity.class);
                }
            }
        });
        upErrInfo();
        getVM().devHeart();
        BraceletLogUtils.saveLog("app打开");
    }
    boolean isOne;
    private void setBanner(List<BannerPicResponsePara> bannerList){
        getDB().banner.setPages(new CBViewHolderCreator<BannerViewImageHolder>() {
            @Override
            public BannerViewImageHolder createHolder() {
                return new BannerViewImageHolder();
            }
        },bannerList ).setPageIndicator(new int[]{R.drawable.bg_dot_gray, R.drawable.bg_dot_blue});
        isOne = bannerList.size()==1;
        if(!isOne) {
            getDB().banner.startTurning(3000);
        }else {
            getDB().banner.stopTurning();
        }
    }
    private boolean isHavePermission = false;
    //获取权限
    private void getPermission(){
        PermissionUtils.getPermission(this, new PermissionUtils.CallBack() {
            @Override
            public void sucess() {
                //显示
                isHavePermission = true;
                checkUpdate();
            }
            @Override
            public void fail(List<String> permissions) {
                showNoPermissionTip();
            }
        }, new String[]{Permission.WRITE_EXTERNAL_STORAGE,RECEIVE_BOOT_COMPLETED});
    }
    private Long lastDownTime1;
    private int downCount1;
    private Long lastDownTime2;
    private int downCount2;
    @Override
    protected void doRegister(int type, ActionEventData data) {
        switch (type){
            case 2:
            case 3:
                /*tipDownCount = 10;
                isShowTip = true;
                getDB().tvDjs.setText(tipDownCount+"s");
                getDB().tvTip21.setText(getTipText("AC101"), TextView.BufferType.SPANNABLE);
                getDB().clTip.setVisibility(View.VISIBLE);*/
                //校验是否登录
                if(MApplication.getConfigBean().getId()==null){
                    Toast.makeText(mContext, "设备未添加,无法操作", Toast.LENGTH_SHORT).show();
                    getVM().devLogin();
                    return;
                }
                MApplication.getLoginBean().setFlag(type==2?0:1);
                startActivity(FaceActivity.class);
                //startActivity(KeyCabinetActivity.class,b);
                break;
            case 4:
                isShowTip = false;
                getDB().clTip.setVisibility(View.GONE);
                break;
            default:
                break;
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        showTime = System.currentTimeMillis();
        MApplication.setLoginBean(new LoginBean());
        if(!isFaceOk) {
            //initLicense();
        }
        if(isHavePermission) {
            checkUpdate();
        }
        triggerGarbageCollection();
        getVM().resetReq();
        if(!isOne) {
            getDB().banner.startTurning(3000);
        }else {
            getDB().banner.stopTurning();
        }
    }
    // è¿™æ˜¯ä¸€ä¸ªç¤ºä¾‹æ–¹æ³•,用于手动触发垃圾回收
    public void triggerGarbageCollection() {
        // è¯·æ±‚进行垃圾回收
        System.gc();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (future != null && !future.isDone()) {
            future.cancel(true);
        }
        FaceApi.getInstance().cleanRecords();
        handler.removeCallbacksAndMessages(null);
        handler = null;
        faceHandler.removeCallbacksAndMessages(null);
        faceHandler = null;
        portHandler.removeCallbacksAndMessages(null);
        portHandler = null;
    }
    private void restartApp(){
        // åˆ›å»ºä¸€ä¸ªæ–°çš„启动意图
        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);
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(1);
    }
    @Subscribe
    public void GetFacesEvent(GetFacesEvent event){
        if(!isFinishing()&&!isUpdatingFace){
            if(isDBLoad){
                isNeedUpdateFace = false;
                //查询人脸
                getVM().getFaceDatas();
            }else {
                isNeedUpdateFace = true;
            }
        }
    }
    @Subscribe
    public void ReLoginEvent(ReLoginEvent event){
        if(!isFinishing()){
            handler.sendEmptyMessageDelayed(2,20000);
            getVM().devLogin();
        }
    }
    //判断设备是否已激活
    private void initLicense() {
        FaceSDKManager.getInstance().init(mContext, new SdkInitListener() {
            @Override
            public void initStart() {
            }
            public void initLicenseSuccess() {
                //已激活
                isFaceOk = true;
                initDBApi();
            }
            @Override
            public void initLicenseFail(int errorCode, String msg) {
                //未激活,跳转激活页面
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        /*
                         *要执行的操作*/
                        startActivity(new Intent(mContext, ActivationActivity.class));
                    }
                };
                Timer timer = new Timer();
                timer.schedule(task, 2000);
            }
            @Override
            public void initModelSuccess() {
            }
            @Override
            public void initModelFail(int errorCode, String msg) {
            }
        });
    }
    private void initDBApi(){
        if (future != null && !future.isDone()) {
            future.cancel(true);
        }
        isDBLoad = false;
        future = Executors.newSingleThreadExecutor().submit(new Runnable() {
            @Override
            public void run() {
                FaceApi.getInstance().init(new DBLoadListener() {
                    @Override
                    public void onStart(int successCount) {
                        if (successCount < 5000 && successCount != 0){
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    loadProgress(10);
                                }
                            });
                        }
                    }
                    @Override
                    public void onLoad(final int finishCount, final int successCount, final float progress) {
                        if (successCount > 5000 || successCount == 0) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    getDB().progressBar.setProgress((int) (progress * 100));
                                    getDB().progressText.setText(((int) (progress * 100)) + "%");
                                }
                            });
                        }
                    }
                    @Override
                    public void onComplete(final List<User> users , final int successCount) {
//                        FileUtils.saveDBList(HomeActivity.this, users);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                FaceApi.getInstance().setUsers(users);
                                initFaceSDKManager(null);
                                if (successCount > 5000 || successCount == 0) {
                                    getDB().progressGroup.setVisibility(View.GONE);
                                    isDBLoad = true;
                                    isFaceOk = true;
                                }
                            }
                        });
                    }
                    @Override
                    public void onFail(final int finishCount, final int successCount, final List<User> users) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                FaceApi.getInstance().setUsers(users);
                                initFaceSDKManager(null);
                                getDB().progressGroup.setVisibility(View.GONE);
                                Toast.makeText(MainActivity.this, String.format(getString(R.string.main_tip3),successCount,finishCount), Toast.LENGTH_SHORT).show();
                                isDBLoad = true;
                                isFaceOk = true;
                            }
                        });
                    }
                }, mContext);
            }
        });
    }
    private void loadProgress(float i){
        getDB().progressGroup.setVisibility(View.VISIBLE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                getDB().progressBar.setProgress((int) ((i / 5000f) * 100));
                getDB().progressText.setText(((int) ((i / 5000f) * 100)) + "%");
                if (i < 5000){
                    loadProgress(i + 100);
                }else {
                    getDB().progressGroup.setVisibility(View.GONE);
                    isDBLoad = true;
                    isFaceOk = true;
                }
            }
        },10);
    }
    private void initModel(List<FaceUserBean> userBeans) {
        if (com.example.datalibrary.manager.FaceSDKManager.initStatus == com.example.datalibrary.manager.FaceSDKManager.SDK_MODEL_LOAD_SUCCESS) {
            waitUpdate(userBeans);
        }else {
            initFaceSDKManager(userBeans);
        }
    }
    private void initFaceSDKManager(List<FaceUserBean> userBeans){
        //开始后去初始化
        com.example.datalibrary.manager.FaceSDKManager.getInstance().initModel(mContext,
                FaceUtils.getInstance().getBDFaceSDKConfig() , new SdkInitListener() {
                    @Override
                    public void initStart() {
                    }
                    @Override
                    public void initLicenseSuccess() {
                    }
                    @Override
                    public void initLicenseFail(int errorCode, String msg) {
                    }
                    @Override
                    public void initModelSuccess() {
                        com.example.datalibrary.manager.FaceSDKManager.initModelSuccess = true;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(mContext, getString(R.string.main_tip4), Toast.LENGTH_SHORT).show();
                                getDB().progressGroup.setVisibility(View.GONE);
                                if(userBeans!=null){
                                    waitUpdate(userBeans);
                                }
                            }
                        });
                    }
                    @Override
                    public void initModelFail(int errorCode, String msg) {
                        com.example.datalibrary.manager.FaceSDKManager.initModelSuccess = false;
                        if (errorCode != -12) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(mContext, getString(R.string.main_tip5), Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                });
    }
    @Override
    protected void onPause() {
        super.onPause();
        showTime = null;
    }
    private int finishCount;
    private List<FaceUserBean> selectBeans = new ArrayList<>();
    //待更新数据
    private List<FaceUserBean> waitBeans = new ArrayList<>();
    private Handler faceHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            if(!isFinishing()){
                switch (msg.what){
                    case 0:
                        if(finishCount<selectBeans.size()){
                            isUpdatingFace = true;
                            repeatCount = 0;
                            updateFace(selectBeans.get(finishCount));
                        }else {
                            //结束
                            isUpdatingFace = false;
                            //System.out.println("==UpdatingFace==>更新结束:");
                            // æ¸…除内存缓存
                            Glide.get(MainActivity.this).clearMemory();
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    };
    private void waitUpdate(List<FaceUserBean> userBeans){
        if(isUpdatingFace){
            //正在更新
            waitBeans.addAll(userBeans);
        }else {
            selectBeans.clear();
            selectBeans.addAll(waitBeans);
            waitBeans.clear();
            selectBeans.addAll(userBeans);
            finishCount=0;
            faceHandler.sendEmptyMessage(0);
        }
    }
    private int repeatCount = 0;
    private void updateFace(FaceUserBean bean){
        Timber.d("==UpdatingFace==>完成数量 "+finishCount);
        if (TextUtils.isEmpty(bean.getFaceImg())||bean.getFaceImg().endsWith("null")) {
            finishCount++;
            faceHandler.sendEmptyMessage(0);
            return;
        }
        repeatCount++;
        //System.out.println("==UpdatingFace==>开始:" + bean.getName());
        Glide.with(this)
                .asBitmap()
                .load(bean.getFaceImg())
                .addListener(new RequestListener<Bitmap>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                        if(repeatCount==1) {
                            finishCount++;
                        }
                        faceHandler.sendEmptyMessage(0);
                        return false;
                    }
                    @Override
                    public boolean onResourceReady(Bitmap bitmap, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                        if(repeatCount==1) {
                            finishCount++;
                        }
                        if (bitmap != null) {
                            //System.out.println("==UpdatingFace==>开始解析人脸");
                            byte[] secondFeature = new byte[512];
                            ImportFeatureResult result = null;
                            // 10、走人脸SDK接口,通过人脸检测、特征提取拿到人脸特征值
                            try {
                                result = ImportFileManager.getInstance().getFeature(bitmap, secondFeature,
                                        BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO);
                            }catch (OutOfMemoryError e){
                                e.printStackTrace();
                                faceHandler.sendEmptyMessage(0);
                                return false;
                            }catch (Exception e){
                                e.printStackTrace();
                                faceHandler.sendEmptyMessage(0);
                                return false;
                            }
                            // 11、判断是否提取成功:128为成功,-1为参数为空,-2表示未检测到人脸
                            float ret = result.getResult();
                            //System.out.println("==UpdatingFace==>提取特征值" + ret);
                            // æå–特征值
                            if (ret != -1) {
                                //有人脸
                                // åˆ¤æ–­è´¨é‡æ£€æµ‹ï¼Œé’ˆå¯¹æ¨¡ç³Šåº¦ã€é®æŒ¡ã€è§’度
                                if (ret == 128) {
                                    Timber.d("==UpdatingFace==>图片特征抽取成功: %s", JSON.toJSONString(bean));
                                    User user = new User();
                                    user.setUserId(bean.getMemberId());
                                    user.setGroupId(bean.getGroupId());
                                    user.setUserName(bean.getMemberName());
                                    user.setImageName(bean.getFaceImg());
                                    user.setUserInfo(GsonTools.changeGsonToJson(bean));
                                    user.setFeature(secondFeature);
                                    insertOrUpdate(user);
                                    faceHandler.sendEmptyMessage(0);
                                } else {
                                    Timber.e("==UpdatingFace==>图片特征抽取失败: %s", JSON.toJSONString(bean));
                                    if(repeatCount>3) {
                                        faceHandler.sendEmptyMessage(0);
                                    }else {
                                        updateFace(bean);
                                    }
                                }
                            } else {
                                // ä¸Šä¼ å›¾ç‰‡æ— äººè„¸éšè—
                                Timber.e("==UpdatingFace==>图片特征抽取失败: %s", JSON.toJSONString(bean));
                                if(repeatCount>3) {
                                    faceHandler.sendEmptyMessage(0);
                                }else {
                                    updateFace(bean);
                                }
                            }
                        } else {
                            if(repeatCount>3) {
                                faceHandler.sendEmptyMessage(0);
                            }else {
                                updateFace(bean);
                            }
                        }
                        return false;
                    }
                })
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
                    }
                });
    }
    private void insertOrUpdate(User newDo){
        //插入数据库
        //System.out.println("==isOk==>bean" + GsonTools.changeGsonToJson(newDo));
        User user = FaceApi.getInstance().getByUserId(newDo.getGroupId(), newDo.getUserId());
        //System.out.println("==isOk==>查询" + user.getId()+","+user.getUserId()+","+user.getUserName());
        boolean isSave = false;
        if (user == null) {
            //新增
            isSave = FaceApi.getInstance().registerUserIntoDBmanager(newDo.getGroupId(),
                    newDo.getUserId(), newDo.getUserName(), newDo.getImageName(), newDo.getUserInfo(), newDo.getFeature());
            //System.out.println("==isOk==>保存成功");
        } else {
            //更新
            user.setUserName(newDo.getUserName());
            user.setImageName(newDo.getImageName());
            user.setFeature(newDo.getFeature());
            isSave = FaceApi.getInstance().userUpdateOnly(user);
            //System.out.println("==isOk==>更新成功");
        }
        if (isSave) {
            //保存成功
            //System.out.println("==UpdatingFace==>修改成功");
            UserInfoManager.getInstance();
        } else {
            Timber.d("==isOk==>人脸保存失败: %s", JSON.toJSONString(newDo));
        }
    }
    //弹窗
    private void initPopupWindow() {
        if(popupWindow!=null&&popupWindow.isShowing()){
            return;
        }
        View contentView = LayoutInflater.from(mContext).inflate(R.layout.popup_menu_home, null);
        popupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        // ç‚¹å‡»æ¡†å¤–可以使得popupwindow消失
        popupWindow.setFocusable(false);
        popupWindow.setOutsideTouchable(false);
        popupWindow.setTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.showAtLocation(getDB().clRoot, Gravity.CENTER, 0, 0);
        RelativeLayout relativeRegister = contentView.findViewById(R.id.relative_register);
        RelativeLayout mPopRelativeManager = contentView.findViewById(R.id.relative_manager);
        RelativeLayout mPopRelativeCamra = contentView.findViewById(R.id.relative_camra);
        RelativeLayout mRlErr = contentView.findViewById(R.id.rl_err);
        relativeRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(AddFaceActivity.class);
            }
        });
        mPopRelativeManager.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(UserManagerActivity.class);
            }
        });
        mPopRelativeCamra.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //startActivity();
            }
        });
        mRlErr.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(ErrActivity.class);
            }
        });
        //自动关闭
        initHandler();
    }
    private void initHandler() {
        new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                // å®žçŽ°é¡µé¢è·³è½¬
                popupWindow.dismiss();
                return false;
            }
        }).sendEmptyMessageDelayed(0, 5000);
    }
    private void initRGBCheck(){
        if(true){
            return;
        }
        String index = SpUtil.getString("rbgCameraId");
        if(index==null){
            index = "0";
        }
        setRgbCameraId(Integer.parseInt(index));
        /*if (isSetCameraId()){
            return;
        }
        int mCameraNum = Camera.getNumberOfCameras();
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, cameraInfo);
        }
        if (mCameraNum > 1){
            try {
                mCamera = new Camera[mCameraNum];
                previewTextures = new PreviewTexture[mCameraNum];
                mCamera[0] = Camera.open(0);
                previewTextures[0] = new PreviewTexture(this, getDB().checkRgbTexture);
                previewTextures[0].setCamera(mCamera[0], PREFER_WIDTH, PREFER_HEIGHT);
                mCamera[0].setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
                        if (check == 1){
                            setRgbCameraId(0);
                        }
                        release(0);
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                mCamera[1] = Camera.open(1);
                previewTextures[1] = new PreviewTexture(this, getDB().checkNirTexture);
                previewTextures[1].setCamera(mCamera[1], PREFER_WIDTH, PREFER_HEIGHT);
                mCamera[1].setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        int check = StreamUtil.checkNirRgb(data, PREFER_WIDTH, PREFER_HEIGHT);
                        if (check == 1){
                            setRgbCameraId(1);
                        }
                        release(1);
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        } else {
            setRgbCameraId(0);
        }*/
    }
    private void setRgbCameraId(int index){
        //Toast.makeText(mContext, "设置相机"+index, Toast.LENGTH_SHORT).show();
        SpUtil.saveString("rbgCameraId",index+"");
        BraceletLogUtils.saveLog("设置相机("+index+")");
        SingleBaseConfig.getBaseConfig().setRBGCameraId(index);
        SingleBaseConfig.getBaseConfig().setRgbRevert(true);
        SingleBaseConfig.getBaseConfig().setRgbDetectDirection(90);
        SingleBaseConfig.getBaseConfig().setRgbVideoDirection(270);
        GateConfigUtils.modityJson();
        RegisterConfigUtils.modityJson();
    }
    private boolean isSetCameraId(){
        if (SingleBaseConfig.getBaseConfig().getRBGCameraId() == -1){
            return false;
        }else {
            return true;
        }
    }
    private void release(int id){
        if (mCamera != null && mCamera[id] != null) {
            if (mCamera[id] != null) {
                mCamera[id].setPreviewCallback(null);
                mCamera[id].stopPreview();
                previewTextures[id].release();
                mCamera[id].release();
                mCamera[id] = null;
            }
        }
    }
    private void checkUpdate(){
        //版本更新
        new UpdateUtil(this).setShowToast(false).getServerVerCode(new UpdateUtil.VersionCallBack() {
            @Override
            public void isNeedUpdate(boolean isUpdate) {
                isUpdateVersion = isUpdate;
            }
        });
    }
    private PermissiondDialog permissiondDialog;
    private void showNoPermissionTip() {
        try {
            Toast.makeText(this,getString(R.string.guide_permiss_1) , Toast.LENGTH_LONG).show();
            if (permissiondDialog == null) {
                permissiondDialog = new PermissiondDialog(this, getString(R.string.help), getString(R.string.guide_permiss_2), getString(R.string.cancel),
                        getString(R.string.empower), new PermissiondDialog.OnClickListener() {
                    @Override
                    public void clickOk() {
                        permissiondDialog.dismiss();
                        PermissionUtils.gotoPermission(getContext());
                    }
                    @Override
                    public void clickNo() {
                        permissiondDialog.dismiss();
                        finish();
                    }
                });
            }
            if (!permissiondDialog.isShowing()) {
                permissiondDialog.show();
            }
        } catch (Exception e) {
        }
    }
    private int tipDownCount = 10;
    private boolean isShowTip;
    @Subscribe
    public void TimeClockEvent(TimeClockEvent e){
        if(isShowTip){
            if(tipDownCount==0){
                isShowTip = false;
                getDB().clTip.setVisibility(View.GONE);
            }else {
                tipDownCount--;
                getDB().tvDjs.setText(tipDownCount+"s");
            }
        }
    }
    /**
     * ç›‘听开门
     * @param e
     */
    @Subscribe
    public void OpenGridEvent(OpenGridEvent e){
        if(!isFinishing()){
            EventBus.getDefault().post(new KeyDoorEvent(MApplication.nextBoolean()?"0":"1"));
        }
    }
    /**
     * ç›‘听钥匙
     * @param e
     */
    @Subscribe
    public void KeyStatusListener(KeyStatusListener e){
        if(!isFinishing()){
            if(e.getStatus()==0){
                //开始
                Random random = new Random();
                EventBus.getDefault().post(new KeyResultEvent(random.nextBoolean()?"0":"1"));
            }else {
                //结束
            }
        }
    }
    private SpannableString getTipText(String name){
        String text = name+"柜门未关闭";
        SpannableString styledText = new SpannableString(text);
        styledText.setSpan(new TextAppearanceSpan(this, R.style.style_tip1),
                0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        styledText.setSpan(new TextAppearanceSpan(this,R.style.style_tip2), name.length()+1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return styledText;
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        getVM().devHeart();
    }
    @Subscribe
    public void HeartEvent(HeartEvent e){
        if(!isFinishing()){
            getVM().devHeart();
        }
    }
    private SerialPortModel gridPort;
    private SerialPortReadObserver gridReadObserver = new SerialPortReadObserver() {
        @Override
        public void onResult(String result) {
        }
        @Override
        public void onResultBytes(byte[] bytes) {
            if(gridPort!=null && !gridPort.isOk()){
                gridPort.setOk(true);
            }
        }
    };
    private SerialPortModel keyPort;
    private SerialPortReadObserver keyReadObserver = new SerialPortReadObserver() {
        @Override
        public void onResult(String result) {
        }
        @Override
        public void onResultBytes(byte[] bytes) {
            if(keyPort!=null && !keyPort.isOk()){
                keyPort.setOk(true);
            }
        }
    };
    private SerialPortModel jiuPort;
    private SerialPortReadObserver jiuReadObserver = new SerialPortReadObserver() {
        @Override
        public void onResult(String result) {
        }
        @Override
        public void onResultBytes(byte[] bytes) {
            if(jiuPort!=null && !jiuPort.isOk()){
                jiuPort.setOk(true);
            }
        }
    };
    List<String> ports;
    private int index = 0;
    private Handler portHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 0:
                    if(index>=1&&!checkEnd()){
                        index--;
                        chosePort(ports.get(index));
                    }
                    break;
                default:
                    break;
            }
        }
    };
    //初始化串口
    private void initPort(){
        ports = SportUtils.getSerialPortPaths(this);
        if(ports.size()>0){
            index = ports.size()-1;
            chosePort(ports.get(ports.size()-1));
        }
    }
    private void chosePort(String path){
        if(gridPort==null||!gridPort.isOk()){
            closePort(gridPort);
            gridPort = new SerialPortModel(path,9600 ,8
                    ,1 , 0);
            boolean isSucc = gridPort.open();
            if(isSucc) {
                String msg = isSucc ? "成功" : "失败";
                //getVM().append("串口 "+ settingBean.getDevicePath() + " -连接"+msg);
                gridPort.startRead(gridReadObserver);
                //todo å‘送柜格校验信息
            }
        }
        if(keyPort==null||!keyPort.isOk()){
            closePort(keyPort);
            keyPort = new SerialPortModel(path,115200 ,8
                    ,1 , 0);
            boolean isSucc = keyPort.open();
            if(isSucc) {
                String msg = isSucc ? "成功" : "失败";
                //getVM().append("串口 "+ settingBean.getDevicePath() + " -连接"+msg);
                keyPort.startRead(keyReadObserver);
                //todo å‘送钥匙校验信息
            }
        }
        if(jiuPort==null||!jiuPort.isOk()){
            closePort(jiuPort);
            jiuPort = new SerialPortModel(path,9600 ,8
                    ,1 , 0);
            boolean isSucc = jiuPort.open();
            if(isSucc) {
                String msg = isSucc ? "成功" : "失败";
                //getVM().append("串口 "+ settingBean.getDevicePath() + " -连接"+msg);
                jiuPort.startRead(jiuReadObserver);
                //todo å‘送酒精校验信息
            }
        }
        portHandler.sendEmptyMessageDelayed(0,2000);
    }
    private void closePort(SerialPortModel port){
        if(port==null){
            return;
        }
        port.startRead(null);
        port.stopRead();
        port.close();
        port = null;
    }
    private boolean checkEnd(){
        if(gridPort==null||!gridPort.isOk()){
            return false;
        }
        if(keyPort==null||!keyPort.isOk()){
            return false;
        }
        if(jiuPort==null||!jiuPort.isOk()){
            return false;
        }
        return true;
    }
}