扫一扫
This commit is contained in:
2
.idea/deploymentTargetSelector.xml
generated
2
.idea/deploymentTargetSelector.xml
generated
@@ -4,7 +4,7 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-05-16T03:07:32.812890200Z">
|
<DropdownSelection timestamp="2026-05-18T03:55:13.002969200Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />
|
||||||
|
|||||||
@@ -91,5 +91,12 @@ dependencies {
|
|||||||
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
|
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
|
||||||
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
|
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
|
||||||
implementation("androidx.core:core-ktx:1.12.0")
|
implementation("androidx.core:core-ktx:1.12.0")
|
||||||
|
//二维码三方库
|
||||||
|
implementation("com.github.maning0303:MNMLKitScanner:V1.0.4")
|
||||||
|
implementation("com.google.mlkit:barcode-scanning:17.0.2")
|
||||||
|
implementation("androidx.camera:camera-core:1.0.2")
|
||||||
|
implementation("androidx.camera:camera-camera2:1.0.2")
|
||||||
|
implementation("androidx.camera:camera-lifecycle:1.0.2")
|
||||||
|
implementation("androidx.camera:camera-view:1.0.0-alpha25")
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.example.defenseapplication.home
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -30,6 +36,8 @@ import com.example.defenseapplication.utils.UserinfoUtil
|
|||||||
import com.example.defenseapplication.view.DefenseDialogs
|
import com.example.defenseapplication.view.DefenseDialogs
|
||||||
import com.example.defenseapplication.view.showDefenseDialog
|
import com.example.defenseapplication.view.showDefenseDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import com.maning.mlkitscanner.scan.MNScanManager
|
||||||
|
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -45,6 +53,85 @@ class HomeMenuFragment : Fragment() {
|
|||||||
private var isFamilyExpanded = false
|
private var isFamilyExpanded = false
|
||||||
private lateinit var currentFamily: String
|
private lateinit var currentFamily: String
|
||||||
|
|
||||||
|
private val requestPermissionsLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestMultiplePermissions()
|
||||||
|
) { permissions ->
|
||||||
|
val cameraGranted = permissions[Manifest.permission.CAMERA] ?: false
|
||||||
|
|
||||||
|
val storageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
permissions[Manifest.permission.READ_MEDIA_IMAGES] ?: false
|
||||||
|
} else {
|
||||||
|
permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraGranted && storageGranted) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPermissionsAndScan() {
|
||||||
|
val cameraPermission = ContextCompat.checkSelfPermission(
|
||||||
|
requireContext(),
|
||||||
|
Manifest.permission.CAMERA
|
||||||
|
)
|
||||||
|
|
||||||
|
val storagePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
ContextCompat.checkSelfPermission(
|
||||||
|
requireContext(),
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ContextCompat.checkSelfPermission(
|
||||||
|
requireContext(),
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraPermission == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
storagePermission == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
val permissionsToRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
requestPermissionsLauncher.launch(permissionsToRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startScan() {
|
||||||
|
MNScanManager.startScan(requireContext() as Activity, object: MNScanCallback {
|
||||||
|
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||||
|
when (resultCode) {
|
||||||
|
MNScanManager.RESULT_SUCCESS -> {
|
||||||
|
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
||||||
|
if (!result.isNullOrEmpty()) {
|
||||||
|
ToastUtils.showToast(requireContext(), "扫码成功: $result")
|
||||||
|
} else {
|
||||||
|
ToastUtils.showToast(requireContext(), "扫码结果为空")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_FAIL -> {
|
||||||
|
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||||
|
ToastUtils.showToast(requireContext(), "扫码失败: $error")
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_CANCLE -> {
|
||||||
|
ToastUtils.showToast(requireContext(), "扫码取消")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
||||||
override fun onUnreadCountChanged(count: Int) {
|
override fun onUnreadCountChanged(count: Int) {
|
||||||
updateUnreadCountUI(count)
|
updateUnreadCountUI(count)
|
||||||
@@ -112,8 +199,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
binding.addFamily.setOnClickListener {
|
binding.addFamily.setOnClickListener {
|
||||||
val intent = Intent(requireContext(), ScanActivity::class.java)
|
checkPermissionsAndScan()
|
||||||
startActivity(intent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchFamilyList()
|
fetchFamilyList()
|
||||||
|
|||||||
@@ -1,295 +0,0 @@
|
|||||||
package com.example.defenseapplication.home
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.graphics.ImageFormat
|
|
||||||
import android.graphics.Matrix
|
|
||||||
import android.graphics.RectF
|
|
||||||
import android.graphics.SurfaceTexture
|
|
||||||
import android.hardware.Camera
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.provider.MediaStore
|
|
||||||
import android.view.SurfaceHolder
|
|
||||||
import android.view.SurfaceView
|
|
||||||
import android.view.View
|
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import android.view.animation.TranslateAnimation
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.databinding.ScanActivityBinding
|
|
||||||
import com.google.zxing.*
|
|
||||||
import com.google.zxing.common.HybridBinarizer
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
|
||||||
import java.util.*
|
|
||||||
//扫一扫页面
|
|
||||||
class ScanActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
|
||||||
|
|
||||||
private lateinit var binding: ScanActivityBinding
|
|
||||||
private var camera: Camera? = null
|
|
||||||
private var isFlashlightOn = false
|
|
||||||
private var scanHandler: Handler? = null
|
|
||||||
private var scanRunnable: Runnable? = null
|
|
||||||
private val REQUEST_CODE_CAMERA = 100
|
|
||||||
private val REQUEST_CODE_ALBUM = 101
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ScanActivityBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
ImmersionBar.with(this)
|
|
||||||
.statusBarDarkFont(true)
|
|
||||||
.titleBar(binding.btnBack)
|
|
||||||
.init()
|
|
||||||
initView()
|
|
||||||
initListener()
|
|
||||||
startScanLineAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
binding.surfaceView.holder.addCallback(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initListener() {
|
|
||||||
binding.btnBack.setOnClickListener {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llAlbum.setOnClickListener {
|
|
||||||
openAlbum()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llFlashlight.setOnClickListener {
|
|
||||||
toggleFlashlight()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startScanLineAnimation() {
|
|
||||||
val animation = TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_PARENT, 0f,
|
|
||||||
Animation.RELATIVE_TO_PARENT, 0f,
|
|
||||||
Animation.RELATIVE_TO_PARENT, 0f,
|
|
||||||
Animation.RELATIVE_TO_PARENT, 1f
|
|
||||||
)
|
|
||||||
animation.duration = 2000
|
|
||||||
animation.repeatCount = Animation.INFINITE
|
|
||||||
animation.interpolator = LinearInterpolator()
|
|
||||||
binding.scanLine.startAnimation(animation)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun openAlbum() {
|
|
||||||
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_ALBUM)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleFlashlight() {
|
|
||||||
if (camera == null) {
|
|
||||||
Toast.makeText(this, "相机未准备好", Toast.LENGTH_SHORT).show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isFlashlightOn = !isFlashlightOn
|
|
||||||
val params = camera?.parameters
|
|
||||||
|
|
||||||
if (isFlashlightOn) {
|
|
||||||
params?.flashMode = Camera.Parameters.FLASH_MODE_TORCH
|
|
||||||
binding.ivFlashlight.setColorFilter(ContextCompat.getColor(this, R.color.green))
|
|
||||||
} else {
|
|
||||||
params?.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
|
||||||
binding.ivFlashlight.clearColorFilter()
|
|
||||||
}
|
|
||||||
|
|
||||||
camera?.parameters = params
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkCameraPermission(): Boolean {
|
|
||||||
return ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.CAMERA
|
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun requestCameraPermission() {
|
|
||||||
ActivityCompat.requestPermissions(
|
|
||||||
this,
|
|
||||||
arrayOf(Manifest.permission.CAMERA),
|
|
||||||
REQUEST_CODE_CAMERA
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun openCamera() {
|
|
||||||
if (!checkCameraPermission()) {
|
|
||||||
requestCameraPermission()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
camera = Camera.open()
|
|
||||||
camera?.setDisplayOrientation(90)
|
|
||||||
|
|
||||||
val params = camera?.parameters
|
|
||||||
params?.previewFormat = ImageFormat.NV21
|
|
||||||
|
|
||||||
val sizes = params?.supportedPreviewSizes
|
|
||||||
val optimalSize = getOptimalPreviewSize(sizes, binding.surfaceView.width, binding.surfaceView.height)
|
|
||||||
if (optimalSize != null) {
|
|
||||||
params?.setPreviewSize(optimalSize.width, optimalSize.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
camera?.parameters = params
|
|
||||||
camera?.setPreviewDisplay(binding.surfaceView.holder)
|
|
||||||
camera?.startPreview()
|
|
||||||
|
|
||||||
startScanDecode()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Toast.makeText(this, "无法打开相机", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getOptimalPreviewSize(sizes: List<Camera.Size>?, w: Int, h: Int): Camera.Size? {
|
|
||||||
if (sizes == null) return null
|
|
||||||
|
|
||||||
var optimalSize: Camera.Size? = null
|
|
||||||
val targetRatio = h.toDouble() / w.toDouble()
|
|
||||||
|
|
||||||
for (size in sizes) {
|
|
||||||
val ratio = size.width.toDouble() / size.height.toDouble()
|
|
||||||
if (Math.abs(ratio - targetRatio) < 0.01) {
|
|
||||||
optimalSize = size
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optimalSize == null) {
|
|
||||||
var minDiff = Int.MAX_VALUE
|
|
||||||
for (size in sizes) {
|
|
||||||
val diff = Math.abs(size.width - w) + Math.abs(size.height - h)
|
|
||||||
if (diff < minDiff) {
|
|
||||||
optimalSize = size
|
|
||||||
minDiff = diff
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return optimalSize
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startScanDecode() {
|
|
||||||
scanHandler = Handler(Looper.getMainLooper())
|
|
||||||
scanRunnable = object : Runnable {
|
|
||||||
override fun run() {
|
|
||||||
decodeQRCode()
|
|
||||||
scanHandler?.postDelayed(this, 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scanHandler?.post(scanRunnable!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun decodeQRCode() {
|
|
||||||
if (camera == null) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
val parameters = camera?.parameters
|
|
||||||
val size = parameters?.previewSize
|
|
||||||
if (size == null) return
|
|
||||||
|
|
||||||
val data = ByteArray(size.width * size.height * 3 / 2)
|
|
||||||
camera?.setOneShotPreviewCallback { bytes, _ ->
|
|
||||||
val source = PlanarYUVLuminanceSource(
|
|
||||||
bytes, size.width, size.height, 0, 0,
|
|
||||||
size.width, size.height, false
|
|
||||||
)
|
|
||||||
val binarizer = HybridBinarizer(source)
|
|
||||||
val bitmap = BinaryBitmap(binarizer)
|
|
||||||
|
|
||||||
val reader = MultiFormatReader()
|
|
||||||
val hints = Hashtable<DecodeHintType, Any>()
|
|
||||||
hints[DecodeHintType.CHARACTER_SET] = "UTF-8"
|
|
||||||
reader.setHints(hints)
|
|
||||||
|
|
||||||
try {
|
|
||||||
val result = reader.decode(bitmap)
|
|
||||||
handleScanResult(result.text)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleScanResult(result: String) {
|
|
||||||
stopScanDecode()
|
|
||||||
camera?.stopPreview()
|
|
||||||
|
|
||||||
Toast.makeText(this, "扫描结果: $result", Toast.LENGTH_SHORT).show()
|
|
||||||
|
|
||||||
val intent = Intent(this, AddFamilyActivity::class.java)
|
|
||||||
intent.putExtra("device_code", result)
|
|
||||||
startActivity(intent)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun stopScanDecode() {
|
|
||||||
scanRunnable?.let { scanHandler?.removeCallbacks(it) }
|
|
||||||
scanHandler = null
|
|
||||||
scanRunnable = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun surfaceCreated(holder: SurfaceHolder) {
|
|
||||||
openCamera()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
|
|
||||||
if (camera != null) {
|
|
||||||
camera?.stopPreview()
|
|
||||||
try {
|
|
||||||
camera?.setPreviewDisplay(holder)
|
|
||||||
camera?.startPreview()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
|
||||||
stopScanDecode()
|
|
||||||
camera?.stopPreview()
|
|
||||||
camera?.release()
|
|
||||||
camera = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
||||||
if (requestCode == REQUEST_CODE_CAMERA) {
|
|
||||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
openCamera()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, "需要相机权限", Toast.LENGTH_SHORT).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
|
||||||
if (requestCode == REQUEST_CODE_ALBUM && resultCode == RESULT_OK && data != null) {
|
|
||||||
val uri = data.data
|
|
||||||
uri?.let {
|
|
||||||
Toast.makeText(this, "已选择图片", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
stopScanDecode()
|
|
||||||
camera?.stopPreview()
|
|
||||||
camera?.release()
|
|
||||||
camera = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="@color/green" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke
|
|
||||||
android:width="3dp"
|
|
||||||
android:color="@color/green"
|
|
||||||
android:bottom="3dp"
|
|
||||||
android:left="3dp"
|
|
||||||
android:right="0dp"
|
|
||||||
android:top="0dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke
|
|
||||||
android:width="3dp"
|
|
||||||
android:color="@color/green"
|
|
||||||
android:bottom="3dp"
|
|
||||||
android:left="0dp"
|
|
||||||
android:right="3dp"
|
|
||||||
android:top="0dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke
|
|
||||||
android:width="3dp"
|
|
||||||
android:color="@color/green"
|
|
||||||
android:bottom="0dp"
|
|
||||||
android:left="3dp"
|
|
||||||
android:right="0dp"
|
|
||||||
android:top="3dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@android:color/transparent" />
|
|
||||||
<stroke
|
|
||||||
android:width="3dp"
|
|
||||||
android:color="@color/green"
|
|
||||||
android:bottom="0dp"
|
|
||||||
android:left="0dp"
|
|
||||||
android:right="3dp"
|
|
||||||
android:top="3dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/black">
|
|
||||||
|
|
||||||
<SurfaceView
|
|
||||||
android:id="@+id/surfaceView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="#B2000000" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="#B2000000" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="250dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="#B2000000" />
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="250dp"
|
|
||||||
android:layout_height="250dp">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@drawable/bg_scan_frame" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/scanLine"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="2dp"
|
|
||||||
android:background="@color/green" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:background="@drawable/corner_top_left"
|
|
||||||
android:layout_gravity="top|left" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:background="@drawable/corner_top_right"
|
|
||||||
android:layout_gravity="top|right" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:background="@drawable/corner_bottom_left"
|
|
||||||
android:layout_gravity="bottom|left" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:background="@drawable/corner_bottom_right"
|
|
||||||
android:layout_gravity="bottom|right" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="250dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="#B2000000" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="#B2000000" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnBack"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_marginTop="40dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:background="@drawable/back2"
|
|
||||||
android:contentDescription="返回" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvScanTip"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="550dp"
|
|
||||||
android:text="@string/scan_device_qr"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginBottom="80dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/llAlbum"
|
|
||||||
android:layout_width="80dp"
|
|
||||||
android:layout_height="80dp"
|
|
||||||
android:layout_marginRight="80dp"
|
|
||||||
android:background="@drawable/bg_button_circle"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/ivAlbum"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/album" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:text="@string/album"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/llFlashlight"
|
|
||||||
android:layout_width="80dp"
|
|
||||||
android:layout_height="80dp"
|
|
||||||
android:layout_marginLeft="80dp"
|
|
||||||
android:background="@drawable/bg_button_circle"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/ivFlashlight"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/flashlight" />
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:text="@string/flashlight"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="12dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@@ -53,11 +53,10 @@
|
|||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
<!-- 虚线边框 -->
|
<!-- 虚线边框 android:background="@drawable/bg_scan_frame"-->
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
android:background="@drawable/bg_scan_frame" />
|
|
||||||
|
|
||||||
<!-- 人体模型图片 -->
|
<!-- 人体模型图片 -->
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|||||||
@@ -353,6 +353,7 @@
|
|||||||
<string name="camera_not_ready">相机未准备好</string>
|
<string name="camera_not_ready">相机未准备好</string>
|
||||||
<string name="cannot_open_camera">无法打开相机</string>
|
<string name="cannot_open_camera">无法打开相机</string>
|
||||||
<string name="camera_permission_needed">需要相机权限</string>
|
<string name="camera_permission_needed">需要相机权限</string>
|
||||||
|
<string name="permission_denied">需要获取相机和存储权限</string>
|
||||||
<string name="image_selected">已选择图片</string>
|
<string name="image_selected">已选择图片</string>
|
||||||
<string name="please_try_later">请稍后再试</string>
|
<string name="please_try_later">请稍后再试</string>
|
||||||
<string name="phone_format_invalid">手机号格式不正确</string>
|
<string name="phone_format_invalid">手机号格式不正确</string>
|
||||||
|
|||||||
@@ -339,6 +339,7 @@
|
|||||||
<string name="camera_not_ready">Camera not ready</string>
|
<string name="camera_not_ready">Camera not ready</string>
|
||||||
<string name="cannot_open_camera">Cannot open camera</string>
|
<string name="cannot_open_camera">Cannot open camera</string>
|
||||||
<string name="camera_permission_needed">Camera permission is required</string>
|
<string name="camera_permission_needed">Camera permission is required</string>
|
||||||
|
<string name="permission_denied">Camera and storage permissions are required</string>
|
||||||
<string name="image_selected">Image selected</string>
|
<string name="image_selected">Image selected</string>
|
||||||
<string name="please_try_later">Please try again later</string>
|
<string name="please_try_later">Please try again later</string>
|
||||||
<string name="phone_format_invalid">Invalid phone number format</string>
|
<string name="phone_format_invalid">Invalid phone number format</string>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
plugins {
|
||||||
@@ -22,6 +21,7 @@ dependencyResolutionManagement {
|
|||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven(url = "https://maven.aliyun.com/repository/public/")
|
maven(url = "https://maven.aliyun.com/repository/public/")
|
||||||
|
maven { url = uri("https://jitpack.io") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user