Procházet zdrojové kódy

1. 新增人脸底库预览
2. 新增危险源视频标签注入封面
3. 底部物联控制默认设置为白色
4. 增加正在查阅人脸底库不去同步人脸判断

JaycePC před 5 dny
rodič
revize
2e69288e78
27 změnil soubory, kde provedl 341 přidání a 34 odebrání
  1. 1 1
      app/build.gradle
  2. 11 4
      app/src/main/AndroidManifest.xml
  3. binární
      app/src/main/assets/images/play_cover.png
  4. 8 5
      app/src/main/java/xn/xxp/HomeActivity.java
  5. 1 0
      app/src/main/java/xn/xxp/app/InitActivity.java
  6. 5 0
      app/src/main/java/xn/xxp/app/SyncFaceTool.java
  7. 5 3
      app/src/main/java/xn/xxp/home/auth/ChoiceAuthActivity.java
  8. 5 1
      app/src/main/java/xn/xxp/home/auth/fragment/LzFaceAuthFragment.java
  9. 72 0
      app/src/main/java/xn/xxp/home/setting/FaceAdapter.java
  10. 48 0
      app/src/main/java/xn/xxp/home/setting/FaceListActivity.java
  11. 9 1
      app/src/main/java/xn/xxp/app/SettingActivity.java
  12. 3 1
      app/src/main/java/xn/xxp/home/sign/SafetyCheckFragment.kt
  13. 11 6
      app/src/main/java/xn/xxp/home/sign/SignInActivity.kt
  14. 2 2
      app/src/main/java/xn/xxp/main/MainActivity.kt
  15. 5 0
      app/src/main/java/xn/xxp/main/monitor/MonitorActivity.java
  16. 2 0
      app/src/main/java/xn/xxp/main/risk/RiskListActivity.java
  17. 5 3
      app/src/main/java/xn/xxp/main/things/ThingsActivity.kt
  18. 27 7
      app/src/main/java/xn/xxp/widget/ItemBoardView.kt
  19. 11 0
      app/src/main/res/drawable-anydpi/ic_face.xml
  20. binární
      app/src/main/res/drawable-hdpi/ic_face.png
  21. binární
      app/src/main/res/drawable-mdpi/ic_face.png
  22. binární
      app/src/main/res/drawable-xhdpi/ic_face.png
  23. binární
      app/src/main/res/drawable-xxhdpi/ic_face.png
  24. 57 0
      app/src/main/res/layout/activity_face_list.xml
  25. 17 0
      app/src/main/res/layout/activity_setting.xml
  26. 35 0
      app/src/main/res/layout/item_face.xml
  27. 1 0
      gradle/libs.versions.toml

+ 1 - 1
app/build.gradle

@@ -19,7 +19,7 @@ android {
         minSdk 31
         targetSdk 35
         versionCode 2
-        versionName "2.0"
+        versionName "2.3"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         room {

+ 11 - 4
app/src/main/AndroidManifest.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools">
+    xmlns:tools="http://schemas.android.com/tools" >
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -33,7 +33,10 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/Theme.西农电子信息牌"
-        android:usesCleartextTraffic="true">
+        android:usesCleartextTraffic="true" >
+        <activity
+            android:name=".home.setting.FaceListActivity"
+            android:exported="false" />
         <activity
             android:name=".home.leave.LeaveActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
@@ -70,6 +73,10 @@
             android:name=".main.risk.RiskListActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="false" />
+        <activity
+            android:name=".home.sign.SignInActivity"
+            android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
+            android:exported="false" />
         <activity
             android:name=".main.person.LaboratoryPersonActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
@@ -104,14 +111,14 @@
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="false" />
         <activity
-            android:name=".app.SettingActivity"
+            android:name=".home.setting.SettingActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="false" />
         <activity
             android:name=".StartActivity"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="true"
-            android:launchMode="singleTop">
+            android:launchMode="singleTop" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 

binární
app/src/main/assets/images/play_cover.png


+ 8 - 5
app/src/main/java/xn/xxp/HomeActivity.java

@@ -37,7 +37,7 @@ import http.vo.response.LabWarnVo;
 import kotlin.Unit;
 import kotlin.jvm.functions.Function1;
 import xn.xxp.app.InitActivity;
-import xn.xxp.app.SettingActivity;
+import xn.xxp.home.setting.SettingActivity;
 import xn.xxp.app.SyncFaceTool;
 import xn.xxp.databinding.ActivityHomeBinding;
 import xn.xxp.home.AccessVerify;
@@ -341,10 +341,13 @@ public class HomeActivity extends BaseCountDownActivity<ActivityHomeBinding> imp
         if (null == windowFragment) {
             windowFragment = new WindowFragment();
         }
-        Fragment topFragment = FragmentUtils.getTop(fragmentManager);
-        if (!(topFragment instanceof WindowFragment)) {
-            FragmentUtils.replace(fragmentManager, windowFragment, R.id.container, R.anim.from_right, R.anim.out_right);
-            switchPersonPanel(View.VISIBLE);
+        List<FragmentUtils.FragmentNode> fragmentNodeList = FragmentUtils.getAllFragments(fragmentManager);
+        if (fragmentNodeList != null && !fragmentNodeList.isEmpty()) {
+            Fragment topFragment = FragmentUtils.getTop(fragmentManager);
+            if (!(topFragment instanceof WindowFragment)) {
+                FragmentUtils.replace(fragmentManager, windowFragment, R.id.container, R.anim.from_right, R.anim.out_right);
+                switchPersonPanel(View.VISIBLE);
+            }
         }
     }
 

+ 1 - 0
app/src/main/java/xn/xxp/app/InitActivity.java

@@ -37,6 +37,7 @@ import http.client.HttpTool;
 import http.vo.response.LaboratoryVo;
 import io.reactivex.rxjava3.functions.Consumer;
 import xn.xxp.HomeActivity;
+import xn.xxp.home.setting.SettingActivity;
 import xn.xxp.room.bean.DeviceConfig;
 import xn.xxp.room.bean.LabConfig;
 import http.vo.response.TerminalAuthResp;

+ 5 - 0
app/src/main/java/xn/xxp/app/SyncFaceTool.java

@@ -41,6 +41,7 @@ import java.util.Map;
 import http.client.HttpTool;
 import okhttp3.Response;
 import xn.xxp.home.auth.ChoiceAuthActivity;
+import xn.xxp.home.setting.FaceListActivity;
 import xn.xxp.room.RoomTool;
 import xn.xxp.room.bean.Face;
 import xn.xxp.room.dao.FaceDao;
@@ -70,6 +71,10 @@ public enum SyncFaceTool {
             LogUtils.d("人脸识别中,不去同步人脸!");
             return;
         }
+        if (topActivity instanceof FaceListActivity) {
+            LogUtils.d("正在查阅底库,不去同步人脸!");
+            return;
+        }
         if (isSyncFace) {
             LogUtils.d("正在同步人脸");
             return;

+ 5 - 3
app/src/main/java/xn/xxp/home/auth/ChoiceAuthActivity.java

@@ -70,7 +70,7 @@ public class ChoiceAuthActivity extends BaseSignActivity<ActivityAuthChoiceBindi
             noticeSummaryList = new ArrayList<>();
         }
         binding.titleBar.updateNotice(noticeSummaryList);
-        
+
         deviceConfig = RoomTool.getInstance().deviceConfigDao().getDeviceConfig();
         labConfig = RoomTool.getInstance().labConfigDao().getLabConfig();
         String access = getIntent().getStringExtra("access");
@@ -126,8 +126,10 @@ public class ChoiceAuthActivity extends BaseSignActivity<ActivityAuthChoiceBindi
     @Override
     protected void onSignInFinish(boolean completed) {
         super.onSignInFinish(completed);
-        if (completed) LabApp.userVo = null;
-        Tool.INSTANCE.openDoor();
+        if (completed) {
+            LabApp.userVo = null;
+            Tool.INSTANCE.openDoor();
+        }
         finish();
     }
 

+ 5 - 1
app/src/main/java/xn/xxp/home/auth/fragment/LzFaceAuthFragment.java

@@ -182,10 +182,12 @@ public class LzFaceAuthFragment extends RcBaseFragment<FragmentAuthLzFaceBinding
             FaceIdentifyData[] datas = FaceUtils.getInstance().getIdentifyResultDatas();
             if (datas != null && datas.length > 0) {
                 ThreadUtils.cancel(faceTask);
+                LogUtils.json("识别到人", datas);
                 faceTask = new ThreadUtils.SimpleTask<UserVo>() {
                     @Override
                     public UserVo doInBackground() throws Throwable {
                         FaceIdentifyData faceIdentifyData = datas[0];
+                        LogUtils.json("识别结果", faceIdentifyData);
                         String faceId = faceIdentifyData.getFaceId();
                         if (null == faceId || faceId.isEmpty() || null == faceList) {
                             return null;
@@ -208,13 +210,14 @@ public class LzFaceAuthFragment extends RcBaseFragment<FragmentAuthLzFaceBinding
 
                     @Override
                     public void onSuccess(UserVo result) {
+                        LogUtils.json("识别结果", result);
                         if (!isDetached()) {
                             if (result == null) {
                                 ThreadUtils.runOnUiThreadDelayed(() -> {
                                     checking = false;
                                     FaceUtils.getInstance().startFaceRecog();
                                 }, 1000);
-                                showToast("人员未授权,请重试!");
+                                showToast("识别失败,请重试!");
                             } else {
                                 ThreadUtils.cancel(labUserTask);
                                 labUserTask = new ThreadUtils.SimpleTask<Triple<Integer, String, UserVo>>() {
@@ -224,6 +227,7 @@ public class LzFaceAuthFragment extends RcBaseFragment<FragmentAuthLzFaceBinding
                                             Response response = HttpTool.getLabStatusById(String.valueOf(labConfig.getLabId()), result.userId);
                                             if (response.isSuccessful()) {
                                                 String json = response.body().string();
+                                                LogUtils.d("识别准入", json);
                                                 JSONObject jsonObject = new JSONObject(json);
                                                 int code = jsonObject.getInt("code");
                                                 String message = jsonObject.getString("message");

+ 72 - 0
app/src/main/java/xn/xxp/home/setting/FaceAdapter.java

@@ -0,0 +1,72 @@
+package xn.xxp.home.setting;
+
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import com.bumptech.glide.Glide;
+import com.njlz.face.FaceUtils;
+
+import java.util.List;
+
+import http.client.HttpTool;
+import xn.xxp.databinding.ItemFaceBinding;
+import xn.xxp.room.RoomTool;
+import xn.xxp.room.bean.Face;
+
+public class FaceAdapter extends BaseAdapter {
+    private final List<String> faceIdList;
+
+    public FaceAdapter(List<String> faceIdList) {
+        this.faceIdList = faceIdList;
+    }
+
+    @Override
+    public int getCount() {
+        return null != faceIdList && !faceIdList.isEmpty() ? faceIdList.size() : 0;
+    }
+
+    @Override
+    public String getItem(int position) {
+        return null != faceIdList && !faceIdList.isEmpty() ? faceIdList.get(position) : null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return 0;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder viewHolder;
+        if (convertView == null) {
+            ItemFaceBinding binding = ItemFaceBinding.inflate(LayoutInflater.from(parent.getContext()));
+            convertView = binding.getRoot();
+            viewHolder = new ViewHolder(binding);
+            convertView.setTag(viewHolder);
+        } else {
+            viewHolder = (ViewHolder) convertView.getTag();
+        }
+        String faceId = getItem(position);
+        if (null != faceId) {
+            Face face = RoomTool.getInstance().faceDao().getById(Long.parseLong(faceId));
+            if (null != face) {
+                Glide.with(viewHolder.binding.iv).load(HttpTool.checkUrl(face.getFaceUrl())).into(viewHolder.binding.iv);
+                viewHolder.binding.name.setText(TextUtils.isEmpty(face.getUserName()) ? "" : face.getUserName());
+            }
+            viewHolder.binding.faceId.setText(TextUtils.isEmpty(faceId) ? "" : faceId);
+        }
+
+        return convertView;
+    }
+
+    static class ViewHolder {
+        private final ItemFaceBinding binding;
+
+        public ViewHolder(ItemFaceBinding binding) {
+            this.binding = binding;
+        }
+    }
+}

+ 48 - 0
app/src/main/java/xn/xxp/home/setting/FaceListActivity.java

@@ -0,0 +1,48 @@
+package xn.xxp.home.setting;
+
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+
+import androidx.activity.EdgeToEdge;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.blankj.utilcode.util.Utils;
+import com.njlz.face.FaceUtils;
+
+import java.util.List;
+
+import xn.xxp.R;
+import xn.xxp.databinding.ActivityFaceListBinding;
+
+public class FaceListActivity extends AppCompatActivity {
+
+    private FaceAdapter faceAdapter;
+    private ActivityFaceListBinding binding;
+    private List<String> faceIdList;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        binding = ActivityFaceListBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
+        FaceUtils.getInstance().init(Utils.getApp());
+        faceIdList = FaceUtils.getInstance().getAllFaceId();
+        faceAdapter = new FaceAdapter(faceIdList);
+        binding.faceGV.setAdapter(faceAdapter);
+        binding.back.setOnClickListener(v -> finish());
+        if (null != faceIdList && !faceIdList.isEmpty()) {
+            binding.size.setText("共" + faceIdList.size() + "人");
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        FaceUtils.getInstance().destroy();
+    }
+}

+ 9 - 1
app/src/main/java/xn/xxp/app/SettingActivity.java

@@ -1,4 +1,4 @@
-package xn.xxp.app;
+package xn.xxp.home.setting;
 
 import android.annotation.SuppressLint;
 import android.os.Bundle;
@@ -10,6 +10,7 @@ import android.view.View;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 
+import com.blankj.utilcode.util.ActivityUtils;
 import com.blankj.utilcode.util.AppUtils;
 import com.blankj.utilcode.util.LogUtils;
 import com.blankj.utilcode.util.RegexUtils;
@@ -109,6 +110,13 @@ public class SettingActivity extends AppCompatActivity {
             binding.oldPasswordET.setText(deviceConfig.getAdminPas());
             // 保存
             binding.save.setOnClickListener(v -> saveAndReStart());
+            // 人脸
+            binding.faceBT.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    ActivityUtils.startActivity(FaceListActivity.class);
+                }
+            });
 
             binding.testBaseUrlBT.setOnClickListener(v -> binding.httpUriET.setText("http://192.168.1.8/api/"));
             binding.xnBaseUrlBT.setOnClickListener(v -> binding.httpUriET.setText("http://172.16.0.65/api/"));

+ 3 - 1
app/src/main/java/xn/xxp/home/sign/SafetyCheckFragment.kt

@@ -380,7 +380,9 @@ class SafetyCheckFragment :
                     ).apply {
                         setCancelable(false)
                         setOnDismissListener {
-                            requireActivity().finish() }
+                            Tool.INSTANCE.openDoor()
+                            requireActivity().finish()
+                        }
                         show()
                     }
                 }

+ 11 - 6
app/src/main/java/xn/xxp/home/sign/SignInActivity.kt

@@ -1,5 +1,6 @@
 package xn.xxp.home.sign
 
+import android.os.Build
 import android.os.Bundle
 import androidx.lifecycle.ViewModelProvider
 import core.ui.activity.BaseCountDownActivity
@@ -33,12 +34,16 @@ open class SignInActivity : BaseCountDownActivity<ActivitySignInBinding>(), ICou
     override fun initViews(savedInstanceState: Bundle?) {
         super.initViews(savedInstanceState)
         viewModel.setSignType(mSignType)
-        viewModel.setSignFace(
-            intent.getParcelableExtra(
-                "sign_face",
-                SignFaceVo::class.java
-            ) as SignFaceVo
-        )
+
+        val signFace = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // API 33
+            intent.getParcelableExtra("sign_face", SignFaceVo::class.java)
+        } else {
+            @Suppress("DEPRECATION")
+            intent.getParcelableExtra("sign_face") as? SignFaceVo
+        }
+        if (null != signFace) {
+            viewModel.setSignFace(signFace)
+        }
         showDefaultFragment()
     }
 

+ 2 - 2
app/src/main/java/xn/xxp/main/MainActivity.kt

@@ -44,9 +44,8 @@ import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import xn.xxp.R
 import xn.xxp.app.LabApp
-import xn.xxp.app.SettingActivity
+import xn.xxp.home.setting.SettingActivity
 import xn.xxp.databinding.ActivityMainBinding
-import xn.xxp.home.lab_info.LabDetailActivity
 import xn.xxp.main.monitor.MonitorActivity
 import xn.xxp.main.person.LaboratoryPersonActivity
 import xn.xxp.main.risk.RiskListActivity
@@ -432,6 +431,7 @@ class MainActivity :
 
     lateinit var labConfig: LabConfig
     override fun initData() {
+        Tool.INSTANCE.openDoor()
         labConfig = RoomTool.getInstance().labConfigDao().labConfig
         val laboratoryVo = LabApp.laboratory
         if (null == laboratoryVo || null == labConfig) {

+ 5 - 0
app/src/main/java/xn/xxp/main/monitor/MonitorActivity.java

@@ -3,6 +3,7 @@ package xn.xxp.main.monitor;
 import android.content.DialogInterface;
 import android.graphics.SurfaceTexture;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.TextureView;
 import android.view.View;
 import android.view.ViewTreeObserver;
@@ -196,12 +197,16 @@ public class MonitorActivity extends BaseCountDownActivity<ActivityMonitorBindin
                             dismissLoading();
                         }
                     });
+                } else {
+                    dismissLoading();
+                    showToast("无监控信息!");
                 }
             }
         }, new Consumer<Throwable>() {
             @Override
             public void accept(Throwable throwable) throws Throwable {
                 dismissLoading();
+                LogUtils.e(Log.getStackTraceString(throwable));
             }
         }));
     }

+ 2 - 0
app/src/main/java/xn/xxp/main/risk/RiskListActivity.java

@@ -204,6 +204,7 @@ public class RiskListActivity extends BaseCountDownActivity<ActivityRiskListBind
             String width = video.attr("width");
             String height = video.attr("height");
             String src = video.attr("src");
+            String poster = video.attr("poster");
             // 清除所有属性
             video.clearAttributes();
             // 重新设置需要保留的属性
@@ -219,6 +220,7 @@ public class RiskListActivity extends BaseCountDownActivity<ActivityRiskListBind
             if (!src.isEmpty()) {
                 video.attr("src", src);
             }
+            video.attr("poster", "file:///android_asset/images/play_cover.png");
 
             // 移除video标签内的所有子元素(如source标签)
             video.html("");

+ 5 - 3
app/src/main/java/xn/xxp/main/things/ThingsActivity.kt

@@ -3,6 +3,7 @@ package xn.xxp.main.things
 import android.os.Bundle
 import android.view.View
 import androidx.recyclerview.widget.GridLayoutManager
+import com.blankj.utilcode.util.LogUtils
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.viewholder.BaseViewHolder
 import core.ui.activity.BaseCountDownActivity
@@ -67,10 +68,11 @@ open class ThingsActivity :
         val horizontalSpacing = Tool.INSTANCE.dip2px(25f)
         val spanCount = Tool.INSTANCE.spanCount(gridExpectedSize, offset, horizontalSpacing)
         binding.lotThings.layoutManager = GridLayoutManager(this, spanCount)
+        val verticalSpacing = Tool.INSTANCE.dip2px(16f)
         val decor = GridSpacingItemDecoration(
-            spanCount,
-            horizontalSpacing,
-            Tool.INSTANCE.dip2px(16f), false
+            3,
+            28,
+            24, false
         )
         binding.lotThings.addItemDecoration(decor)
         binding.lotThings.adapter = mLotThingsAdapter

+ 27 - 7
app/src/main/java/xn/xxp/widget/ItemBoardView.kt

@@ -2,27 +2,33 @@ package xn.xxp.widget
 
 import android.content.Context
 import android.graphics.Color
-import android.graphics.Paint
 import android.graphics.PorterDuff
 import android.graphics.PorterDuffColorFilter
 import android.graphics.drawable.AnimationDrawable
-import android.graphics.drawable.PictureDrawable
 import android.text.SpannableString
 import android.text.Spanned
 import android.text.TextUtils
 import android.text.style.RelativeSizeSpan
 import android.util.AttributeSet
 import android.view.LayoutInflater
+import android.widget.ImageView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.ContextCompat
-import coil.ImageLoader
 import coil.decode.SvgDecoder
-import coil.load
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
 import xn.xxp.R
 import xn.xxp.databinding.WidgetItemBoardBinding
 
+import android.graphics.*
+import android.graphics.drawable.VectorDrawable
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.graphics.applyCanvas
+import coil.ImageLoader
+import coil.load
+import coil.request.ImageRequest
+import coil.size.Size
+import coil.transform.Transformation
+
 /**
  * info
  *
@@ -57,7 +63,10 @@ class ItemBoardView @JvmOverloads constructor(
 //        val tintPaint = Paint().apply {
 //            colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
 //        }
-        viewBinding.sensorIcon.load(url)
+        viewBinding.sensorIcon.load(url) {
+            decoderFactory { result, options, _ -> SvgDecoder(result.source, options) }
+            transformations(WhiteTintTransformation())
+        }
 //        Glide.with(this)
 //            .`as`(PictureDrawable::class.java)
 //            .transition(DrawableTransitionOptions.withCrossFade())
@@ -66,6 +75,17 @@ class ItemBoardView @JvmOverloads constructor(
 //            .into(viewBinding.sensorIcon)
     }
 
+    class WhiteTintTransformation : Transformation {
+        override val cacheKey: String = "white_tint"
+
+        override suspend fun transform(input: Bitmap, size: Size): Bitmap {
+            return input.apply {
+                Canvas(this).drawColor(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
+            }
+        }
+    }
+
+
     fun setSensorValue(value: String?, unit: String?, warning: Boolean, online: Boolean) {
         val formatVal = SpannableString("${value ?: ""}${unit ?: ""}")
         if (null != unit) {

+ 11 - 0
app/src/main/res/drawable-anydpi/ic_face.xml

@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#333333"
+    android:alpha="0.6">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
+</vector>

binární
app/src/main/res/drawable-hdpi/ic_face.png


binární
app/src/main/res/drawable-mdpi/ic_face.png


binární
app/src/main/res/drawable-xhdpi/ic_face.png


binární
app/src/main/res/drawable-xxhdpi/ic_face.png


+ 57 - 0
app/src/main/res/layout/activity_face_list.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".home.setting.FaceListActivity">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="56dp"
+        android:background="@color/black">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:text="设置"
+            android:textColor="@color/white"
+            android:textSize="27sp"
+            android:textStyle="bold" />
+
+        <TextView
+            android:id="@+id/size"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_marginStart="10dp"
+            android:textColor="@color/white"
+            android:textSize="27sp"
+            android:textStyle="bold" />
+
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
+            android:layout_marginEnd="5dp"
+            android:text="关闭" />
+
+    </RelativeLayout>
+
+    <GridView
+        android:id="@+id/faceGV"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:horizontalSpacing="8dp"
+        android:numColumns="3"
+        android:stretchMode="columnWidth"
+        android:verticalSpacing="8dp"
+        tools:listitem="@layout/item_face" />
+
+</LinearLayout>

+ 17 - 0
app/src/main/res/layout/activity_setting.xml

@@ -216,6 +216,22 @@
                         android:text="系统设置" />
                 </androidx.cardview.widget.CardView>
 
+                <androidx.cardview.widget.CardView
+                    android:layout_width="wrap_content"
+                    android:layout_height="50dp"
+                    android:layout_margin="5dp">
+
+                    <androidx.appcompat.widget.AppCompatButton
+                        android:id="@+id/face_BT"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center"
+                        android:layout_marginHorizontal="10dp"
+                        android:drawableStart="@drawable/ic_face"
+                        android:drawablePadding="10dp"
+                        android:text="人脸底库" />
+                </androidx.cardview.widget.CardView>
+
             </com.google.android.flexbox.FlexboxLayout>
 
             <com.google.android.flexbox.FlexboxLayout
@@ -395,6 +411,7 @@
 
                 </androidx.cardview.widget.CardView>
 
+
             </com.google.android.flexbox.FlexboxLayout>
         </LinearLayout>
     </androidx.core.widget.NestedScrollView>

+ 35 - 0
app/src/main/res/layout/item_face.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="640px"
+    android:layout_height="wrap_content"
+    tools:ignore="PxUsage">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv"
+        android:layout_width="300px"
+        android:layout_height="300px" />
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="wrap_content"
+        android:layout_height="150px"
+        android:layout_marginStart="10px"
+        android:layout_toEndOf="@id/iv"
+        android:gravity="center_vertical"
+        android:text="名字"
+        android:textSize="40px"
+        android:textStyle="bold" />
+
+
+    <TextView
+        android:id="@+id/faceId"
+        android:layout_width="wrap_content"
+        android:layout_height="150px"
+        android:layout_below="@id/name"
+        android:layout_marginStart="10px"
+        android:layout_toEndOf="@id/iv"
+        android:gravity="center_vertical"
+        android:text="人脸id"
+        android:textSize="25px" />
+</RelativeLayout>

+ 1 - 0
gradle/libs.versions.toml

@@ -53,6 +53,7 @@ androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref =
 androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" }
 androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "swiperefreshlayout" }
 androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "workRuntime" }
+coil-base = { module = "io.coil-kt:coil-base", version.ref = "coil" }
 coil-svg = { module = "io.coil-kt:coil-svg", version.ref = "coilSvg" }
 coil = { module = "io.coil-kt:coil", version.ref = "coil" }
 converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }