From 8c12a6d167fe05c76e3483eab72190ce2da70513 Mon Sep 17 00:00:00 2001 From: hwf453 Date: Wed, 11 Dec 2024 18:15:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=BA=E8=84=B8=E8=AF=86?= =?UTF-8?q?=E5=88=AB=EF=BC=8C=E9=9A=90=E6=82=A3=E9=9A=8F=E6=89=8B=E6=8B=8D?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E5=85=A5=E5=8F=A3=EF=BC=8C=E4=BA=BA=E8=84=B8?= =?UTF-8?q?=E8=AF=86=E5=88=AB=20=E6=89=8B=E6=9C=BA=E7=AB=AF=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=AE=9E=E7=8E=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 4 + app/src/main/java/com/rehome/dywoa/App.java | 25 +- .../main/java/com/rehome/dywoa/Contans.java | 2 + .../activity/FaceRecognitionAppActivity.java | 798 ++++++++++++++++++ .../rehome/dywoa/ui/activity/LoginActivity.kt | 7 +- .../dywoa/ui/activity/sbxdjgl/CJFragment.java | 15 + .../ui/activity/sbxdjgl/SdjgzActivity.java | 2 +- .../ui/activity/sbxdjgl/SjcjFragment.java | 20 +- .../dywoa/ui/activity/sbxj/SxgzActivity.java | 2 +- .../dywoa/ui/fragment/HomeFragment.java | 200 ++++- .../main/res/drawable-xhdpi/icon_face_re.png | Bin 0 -> 2137 bytes .../res/drawable-xhdpi/icon_rinhuan_take.png | Bin 0 -> 3321 bytes .../main/res/drawable-xxhdpi/icon_face_re.png | Bin 0 -> 3032 bytes .../res/drawable-xxhdpi/icon_rinhuan_take.png | Bin 0 -> 4557 bytes .../res/drawable-xxxhdpi/icon_face_re.png | Bin 0 -> 4002 bytes .../drawable-xxxhdpi/icon_rinhuan_take.png | Bin 0 -> 6150 bytes .../layout/activity_face_recognition_app.xml | 46 + autolayout/build.gradle | 4 +- litepal/build.gradle | 4 +- matisse/build.gradle | 4 +- nohttp/build.gradle | 4 +- tkrefreshlayout/build.gradle | 4 +- videocompressor/build.gradle | 4 +- 24 files changed, 1100 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/com/rehome/dywoa/ui/activity/FaceRecognitionAppActivity.java create mode 100644 app/src/main/res/drawable-xhdpi/icon_face_re.png create mode 100644 app/src/main/res/drawable-xhdpi/icon_rinhuan_take.png create mode 100644 app/src/main/res/drawable-xxhdpi/icon_face_re.png create mode 100644 app/src/main/res/drawable-xxhdpi/icon_rinhuan_take.png create mode 100644 app/src/main/res/drawable-xxxhdpi/icon_face_re.png create mode 100644 app/src/main/res/drawable-xxxhdpi/icon_rinhuan_take.png create mode 100644 app/src/main/res/layout/activity_face_recognition_app.xml 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 0000000000000000000000000000000000000000..b6bb21039ce78390092454c45e5802249898dc8b GIT binary patch literal 2137 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..34b990522b608d4bda82a5b488f12b1d7923f41a GIT binary patch literal 3321 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d0165e370a88b66e5ecec5f61841d43ad9d4637b GIT binary patch literal 3032 zcmcImXH=725)L&OK0riDKtv2p2+~xRj)ay-krF_J5ah#82rNoKI)to+CLkywD55l_ zhK`g_M4C#C1OzEckPe~{6il)&?)iS~|K0bT`_7#^^URrh&%HBG;zc_vA&4{t1Of>m zt<4<)IdL!q_nfy24R`b8}c-%jh~j2rqaFdAT&CyBJ=IswzUg0mSY<|(~?|y=9Lp0AceJXxVODJ{VE@Hkqrdeug$7(HnZGQ$ol*_SiKAhI8 zL)p|DdW;{UKDmMFm?Oo~Uf*iyFSEde^(|W}doC8KWrjz0WMo=W&nQsR7$J^!R5V(D z^!mdn<@jC4B^;@fFa@{{59+bpQ=o%~|^;jW_ z_5$Ypt7kQgXwHkNr0+hyd;!?k9GB5dUvYlMTOAqPG$ku)(U-5BgXb9OmIxyU)J_Zb zrOmfJowi+_zD#PF_vN|C#J9%;J8CF9N~FVX6ORXaY+^2bGrka08#l2D^XMqDwOd(W zd$$Lb?8EhmJ0klrgUcTnZ@Is9N392y;)gs}qDX&8(afG2&fub)at#bQOg^qh?!)0a zxiy4eD*p%!Z0!jhXbNQK7P|;?J@6YXi(v=ixzB|@NiGV<`cCrSVL8*dLFwm6D7G(YN_1yke6}c8A?W)a&r-q!SLU< zULq0<$x`E8qwkN77#JOGICjG8@%B@NrcMo3apH|!0nfwfy50G0nC$G~hT+?w2xrfN zK)#6jTc>&ZV9NCpj8Lm3GlEBObM1-eGKg_5#(Q->Wlzaw$O%%bG^Dj&8e4p`zx^72 zl`5L|4^8t95aRzUoMoE{V|$%m9I@tGdhDB=JHv|QkbRv?BVZfj5H7tgwvF>PSAmH_ zGK*Zk#ABIeEw!)Xum!d`{U76zvIN4jA6A;hXZo+iDXH!eM&vTO*)}c!#!4ZDMOI1e z1R+we*#KO{QnTaYHY|I0A-C~oFVDCPIzuFm<4s+jkK+vG5m1_?7B1V9f+8{(0i-#AAx?c*P;-LvKXmI^K8`r*&3;%8$I; z8?qLC<9yYZDUU|WN0bVO3)9kpm1W41SLi6#4>d0-L*?5G+o2uwoh8J zqc1jcAyYn$7(ZwEH{vlJ(ZXN0!9yu4!(>4xuZmydZJW^!F^kFi=bYdB%(iN0!rYHf zmK}Qx7F?SnJIF?I%$Da&o>c%&Q3h6ZjW~sMFYx!nRi?#=>t9)d$g8-)bF5I+*V~91ZykZ_$R}4(U0`g2MezYXEj1gAV>j%o(7F%jivTAT_)Io@li2E! zzMfc+cbmOafTN57hf;)Y3~spoBz#|IN9cpSpk(f8Ve!y8>hjo|i=X`{3g+!La&HZ( zK`-1Ou2`@=iJSSOu}z|wU_GgJY6}cM0=DydQP;+|AdeN@o@{%TAE~1mX=`x3G-PId zYl=JNifEl{M!pGuviI0-k&~ptrgr^KthCZsEnxYxT<6JQgEPmQZ}HW*IUTn!A^Nfu zwHT$J78*!)d~Oc!!lM-LiN2eVvx|NBDfI|PJDhGIR~0T?M@2l~ioGuYXdug}ROCfEKX`+w1A7vYq$*-K_gc?QU^lgn5T!)%VKK z&gcIUe13N|B@SoJ3qNbHfsxdA(z*Qhj(`0>v60#QrM#Ehf41Dv^_8+*=t%_Zv6D+2-*i!?5u?(b|== zai=zYd`LJ~ollT^1mD-+do@o`C!LN5Pmm73)uWuKQEE=?1)utxjg|7(Pt6;;q4Xnr-;d}>H2;Ad z-JqYHoUTy{fr`fyptwya?K|`kJs|KNdXmc0tfvI=9qIy<$|aCVaR=GxWU z1ZbkX2d&|Z%ko@WILS*8PLsK|dECir-0iFG%S#*dovmAwun4UL+wHQ10gV_3IxCH{ z=3jt9O}6yDpFux3I^HYs&_9b=_rXrGmX4w4i@0SO*SD?CCz4a83(lBj6){nWZLYT& z%)uWfnN6eISamkRw-6B~Wb*>wv5}NgR~MF*+8tZnz0@VIJ&N)3z7Lac-%JVf7cdwB zmw&X-QS;=yDdAbW`)WDdh>Fg6$a8Bik4>|9#E%t^sTfe0|w@>wid!0kxuTd!9ym9#{G0D|Cw zBA=@0Q0rRgm4h@6Vnz!a*v-V|nF0a$EmNtx-R&|?nej}Nm=TQYau6d)$HV;>myfC# z34)_6@wj-ei&Ig*XE)R(S|B(L;p4yC&r#OV>W^XP_n4b)+NFhzy!MoR+2D#@`yy5o z1a?rbMaxHpa|WtS#JUCerLORHd8`eYTgYkdA!;V_`hj}2op9^Gs0H}4May3emQDD? zDV<^yw2F`tKsy-$r?AuE%)e^#MWl>QdIR95`1>EJk9gCe-cr_;*u)RqNU+|s|CZMAiW*$^LEMzS1v}zcnhE2&Yeo0KA6VN(bCco zg%Eku2gz zk?0)AL{DTG3PZWAeyHyrv!`rY&yQZ@h>2A4FfxrzxiDnMiBiJahHktRfL7^a>}Q=< zjkDRK0~~fof{9Xz-dH{%dTGXOwc%ZxcjwqPz_6Cbco?E8Dhg%_5C}x2uBN01=&64~P6|AuI0SbA zMc}EYssJhA4;E8Qf~X$ z;KS#OIQ=yEn{UOUGz7^L_8-j}Ft-icXS%xRNoJz*6<|pLse~aEaCRC0mz)V=A*k>( zGv@K+S0SkUuvoc~8^XonyLV$A8PB^~7F-Yi=~E$KxzcMZ&wdNS3iW*Fq=@5x_Fhr2 zbo`6QYXKH?6J!gMBm3RN=%X^2Badc&y2dn%{~}XQjx}R!|B1O0{6+A`YFN@`i{22Q zX=JR{*4cj@WP6O!kBn=&6H-)8q7~%$nM5QgqaGKC&%4+gtTW2CK7uyfiH#oTW6*Vb z4}K=`qGI{@zS()9x$6VkHyhtnoR(n6gegsf-^=|tZBJufZ{-XGFPhN1JL&D~Q51{| z)9a#t5()=9#$K|f=|}R-=e=D0_-s+_dV!*MzCN0~JkW?cA9@R3X*K%zgo7CLI0Dlw zM5Fu3+UAg+V^V31!ZpB*H6N;rWdY^x1*0JSKbN^GD3!osn_?1(r}uV_8##cwU~F%t z5yLeLk?Yd%aWF@8`&3XWfYm5u6m|TDw>@Y`#(WhhjMu&Skc8?m7*es6)}*>t=L`7}XLhycD;?teAe?;a*Sfw`pyQA2 zw_}B(4ZGz8UQeu}k*=I~=4|Tmi#sU38114Kp%42=>ZuJSX6D7^$ahGxM&&L^+9dkt z>zp@q>>~317N8&M+UThIPv<qj^3eFvN8pfBi9D5 ziVjegjNc~{>Fv3B^_VW5aNGGvLw$m6;FX22q@TrYTGL4t53&dFydl5fe!hzqTy$ou1+=g1Om?4*O5V z?$Nm^;l;x~G zJ?isGQ3=5YEsu#;<4T=hs4|s5Tqd#!crsa(G2(~21`o&=%EEB&PHSAfSMSFW8$6{n#S@L{^%fYdv zQ|aFTsz2#K?o#ukOOHrO7FSxNOp}d{P_N@oPOzYEzZ1FXr243#6fL{)}lemMx67bH#hU9V|( zyO=q`h?`ha-|U{?m4dK^=Df^mgG|ZZLq*S6tH9{I8GWg0DCenz|Jj%1jR5;EycN3- z59j{SaqroPNIi#n!S=Ibt@z*dYIn(6oNW7D{Qilu$6HWop9{5;dTt9*Wi0#J#y*4H zQAu6V$@qfnC)1ziVW&vjnR{2(F2KU{xgG09!CbQQmfsu{<1pkP&=-ZH_zV>8Iw>7r z!8%(EZkPCzM>(_DGSS*P8?Qv>Qy~as%mdR5Ngt8DZg!$!7m;H@W_b6r<6t-GsX5e2 zFT2A`=rjsr;wBKd)B@Ld|6`F*wo*Ma!vBj3R*agAyQi61f+5?8y z?E~)g2$$DOWvY|t**_JMS-u|4TnDDpUuQV+1JkB-2nOtmM_@s%8|tIB@9mA!+I&M<<51>G(fPBq708ffu?toA-dfJNvpmoIOzvx#jB#hcb>6gIuFmq?jU(c_n;E0W*FG!W+6$RNZL$-=K>lRKN;Ls3mbXTJ*A!4+m(Y6+aTIXBwQL+_&cEBqu|qAz8* z9!azY1!^!MWY|uFOj-u1_vMcGT+ly0BT8vBW^Cjj5&^g%X`57%nW@SPirQ zqS%ZxAYl`<`s1s@5ZgC3&uXeyUt>6tQtnK(F}?QOnDWHQ5nH)02RZfbx3^$-$2Wy= zwnlA8B4oIvX79BRYuI}=r@aXAu90e^){(pF4DPvpD~_9J3Vrd-JD522+J^1&`bvZQ z#=L&?EkKfJRM)FlY)mBM(A#Mb5fES3p4wsVt?6MM3G>b~TX%fH_s*ZcRas;YOgHm> z2h>%_FTgolBHqo9eshf1z#C`_^2k9W;%wp?@b~|5q;23~-_eH~vFN{TH;t=9;X6V0 zS8YZRF+1mNF66FRZ0pUX$MBHK{X+L69PH1Yv3VT8uc<*piG%H3WSS#yf>k}%p)Q-# z4f%`ORMwH6_#a6hdGIn%F1efV(rRFVEsgGaDQ0Rno7Fy@F4DUt0!dI?Ix- zdfsJ6r!OwkHW}0hgr>H^+K#fC&V2Qy(1HH#pP>Q1W!T=oUP4mGS(jogRr<-zX}QcX zEy&hl^9bz)JSPE5^V1be5gi%ekS zf^hMN_JW~x;!)R}$)vC)BTHoH4L|?vtxAq%A_gy)Hv+?);>OF`-Qzg^HgGx-%2_c> z=7P>3x{ulz6dw>>k2X@F9D@>Z?PUcDnv<%0461JGb`bFy)qox&ogEQ^Rr7U4@_;p&W@i(LN`rHwbA(57n zWVy!O#sf-g#JU{6XTm~v8nq@_uPJAoaIHM07Ff01HB=lfJ`R`9vY zN`vIqFvj=uiZ@0Q;l79X-m}5P>a&ff%$I$AK~PE}w3kNI`MtRIMYCi?YfExYQtdyp z*nk?wdoLWJg%X`4#1EiF&c5xl_{ZvaZBmOH!yw}M&MaEB=+DoK+Hx9kpR@TJ2s7|m6dxnl2@?ow-pcftZ7)XUqWimSGO+?*@WZYxm`pT zABRjFzU{Ru>zM*}BC-bfEI#H20j&A0fV~KSOGsq1*%iW(kfqotY#LCM8kd4D2-k;o zew%fi;wV<83**V3rep74Ok3JX3duhXH8v()7DbwnzZ6L5ke~g1ER?ryC9WSyFn#Mt zEUcyBvrZxUA~xLkIUKlUJ8w;EL@o4jFuZ;c!b_xH8>1zDR|JF%PE+~m#`6kuvOBPc zz5CkA0M6yJaP9nKj*9lZQh%oe(9Y>Y`gnYU4mp^25sF z-#HtKJdAEyJVq7baXg7<$a9|MrAe-AjA5q0-@8AJKz%v zODW)Ne-)Wkh5bF9`=jDgXa;YbH#dzar33gZM#ZOr?HcL(ILdHxrh|b&%t5z-T;Brs z_8NX*)iwMUQv!RG92wVN<=%&j9sJtXqajJ`XrU2nJ!oWA zA~@-x0hb3_P~^*x)H6qPASZuwP;gS+Ms!%2AN(8S#4@_!zq;4QdUWbHy{(Xh$}7v5 zjIlWy(4*J|Ka2bM9K%@G@L9M`R=2-vv?5qw=^37)m!zygeJ-rKqD7ES7uqF((xVQO z#=Np$4Br2t2xhIul3j$#Q5tI$G!lM@v9lKoxkia^9pgjCJ96UXMhZYaZ)$av+CSM@ z7U0%p(HkxSY#n)9$%sc%3KYT7z@#hR@8Hb`?vQ!IN2@Du7mJYuCSXc-;qzd$R_VAj z%DpS361h6ctZK^qrd`7#da!+s85p+tPPF35X$Mj%Cxt)$ZMMdOpiX*iU%-P6W&)fS zHQh7c9m<=l6iI8uN{%1E?|^PizEa^f<1GB8D`Xz_l1gIoyzu%S_`1)(0r`IP+~2d{ z(ss1i2rL3RUr@bl^2X9a-BY=B!@k>uQ?FSnN$9#`kM=^oWIU}tk0P88>p06QNAzOE zgd7$zK#CrRx>|icHZB0ZtU+;HZ8GvAN<2!-W9LiFJ`Iap6D$L)szz-tD-rgt;4 zaCyqy&v`70u)g4Iby=PuA?1XI6MUTQkcG1E%&b!&Wow3xP$>Ha%So8#vxmlXYTN4%m`ZT7c7 z)!h{9sHwnV8MH!F`KDBzn^s+-VnEP~uk94B&FR*4&N#g4lGG}_w9M#2+-czM{PU2# zl+Ksi6HQCx!jKNMoohWH-1#GdSoI+$&d$pBWvw7=Dlgb#l}MS|`n=*NRjU*MxIEv| zQm*UFr8z>EKzykk=n-8V(#)5I7PK=+MQxe)6IE=(nH`C|!g%wdS5%HU<0(|IHqc`B zpl#GCJtyh zPF<`jI`6c6l)H%c2iRTP^$cc<`PX><%4yiGoZoNq!a=gh+k2!rIMZ@lYaq>9X?mFr z!I>Y5t@$eIu)=)CgRSRe7G5rT9pC_1{U}@6vQ-b=ru12KIbUA@V}sj9{<5x*Ve|1D z7n|kq22Re=557HNc1_8UFF~Dl+$k;NHc;`i$|(iWvEBu(xX5l%(ZTNWaS&Gcxw>{m zr&DzI@-d%-RPvmuruF`FpsX9->s4;#W;7t@OFK6Rr+9aSRZJ)-hSJO7x_fRYcsz=2|AMgZVoW+ zACn>;PD=w!&uqUh=dvfVHSTI_ae=;W%T$S4ygO{M- zf4V2VdtPX@R9ui?sSpYS`uSLPP8Zs@uOKu`*dab(;hthU#4dMlORvWb5ld5Lyj3+F zoP)=IX)jDPc>e6hoE~lQe6i*C9nm2CSt&mFEK=i1g2Rg(L%K_$gPMKvujQpFVQx{sg#BJZrxOVoz45vB5>0JGkjX z*(LALt4OP8!Jj*@tJ8hHm4F4wf-1$R|2`A%9>c;4dIoKf4^Y0=Lb zsWZfLy9_Gxj;$w!_WUdtU={mkarcKoJ&}F$IP!zM50>(Spx*umOohIWbSF9)TH*&m zlqni~_;OOixKZy7o3u5VI;U64zCi**TXqAF>Djz-6doFyT?$S^jJ@NTcayfI z@C30uo7)59wf^*o6Dk`oSl>`osY}x`e6XRVNs^E5z1M?V?TR6g&}t5>@iOyMGO49& zkJr}F?R4dYC<3yT@REpw+~gER^k_EuBYwNBG)`?Td+nW6W|RGMKSKTc046vfR5wTx zDM5PMeq%pe-ND=V`$Wgoeal}Q*pDfb&}A89sSzOMPPW6xNIbAtCOrmBU;``CVFA1g z&Dglsf>DF*90;2%zY+5n_tNCFPmz38K+(kMudMJ{;zhk|+sLeBuQr8cwA5FA>(CaeI<>d+Y>Ro9fJ14CFdQ3j;eqb)cR8^4 zm-oM-Qgz-jX8x)b&DbN3Ej3*<2;+x6irK~w&{imx<^in>6luEBvWc+vy_x9ZXqfBp zkZ>wuEc1H%ZyMOF1;&1VfU!gK){Ne3cs)(9be+7m_O}`v$M()TWk7{CB+nCn)h?S# zogTuDZ4a*h?F!*rp@s{^HFhX1#W(8J>1ua&jL>DflIQqg_6=Q+=gF6xYL%C!ht_t< zoFdiyAjtcpM*3hS0|4|N4bOk;(djm;{KrmDs#Laz^;&}(B zrWa$~e+*<0o?@SA9M=RT+s%(^srXJWSKCB5C2ze`=ey1+j+78^T$5YKsLg=f=*dem z^jZ5<7|o79R%~c=#Cxut<`)B|8uGKIrvLA!SK9Z))NA@G($sP4OEAGHgxMleVpvP1 zN;0{Dr)naw6^ZL> zk0VS@f}U*KeEX=y&0X&|ti?#x6ItA;6oeqK(fi&tnC-9z9@OVM?kEM>Ys5}&fzpV* zbhI}E_+i=so^e5G*qh^pbaw|q(2DH@huDsZ_jBklPFVxizwI+kQG8z4GD;QEn~uZF_Tp2_&6?C${1H60ck+p`6W=!V?~ zxPB3@23DRMz`7Opb{zFP7%gC310UD_xIGl~r`;@G7~w9ocJXIDrzHz7@Wr!;E?dG0 zISmK`DYW?z3OXTT#8&gLcXyBvR-&D6P}TG-F9|BM3vl@#M8ac_$4AXtMzY%UcjOU9 zTBLiD0g&>|eC=A5*x5{sral0j$1u~#-TGHG`1p~hG{s*je@tG_F=cV;j@}s*CiefB z*;FXl<6u^woi&n&V`;7A=rh~3LzLPDK54}lU%gpjEIOyTNs=C!X!2t0NMcxoRTs!1 zy03T}!Y3cfVs*V+{KEgR=c!lj|1FIZa?>7UFa%XJ#Q`tYeQl3FdU{{ckI2p^sS)_A z6MM+ogbed2R|6mq3;y5Te-8IDPlcS3@_#nA3^P~t>M9_sjGCXLQ(wyli!M|thU0D@ zZg@}H;tN=6fs_ImTh527U5sLk;lhI~JFs%pI6h7u-hcNNFecUv$IffOH&|-pj=Aw&)fz4s*O$;noT4eW zXjaG-4bLW{7*X5E(kSmuiaEy`n{Xv3 zf8UE*cAE5vVpK$Xf*uxaYmSnZGOKCKzFLsHs@j~T$)1;C6&s&!d5)<3%EY#ApD@aN z7Xy!OkuU@qcl}#_+%ebf8yQ-1%^o2hsIszzXtq3C%Od_9@DYu;CT?|lb6Hc-&HfMB7@{g&hVf`M)4LVnJb^ZyTHYRX)b{>8J5ll;D#30YW3Zd{srR8Zmj?S literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1ae5073c05d7b3ae9e47ad39209337b5d02ee4e0 GIT binary patch literal 6150 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 R;JAE1`H4EBSl%??{{TY}bld;{ literal 0 HcmV?d00001 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'