|
@@ -2,15 +2,10 @@ package xn.xxp.app;
|
|
|
|
|
|
import android.annotation.SuppressLint;
|
|
|
import android.app.Activity;
|
|
|
-import android.app.DownloadManager;
|
|
|
-import android.content.Context;
|
|
|
-import android.net.Uri;
|
|
|
import android.os.Environment;
|
|
|
-import android.os.FileObserver;
|
|
|
import android.util.Log;
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
-import androidx.annotation.Nullable;
|
|
|
import androidx.annotation.WorkerThread;
|
|
|
import androidx.core.util.Pair;
|
|
|
|
|
@@ -32,15 +27,27 @@ import org.greenrobot.eventbus.ThreadMode;
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
import java.lang.reflect.Type;
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.LinkedHashMap;
|
|
|
-import java.util.LinkedList;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.CountDownLatch;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
+import http.OkHttpUtils;
|
|
|
import http.client.HttpTool;
|
|
|
+import okhttp3.Call;
|
|
|
+import okhttp3.Callback;
|
|
|
+import okhttp3.OkHttpClient;
|
|
|
+import okhttp3.Request;
|
|
|
import okhttp3.Response;
|
|
|
+import okio.BufferedSink;
|
|
|
+import okio.Okio;
|
|
|
import xn.xxp.home.auth.ChoiceAuthActivity;
|
|
|
import xn.xxp.home.setting.FaceListActivity;
|
|
|
import xn.xxp.room.RoomTool;
|
|
@@ -50,16 +57,12 @@ import xn.xxp.room.dao.FaceDao;
|
|
|
public enum SyncFaceTool {
|
|
|
INSTANCE;
|
|
|
|
|
|
- private DownloadManager downloadManager;
|
|
|
- private long lastEventTime = 0;
|
|
|
- private long lastBuildTime = 0;
|
|
|
+ private static final String TAG = "SyncFaceTool";
|
|
|
+ private static final int MAX_DOWNLOAD_THREADS = 4;
|
|
|
private volatile boolean isBuildFaceEnd = false;
|
|
|
private List<Face> faceList;
|
|
|
public volatile boolean isSyncFace = false;
|
|
|
-
|
|
|
- SyncFaceTool() {
|
|
|
-
|
|
|
- }
|
|
|
+ private long lastBuildTime = 0;
|
|
|
|
|
|
@WorkerThread
|
|
|
public void doWork() {
|
|
@@ -67,247 +70,250 @@ public enum SyncFaceTool {
|
|
|
LogUtils.e("该方法必须在子线程调用");
|
|
|
return;
|
|
|
}
|
|
|
- Activity topActivity = ActivityUtils.getTopActivity();
|
|
|
- if (topActivity instanceof ChoiceAuthActivity) {
|
|
|
- LogUtils.d("人脸识别中,不去同步人脸!");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (topActivity instanceof FaceListActivity) {
|
|
|
- LogUtils.d("正在查阅底库,不去同步人脸!");
|
|
|
- return;
|
|
|
- }
|
|
|
+
|
|
|
+ if (!checkActivityState()) return;
|
|
|
+
|
|
|
+
|
|
|
if (isSyncFace) {
|
|
|
LogUtils.d("正在同步人脸");
|
|
|
return;
|
|
|
}
|
|
|
- if (null == downloadManager) {
|
|
|
- downloadManager = (DownloadManager) Utils.getApp().getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
|
|
|
- }
|
|
|
- // 初始化
|
|
|
+
|
|
|
isSyncFace = true;
|
|
|
try {
|
|
|
- // 同步人脸
|
|
|
FaceUtils.getInstance().init(Utils.getApp());
|
|
|
FaceConfig faceConfig = FaceUtils.getInstance().getFaceConfig();
|
|
|
LogUtils.json("底库配置", faceConfig);
|
|
|
+
|
|
|
EventBus.getDefault().register(this);
|
|
|
- // http请求同步
|
|
|
- List<Pair<String, String>> faceUrlList = getLabFaceList();
|
|
|
- if (null != faceUrlList && !faceUrlList.isEmpty()) {
|
|
|
- // 下载人脸
|
|
|
- List<FaceBuildBean> faceBuildBeanList = downloadPicAndBuild(faceUrlList);
|
|
|
- LogUtils.json("需要变更的人脸", faceBuildBeanList);
|
|
|
- // 人脸建模
|
|
|
- if (null != faceBuildBeanList && !faceBuildBeanList.isEmpty()) {
|
|
|
- FaceUtils.getInstance().faceBuild(faceBuildBeanList);
|
|
|
- lastBuildTime = System.currentTimeMillis();
|
|
|
- // 等待人脸建模
|
|
|
- while (!isBuildFaceEnd) {
|
|
|
- Thread.sleep(10);
|
|
|
- if (System.currentTimeMillis() - lastBuildTime > 2000) {
|
|
|
- isBuildFaceEnd = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- LogUtils.json(RoomTool.getInstance().faceDao().getAll());
|
|
|
- } else {
|
|
|
+
|
|
|
+ List<Pair<String, String>> faceUrlList = fetchLabFaceList();
|
|
|
+ if (faceUrlList == null || faceUrlList.isEmpty()) {
|
|
|
LogUtils.d("不需要下载变更人脸");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<FaceBuildBean> faceBuildBeanList = downloadFaceImages(faceUrlList);
|
|
|
+ if (faceBuildBeanList != null && !faceBuildBeanList.isEmpty()) {
|
|
|
+ processFaceBuilding(faceBuildBeanList);
|
|
|
}
|
|
|
- // 删除本地多余的人脸
|
|
|
- delRedundantFace();
|
|
|
- LogUtils.d("底库", FaceUtils.getInstance().getAllFaceId());
|
|
|
+
|
|
|
+ cleanRedundantFaces();
|
|
|
+ LogUtils.d("最终底库", FaceUtils.getInstance().getAllFaceId());
|
|
|
} catch (Exception e) {
|
|
|
LogUtils.e(Log.getStackTraceString(e));
|
|
|
} finally {
|
|
|
- try {
|
|
|
- // 销毁
|
|
|
- EventBus.getDefault().unregister(this);
|
|
|
- FaceUtils.getInstance().destroy();
|
|
|
- } catch (Exception e) {
|
|
|
- LogUtils.e(Log.getStackTraceString(e));
|
|
|
+ cleanupResources();
|
|
|
+ isSyncFace = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean checkActivityState() {
|
|
|
+ Activity topActivity = ActivityUtils.getTopActivity();
|
|
|
+ if (topActivity instanceof ChoiceAuthActivity) {
|
|
|
+ LogUtils.d("人脸识别中,不去同步人脸!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (topActivity instanceof FaceListActivity) {
|
|
|
+ LogUtils.d("正在查阅底库,不去同步人脸!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Pair<String, String>> fetchLabFaceList() {
|
|
|
+ try (Response response = HttpTool.getLabFaceList()) {
|
|
|
+ if (response == null || !response.isSuccessful()) return null;
|
|
|
+
|
|
|
+ JSONObject jsonObject = new JSONObject(response.body().string());
|
|
|
+ if (jsonObject.getInt("code") != 200) return null;
|
|
|
+
|
|
|
+ Type faceListType = new TypeToken<List<Face>>() {
|
|
|
+ }.getType();
|
|
|
+ faceList = GsonUtils.fromJson(jsonObject.getJSONArray("data").toString(), faceListType);
|
|
|
+ if (faceList == null || faceList.isEmpty()) return Collections.emptyList();
|
|
|
+
|
|
|
+ return filterNeedDownloadFaces();
|
|
|
+ } catch (Exception e) {
|
|
|
+ LogUtils.e(Log.getStackTraceString(e));
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Pair<String, String>> filterNeedDownloadFaces() {
|
|
|
+ List<Pair<String, String>> results = new ArrayList<>();
|
|
|
+ FaceDao faceDao = RoomTool.getInstance().faceDao();
|
|
|
+ List<String> existingFaceIds = FaceUtils.getInstance().getAllFaceId();
|
|
|
+
|
|
|
+ for (Face face : faceList) {
|
|
|
+ Face localFace = faceDao.getById(face.getUserId());
|
|
|
+ if (shouldDownloadFace(localFace, face, existingFaceIds)) {
|
|
|
+ results.add(Pair.create(
|
|
|
+ String.valueOf(face.getUserId()),
|
|
|
+ HttpTool.checkUrl(face.getFaceUrl())
|
|
|
+ ));
|
|
|
}
|
|
|
}
|
|
|
- isSyncFace = false;
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean shouldDownloadFace(Face localFace, Face remoteFace, List<String> existingFaceIds) {
|
|
|
+ if (localFace == null) return true;
|
|
|
+ if (remoteFace.getLastUpdated() <= localFace.getLastUpdated()) return false;
|
|
|
+ return !existingFaceIds.contains(String.valueOf(remoteFace.getUserId()));
|
|
|
}
|
|
|
|
|
|
- private List<Pair<String, String>> getLabFaceList() {
|
|
|
+ private List<FaceBuildBean> downloadFaceImages(List<Pair<String, String>> faceUrlList) {
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(MAX_DOWNLOAD_THREADS);
|
|
|
+ ConcurrentHashMap<String, File> downloadedFiles = new ConcurrentHashMap<>();
|
|
|
+ CountDownLatch latch = new CountDownLatch(faceUrlList.size());
|
|
|
+ AtomicInteger failureCount = new AtomicInteger(0);
|
|
|
+
|
|
|
try {
|
|
|
- Response response = HttpTool.getLabFaceList();
|
|
|
- if (null != response && response.isSuccessful()) {
|
|
|
- String json = response.body().string();
|
|
|
- JSONObject jsonObject = new JSONObject(json);
|
|
|
- int code = jsonObject.getInt("code");
|
|
|
- if (200 == code) {
|
|
|
- Type faceListType = new TypeToken<List<Face>>() {
|
|
|
- }.getType();
|
|
|
- faceList = GsonUtils.fromJson(jsonObject.getJSONArray("data").toString(), faceListType);
|
|
|
-
|
|
|
- if (null != faceList && !faceList.isEmpty()) {
|
|
|
- FaceDao faceDao = RoomTool.getInstance().faceDao();
|
|
|
- @SuppressLint("SdCardPath") final String savePath = "/sdcard/facePic/";
|
|
|
- FileUtils.createOrExistsDir(savePath);
|
|
|
- // 1.id 2.url
|
|
|
- List<Pair<String, String>> faceUrlList = new ArrayList<>();
|
|
|
- List<String> allFaceIdList = FaceUtils.getInstance().getAllFaceId();
|
|
|
- for (int i = 0; i < faceList.size(); i++) {
|
|
|
- Face face = faceList.get(i);
|
|
|
- Face sqlFace = faceDao.getById(face.getUserId());
|
|
|
- if (null != sqlFace) {
|
|
|
- boolean sqlInDb = false;
|
|
|
- for (int j = 0; j < allFaceIdList.size(); j++) {
|
|
|
- if (allFaceIdList.get(j).equals(String.valueOf(sqlFace.getUserId()))) {
|
|
|
- sqlInDb = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (sqlInDb && face.getLastUpdated() <= sqlFace.getLastUpdated()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
- faceUrlList.add(Pair.create(String.valueOf(face.getUserId()), HttpTool.checkUrl(face.getFaceUrl())));
|
|
|
+ String downloadDir = createDownloadDirectory();
|
|
|
+
|
|
|
+ for (Pair<String, String> pair : faceUrlList) {
|
|
|
+ executor.submit(() -> {
|
|
|
+ try {
|
|
|
+ File outputFile = new File(downloadDir, pair.first + ".jpg");
|
|
|
+ if (downloadImage(pair.second, outputFile)) {
|
|
|
+ downloadedFiles.put(pair.first, outputFile);
|
|
|
}
|
|
|
- return faceUrlList;
|
|
|
- } else {
|
|
|
- return new ArrayList<>();
|
|
|
+ } finally {
|
|
|
+ latch.countDown();
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- LogUtils.e(Log.getStackTraceString(e));
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
|
|
|
- private List<FaceBuildBean> downloadPicAndBuild(List<Pair<String, String>> faceUrlList) {
|
|
|
- if (null == faceUrlList || faceUrlList.isEmpty()) {
|
|
|
+ latch.wait();
|
|
|
+ executor.shutdown();
|
|
|
+
|
|
|
+ if (failureCount.get() > 0) {
|
|
|
+ LogUtils.w("部分人脸下载失败,失败数量:" + failureCount.get());
|
|
|
+ }
|
|
|
+
|
|
|
+ return buildFaceBeans(downloadedFiles);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
return null;
|
|
|
+ } finally {
|
|
|
+ executor.shutdownNow();
|
|
|
}
|
|
|
- try {
|
|
|
- @SuppressLint("SdCardPath") final String filePathDir = "/sdcard/" + Environment.DIRECTORY_DOWNLOADS + "/facePic/";
|
|
|
- FileUtils.createOrExistsDir(filePathDir);
|
|
|
- FileUtils.deleteAllInDir(filePathDir);
|
|
|
- List<FaceBuildBean> faceBuildBeanList = new ArrayList<>();
|
|
|
- List<File> downloadList = new LinkedList<>();
|
|
|
- for (int i = 0; i < faceUrlList.size(); i++) {
|
|
|
- // 1.id 2.url
|
|
|
- Pair<String, String> downloadPair = faceUrlList.get(i);
|
|
|
- DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadPair.second));
|
|
|
- request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "facePic/" + downloadPair.first + ".jpg");
|
|
|
- request.setMimeType("image/jpeg");
|
|
|
- request.setVisibleInDownloadsUi(false);
|
|
|
- request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
|
|
|
- downloadManager.enqueue(request);
|
|
|
- downloadList.add(new File(filePathDir + downloadPair.first + ".jpg"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean downloadImage(String url, File outputFile) {
|
|
|
+ Request request = new Request.Builder().url(url).build();
|
|
|
+ try (Response response = OkHttpUtils.client.newCall(request).execute()) {
|
|
|
+ if (!response.isSuccessful() || response.body() == null) {
|
|
|
+ LogUtils.w("下载失败: " + url);
|
|
|
+ return false;
|
|
|
}
|
|
|
- // 文件观察者
|
|
|
- FileObserver fileObserver = getFileObserver(filePathDir, downloadList);
|
|
|
- // 开始观察
|
|
|
- fileObserver.startWatching();
|
|
|
- lastEventTime = System.currentTimeMillis();
|
|
|
- // 观察者无响应2秒后 认为下载结束
|
|
|
- while (!downloadList.isEmpty()) {
|
|
|
- Thread.sleep(1000);
|
|
|
- if (System.currentTimeMillis() - lastEventTime > 2000) {
|
|
|
- downloadList.clear();
|
|
|
- }
|
|
|
+
|
|
|
+ try (InputStream is = response.body().byteStream();
|
|
|
+ BufferedSink sink = Okio.buffer(Okio.sink(outputFile))) {
|
|
|
+ sink.writeAll(Okio.source(is));
|
|
|
+ return true;
|
|
|
}
|
|
|
- // 停止观察
|
|
|
- fileObserver.stopWatching();
|
|
|
-
|
|
|
- // 同步人脸
|
|
|
- List<File> facePicList = FileUtils.listFilesInDir(filePathDir);
|
|
|
- if (!facePicList.isEmpty()) {
|
|
|
- for (int i = 0; i < facePicList.size(); i++) {
|
|
|
- File file = facePicList.get(i);
|
|
|
- FaceBuildBean faceBuildBean = new FaceBuildBean();
|
|
|
- faceBuildBean.setPicPath(file.getAbsolutePath());
|
|
|
- faceBuildBean.setFaceUuid(file.getName().replace(".jpg", ""));
|
|
|
- faceBuildBeanList.add(faceBuildBean);
|
|
|
- }
|
|
|
+ } catch (IOException e) {
|
|
|
+ LogUtils.e("下载异常: " + url, e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @NonNull
|
|
|
+ private String createDownloadDirectory() {
|
|
|
+ @SuppressLint("SdCardPath")
|
|
|
+ String dirPath = Environment.getExternalStorageDirectory() + "/Download/facePic/";
|
|
|
+ FileUtils.createOrExistsDir(dirPath);
|
|
|
+ FileUtils.deleteAllInDir(dirPath);
|
|
|
+ return dirPath;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<FaceBuildBean> buildFaceBeans(ConcurrentHashMap<String, File> downloadedFiles) {
|
|
|
+ List<FaceBuildBean> beans = new ArrayList<>();
|
|
|
+ downloadedFiles.forEach((id, file) -> {
|
|
|
+ FaceBuildBean bean = new FaceBuildBean();
|
|
|
+ bean.setPicPath(file.getAbsolutePath());
|
|
|
+ bean.setFaceUuid(id);
|
|
|
+ beans.add(bean);
|
|
|
+ });
|
|
|
+ return beans;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processFaceBuilding(List<FaceBuildBean> faceBuildBeanList)
|
|
|
+ throws InterruptedException {
|
|
|
+
|
|
|
+ FaceUtils.getInstance().faceBuild(faceBuildBeanList);
|
|
|
+ lastBuildTime = System.currentTimeMillis();
|
|
|
+ isBuildFaceEnd = false;
|
|
|
+
|
|
|
+ while (!isBuildFaceEnd) {
|
|
|
+ Thread.sleep(10);
|
|
|
+ if (System.currentTimeMillis() - lastBuildTime > 2000) {
|
|
|
+ isBuildFaceEnd = true;
|
|
|
}
|
|
|
- return faceBuildBeanList;
|
|
|
- } catch (Exception e) {
|
|
|
- LogUtils.e(Log.getStackTraceString(e));
|
|
|
}
|
|
|
- return null;
|
|
|
}
|
|
|
|
|
|
@Subscribe(threadMode = ThreadMode.ASYNC)
|
|
|
- public void onReceive(BuildModelEvent buildModelEvent) {
|
|
|
- if (buildModelEvent.isDone()) {
|
|
|
- List<FaceBuildBean> list = FaceUtils.getInstance().getFaceResult();
|
|
|
- FaceDao faceDao = RoomTool.getInstance().faceDao();
|
|
|
- if (list != null && !list.isEmpty()) {
|
|
|
- for (FaceBuildBean faceBuildBean : list) {
|
|
|
- if (faceBuildBean.getErrCode() != 0) {
|
|
|
- LogUtils.e("建模失败", faceBuildBean.getFaceUuid(), faceBuildBean.getErrCode());
|
|
|
- } else {
|
|
|
- if (null != faceList && !faceList.isEmpty()) {
|
|
|
- long uuid = Long.parseLong(faceBuildBean.getFaceUuid());
|
|
|
- for (int i = 0; i < faceList.size(); i++) {
|
|
|
- Face face = faceList.get(i);
|
|
|
- if (face.getUserId() == uuid) {
|
|
|
- faceDao.insertAll(face);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ public void onReceive(BuildModelEvent event) {
|
|
|
+ if (event.isDone()) {
|
|
|
+ processBuildResults();
|
|
|
isBuildFaceEnd = true;
|
|
|
}
|
|
|
lastBuildTime = System.currentTimeMillis();
|
|
|
}
|
|
|
|
|
|
- private @NonNull FileObserver getFileObserver(String filePathDir, List<File> downloadList) {
|
|
|
- return new FileObserver(filePathDir) {
|
|
|
- final Map<String, Integer> fileStateMap = new LinkedHashMap<>();
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onEvent(int event, @Nullable String path) {
|
|
|
- lastEventTime = System.currentTimeMillis();
|
|
|
- if (null != path) {
|
|
|
- if (event == CLOSE_WRITE) {
|
|
|
- Integer count = fileStateMap.get(path);
|
|
|
- if (null == count) {
|
|
|
- fileStateMap.put(path, 1);
|
|
|
- } else if (count >= 2) {
|
|
|
- downloadList.removeIf(file -> path.equals(file.getName()));
|
|
|
- } else {
|
|
|
- fileStateMap.put(path, count + 1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ private void processBuildResults() {
|
|
|
+ List<FaceBuildBean> results = FaceUtils.getInstance().getFaceResult();
|
|
|
+ if (results == null || results.isEmpty()) return;
|
|
|
+
|
|
|
+ FaceDao faceDao = RoomTool.getInstance().faceDao();
|
|
|
+ results.forEach(bean -> {
|
|
|
+ if (bean.getErrCode() != 0) {
|
|
|
+ LogUtils.e("建模失败", bean.getFaceUuid(), bean.getErrCode());
|
|
|
+ } else {
|
|
|
+ updateFaceDatabase(faceDao, bean.getFaceUuid());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateFaceDatabase(FaceDao faceDao, String faceUuid) {
|
|
|
+ if (faceList == null) return;
|
|
|
+
|
|
|
+ long uuid = Long.parseLong(faceUuid);
|
|
|
+ for (Face face : faceList) {
|
|
|
+ if (face.getUserId() == uuid) {
|
|
|
+ faceDao.insertAll(face);
|
|
|
+ break;
|
|
|
}
|
|
|
- };
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 删除本地多余的人脸
|
|
|
- */
|
|
|
- private void delRedundantFace() {
|
|
|
- List<String> allFaceIdList = FaceUtils.getInstance().getAllFaceId();
|
|
|
+ private void cleanRedundantFaces() {
|
|
|
+ List<String> existingIds = FaceUtils.getInstance().getAllFaceId();
|
|
|
+ if (existingIds == null || existingIds.isEmpty()) return;
|
|
|
+
|
|
|
FaceDao faceDao = RoomTool.getInstance().faceDao();
|
|
|
- if (faceList != null && allFaceIdList != null && !allFaceIdList.isEmpty()) {
|
|
|
- if (faceList.isEmpty()) {
|
|
|
- FaceUtils.getInstance().deleteAllFace();
|
|
|
- faceDao.clear();
|
|
|
- } else {
|
|
|
- for (int i = 0; i < allFaceIdList.size(); i++) {
|
|
|
- String uuid = allFaceIdList.get(i);
|
|
|
- boolean hasFace = false;
|
|
|
- for (int j = 0; j < faceList.size(); j++) {
|
|
|
- if (faceList.get(j).getUserId() == Long.parseLong(uuid)) {
|
|
|
- hasFace = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (!hasFace) {
|
|
|
- FaceUtils.getInstance().deleteFace(uuid);
|
|
|
- faceDao.delete(Long.parseLong(uuid));
|
|
|
- }
|
|
|
- }
|
|
|
+ existingIds.forEach(id -> {
|
|
|
+ if (!containsFace(id)) {
|
|
|
+ FaceUtils.getInstance().deleteFace(id);
|
|
|
+ faceDao.delete(Long.parseLong(id));
|
|
|
}
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean containsFace(String faceId) {
|
|
|
+ return faceList.stream().anyMatch(f ->
|
|
|
+ String.valueOf(f.getUserId()).equals(faceId));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void cleanupResources() {
|
|
|
+ try {
|
|
|
+ EventBus.getDefault().unregister(this);
|
|
|
+ FaceUtils.getInstance().destroy();
|
|
|
+ } catch (Exception e) {
|
|
|
+ LogUtils.e(Log.getStackTraceString(e));
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|