package com.doumee.keyCabinet.ui.face; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.Observer; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.text.TextWatcher; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.alibaba.fastjson.JSON; 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.R; import com.doumee.keyCabinet.base.MyBaseActivity; import com.doumee.keyCabinet.bean.FaceUserBean; import com.doumee.keyCabinet.databinding.AddFaceActivityBinding; import com.doumee.keyCabinet.ui.face.adapter.FaceRcvAdapter; import com.doumee.keyCabinet.ui.view.TipDialog; import com.doumee.keyCabinet.utils.face.FaceUtils; import com.example.datalibrary.api.FaceApi; import com.example.datalibrary.listener.DBLoadListener; import com.example.datalibrary.manager.FaceSDKManager; import com.example.datalibrary.model.KeyboardsUtils; import com.example.datalibrary.model.User; import java.util.ArrayList; import java.util.List; import dagger.hilt.android.AndroidEntryPoint; import timber.log.Timber; @AndroidEntryPoint public class AddFaceActivity extends MyBaseActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, TipDialog.OnTipDialogClickListener { // view private RecyclerView mRecyclerUserManager; private ImageView mImageIconSearch; // title中的搜索按钮 private RelativeLayout mRelativeStandard; // title中的常规布局 private LinearLayout mLinearSearch; // title中的搜索布局 private boolean isCheck = false; // title菜单点击状态 private TextView mTextCancel; // title中的取消按钮 private RelativeLayout mRelativeEmpty; // 暂无内容 private TextView mTextEmpty; private EditText mEditTitleSearch; private RelativeLayout mRelativeDelete; // 导入人脸布局 private CheckBox mCheckAll; // 全选 private TextView mTextDelete; // 导入人脸 private TextView textAll; private TipDialog mTipDialog; private Context mContext; private FaceRcvAdapter mFaceUserAdapter; private List mUserInfoList; private int mSelectCount; // 选中的个数 private boolean mIsLongClick; // 是否是长按 private ProgressBar progressBar; private TextView progressText; private View progressGroup; @Override public int getLayoutId() { return R.layout.add_face_activity; } @Override public void initView(@Nullable Bundle savedInstanceState) { isAddCountTimer = false; normalConfig(); getDB().setModel(getVM()); mContext = this; initView(); } @Override public void initData(@Nullable Bundle savedInstanceState) { getVM().getDatasLD().observe(this, new Observer>() { @Override public void onChanged(List beans) { mUserInfoList = beans; if (beans == null || beans.size() == 0) { mFaceUserAdapter.refreshData(new ArrayList<>()); mFaceUserAdapter.notifyDataSetChanged(); mRelativeEmpty.setVisibility(View.VISIBLE); mRecyclerUserManager.setVisibility(View.GONE); // 显示无内容判断 if (mEditTitleSearch.getText().length()>0) { mTextEmpty.setText(getString(R.string.addface_zwnr)); updateDeleteUI(false); } else { mTextEmpty.setText(getString(R.string.addface_tip1)); mRelativeDelete.setVisibility(View.GONE); } return; } // 恢复默认状态 resetDeleteData(); mRelativeEmpty.setVisibility(View.GONE); mRecyclerUserManager.setVisibility(View.VISIBLE); mFaceUserAdapter.refreshData(mUserInfoList); mFaceUserAdapter.notifyDataSetChanged(); } }); getVM().getDatas(); } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); handler = null; } private Handler handler = new Handler(){ @Override public void handleMessage(@NonNull Message msg) { if(!isFinishing()){ switch (msg.what){ case 0: if(finishCount(),finishCount); if(failCount>0){ Toast.makeText(mContext, String.format(getString(R.string.addface_tip2),failCount,failStr.toString()), Toast.LENGTH_LONG).show(); } } break; } } } }; private List selectBeans = new ArrayList<>(); private int finishCount = 0; private int failCount = 0; private StringBuilder failStr = new StringBuilder(); private void datasToBitmap(FaceUserBean bean){ // 使用 Glide 加载图片并转换为 Bitmap Glide.with(this) .asBitmap() .load(bean.getFaceImg()) .addListener(new RequestListener() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { //加载失败 Timber.d("====>图片下载失败%s",bean.getMemberName()); failCount++; if(failStr.length()>0){ failStr.append(","); } failStr.append(bean.getMemberName()); finishCount++; loadListener.onLoad(finishCount, mSelectCount, finishCount * 1.0f / mSelectCount); if (finishCount == mSelectCount) { loadListener.onComplete(new ArrayList<>(), finishCount); if(failCount>0){ Toast.makeText(mContext, String.format(getString(R.string.addface_tip2),failCount,failStr.toString()), Toast.LENGTH_LONG).show(); } } handler.sendEmptyMessage(0); return false; } @Override public boolean onResourceReady(Bitmap bitmap, Object model, Target target, DataSource dataSource, boolean isFirstResource) { boolean fail = true; if (bitmap != null) { byte[] secondFeature = new byte[512]; // 提取特征值 float ret = FaceSDKManager.getInstance().personDetect(bitmap, secondFeature, FaceUtils.getInstance().getBDFaceCheckConfig(), AddFaceActivity.this); // 提取特征值 if (ret != -1) { //有人脸 // 判断质量检测,针对模糊度、遮挡、角度 if (ret == 128) { Timber.d("====>图片特征抽取成功: %s", bean.getMemberName()); //插入数据库 User user = FaceApi.getInstance().getByUserId(bean.getGroupId(), bean.getMemberId().toString()); boolean isSave = false; if (user == null) { //新增 isSave = FaceApi.getInstance().registerUserIntoDBmanager(bean.getGroupId(), bean.getMemberId().toString(), bean.getMemberName(), bean.getFaceImg(), JSON.toJSONString(bean), secondFeature); } else { //更新 user.setUserName(bean.getMemberName()); user.setImageName(bean.getFaceImg()); user.setFeature(secondFeature); isSave = FaceApi.getInstance().userUpdateOnly(user); } if (isSave) { //保存成功 Timber.d("====>录入成功%s",bean.getMemberName()); fail = false; } else { Timber.d("====>录入失败%s",bean.getMemberName()); } } else { Timber.d("====>图片特征抽取失败%s",bean.getMemberName()); } } else { // 上传图片无人脸隐藏 Timber.d("====>图片特征抽取失败%s",bean.getMemberName()); } } if(fail){ failCount++; if(failStr.length()>0){ failStr.append(","); } failStr.append(bean.getMemberName()); }else { bean.setChecked(false); } finishCount++; loadListener.onLoad(finishCount, mSelectCount, finishCount * 1.0f / mSelectCount); if (finishCount == mSelectCount) { loadListener.onComplete(new ArrayList<>(), finishCount); if(failCount>0){ Toast.makeText(mContext, String.format(getString(R.string.addface_tip2),failCount,failStr.toString()), Toast.LENGTH_LONG).show(); } } handler.sendEmptyMessage(0); return false; } }) .into(new SimpleTarget() { @Override public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition transition) { } }); /*FrescoUtils.loadImage(this, bean.getFaceUrl(), 0, 0, new IResult() { @Override public void onResult(Bitmap bitmap) { if(handler.hasMessages(0)){ handler.removeMessages(0); } boolean fail = true; if (bitmap != null) { byte[] secondFeature = new byte[512]; // 提取特征值 float ret = FaceSDKManager.getInstance().personDetect(bitmap, secondFeature, FaceUtils.getInstance().getBDFaceCheckConfig(), AddFaceActivity.this); if (bitmap != null && !bitmap.isRecycled()) { //销毁图片 bitmap.recycle(); } // 提取特征值 if (ret != -1) { //有人脸 // 判断质量检测,针对模糊度、遮挡、角度 if (ret == 128) { Timber.d("====>图片特征抽取成功: %s", bean.getMemberName()); //插入数据库 User user = FaceApi.getInstance().getByUserId(bean.getType(), bean.getId()); boolean isSave = false; if (user == null) { //新增 isSave = FaceApi.getInstance().registerUserIntoDBmanager(bean.getType(), bean.getId(), bean.getMemberName(), bean.getFaceUrl(), JSON.toJSONString(bean), secondFeature); } else { //更新 user.setUserName(bean.getMemberName()); user.setImageName(bean.getFaceUrl()); user.setFeature(secondFeature); isSave = FaceApi.getInstance().userUpdateOnly(user); } if (isSave) { //保存成功 Timber.d("====>录入成功%s",bean.getMemberName()); fail = false; } else { Timber.d("====>录入失败%s",bean.getMemberName()); } } else { Timber.d("====>图片特征抽取失败%s",bean.getMemberName()); } } else { // 上传图片无人脸隐藏 Timber.d("====>图片特征抽取失败%s",bean.getMemberName()); } } else { Timber.d("====>图片下载失败%s",bean.getMemberName()); } bean.setChecked(false); if(fail){ failCount++; if(failStr.length()>0){ failStr.append(","); } failStr.append(bean.getMemberName()); } finishCount++; loadListener.onLoad(finishCount, mSelectCount, finishCount * 1.0f / mSelectCount); if (finishCount == mSelectCount) { loadListener.onComplete(new ArrayList<>(), finishCount); if(failCount>0){ Toast.makeText(mContext, "共"+failCount+"条导入失败【"+failStr.toString()+"】", Toast.LENGTH_LONG).show(); } } } });*/ } private void initView() { mRecyclerUserManager = findViewById(R.id.recycler_user_manager); mRecyclerUserManager.setOnClickListener(this); RecyclerView.LayoutManager layoutManager = new GridLayoutManager(mContext,2); mRecyclerUserManager.setLayoutManager(layoutManager); // title相关的控件 mRelativeStandard = findViewById(R.id.relative_standard); mLinearSearch = findViewById(R.id.linear_title_search); mImageIconSearch = findViewById(R.id.image_icon_research); mImageIconSearch.setOnClickListener(this); mTextCancel = findViewById(R.id.text_cancel); mTextCancel.setOnClickListener(this); mRelativeEmpty = findViewById(R.id.relative_empty); mTextEmpty = findViewById(R.id.text_empty); // 删除相关的控件 mRelativeDelete = findViewById(R.id.relative_botton_delete); mRelativeDelete.setOnClickListener(this); mCheckAll = findViewById(R.id.check_all); mCheckAll.setOnCheckedChangeListener(this); textAll = findViewById(R.id.text_all); textAll.setOnClickListener(this); mTextDelete = findViewById(R.id.text_delete); mTextDelete.setOnClickListener(this); // title中的搜索框取消按钮 Button btnTitleCancel = findViewById(R.id.btn_title_cancel); btnTitleCancel.setOnClickListener(this); ImageView imageBack = findViewById(R.id.image_back); imageBack.setOnClickListener(this); ImageView imageInputDelete = findViewById(R.id.image_input_delete); imageInputDelete.setOnClickListener(this); mTipDialog = new TipDialog(mContext); mTipDialog.setOnTipDialogClickListener(this); mFaceUserAdapter = new FaceRcvAdapter(this, R.layout.face_rcv_item, new FaceRcvAdapter.OnItemClick() { @Override public void onItemClick(FaceUserBean item) { // 如果当前item未选中,则选中 if (item.isChecked()) { mSelectCount++; mTextDelete.setText(getString(R.string.addface_drrl)+"(" + mSelectCount + ")"); mTextDelete.setTextColor(Color.parseColor("#F34B56")); } else { // 如果当前item已经选中,则取消选中 mSelectCount--; mTextDelete.setText(getString(R.string.addface_drrl)+"(" + mSelectCount + ")"); if (mSelectCount == 0) { mTextDelete.setTextColor(Color.parseColor("#666666")); } } } }); mRecyclerUserManager.setAdapter(mFaceUserAdapter); progressBar = findViewById(R.id.progress_bar); progressText = findViewById(R.id.progress_text); progressGroup = findViewById(R.id.progress_group); // title中的搜索框 mEditTitleSearch = findViewById(R.id.edit_title_search); // 搜索框输入监听事件 mEditTitleSearch.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (mUserInfoList!=null&&s != null) { // 读取数据库,获取用户信息 if(s.toString().trim().length()==0){ mFaceUserAdapter.refreshData(mUserInfoList); }else { List beans = new ArrayList<>(); for(FaceUserBean d:mUserInfoList){ if(s.toString().trim().contains(d.getMemberName())){ beans.add(d); } } mFaceUserAdapter.refreshData(beans); } } } @Override public void afterTextChanged(Editable s) { } }); } @Override public void onClick(View v) { int id = v.getId(); if (id == R.id.btn_title_cancel) { // 取消按钮 mEditTitleSearch.setText(""); mLinearSearch.setVisibility(View.GONE); mRelativeStandard.setVisibility(View.VISIBLE); } else if (id == R.id.image_icon_research) { // 搜索按钮 mLinearSearch.setVisibility(View.VISIBLE); mRelativeStandard.setVisibility(View.GONE); } else if (id == R.id.image_back) { finish(); } else if (id == R.id.text_all) { mCheckAll.setChecked(!mCheckAll.isChecked()); }else if (id == R.id.relative_delete) { // 显示导入人脸UI updateDeleteUI(true); } else if (id == R.id.text_cancel) { // 批量导入人脸取消 updateDeleteUI(false); } else if (id == R.id.text_delete) { // 批量导入人脸 if (mSelectCount == 0) { Toast.makeText(mContext, getString(R.string.addface_tip3), Toast.LENGTH_SHORT).show(); return; } if(FaceSDKManager.initStatus != FaceSDKManager.SDK_MODEL_LOAD_SUCCESS){ Toast.makeText(mContext, getString(R.string.addface_tip4), Toast.LENGTH_SHORT).show(); return; } mTipDialog.show(); mTipDialog.setTextTitle(getString(R.string.addface_qrdr)); mTipDialog.setTextMessage(getString(R.string.addface_tip5)); mTipDialog.setTextConfirm(getString(R.string.addface_drrl)+"(" + mSelectCount + ")"); mTipDialog.setCancelable(false); } else if (id == R.id.image_input_delete) { mEditTitleSearch.setText(""); } else if (id == R.id.recycler_user_manager) { KeyboardsUtils.hintKeyBoards(v); } else if (id == R.id.relative_botton_delete) { Timber.d( "relative_botton_delete"); } } /** * 全选多选框的监听事件 */ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { // 全选 mSelectCount = mUserInfoList.size(); for (int i = 0; i < mUserInfoList.size(); i++) { mUserInfoList.get(i).setChecked(true); } mTextDelete.setTextColor(Color.parseColor("#F34B56")); } else { // 取消全选 mSelectCount = 0; for (int i = 0; i < mUserInfoList.size(); i++) { mUserInfoList.get(i).setChecked(false); } mTextDelete.setTextColor(Color.parseColor("#666666")); } mTextDelete.setText(getString(R.string.addface_drrl)+"(" + mSelectCount + ")"); mFaceUserAdapter.notifyDataSetChanged(); } // 对话框“取消”按钮 @Override public void onCancel() { if (mIsLongClick) { resetDeleteData(); mIsLongClick = false; } mFaceUserAdapter.notifyDataSetChanged(); if (mTipDialog != null) { mTipDialog.dismiss(); } } private DBLoadListener loadListener = new DBLoadListener() { @Override public void onStart(final int successCount) { runOnUiThread(new Runnable() { @Override public void run() { progressGroup.setVisibility(View.VISIBLE); progressBar.setProgress(0); progressText.setText(0 + "/" + successCount); } }); } @Override public void onLoad(final int finishCount, final int successCount, final float progress) { // if (successCount > 50 || successCount == 0) { runOnUiThread(new Runnable() { @Override public void run() { Timber.d("====>人脸导入进度%s",finishCount+"=="+successCount+"=="+progress); progressBar.setProgress((int) (progress * 100)); progressText.setText(finishCount + "/" + successCount); } }); // } } @Override public void onComplete(List features, final int successCount) { progressGroup.setVisibility(View.GONE); mFaceUserAdapter.notifyDataSetChanged(); mCheckAll.setChecked(false); } @Override public void onFail(int finishCount, int successCount, List features) { } }; // 对话框“导入人脸”按钮 @Override public void onConfirm(String tipType) { if (mTipDialog != null) { mTipDialog.dismiss(); } if (mSelectCount != 0) { //导入人脸 selectBeans.clear(); for(FaceUserBean bean:mUserInfoList){ if(bean.isChecked()) { selectBeans.add(bean); } } loadListener.onStart(mSelectCount); finishCount = 0; failCount = 0; failStr = new StringBuilder(); handler.sendEmptyMessage(0); } else { updateDeleteUI(false); } } // 更新导入人脸相关的UI private void updateDeleteUI(boolean isShowDeleteUI) { mRelativeDelete.setVisibility(View.VISIBLE); mImageIconSearch.setVisibility(View.GONE); mTextCancel.setVisibility(View.VISIBLE); mFaceUserAdapter.notifyDataSetChanged(); } private void resetDeleteData() { mSelectCount = 0; for (int i = 0; i < mUserInfoList.size(); i++) { mUserInfoList.get(i).setChecked(false); } mTextDelete.setText(getString(R.string.addface_drrl)); } /** * 点击非编辑区域收起键盘 * 获取点击事件 */ @CallSuper @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { View view = getCurrentFocus(); if (KeyboardsUtils.isShouldHideKeyBord(view, ev)) { KeyboardsUtils.hintKeyBoards(view); } } return super.dispatchTouchEvent(ev); } }