diff --git a/app/build.gradle b/app/build.gradle index 4d7df0a..d4839de 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,11 +5,11 @@ plugins { android { namespace 'com.rehome.dywoa' - compileSdk 34 + compileSdk 35 defaultConfig { applicationId "com.rehome.dywoa" minSdk 24 - targetSdk 34 + targetSdk 35 versionCode 19 versionName "1.1.8" multiDexEnabled true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ab7aba1..4f61fc5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -116,6 +116,10 @@ android:name=".ui.activity.FaceRecognitionActivity" android:exported="false" android:screenOrientation="portrait" /> + extra = new HashMap<>(); - int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 + int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 sdkFlags |= SFSDKFlags.FLAGS_VPN_MODE_TCP; //表明使用VPN功能中的TCP模式 - SFUemSDK.getInstance().initSDK(this, sdkMode,sdkFlags,null); + SFUemSDK.getInstance().initSDK(this, sdkMode, sdkFlags, null); break; } case MODE_SANDBOX: { //只使用安全沙箱功能场景 - int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 - SFUemSDK.getInstance().initSDK(this, sdkMode,sdkFlags,null); + int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 + SFUemSDK.getInstance().initSDK(this, sdkMode, sdkFlags, null); break; } case MODE_VPN_SANDBOX: { //同时使用VPN功能+安全沙箱功能场景 - int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 + int sdkFlags = SFSDKFlags.FLAGS_HOST_APPLICATION; //表明是单应用或者是主应用 sdkFlags |= SFSDKFlags.FLAGS_VPN_MODE_TCP; //表明使用VPN功能中的TCP模式 - SFUemSDK.getInstance().initSDK(this, sdkMode,sdkFlags,null); + SFUemSDK.getInstance().initSDK(this, sdkMode, sdkFlags, null); break; } default: { diff --git a/app/src/main/java/com/rehome/dywoa/Contans.java b/app/src/main/java/com/rehome/dywoa/Contans.java index aa73555..875709b 100644 --- a/app/src/main/java/com/rehome/dywoa/Contans.java +++ b/app/src/main/java/com/rehome/dywoa/Contans.java @@ -64,6 +64,8 @@ public class Contans { public static final String YJYA_GET_ACTION_LIST = "api/emergency/getExecutionList"; //执行应急预案 public static final String YJYA_ACTION_URL = "api/emergency/updateExecutionToIdAndUser"; + //海康人脸识别 + public static final String FACE_RECOGNITION_APP_URL = "api/app/face/faceRecognition"; public static String YHPC = "AJH/AJH_YHPCSC.ashx";//隐患排查 diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/FaceRecognitionAppActivity.java b/app/src/main/java/com/rehome/dywoa/ui/activity/FaceRecognitionAppActivity.java new file mode 100644 index 0000000..503612a --- /dev/null +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/FaceRecognitionAppActivity.java @@ -0,0 +1,798 @@ +package com.rehome.dywoa.ui.activity; + + +import static com.google.mlkit.vision.face.FaceDetectorOptions.PERFORMANCE_MODE_FAST; +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Rect; +//import android.hardware.Camera; +import android.graphics.RectF; +import android.graphics.SurfaceTexture; +import android.hardware.Camera; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CameraMetadata; +import android.hardware.camera2.CaptureRequest; +import android.media.Image; +import android.media.ImageReader; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.text.TextUtils; +import android.util.Log; +import android.util.Size; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.TextureView; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.mlkit.vision.common.InputImage; +import com.google.mlkit.vision.face.Face; +import com.google.mlkit.vision.face.FaceDetection; +import com.google.mlkit.vision.face.FaceDetector; +import com.google.mlkit.vision.face.FaceDetectorOptions; +import com.rehome.dywoa.R; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import com.rehome.dywoa.base.BaseActivity; +import com.rehome.dywoa.utils.BitmapUtil; +import com.rehome.dywoa.utils.BitmapUtils; + + +public class FaceRecognitionAppActivity extends BaseActivity { + + private LinearLayout ll_textureView; + private TextureView mTextureView; + private Surface mPreviewSurface; + private String mCameraId; // 后置相机id + private HandlerThread mBackgroundThread; // 处理回调结果的后台线程 + private Handler mBackgroundHandler; // 处理回调结果的handler + private Size[] supportedSizes; // 相机支持的拍照分辨率大小 + private CameraDevice mCameraDevice; + private CameraCaptureSession mCameraCaptureSession; // 相机会话 + private CaptureRequest.Builder mPreviewBuilder; + private ImageReader mImageReader; + private int cameraPosition;//0代表前置摄像头,1代表后置摄像头 + //摄像头Id数组 + private String[] cameraIdList; + private static final int CAMERA_REQUEST_CODE = 3;//请求码 + + private ImageView imgView; + + + private Timer timer; + private int faceRecognTricker = 1; + static boolean startFaceRecognition = true; + +// private static final String[] permission = new String[]{ +// Manifest.permission.CAMERA +// }; + + @Override + public int getContentViewID() { + return R.layout.activity_face_recognition_app; + } + + @Override + public void initView() { + initToolbar("人脸识别", "切换摄像头", new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }, new View.OnClickListener() { + @Override + public void onClick(View v) { + if (cameraIdList != null && cameraIdList.length > 1) { + changeCamera(); + } else { + showToast("当前设备不支持摄像头切换"); + } + } + }); + + + } + + @Override + public void initData() { + + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //setContentView(R.layout.activity_face_recognition); + startFaceRecognition = true; + faceRecognTricker = 1; + + +// ll_textureView = findViewById(R.id.ll_textureView); +// mTextureView = new TextureView(this); +// ll_textureView.addView(mTextureView); + mTextureView = findViewById(R.id.textureView); + + imgView = findViewById(R.id.iv_photo); + + mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { + @Override + public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) { + mPreviewSurface = new Surface(surfaceTexture); // 得到用于预览的Surface + } + + @Override + public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) { + } + + @Override + public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) { + return false; + } + + @Override + public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) { + } + }); + + + + + +// button.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// +// // 1、配置人脸检测器 +// FaceDetectorOptions faceDetectorOptions = new FaceDetectorOptions.Builder() +// .setPerformanceMode(PERFORMANCE_MODE_FAST) +// .build(); +// //2、获取人脸检测器 +// FaceDetector detector = FaceDetection.getClient(faceDetectorOptions); +// +// // 3、从资源中加载图片 +// bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_photo); +// imgView.setImageBitmap(bitmap); +// InputImage image = InputImage.fromBitmap(bitmap, 0); +// +// // 4、处理图片 +// detector.process(image) +// .addOnSuccessListener(new OnSuccessListener>() { +// @Override +// public void onSuccess(List faces) { +// //Log.e("TAG", "onSuccess: " + 1); +// showLog("onSuccess: " + 1); +// if (faces != null) { +// showLog(String.valueOf(faces.size())); +// } +// +// imgView.setImageBitmap(drawWithRectangle(faces)); +// } +// }) +// .addOnFailureListener(new OnFailureListener() { +// @Override +// public void onFailure(@NonNull Exception e) { +// Notice(); +// } +// }); +// } +// }); + + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + + @Override + public void run() { + openFrontCamera(); + } + }, 1000); + + } + + private void startFaceDetector(Bitmap rectBitmap, byte[] bytes) { + // 1、配置人脸检测器 + FaceDetectorOptions faceDetectorOptions = new FaceDetectorOptions.Builder() + .setPerformanceMode(PERFORMANCE_MODE_FAST) + .build(); + //2、获取人脸检测器 + FaceDetector detector = FaceDetection.getClient(faceDetectorOptions); + + // 3、从资源中加载图片 +// bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_photo); +// imgView.setImageBitmap(bitmap); + InputImage image = InputImage.fromBitmap(rectBitmap, 0); + + // 4、处理图片 + detector.process(image) + .addOnSuccessListener(new OnSuccessListener>() { + @Override + public void onSuccess(List faces) { + //Log.e("TAG", "onSuccess: " + 1); + showLog("onSuccess: " + 1); +// imgView.setImageBitmap(rectBitmap); +// mTextureView.setVisibility(View.GONE); + if (faces != null && faces.size() > 0) { + showLog(String.valueOf(faces.size())); + //imgView.setImageBitmap(drawWithRectangle(faces,rectBitmap)); + //imgView.setImageBitmap(rectBitmap); + showLog(String.valueOf(rectBitmap.getWidth())); + showLog(String.valueOf(rectBitmap.getHeight())); + //Bitmap bitmapResize = BitmapUtils.resizeBitmap(rectBitmap, rectBitmap.getWidth()/4, rectBitmap.getHeight()/4); + Bitmap bitmapResize = BitmapUtils.resizeBitmap(rectBitmap, 480, 640); + byte[] bitmapResizeByte = BitmapUtils.bitmapToByte(bitmapResize); + showLog(String.valueOf(bitmapResize.getWidth())); + showLog(String.valueOf(bitmapResize.getHeight())); + showLog(String.valueOf(bitmapResizeByte.length)); + //imgView.setImageBitmap(bitmapResize); + imgView.setImageBitmap(drawWithRectangle(faces, bitmapResize)); + + //BitmapUtils.resizeBitmap(rectBitmap,rectBitmap.getWidth()/3, rectBitmap.getHeight()/3); + mTextureView.setVisibility(View.GONE); + //stopCamera(); + + Intent resultIntent = new Intent(); + resultIntent.putExtra("FaceRecognition", bitmapResizeByte); + setResult(RESULT_OK, resultIntent); + finish(); + } else { + startFaceRecognition = true; + } + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Notice(); + startFaceRecognition = true; + } + }); + } + + //Bitmap保存成文件 + private void saveBitmapToFile(Bitmap bitmap) { + + // 创建一个输出流来写入图片数据 + FileOutputStream fos = null; + try { + File file = new File("路径/文件名"); // 指定保存位置及文件名 + fos = new FileOutputStream(file); + // 将Bitmap对象转换成字节数组并写入输出流 + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 0 /* 无压缩 */, bos); + byte[] bytes = bos.toByteArray(); + fos.write(bytes); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + protected void onResume() { + super.onResume(); + faceRecognTricker = 1; + if (timer == null) { + try { + timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + faceRecognTricker++; + } + }, 1000, 1000); + // 设定指定的时间time,此处为10000毫秒 + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + startFaceRecognition = true; + if (timer != null) { + timer.cancel(); + } + stopPreview(); + closeCaptureSession(); + stopBackgroundThread(); + closeCamera(); + } + + private void openFrontCamera() { + // 获取CameraManager + CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE); + try { + // 获取相机列表 + cameraIdList = cameraManager.getCameraIdList(); + mCameraId = null; + for (String cameraId : cameraIdList) { + CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); // 获取相机特性 + if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) { // 前置相机 + cameraPosition = 0; + mCameraId = cameraId; + // 拍照支持的分辨率 + supportedSizes = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageReader.class); + break; + } + } + // 打开相机结果的回调函数(监听器) + CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { + @Override + public void onOpened(@NonNull CameraDevice cameraDevice) { + mCameraDevice = cameraDevice; + // 回调函数的代码在子线程中执行,所以不能直接发出Toast消息,只能通过主线程发出 + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + createCaptureSession(); + //Toast.makeText(getBaseContext(), "Camera opened", Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @Override + public void onDisconnected(@NonNull CameraDevice cameraDevice) { + mCameraDevice = null; + } + + @Override + public void onError(@NonNull CameraDevice cameraDevice, int i) { + cameraDevice.close(); + mCameraDevice = null; + } + }; + + // 启动处理返回结果的后台线程 + if (mBackgroundHandler == null) startBackgroundThread(); + // 打开相机需要的权限检查 + + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(FaceRecognitionAppActivity.this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE); + showToast("像机权限未授权,请先授权像机权限"); + return; + } + // 打开相机 + cameraManager.openCamera(mCameraId, stateCallback, mBackgroundHandler); + showLog(mCameraId); + //cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, null); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void openBackCamera() { + // 获取CameraManager + CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE); + try { + // 获取相机列表 + cameraIdList = cameraManager.getCameraIdList(); + mCameraId = null; + for (String cameraId : cameraIdList) { + CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); // 获取相机特性 + if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) { // 后置相机 + cameraPosition = 1; + mCameraId = cameraId; + // 拍照支持的分辨率 + supportedSizes = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageReader.class); + break; + } + } + // 打开相机结果的回调函数(监听器) + CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { + @Override + public void onOpened(@NonNull CameraDevice cameraDevice) { + mCameraDevice = cameraDevice; + // 回调函数的代码在子线程中执行,所以不能直接发出Toast消息,只能通过主线程发出 + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + createCaptureSession(); + //Toast.makeText(getBaseContext(), "Camera opened", Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @Override + public void onDisconnected(@NonNull CameraDevice cameraDevice) { + mCameraDevice = null; + } + + @Override + public void onError(@NonNull CameraDevice cameraDevice, int i) { + cameraDevice.close(); + mCameraDevice = null; + } + }; + + // 启动处理返回结果的后台线程 + if (mBackgroundHandler == null) startBackgroundThread(); + // 打开相机需要的权限检查 + + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(FaceRecognitionAppActivity.this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE); + showToast("像机权限未授权,请先授权像机权限"); + return; + } + // 打开相机 + cameraManager.openCamera(mCameraId, stateCallback, mBackgroundHandler); + showLog(mCameraId); + //cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, null); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void startBackgroundThread() { + mBackgroundThread = new HandlerThread("CameraBackground"); + mBackgroundThread.start(); + mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); + } + + private void stopBackgroundThread() { + if (mBackgroundThread != null) { + mBackgroundThread.quitSafely(); + try { + mBackgroundThread.join(); + mBackgroundThread = null; + mBackgroundHandler = null; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + /** + * 创建CaptureSession + */ + private void createCaptureSession() throws CameraAccessException { + // 创建ImageReader + createImageReader(); + // 接收图像数据的Surface + List surfaceList = new ArrayList(); + surfaceList.add(mPreviewSurface); + surfaceList.add(mImageReader.getSurface()); + // 处理创建结果的回调函数(监听器) + CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() { + @Override + public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { + mCameraCaptureSession = cameraCaptureSession; + // 回调函数的代码在子线程中执行,所以不能直接发出Toast消息,只能通过主线程发出 + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + startPreview(); + //Toast.makeText(getBaseContext(), "CaptureSession created", Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @Override + public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { + } + }; + // 创建CameSession + mCameraDevice.createCaptureSession(surfaceList, sessionStateCallback, mBackgroundHandler); + } + + /** + * 创建ImageReader + */ + private void createImageReader() { + if (mImageReader == null) { + // 创建ImageReader,最多保存5张图片 + int width = supportedSizes[0].getWidth(); + int height = supportedSizes[0].getHeight(); + Log.i("app", "capture: size=" + width + ", " + height); + mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1); + ImageReader.OnImageAvailableListener listener = new ImageReader.OnImageAvailableListener() { + @Override + public void onImageAvailable(ImageReader imageReader) { + //获取最新的一帧的Image + Image image = imageReader.acquireLatestImage(); + //因为是ImageFormat.JPEG格式,所以 image.getPlanes()返回的数组只有一个,也就是第0个。 + ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer(); + byte[] bytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(bytes); + //ImageFormat.JPEG格式直接转化为Bitmap格式。 + Bitmap temp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); + //因为摄像机数据默认是横的,所以需要旋转90度。 + //Bitmap newBitmap = BitmapUtil.rotateBitmap(temp, 90); + //抛出去展示或存储。 + + //一定需要close,否则不会收到新的Image回调。 + image.close(); +// showLog("Image available"); + + + runOnUiThread(new Runnable() { + @Override + public void run() { + try { +// ByteBuffer buffer = image.getPlanes()[0].getBuffer(); +// byte[] bytes = new byte[buffer.remaining()]; +// buffer.get(bytes); +// Bitmap rectBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);//将data byte型数组转换成bitmap文件 + if(faceRecognTricker%4==0){ + showLog("Image available"); + if(startFaceRecognition==true){ + startFaceRecognition=false; + Bitmap newBitmap; + if (cameraPosition == 1) { + newBitmap = BitmapUtil.rotateBitmap(temp, 90); + } else { + newBitmap = BitmapUtil.rotateBitmap(temp, -90); + } + startFaceDetector(newBitmap, bytes); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + //mBackgroundHandler.post(new ImageSaver(image, picFile)); // 在后台线程中将图像保存到文件 + } + }; + mImageReader.setOnImageAvailableListener(listener, mBackgroundHandler); // 设置监听器,拍照完成后会执行上面的方法 + } + } + + + /** + * 开始预览 + * + * @throws CameraAccessException + */ + private void startPreview() throws CameraAccessException { + // 通过Builder模式创建CaptureRequest,创建时使用预览模板 + CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + // 自动对焦 +// builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); +// // 人脸检测模式 +// builder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_SIMPLE); + // 加入接收图像数据的Surface + builder.addTarget(mPreviewSurface); + builder.addTarget(mImageReader.getSurface()); + // 创建处理结果的回调函数(监听器) + CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {}; + // 发送重复请求,让相机不断向预览组件发送图像数据 + mCameraCaptureSession.setRepeatingRequest(builder.build(), captureCallback, mBackgroundHandler); + } + + + /** + * 停止预览 + * + * @throws CameraAccessException + */ + private void stopPreview() { + try { + if (mCameraCaptureSession != null) { + mCameraCaptureSession.stopRepeating(); // 取消重复请求 + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 关闭CaptureSession + */ + private void closeCaptureSession() { + try { + if (mCameraCaptureSession != null) { + mCameraCaptureSession.close(); + mCameraCaptureSession = null; + //Toast.makeText(getBaseContext(), "CaptureSession closed", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 关闭相机 + */ + private void closeCamera() { + try { + if (mCameraDevice != null) { + mCameraDevice.close(); + mCameraDevice = null; + //Toast.makeText(getBaseContext(), "Camera closed", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 停止相机 + */ + private void stopCamera() { + try { + stopPreview(); + closeCaptureSession(); + stopBackgroundThread(); + closeCamera(); + if(mImageReader!=null){ + mImageReader=null; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /* + 切换摄像头 + */ + public synchronized void changeCamera() { + //startFaceRecognition=true; + stopCamera(); + if (cameraPosition == 0) { + openBackCamera(); + } else { + openFrontCamera(); + } + } + + public void showLog(String logText) { + if (isApkInDebug(context)) { + if (TextUtils.isEmpty(logText)) { + Log.i("app", "logText is null"); + } else { + Log.i("app", logText); + } + } + } + + private void Notice() { + showLog("识别失败"); + Toast.makeText(this, "识别失败", Toast.LENGTH_SHORT); + } + + /** + * 为人脸绘制边框 + * + * @param faces 采集的人脸 + * @return {@link Bitmap} + */ + private Bitmap drawWithRectangle(List faces, Bitmap rectBitmap) { + + //复制一个新的Bitmap + Bitmap copiedBitmap = rectBitmap.copy(rectBitmap.getConfig(), true); + ; + + for (Face face : faces) { + //获取边界状态 + Rect bounds = face.getBoundingBox(); + // 初始化Paint + Paint paint = new Paint(); + // 设置矩形颜色 + paint.setColor(Color.BLUE); + // 设置绘制样式为轮廓绘制 + paint.setStyle(Paint.Style.STROKE); + // 设置为你需要的宽度 + paint.setStrokeWidth(10); + + Canvas canvas = new Canvas(copiedBitmap); + canvas.drawRect(bounds, paint); + } + return copiedBitmap; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (CAMERA_REQUEST_CODE == requestCode) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + openFrontCamera(); + } else { + //权限拒绝 + Toast.makeText(this, "权限拒绝,无法开启摄像头,请手动设置开启APP访问摄像头权限", Toast.LENGTH_SHORT).show(); + } + } + } + + /** + * @param sizeMap 相机尺寸集合 + * @param viewWidth 相机宽度 + * @param viewHeight 相机高度 + * @return + */ + public static Size getMinPreSizeNew(Size[] sizeMap, int viewWidth, final int viewHeight) { + List sizeWidthEqual = new ArrayList<>(); + //先查找preview中是否存在与surfaceview相同宽高的尺寸 + for (Size size : sizeMap) { + //选择更高倍率相机尺寸 + if (size.getWidth() > viewHeight && size.getHeight() > viewWidth) { + float beishuW = size.getWidth() * 1.0f / viewHeight * 1.0f; + float beishuH = size.getHeight() * 1.0f / viewWidth * 1.0f; + if (beishuH == beishuW) { + return size; + } + } + //优先选择大小相等的尺寸 + if ((size.getWidth() == viewHeight) && (size.getHeight() == viewWidth)) { + return size; + } + //再次选择能够满足我们遮罩层的的容差的 + if (size.getHeight() == viewWidth) { + sizeWidthEqual.add(size); + } + } + if (sizeWidthEqual.size() > 0) { + //找一个分辨率最大的尺寸 + Collections.sort(sizeWidthEqual, new Comparator() { + @Override + public int compare(Size o1, Size o2) { + return Math.abs(o1.getWidth()-viewHeight) -Math.abs(o2.getWidth()-viewHeight);//相机宽度由小到大排序 + } + }); + //图片宽度和屏幕高度越接近 像素越好 + return sizeWidthEqual.get(0); + } else { + //以上都不满足自己设置一个条件选择一个相机尺寸展示就可以了。理论上都是被淘汰四五年前的低端机 + return sizeMap[0]; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/LoginActivity.kt b/app/src/main/java/com/rehome/dywoa/ui/activity/LoginActivity.kt index cfd9fac..eb90a0f 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/LoginActivity.kt +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/LoginActivity.kt @@ -211,10 +211,11 @@ class LoginActivity : BaseActivityOaToolbarViewBinding() { // binding.etPassword.setText("A000000a.") //ceshi1 -// binding.etUsername.setText("ceshi1") -// binding.etPassword.setText("A000000a.") - //瑞洪 RH00002/王总 RH00002/chao工 RH00003/范红波 + binding.etUsername.setText("ceshi1") + binding.etPassword.setText("A000000a.") + + //瑞洪 RH00002/王总 RH00002/chao工 RH00003/范红波 // binding.etUsername.setText("RH00002") // binding.etPassword.setText("A000000a.") diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/CJFragment.java b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/CJFragment.java index 5dcac56..65444f0 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/CJFragment.java +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/CJFragment.java @@ -286,9 +286,24 @@ public class CJFragment extends BaseFragment { btn_selectCheckResult.setText(info.getCJJG()); } } else { + //未检 rb1.setChecked(true); rb2.setChecked(false); rb3.setChecked(false); + if(isEdit){ + if(!TextUtils.isEmpty(info.getMEAMETHOD())){ + if(info.getMEAMETHOD().equals("抄表")){ + + }else{ + //观察 + List selectList = stringToList(info.getMEASTANDARDSELECT()); + if(selectList!=null&&selectList.size()>0){ + btn_selectCheckResult.setText(selectList.get(0)); + et_jg.setText(selectList.get(0)); + } + } + } + } } // rb1.setChecked(info.isSBZT()); diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SdjgzActivity.java b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SdjgzActivity.java index e4e9b86..62d9075 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SdjgzActivity.java +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SdjgzActivity.java @@ -446,7 +446,7 @@ public class SdjgzActivity extends BaseActivity { public void handleNfc(String result) { //super.handleNfc(result); //tvNodata.setText(result); - //result = "0475ABEAC21B90"; + //result = "04D49CEAC21B90"; if (list.size() != 0) { showLog("--------"); showLog(GsonUtils.GsonString(list)); diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SjcjFragment.java b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SjcjFragment.java index 6edc9be..ebc79f5 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SjcjFragment.java +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxdjgl/SjcjFragment.java @@ -85,12 +85,22 @@ public class SjcjFragment extends BaseFragment { btn_submit_qx.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(requireActivity(), SQxgdlrfActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); - if (!TextUtils.isEmpty(lists.get(item - 1).getASSETNUM())) { - intent.putExtra("kks", lists.get(item - 1).getASSETNUM()); + if(lists!=null&&lists.size()>0){ + Intent intent = new Intent(requireActivity(), SQxgdlrfActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + if (!TextUtils.isEmpty(lists.get(item - 1).getASSETNUM())) { + showLog("kks:"+lists.get(item - 1).getASSETNUM()); + String kks = lists.get(item - 1).getASSETNUM(); + intent.putExtra("kks", kks); + } + startActivity(intent); } - startActivity(intent); +// Intent intent = new Intent(requireActivity(), SQxgdlrfActivity.class); +// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); +// if (!TextUtils.isEmpty(lists.get(item - 1).getASSETNUM())) { +// intent.putExtra("kks", lists.get(item - 1).getASSETNUM()); +// } +// startActivity(intent); } }); diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxj/SxgzActivity.java b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxj/SxgzActivity.java index 0e9c12d..4cb63ad 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/sbxj/SxgzActivity.java +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/sbxj/SxgzActivity.java @@ -588,7 +588,7 @@ public class SxgzActivity extends BaseActivity { // result = "048B94EAC21B91"; //result = "041894EAC21B91"; -// result = "048D93EAC21B90"; +// result = "044092EAC21B90"; if(TextUtils.isEmpty(result)){ return; diff --git a/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java b/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java index 617557d..bf600ea 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java +++ b/app/src/main/java/com/rehome/dywoa/ui/fragment/HomeFragment.java @@ -1,22 +1,43 @@ package com.rehome.dywoa.ui.fragment; +import static android.app.Activity.RESULT_OK; + +import android.Manifest; import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Environment; +import android.os.Handler; import android.text.TextUtils; +import android.util.Base64; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; + +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import com.google.gson.Gson; import com.rehome.dywoa.App; import com.rehome.dywoa.Contans; import com.rehome.dywoa.MainActivity; import com.rehome.dywoa.R; import com.rehome.dywoa.adapter.GridViewAdapter; import com.rehome.dywoa.base.BaseFragment; +import com.rehome.dywoa.base.MipcaActivityCapture; +import com.rehome.dywoa.bean.FwSingleLoginResult; import com.rehome.dywoa.bean.GridItem; import com.rehome.dywoa.bean.WaitForBean; import com.rehome.dywoa.ui.activity.BiShowActivity; +import com.rehome.dywoa.ui.activity.FaceRecognitionActivity; +import com.rehome.dywoa.ui.activity.FaceRecognitionAppActivity; import com.rehome.dywoa.ui.activity.FanWeiActivity; import com.rehome.dywoa.ui.activity.HightRiskActivity; import com.rehome.dywoa.ui.activity.JiZhuActivity; @@ -30,32 +51,51 @@ import com.rehome.dywoa.ui.activity.WaitForToDoActivity; import com.rehome.dywoa.ui.activity.YjyaActivity; import com.rehome.dywoa.ui.activity.sbxdjgl.SbxdjglActivity; import com.rehome.dywoa.ui.activity.sbxj.XscbglActivity; +import com.rehome.dywoa.utils.DataPassUtils; import com.rehome.dywoa.utils.GsonUtils; import com.rehome.dywoa.utils.HttpListener; import com.rehome.dywoa.utils.NoProgresshttpUtils; +import com.rehome.dywoa.utils.NohttpUtils; +import com.rehome.dywoa.utils.RSAUtils; +import com.rehome.dywoa.utils.UiUtlis; import com.rehome.dywoa.weiget.AutoGridView; import com.yolanda.nohttp.NoHttp; import com.yolanda.nohttp.RequestMethod; import com.yolanda.nohttp.rest.Request; import com.yolanda.nohttp.rest.Response; +import java.io.File; +import java.io.FileOutputStream; import java.net.URLEncoder; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import cn.hutool.core.io.IoUtil; public class HomeFragment extends BaseFragment { + private static final String[] permission = new String[]{ + Manifest.permission.CAMERA, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + private static final int CAMERA_REQUEST_CODE = 4;//人脸识别请求摄像头权限 + private String username; private String firstDeparment; public static final int REQUEST_CODE_ADD = 1; public static final int REQUEST_CODE_AUDIT = 2; private static HomeFragment instance = null; + private String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "com.rehome.dywoa/images"; + TextView tv_todo_count; LinearLayout ll_account; ImageView iv; @@ -75,6 +115,9 @@ public class HomeFragment extends BaseFragment { SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd"); + //人脸识别 + ActivityResultLauncher launcherResultFaceRecognition; + public static HomeFragment getInstance() { if (instance == null) { instance = new HomeFragment(); @@ -91,9 +134,20 @@ public class HomeFragment extends BaseFragment { protected void initView() { username = App.getInstance().getUserInfo().getManid(); firstDeparment = App.getInstance().getUserInfo().getFirstDeparment(); + + + //android 10 以上 + if (context.getExternalFilesDir(null) != null) { + path = Objects.requireNonNull(context.getExternalFilesDir(null)).getPath() + "/images"; + } else { + path = context.getFilesDir().getPath() + "/images"; + } + + findView(); initLists(); setAdapter(); + launcherResultFaceRecognition = createFaceRecognitionActivityResultLauncher(); ll_account.setOnClickListener(new View.OnClickListener() { @Override @@ -167,6 +221,101 @@ public class HomeFragment extends BaseFragment { initData(); } + /** + * 创建一个ActivityResultLauncher + * + * @return + */ + private ActivityResultLauncher createFaceRecognitionActivityResultLauncher() { + return registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + new ActivityResultCallback() { + @Override + public void onActivityResult(ActivityResult result) { + int resultCode = result.getResultCode(); + if (resultCode == RESULT_OK) { + Intent resultIntent = result.getData(); + byte[] faceByte = resultIntent.getByteArrayExtra("FaceRecognition"); + + String fileName = UUID.randomUUID().toString()+".png"; + File fileDir = new File(path); + if(!fileDir.exists()){ + fileDir.mkdir(); + } + + String fileTempName = path + File.separator + fileName; + showLog(fileTempName); + + try { + FileOutputStream fileOutputStream = new FileOutputStream(fileTempName); + IoUtil.write(fileOutputStream,true,faceByte); + + File fileFaceUpToServer = new File(fileTempName); + showLog(String.valueOf(fileFaceUpToServer.length())); + + String url = "http://10.25.188.110:8088/"+Contans.FACE_RECOGNITION_APP_URL; + Request request = NoHttp.createStringRequest(url, RequestMethod.POST); +// showLog(json); +// request.setDefineRequestBodyForJson(json); + request.add("face", fileFaceUpToServer); + + if(DataPassUtils.checkCanDj()){ + if(App.getInstance().getUserInfo()!=null&&App.getInstance().getUserInfo().getToken()!=null){ + String token = App.getInstance().getUserInfo().getToken(); + String credential = "Bearer " + token; + request.addHeader("Authorization", credential); + request.addHeader("token", token); + showLog(request.url()); + } + } + + NohttpUtils.getInstance().add(mActivity,30,request,new HttpListener(){ + @Override + public void onSucceed(int what, Response response) throws ParseException { + + String jsonResult = response.get(); + showLog("-----face------"); + showLog(jsonResult); + + + } + + @Override + public void onFailed(int what, Response response) { + showLog("getSisToken onFailed"); + } + }, true, true, "人脸识别中,请稍候..."); + + } catch (Exception e) { + e.printStackTrace(); + } + + + + // 将字节数组转换为Base64编码的字符串 +// String base64String = ""; +// try { +// base64String = RSAUtils.encryptBASE64(faceByte); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// showLog(base64String); +// showLog(String.valueOf(base64String.length())); +// +// showLog("----------"); +// String headBase64String = "data:image/png;base64," + base64String; +// //showLog(headBase64String); +// showLog(String.valueOf(headBase64String.length())); + +// HashMap param = new HashMap<>(); +// param.put("face",base64String); +// String json = new Gson().toJson(param); + + + } + } + }); + } + private void setAdapter() { // String[] results = App.getInstance().getUserInfo().getPermissionsResult().split(";"); // final List resultList = Arrays.asList(results); @@ -328,14 +477,25 @@ public class HomeFragment extends BaseFragment { intentHightRisk.putExtra("type",typeHightRisk); intentHightRisk.putExtra("urlLog",urlWHightRisk); startActivity(intentHightRisk); - break; -// case 10: -// TAG = GridViewDialog.TAG_GONGHUI; -// break; -// case 11: -// TAG = GridViewDialog.TAG_JD; -// break; + case 10: + if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { + Intent intentFaceRecognition = new Intent(mActivity, FaceRecognitionAppActivity.class); + intentFaceRecognition.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + launcherResultFaceRecognition.launch(intentFaceRecognition); + } else { + ActivityCompat.requestPermissions(mActivity, permission, CAMERA_REQUEST_CODE); + } + break; + case 11: + Intent intentYhTake = new Intent(mActivity, HightRiskActivity.class); + intentYhTake.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); +// String typeHightRisk = "高风险"; +// String urlWHightRisk = "https://mis.dywzhny.com.cn/mobile/ebdapp/view/998396522831962120/page/1069629959971758112-8233268850081530012"; +// intentYhTake.putExtra("type",typeHightRisk); +// intentYhTake.putExtra("urlLog",urlWHightRisk); + startActivity(intentYhTake); + break; // case 12: // TAG = GridViewDialog.TAG_AF; // break; @@ -346,6 +506,28 @@ public class HomeFragment extends BaseFragment { }); } + /** + * 申请权限回调 + * + * @param requestCode + * @param permissions + * @param grantResults + */ + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + //人脸识别 + if (CAMERA_REQUEST_CODE==requestCode){ + if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED) { + Intent intent = new Intent(mActivity, FaceRecognitionAppActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + launcherResultFaceRecognition.launch(intent); + }else { + //权限拒绝 + showToast("权限拒绝,无法打开摄像头,请手动设置开启APP访问摄像头权限"); + } + } + } private void initLists() { items = new ArrayList<>(); @@ -355,9 +537,9 @@ public class HomeFragment extends BaseFragment { // String[] titles = {"管控一体化","两票系统", "SIS系统", "机组参数","巡检","点检","运行日志","kks码查询","应急预案","用车","用印","BI"}; // int[] imgIds = {R.drawable.icon_runlog_home,R.drawable.icon_liangpiao, R.drawable.icon_sis_new, R.drawable.icon_gcjd_new,R.drawable.xjgz,R.drawable.icon_dianjian,R.drawable.icon_runlog_home,R.drawable.icon_kks,R.drawable.icon_yjya,R.drawable.icon_use_car,R.drawable.icon_use_seal,R.drawable.icon_bi}; - String[] titles = {"管控一体化","两票系统", "SIS系统", "机组参数","巡检","点检","kks码查询","应急预案","BI","高风险"}; + String[] titles = {"管控一体化","两票系统", "SIS系统", "机组参数","巡检","点检","kks码查询","应急预案","BI","高风险","人脸识别","隐患随手拍"}; int[] imgIds = {R.drawable.icon_gkyth,R.drawable.icon_lpqt, R.drawable.icon_sis_new_first, R.drawable.icon_jzcs_new,R.drawable.icon_qj_new,R.drawable.icon_dj_new, - R.drawable.icon_kks_search,R.drawable.icon_yjya,R.drawable.icon_bi,R.drawable.icon_high_risk}; + R.drawable.icon_kks_search,R.drawable.icon_yjya,R.drawable.icon_bi,R.drawable.icon_high_risk,R.drawable.icon_face_re,R.drawable.icon_rinhuan_take}; diff --git a/app/src/main/res/drawable-xhdpi/icon_face_re.png b/app/src/main/res/drawable-xhdpi/icon_face_re.png new file mode 100644 index 0000000..b6bb210 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_face_re.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_rinhuan_take.png b/app/src/main/res/drawable-xhdpi/icon_rinhuan_take.png new file mode 100644 index 0000000..34b9905 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_rinhuan_take.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_face_re.png b/app/src/main/res/drawable-xxhdpi/icon_face_re.png new file mode 100644 index 0000000..d0165e3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_face_re.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_rinhuan_take.png b/app/src/main/res/drawable-xxhdpi/icon_rinhuan_take.png new file mode 100644 index 0000000..091cddf Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_rinhuan_take.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_face_re.png b/app/src/main/res/drawable-xxxhdpi/icon_face_re.png new file mode 100644 index 0000000..6c6e5d8 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_face_re.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_rinhuan_take.png b/app/src/main/res/drawable-xxxhdpi/icon_rinhuan_take.png new file mode 100644 index 0000000..1ae5073 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_rinhuan_take.png differ diff --git a/app/src/main/res/layout/activity_face_recognition_app.xml b/app/src/main/res/layout/activity_face_recognition_app.xml new file mode 100644 index 0000000..2117779 --- /dev/null +++ b/app/src/main/res/layout/activity_face_recognition_app.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/autolayout/build.gradle b/autolayout/build.gradle index 3986e80..3a1151c 100644 --- a/autolayout/build.gradle +++ b/autolayout/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'com.zhy.autolayout' diff --git a/litepal/build.gradle b/litepal/build.gradle index d4de868..f4a269f 100644 --- a/litepal/build.gradle +++ b/litepal/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'org.litepal' diff --git a/matisse/build.gradle b/matisse/build.gradle index e012cf5..3b23f6f 100644 --- a/matisse/build.gradle +++ b/matisse/build.gradle @@ -2,10 +2,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'com.zhihu.matisse' diff --git a/nohttp/build.gradle b/nohttp/build.gradle index f1baad0..859d8e9 100644 --- a/nohttp/build.gradle +++ b/nohttp/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'com.yolanda.nohttp' diff --git a/tkrefreshlayout/build.gradle b/tkrefreshlayout/build.gradle index 38e599a..d39717d 100644 --- a/tkrefreshlayout/build.gradle +++ b/tkrefreshlayout/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'com.lcodecore.tkrefreshlayout' diff --git a/videocompressor/build.gradle b/videocompressor/build.gradle index bcdab27..e2239f4 100644 --- a/videocompressor/build.gradle +++ b/videocompressor/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.library' android { - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 24 - targetSdk 34 + targetSdk 35 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } namespace 'com.vincent.videocompressor'