扫一扫
This commit is contained in:
@@ -91,5 +91,12 @@ dependencies {
|
||||
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
|
||||
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
|
||||
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.RECORD_AUDIO" />
|
||||
<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.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package com.example.defenseapplication.home
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
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.showDefenseDialog
|
||||
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.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -45,6 +53,85 @@ class HomeMenuFragment : Fragment() {
|
||||
private var isFamilyExpanded = false
|
||||
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 {
|
||||
override fun onUnreadCountChanged(count: Int) {
|
||||
updateUnreadCountUI(count)
|
||||
@@ -112,8 +199,7 @@ class HomeMenuFragment : Fragment() {
|
||||
startActivity(intent)
|
||||
}
|
||||
binding.addFamily.setOnClickListener {
|
||||
val intent = Intent(requireContext(), ScanActivity::class.java)
|
||||
startActivity(intent)
|
||||
checkPermissionsAndScan()
|
||||
}
|
||||
|
||||
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:padding="16dp">
|
||||
|
||||
<!-- 虚线边框 -->
|
||||
<!-- 虚线边框 android:background="@drawable/bg_scan_frame"-->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_scan_frame" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<!-- 人体模型图片 -->
|
||||
<ImageView
|
||||
|
||||
@@ -353,6 +353,7 @@
|
||||
<string name="camera_not_ready">相机未准备好</string>
|
||||
<string name="cannot_open_camera">无法打开相机</string>
|
||||
<string name="camera_permission_needed">需要相机权限</string>
|
||||
<string name="permission_denied">需要获取相机和存储权限</string>
|
||||
<string name="image_selected">已选择图片</string>
|
||||
<string name="please_try_later">请稍后再试</string>
|
||||
<string name="phone_format_invalid">手机号格式不正确</string>
|
||||
|
||||
@@ -339,6 +339,7 @@
|
||||
<string name="camera_not_ready">Camera not ready</string>
|
||||
<string name="cannot_open_camera">Cannot open camera</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="please_try_later">Please try again later</string>
|
||||
<string name="phone_format_invalid">Invalid phone number format</string>
|
||||
|
||||
Reference in New Issue
Block a user