Commit 2649c8d5 authored by wanglei's avatar wanglei

...

parent bdc8002b
......@@ -48,5 +48,15 @@ dependencies {
androidTestImplementation(libs.androidx.espresso.core)
//第三方UI
implementation("com.airbnb.android:lottie:6.4.0")
implementation("com.github.angcyo.DslTablayout:TabLayout:3.5.5")
//相机
val cameraxVersion = "1.2.2"
implementation("androidx.camera:camera-core:${cameraxVersion}")
implementation("androidx.camera:camera-camera2:${cameraxVersion}")
implementation("androidx.camera:camera-view:${cameraxVersion}")
implementation("androidx.camera:camera-lifecycle:${cameraxVersion}")
}
\ No newline at end of file
......@@ -2,7 +2,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<!--required设置为true,无相机设备google play上不会分发-->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
......
{"v":"5.5.7","fr":60,"ip":0,"op":60,"w":640,"h":140,"nm":"合成 1","ddd":0,"assets":[{"id":"image_0","w":157,"h":175,"u":"images/","p":"img_0.png","e":0},{"id":"image_1","w":86,"h":50,"u":"images/","p":"img_1.png","e":0},{"id":"image_2","w":540,"h":114,"u":"images/","p":"img_2.png","e":0}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"bu.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[518,94.5,0],"to":[5.917,0,0],"ti":[-5.917,0,0]},{"t":30,"s":[553.5,94.5,0]}],"ix":2},"a":{"a":0,"k":[78.5,87.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"on.png","cl":"png","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[0]},{"t":31,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[502.25,57.5,0],"ix":2},"a":{"a":0,"k":[43,25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"qx2.png","cl":"png","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[320,57,0],"ix":2},"a":{"a":0,"k":[270,57,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
package com.base.browserwhite.ui.activity.scanqrc
import android.Manifest
import android.graphics.Color
import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.view.updatePadding
import com.base.browserwhite.databinding.ActivityScanQrcBinding
import com.base.browserwhite.ui.activity.BaseActivity
import com.base.browserwhite.ui.views.DialogViews.showGerPermission
import com.base.browserwhite.utils.BarUtils
import com.base.browserwhite.utils.PermissionHelp.checkCameraPermission
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
......@@ -9,7 +26,117 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
ActivityScanQrcBinding.inflate(layoutInflater)
}
//相机
private var camera: Camera? = null
private var preview: Preview? = null
private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
private var cameraProvider: ProcessCameraProvider? = null
private lateinit var cameraExecutor: ExecutorService
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
if (checkCameraPermission()) {
initCamera()
} else {
showGerPermission(desc = "") {
launcher.launch(arrayOf(Manifest.permission.CAMERA)) { map ->
if (map.values.all { it }) {
initCamera()
} else {
finishToMain()
}
}
}
}
}
private fun initCamera() {
cameraExecutor = Executors.newSingleThreadExecutor()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
//初始化相机
cameraProvider = cameraProviderFuture.get()
bindCameraUseCases(lensFacing)
}, ContextCompat.getMainExecutor(this))
}
//绑定设置和相机实例
private fun bindCameraUseCases(lensFacing: Int) {
val aspectRation = aspectRatio(
binding.previewView.width,
binding.previewView.height
)
val rotation = binding.previewView.display.rotation
// 选择相机
val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
//构建预览
preview = buildPreview(aspectRation, rotation)
//构建图片捕捉类
// imageCapture = buildImageCapture(aspectRation, rotation)
//构建图片分析器
// imageAnalyzer = buildImageAnalysis(aspectRation, rotation) {
// it.setAnalyzer(cameraExecutor, LuminosityAnalyzer())
// }
//每次绑定需先解绑
cameraProvider?.unbindAll()
try {
camera = cameraProvider?.bindToLifecycle(
this, cameraSelector, preview
)
preview?.setSurfaceProvider(binding.previewView.surfaceProvider)
} catch (exc: Exception) {
exc.printStackTrace()
}
}
/**
* 构建横纵比
*/
private fun aspectRatio(width: Int, height: Int): Int {
val previewRatio = max(width, height).toDouble() / min(width, height)
if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
return AspectRatio.RATIO_4_3
}
return AspectRatio.RATIO_16_9
}
/**
* 构建预览图
* @param aspectRatio 宽高比
* @param rotation 预览图方向
*/
private fun buildPreview(aspectRatio: Int, rotation: Int): Preview {
return Preview.Builder()
.setTargetAspectRatio(aspectRatio)
.setTargetRotation(rotation)
.build()
}
override fun onDestroy() {
super.onDestroy()
cameraExecutor.shutdown()
}
companion object {
//横纵比
private const val RATIO_4_3_VALUE = 4.0 / 3.0
private const val RATIO_16_9_VALUE = 16.0 / 9.0
}
}
\ No newline at end of file
package com.base.browserwhite.ui.views
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
......@@ -13,12 +17,52 @@ import com.base.browserwhite.bean.ConstObject.GOOGLE
import com.base.browserwhite.bean.ConstObject.YAHOO
import com.base.browserwhite.bean.ConstObject.YANDEX
import com.base.browserwhite.databinding.DialogMyAccountBinding
import com.base.browserwhite.databinding.DialogPermissonOpenBinding
import com.base.browserwhite.databinding.DialogSearchEngineBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
object DialogViews {
@SuppressLint("SetTextI18n")
fun Context.showGerPermission(
tittle: String? = null,
desc: String? = null,
denyText: String? = null,
allowText: String? = null,
deny: ((view: Dialog) -> Unit)? = null,
allow: ((view: Dialog) -> Unit)? = null
): Dialog {
val dialog = Dialog(this)
val binding = DialogPermissonOpenBinding.inflate(LayoutInflater.from(this))
dialog.requestWindowFeature(1)
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.window!!.setLayout(-1, -1)
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.setContentView(binding.root)
val str = resources.getString(R.string.app_name)
tittle?.let { binding.tvTitle.text = it }
desc?.let { binding.tvDesc.text = it }
denyText?.let { binding.idDeny.text = it }
allowText?.let { binding.idTvAllow.text = it }
binding.idFullLottie.imageAssetsFolder = "permission_finger/images/"
binding.idFullLottie.setAnimation("permission_finger/data.json")
binding.idFullLottie.playAnimation()
binding.idDeny.setOnClickListener {
dialog.dismiss()
deny?.invoke(dialog)
}
binding.idTvAllow.setOnClickListener {
dialog.dismiss()
allow?.invoke(dialog)
}
dialog.show()
return dialog
}
fun Context.showSearchEngineDialog(selectWebSite: String = GOOGLE, confirmAction: (webSite: String) -> Unit) {
val binding = DialogSearchEngineBinding.inflate(LayoutInflater.from(this))
......
package com.base.browserwhite.ui.views
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import com.airbnb.lottie.LottieAnimationView
class XmlLottieAnimationView : LottieAnimationView {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun draw(canvas: Canvas) {
try {
super.draw(canvas)
} catch (e: Exception) {
}
}
override fun playAnimation() {
super.playAnimation()
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.core.app.ActivityCompat
import com.base.browserwhite.utils.PermissionHelp.checkStorePermission
object PermissionHelp {
fun Context.checkCameraPermission(): Boolean {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
}
fun Context.checkStorePermission(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Environment.isExternalStorageManager()
} else {
val readPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
val writePermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
return readPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;
}
}
fun Context.requestStorePermission(
launcher: ActivityLauncher,
jumpAction: (() -> Unit)? = null,
result: (flag: Boolean) -> Unit
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val intent =
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data = Uri.parse("package:${packageName}")
jumpAction?.invoke()
launcher.launch(intent) {
result.invoke(checkStorePermission())
}
} else {
launcher.launch(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { map ->
result(map.values.all { it })
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="18dp" />
<solid android:color="#355BEA" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F5F5F5" />
<corners android:radius="18dp" />
</shape>
\ No newline at end of file
......@@ -7,4 +7,9 @@
android:layout_height="match_parent"
tools:context=".ui.activity.scanqrc.ScanQRCActivity">
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:background="@drawable/bg_ffffff_10"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="24dp"
android:text="Permission request"
android:textColor="#000000"
android:textSize="17sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="22dp"
android:layout_marginBottom="38dp"
android:textSize="13sp" />
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/id_full_lottie"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="23dp"
android:layout_marginTop="40dp"
android:layout_marginBottom="14dp">
<TextView
android:id="@+id/id_deny"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginEnd="13dp"
android:layout_weight="1"
android:background="@drawable/bg_f5f5f5_18"
android:gravity="center"
android:text="Deny"
android:textColor="#000000"
android:textSize="17sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/id_tv_allow"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_weight="1"
android:background="@drawable/bg_355bea_18"
android:gravity="center"
android:text="Allow"
android:textColor="@color/white"
android:textSize="17sp"
tools:ignore="HardcodedText" />
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment