Parcourir la source

1.相机权限2.相机进度条

everywindchase il y a 4 mois
Parent
commit
081c370c7a

+ 7 - 0
app/build.gradle

@@ -84,6 +84,13 @@ dependencies {
     implementation libs.koin.android
     implementation  libs.preference
     implementation  libs.calender
+    implementation  libs.camera2
+    implementation  libs.camera.core
+    implementation  libs.camera.life
+    implementation  libs.camera.video
+    implementation  libs.camera.view
+    implementation  libs.camera.mlkit
+    implementation  libs.camera.ext
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.5'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

+ 34 - 0
app/src/main/AndroidManifest.xml

@@ -2,6 +2,31 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools">
 
+
+    <uses-feature android:name="android.hardware.camera"
+                  android:required="false" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <!-- Devices running Android 12L (API level 32) or lower  -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+                     android:maxSdkVersion="32"
+                     tools:ignore="ScopedStorage" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+                     android:maxSdkVersion="32" />
+
+    <!-- Devices running Android 13 (API level 33) or higher -->
+    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
+    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
+    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
+
+
+    <!-- To handle the reselection within the app on Android 14 (API level 34) -->
+    <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
+
+
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
+
+
+
     <application
             android:name=".apps.InternalApp"
             android:allowBackup="true"
@@ -57,6 +82,15 @@
                 android:windowSoftInputMode="adjustPan|stateHidden"
         >
         </activity>
+
+
+        <activity
+                android:name=".ui.activity.ActionTaskHandActivity"
+                android:configChanges="screenSize|keyboardHidden|orientation|keyboard|locale|layoutDirection"
+                android:launchMode="singleTask"
+                android:windowSoftInputMode="adjustPan|stateHidden"
+        >
+        </activity>
     </application>
 
 </manifest>

+ 9 - 0
app/src/main/java/jx/cn/escort/adapter/IndexAbilityRecycleAdapter.kt

@@ -10,6 +10,9 @@ import com.xuexiang.xui.widget.textview.supertextview.SuperTextView
 import jx.cn.escort.R
 import jx.cn.escort.beans.AbilityData
 import jx.cn.escort.beans.StatData
+import jx.cn.escort.ui.activity.ActionTaskHandActivity
+import jx.cn.escort.ui.activity.LoginActivity
+import jx.cn.escort.utils.ActivityUtils
 
 
 open class IndexAbilityRecycleAdapter(): RecyclerView.Adapter<IndexAbilityRecycleAdapter.IndexAbilityRecycleViewHolder>() {
@@ -56,6 +59,12 @@ open class IndexAbilityRecycleAdapter(): RecyclerView.Adapter<IndexAbilityRecycl
         val params: ViewGroup.LayoutParams? = statListItem?.layoutParams
         params?.width = width
         statListItem?.setLayoutParams(params)
+        statListItem?.setOnClickListener(object: View.OnClickListener{
+            override fun onClick(v: View?) {
+                context?.let { ActivityUtils.startActivity(it, ActionTaskHandActivity::class.java) }
+            }
+
+        })
 
     }
 

+ 231 - 0
app/src/main/java/jx/cn/escort/ui/activity/ActionTaskHandActivity.kt

@@ -0,0 +1,231 @@
+package jx.cn.escort.ui.activity
+
+
+
+import android.Manifest
+import android.Manifest.permission.*
+import android.content.Context
+import android.content.DialogInterface
+import android.content.Intent
+import android.content.SharedPreferences
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.provider.Settings
+import android.util.Log
+import android.util.Size
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.camera.core.*
+import androidx.camera.core.ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888
+import androidx.camera.core.resolutionselector.ResolutionSelector
+import androidx.camera.core.resolutionselector.ResolutionStrategy
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.view.PreviewView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.LifecycleOwner
+import com.xuexiang.xui.XUI
+import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
+import jx.cn.escort.R
+import jx.cn.escort.databinding.ActivityActionTaskHandleBinding
+import jx.cn.escort.extension.ExtensionBinding.Companion.binding
+import jx.cn.escort.ui.widget.CircleProgressView
+import jx.cn.escort.utils.ActivityUtils
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+
+
+class ActionTaskHandActivity : AppCompatActivity(), KoinComponent {
+
+    private val mBinding: ActivityActionTaskHandleBinding by binding<ActivityActionTaskHandleBinding>()
+
+    private val mContext: Context by  inject()
+
+    private val defaultSharedPreferences: SharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(mContext)
+
+    private lateinit var cameraExecutor: ExecutorService
+    private var cameraProvider: ProcessCameraProvider? = null
+    private var preview: Preview? = null
+    private var imageCamera: ImageCapture? = null
+    private lateinit var camera: Camera //相机对象
+    private lateinit   var imageAnalysis: ImageAnalysis
+
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        XUI.initTheme(this@ActionTaskHandActivity);
+        super.onCreate(savedInstanceState)
+        setContentView(mBinding.root)
+        var taskHandleFace=mBinding.taskHandleFace
+        val taskHandleTitle = mBinding.taskHandleTitle
+        taskHandleTitle.setTitle("人脸验证")
+        taskHandleTitle.setLeftClickListener(object:View.OnClickListener{
+            override fun onClick(v: View?) {
+                ActivityUtils.startActivity(this@ActionTaskHandActivity,MainActivity::class.java)
+            }
+        })
+
+        taskHandleFace.setOnClickListener(object:View.OnClickListener{
+            override fun onClick(v: View?) {
+                val li = LayoutInflater.from(this@ActionTaskHandActivity)
+                val inflate = li.inflate(jx.cn.escort.R.layout.layout_task_face,null)
+                val cameralayoutc = inflate.findViewById<ConstraintLayout>(jx.cn.escort.R.id.camera_layoutc)
+                var circle:View= CircleProgressView(this@ActionTaskHandActivity)
+                //circle.id= androidx.camera.core.R.id.faceCircle
+                cameralayoutc.addView(circle)
+                val dialog = MaterialDialog.Builder(this@ActionTaskHandActivity)
+                    .customView(inflate, true)
+                    .title("拿起手机刷脸").showListener(object: DialogInterface.OnShowListener{
+                        override fun onShow(dialog: DialogInterface?) {
+                            if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission(this@ActionTaskHandActivity    , Manifest.permission.CAMERA)){
+
+
+                                ActivityCompat.requestPermissions(this@ActionTaskHandActivity , arrayOf(Manifest.permission.CAMERA),100)
+
+                                //打开自定义授权弹窗
+                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                                    // Android 13及以上完整照片和视频访问权限
+                                    if(ContextCompat.checkSelfPermission(baseContext, READ_MEDIA_IMAGES) == PERMISSION_GRANTED) {
+                                        ActivityCompat.requestPermissions(this@ActionTaskHandActivity  , arrayOf(Manifest.permission.READ_MEDIA_IMAGES), 101)
+                                    }
+                                    if(ContextCompat.checkSelfPermission(baseContext, READ_MEDIA_VIDEO) == PERMISSION_GRANTED) {
+                                        ActivityCompat.requestPermissions(this@ActionTaskHandActivity, arrayOf(Manifest.permission.READ_MEDIA_VIDEO), 102)
+                                    }
+                                    if(ContextCompat.checkSelfPermission(baseContext, READ_MEDIA_AUDIO) == PERMISSION_GRANTED) {
+                                        ActivityCompat.requestPermissions(this@ActionTaskHandActivity , arrayOf(Manifest.permission.READ_MEDIA_AUDIO), 103)
+                                    }
+
+                                } else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+                                    // Android 12及以下完整本地读写访问权限
+                                    if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission( baseContext   , Manifest.permission.READ_EXTERNAL_STORAGE)){
+                                        ActivityCompat.requestPermissions(this@ActionTaskHandActivity   , arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),104)
+                                    }
+                                    if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission( baseContext   , Manifest.permission.WRITE_EXTERNAL_STORAGE)){
+                                        ActivityCompat.requestPermissions(this@ActionTaskHandActivity   , arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),105)
+                                    }
+                                }
+
+
+                                //弹窗回调完再打开相机
+
+                            }else{
+                                //打开相机
+                                runCamera(this@ActionTaskHandActivity,cameralayoutc.findViewById(R.id.mPreviewView) , context = this@ActionTaskHandActivity)
+                            }
+                        }
+
+                    })
+                dialog.show()
+//检查手机相机权限
+
+
+            }
+        })
+    }
+
+
+
+    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+        when(requestCode){
+            100-> {
+                for (index in permissions.indices) {
+                    Log.i("ActionTask", "申请权限为:${permissions[index]}" + "申请结果为:${grantResults[index]}")
+                }
+                //Toast.makeText(mContext    as AppCompatActivity, "外部读取权限申请成功", Toast.LENGTH_SHORT).show()
+                // ActivityCompat.shouldShowRequestPermissionRationale(this@ActionTaskHandActivity,permissions[0])
+            }
+            else->{
+                //Toast.makeText(mContext    as AppCompatActivity, "外部读取权限申请失败", Toast.LENGTH_SHORT).show()
+
+            }
+        }
+    }
+
+
+    fun runCamera(lifecycleOwner: LifecycleOwner, previewView: PreviewView?, context: Context){
+
+
+        val  cameraSelector: CameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
+
+
+        cameraExecutor = Executors.newSingleThreadExecutor()
+        val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
+        cameraProviderFuture.addListener({ cameraProvider = cameraProviderFuture.get()//获取相机信息
+
+
+
+
+            val resolutionBuilder = ResolutionSelector
+                .Builder()
+                .setResolutionStrategy(ResolutionStrategy(Size(640, 480), ResolutionStrategy.FALLBACK_RULE_NONE))
+                .build()
+            //预览配置
+            preview = Preview.Builder().setResolutionSelector(resolutionBuilder)
+                .build()
+
+
+
+
+
+            imageCamera = ImageCapture.Builder()
+                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+                .build()
+            imageAnalysis = ImageAnalysis.Builder().setOutputImageFormat(OUTPUT_IMAGE_FORMAT_YUV_420_888)
+                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
+                //.setTargetResolution(Size(640, 480))
+                .build()
+
+
+            imageAnalysis.setAnalyzer(cameraExecutor) { imageProxy ->
+                    Log.d("ActionTask", "图片格式${imageProxy.format}")
+
+            }
+
+            try {
+                cameraProvider?.unbindAll()//先解绑所有用例
+                camera = cameraProvider?.bindToLifecycle(
+                    lifecycleOwner,
+                    cameraSelector,
+                    preview,
+                    imageCamera,
+                    imageAnalysis
+                )!!//绑定用例
+                preview?.setSurfaceProvider(previewView?.surfaceProvider)
+                if(null!=previewView) {
+                    observeCameraLife(camera, lifecycleOwner, previewView)
+                }
+
+
+            } catch (e: Exception) {
+                Log.d("ActionTask","初始化相机异常${e.message}")
+            }
+
+        },ContextCompat.getMainExecutor(context))
+
+
+
+    }
+    fun observeCameraLife(camera:Camera,lifecycleOwner:LifecycleOwner,previewView:PreviewView){
+        camera.cameraInfo.cameraState.observe(lifecycleOwner) { value ->
+            when (value.type) {
+                CameraState.Type.OPEN         ->{
+                    Log.d("demo", "相机正在打开中" )
+                }
+
+                CameraState.Type.PENDING_OPEN -> Log.d("demo", "相机待打开" )
+                CameraState.Type.OPENING      -> Log.d("demo", "相机已打开" )
+                CameraState.Type.CLOSING      ->Log.d("demo", "相机关闭中" )
+                CameraState.Type.CLOSED       -> Log.d("demo", "相机已关闭" )
+            }
+
+        }
+    }
+}

+ 152 - 0
app/src/main/java/jx/cn/escort/ui/widget/CircleProgressView.kt

@@ -0,0 +1,152 @@
+package jx.cn.escort.ui.widget
+
+import android.content.Context
+import android.graphics.*
+import android.util.Log
+import android.view.View
+
+
+class CircleProgressView(context: Context) : View(context) {
+
+
+    private var bottomCirclePaint: Paint? = null //底部圆画笔
+    private var paintWidth = 0f //底部圆外扩半径
+    private var centerPoint: PointF? = null //中心点
+
+    private var mInnerPaint: Paint? = null //内环
+    private var mTextPaint: Paint? = null //文字
+    private var InnerRectF: RectF? = null //内环 位置
+
+    private var mProgressPaint: Paint? = null //内环 进度
+
+    private var progress = 0 //进度
+
+    private var progressStartColor = "#b3e6fe" //进度渐变开始颜色
+    private var progressEndColor = "#04adfb" //进度渐变结束颜色
+
+    fun setProgressStartColor(progressStartColor: String) {
+        this.progressStartColor = progressStartColor
+    }
+
+    fun setProgressEndColor(progressEndColor: String) {
+        this.progressEndColor = progressEndColor
+    }
+
+
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        super.onDraw(canvas)
+        initPaint()
+        var text = "未检测到人脸"
+        var angle = progress.toFloat() * 330 / 100
+        if (angle > 330) {
+            angle = 330f
+        } else if (angle > 30) {
+            text = "请保持不动"
+        }
+        val width = mTextPaint!!.measureText(text)
+
+        canvas.drawText(text, centerPoint!!.x - width / 2, InnerRectF!!.top + 100, mTextPaint!!)
+
+        canvas.drawCircle(centerPoint!!.x, centerPoint!!.y, (paintWidth * 3 / 2 + paintWidth / 2), bottomCirclePaint!!)
+        canvas.drawArc(InnerRectF!!, 105f, 330f, false, mInnerPaint!!)
+        canvas.drawArc(InnerRectF!!, 105f, angle, false, mProgressPaint!!)
+    }
+
+    /**
+     * 初始化画笔
+     */
+    private fun initPaint() {
+        if (bottomCirclePaint == null) {
+            bottomCirclePaint = Paint()
+            bottomCirclePaint!!.color = Color.WHITE
+            bottomCirclePaint!!.isAntiAlias = true //抗锯齿
+            bottomCirclePaint!!.style = Paint.Style.STROKE //不加这个不显示
+        }
+        if (mInnerPaint == null) {
+            mInnerPaint = Paint()
+            mInnerPaint!!.color = Color.GRAY
+            mInnerPaint!!.alpha = 60
+            //抗锯齿
+            mInnerPaint!!.isAntiAlias = true
+            //画笔宽度
+            mInnerPaint!!.strokeWidth = 12f
+            //防抖动
+            mInnerPaint!!.isDither = true
+            //设置状态
+            mInnerPaint!!.style = Paint.Style.STROKE
+            //头部小圆点
+            mInnerPaint!!.strokeCap = Paint.Cap.ROUND
+        }
+        if (mTextPaint == null) {
+            mTextPaint = Paint()
+            mTextPaint!!.color = Color.WHITE
+            mTextPaint!!.textSize = 38f
+        }
+        if (mProgressPaint == null) {
+            mProgressPaint = Paint()
+            mProgressPaint!!.color = Color.BLUE
+            //抗锯齿
+            mProgressPaint!!.isAntiAlias = true
+            //画笔宽度
+            mProgressPaint!!.strokeWidth = 12f
+            //防抖动
+            mProgressPaint!!.isDither = true
+            //设置状态
+            mProgressPaint!!.style = Paint.Style.STROKE
+            //头部小圆点
+            mProgressPaint!!.strokeCap = Paint.Cap.ROUND
+        }
+
+        if (centerPoint == null) {
+            centerPoint = PointF()
+        }
+        if (paintWidth < 1) {
+            paintWidth = 180f
+            centerPoint!!.x = (width / 2).toFloat()
+            centerPoint!!.y = (height / 2).toFloat()
+            initRectF()
+        }
+        Log.e("TEST", "onMeasure$paintWidth")
+        bottomCirclePaint!!.strokeWidth = paintWidth
+    }
+
+    private fun initRectF() {
+        if (InnerRectF == null) {
+            InnerRectF = RectF()
+        }
+        val radius = paintWidth * 3 / 2 + 6
+        InnerRectF!!.top = centerPoint!!.y - radius
+        InnerRectF!!.left = centerPoint!!.x - radius
+        InnerRectF!!.bottom = centerPoint!!.y + radius
+        InnerRectF!!.right = centerPoint!!.x + radius
+        val lg = LinearGradient(InnerRectF!!.left, InnerRectF!!.top, InnerRectF!!.right, InnerRectF!!.bottom, Color.parseColor(progressStartColor), Color.parseColor(progressEndColor), Shader.TileMode.MIRROR)
+        mProgressPaint!!.setShader(lg)
+    }
+
+    fun setCenterPoint(x: Float, y: Float) {
+        Log.e("TEST", "setCenterPoint$x   $y")
+        if (centerPoint == null) {
+            centerPoint = PointF()
+        }
+        centerPoint!!.x = x
+        centerPoint!!.y = y
+        initRectF()
+        postInvalidate()
+    }
+
+    fun setProgress(progress: Int) {
+        this.progress = progress
+        postInvalidate()
+    }
+
+    fun setPaintWidth(paintWidth: Float) {
+        Log.e("TEST", "setPaintWidth$paintWidth")
+        this.paintWidth = paintWidth
+    }
+
+}

BIN
app/src/main/res/drawable-hdpi/ic_task_face.png


BIN
app/src/main/res/drawable-hdpi/ic_task_line_car.png


BIN
app/src/main/res/drawable-hdpi/ic_task_line_member.png


+ 20 - 0
app/src/main/res/drawable/task_title_bg.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle"
+>
+<corners  android:topLeftRadius="20dp"   android:topRightRadius="20dp"
+
+          android:bottomLeftRadius="20dp"    android:bottomRightRadius="20dp"
+/>
+    <gradient
+        android:angle="360"
+        android:startColor="#D2F4F4"
+        android:centerColor="#95E4D4"
+        android:endColor="#95E4D4"
+    />
+
+
+
+
+
+</shape>

+ 87 - 0
app/src/main/res/layout/activity_action_task_handle.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:tools="http://schemas.android.com/tools"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.activity.ActionTaskHandActivity"
+        android:background="#f5f5f5"
+>
+    <com.xuexiang.xui.widget.actionbar.TitleBar
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="#8ad1d2"
+            app:tb_barHeight="65dp"
+            app:tb_dividerColor="@color/xui_config_color_white"
+            app:tb_leftText="返回"
+            app:tb_sideTextPadding="20dp"
+            app:tb_actionPadding="20dp"
+            app:tb_titleText="标题"
+            android:id="@+id/task_handle_title"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:tb_useThemeColor="false"
+    />
+
+
+    <androidx.cardview.widget.CardView
+            android:layout_marginTop="15dp"
+            android:id="@+id/task_handle_card"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/task_handle_title"
+            android:layout_width="match_parent"
+            android:layout_height="230dp"
+    >
+
+        <com.xuexiang.xui.widget.textview.supertextview.SuperTextView
+                android:id="@+id/task_handle_face"
+                android:layout_height="100dp"
+                android:layout_width="match_parent"
+                app:sCenterTopTextString="人脸识别"
+                app:sCenterTopTextSize="20sp"
+                app:sCenterTextIsBold="true"
+                app:sCenterTextSize="15sp"
+                app:sCenterTopTextColor="#F5F8F7"
+                app:sCenterTextString="请正对相机,五官需清晰可见"
+                app:sCenterTextColor="@color/xui_config_color_white"
+                app:sBackgroundDrawableRes="@drawable/task_title_bg"
+                app:sLeftIconRes="@drawable/ic_task_face"
+        />
+
+        <com.xuexiang.xui.widget.textview.autofit.AutoFitLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="120dp">
+
+            <com.xuexiang.xui.widget.textview.supertextview.SuperTextView
+                    android:layout_width="match_parent"
+                    android:layout_height="42dp"
+                    app:sLeftTextString="线路车辆:"
+                    app:sLeftTextIsBold="true"
+                    app:sLeftTextSize="21sp"
+                    app:sLeftIconRes="@drawable/ic_task_line_car"
+            />
+
+            <com.xuexiang.xui.widget.textview.supertextview.SuperTextView
+                    android:layout_width="match_parent"
+                    android:layout_height="42dp"
+                    app:sLeftTextString="线路人员:"
+                    app:sLeftTextIsBold="true"
+                    app:sLeftTextSize="21sp"
+                    android:layout_marginTop="40dp"
+                    app:sLeftIconRes="@drawable/ic_task_line_member"
+            />
+        </com.xuexiang.xui.widget.textview.autofit.AutoFitLayout>
+
+
+    </androidx.cardview.widget.CardView>
+
+
+
+
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 4
app/src/main/res/layout/fragment_index.xml

@@ -16,7 +16,6 @@
         >
 
 
-
                 <androidx.cardview.widget.CardView
 
                         android:id="@+id/notification_layout"
@@ -26,7 +25,7 @@
                         app:layout_constraintEnd_toEndOf="parent"
                         app:layout_constraintBottom_toTopOf="@id/statistics_layout"
                         android:layout_marginBottom="6dp"
-                >
+                        app:layout_constraintHorizontal_bias="0.0">
                         <com.xuexiang.xui.widget.textview.MarqueeTextView
                                 android:id="@+id/tv_marquee"
                                 android:layout_width="match_parent"
@@ -37,8 +36,6 @@
 
 
                 </androidx.cardview.widget.CardView>
-
-
                 <androidx.cardview.widget.CardView
                         android:id="@+id/statistics_layout"
                         android:layout_width="match_parent" android:layout_height="80dp"

+ 48 - 0
app/src/main/res/layout/layout_task_face.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             xmlns:app="http://schemas.android.com/apk/res-auto"
+             xmlns:tools="http://schemas.android.com/tools"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:background="@color/xui_transparent">
+
+
+
+     <androidx.constraintlayout.widget.ConstraintLayout
+             android:id="@+id/camera_layoutc"
+             android:layout_width="400dp"
+             android:layout_height="480dp"
+             android:gravity="center"
+             android:layout_gravity="center"
+     >
+
+
+
+
+
+
+
+
+
+     </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+
+
+
+     <androidx.camera.view.PreviewView
+             android:id="@+id/mPreviewView"
+             android:layout_width="100dp"
+             android:layout_height="100dp"
+             android:layout_gravity="center"
+             android:gravity="center"
+             app:layout_constraintBottom_toBottomOf="parent"
+             app:layout_constraintHorizontal_bias="1.0"
+             app:layout_constraintLeft_toLeftOf="parent"
+             app:layout_constraintRight_toRightOf="parent"
+             app:layout_constraintTop_toTopOf="parent"
+             app:layout_constraintVertical_bias="0.0" />
+
+
+
+</FrameLayout>

+ 9 - 0
gradle/libs.versions.toml

@@ -17,6 +17,15 @@ koin-android = "io.insert-koin:koin-android:3.5.6"
 preference= 'androidx.preference:preference:1.2.0'
 calender= 'com.necer.ncalendar:ncalendar:5.0.2'
 
+#cameraX
+camera2 ='androidx.camera:camera-camera2:1.3.2'
+camera-core ='androidx.camera:camera-core:1.3.2'
+camera-life ='androidx.camera:camera-lifecycle:1.3.2'
+camera-video ='androidx.camera:camera-video:1.3.2'
+camera-view ='androidx.camera:camera-view:1.3.2'
+camera-mlkit ='androidx.camera:camera-mlkit-vision:1.4.0-alpha04'
+camera-ext='androidx.camera:camera-extensions:1.3.2'
+
 [plugins]