Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS

 Conflicts:
	vtm
This commit is contained in:
squallzhjch 2023-06-29 17:23:12 +08:00
commit f415ded353
53 changed files with 1142 additions and 68 deletions

View File

@ -115,6 +115,18 @@ dependencies {
//kotlin反射
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
implementation "org.jetbrains.kotlin:kotlin-reflect:1.7.0"
implementation 'com.permissionx.guolindev:permissionx:1.4.0'
def camerax_version = "1.1.0-alpha04"
// The following line is optional, as the core library is included indirectly by camera-camera2
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
// If you want to additionally use the CameraX Lifecycle library
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
// If you want to additionally use the CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha24"
implementation 'com.google.mlkit:barcode-scanning:16.1.1'
}
//
kapt {

View File

@ -4,6 +4,11 @@
android:versionCode="3"
android:versionName="1.4"
package="com.navinfo.omqs">
<!-- 这个权限用于相机权限-->
<uses-feature android:name="android.hardware.camera.any" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位-->
@ -31,7 +36,13 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 读取缓存数据 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 音频权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--闹钟和提醒-->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!--android:largeHeap="true" 大内存 128M -->
<application
android:name=".OMQSApplication"
@ -57,12 +68,24 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activity.map.MainActivity"
android:exported="false"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:theme="@style/Theme.OMQualityInspection" />
<activity
android:name=".ui.activity.scan.QrCodeActivity"
android:theme="@style/Theme.OMQualityInspection"
android:screenOrientation="portrait" />
<activity
android:name=".ui.activity.scan.QRCodeResultActivity"
android:theme="@style/Theme.OMQualityInspection"
android:screenOrientation="portrait" />
<meta-data
android:name="ScopedStorage"
android:value="true" />

View File

@ -52,6 +52,11 @@ class Constant {
* */
var LAYER_CONFIG_LIST: List<ImportConfig>? = null
/**
* 室内整理工具IP
*/
lateinit var INDOOR_IP: String
const val DEBUG = true
var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull<Boolean>()

View File

@ -38,8 +38,8 @@ data class EvaluationInfo(
@SerializedName("problemLink")
val problemLink: String = "",//问题环节
@SerializedName("problemReason")
val problemReason: String = "",//问题原因
@SerializedName("preliminaryAnalysis")
val preliminaryAnalysis: String = "",//初步分析
@SerializedName("evaluatorName")
val evaluatorName: String = "",//测评人名称

View File

@ -0,0 +1,11 @@
package com.navinfo.omqs.bean
data class IndoorConnectionInfoBean(
var username: String = "",
var uname: String = "",
var userid: String = "",
var token: String = "",
var baseurl: String = "",
var plate: String = "",
var platform: String = "Android",
)

View File

@ -0,0 +1,6 @@
package com.navinfo.omqs.bean
data class QRCodeBean(
var errcode: Int = -1,
var msg: String = ""
)

View File

@ -30,8 +30,8 @@ interface ScProblemTypeDao {
/**
* 获取问题分类并去重
*/
@Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE")
suspend fun findClassTypeList(): List<String>?
@Query("select * from ScProblemType group by CLASS_TYPE")
suspend fun findClassTypeList(): List<ScProblemTypeBean>?
@Query("select DISTINCT CLASS_TYPE from ScProblemType where ELEMENT_CODE=:code")
suspend fun findClassTypeByCode(code: Int): String?

View File

@ -2,7 +2,9 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import okhttp3.ResponseBody
import retrofit2.Response
@ -15,14 +17,25 @@ interface NetworkService {
/**
* 获取离线地图城市列表
*/
suspend fun getOfflineMapCityList():NetResult<List<OfflineMapCityBean>>
suspend fun getOfflineMapCityList(): NetResult<List<OfflineMapCityBean>>
/**
* 获取任务列表
*/
suspend fun getTaskList(evaluatorNo:String): NetResult<DefaultResponse<List<TaskBean>>>
suspend fun getTaskList(evaluatorNo: String): NetResult<DefaultResponse<List<TaskBean>>>
/**
* 登录接口
*/
suspend fun loginUser(loginUserBean: LoginUserBean): NetResult<DefaultResponse<SysUserBean>>
/**
* 连接室内整理工具
*/
suspend fun connectIndoorTools(url: String): NetResult<QRCodeBean>
/**
* 更新用户信息
*/
suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean>
}

View File

@ -2,7 +2,9 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -75,4 +77,42 @@ class NetworkServiceImpl @Inject constructor(
NetResult.Error<Any>(e)
}
}
override suspend fun connectIndoorTools(url: String): NetResult<QRCodeBean> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val result = netApi.retrofitConnectIndoorTools(url = url)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
override suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean> =
//在IO线程中运行
withContext(Dispatchers.IO) {
return@withContext try {
val result = netApi.retrofitUpdateServerInfo(url,indoorConnectionInfoBean)
if (result.isSuccessful) {
if (result.code() == 200) {
NetResult.Success(result.body())
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} else {
NetResult.Failure<Any>(result.code(), result.message())
}
} catch (e: Exception) {
NetResult.Error<Any>(e)
}
}
}

View File

@ -3,7 +3,9 @@ package com.navinfo.omqs.http
import com.navinfo.omqs.bean.EvaluationInfo
import com.navinfo.omqs.bean.OfflineMapCityBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import okhttp3.ResponseBody
import retrofit2.Response
@ -64,6 +66,22 @@ interface RetrofitNetworkServiceAPI {
@Query("evaluatorNo") evaluatorNo: String,
): Response<DefaultResponse<List<TaskBean>>>
/**
* 连接室内整理工具
*/
@Streaming
@GET
suspend fun retrofitConnectIndoorTools(@Url url: String): Response<QRCodeBean>
/**
* 登录接口
*/
@Headers("Content-Type: application/json")
@POST
suspend fun retrofitUpdateServerInfo(@Url url: String,@Body indoorConnectionInfoBean: IndoorConnectionInfoBean): Response<QRCodeBean>
@Headers("Content-Type: application/json")
@POST("/devcp/uploadSceneProblem")
suspend fun postRequest(@Body listEvaluationInfo: List<EvaluationInfo>?): Response<DefaultResponse<*>>

View File

@ -146,12 +146,12 @@ class TaskUploadScope(
markId = hadLinkDvoBean.mesh,//"20065597"
trackPhotoNumber = "",
markGeometry = it.geometry,
featureName = it.classType,
featureName = it.classCode,
problemType = problemType,
problemPhenomenon = it.phenomenon,
problemDesc = it.description,
problemLink = it.problemLink,
problemReason = it.cause,
preliminaryAnalysis = it.cause,
evaluatorName = it.checkUserId,
evaluationDate = it.checkTime,
evaluationWay = evaluationWay,
@ -166,10 +166,17 @@ class TaskUploadScope(
bodyList.add(evaluationInfo)
}
}else{
val linkStatus = 1
//存在原因标记未测评
if(hadLinkDvoBean.reason.isNotEmpty()){
val linkStatus = 0
}else{
val linkStatus = 1
}
val evaluationInfo = EvaluationInfo(
evaluationTaskId = taskBean.id.toString(),
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
linkStatus = 0,
linkStatus = linkStatus,
markId = hadLinkDvoBean.mesh,//"20065597"
trackPhotoNumber = "",
markGeometry = "",
@ -178,13 +185,13 @@ class TaskUploadScope(
problemPhenomenon = "",
problemDesc = "",
problemLink = "",
problemReason = "",
preliminaryAnalysis = "",
evaluatorName = "",
evaluationDate = "",
evaluationWay = 2,
roadClassfcation = "",
roadFunctionGrade = "",
noEvaluationreason = "",
noEvaluationreason = hadLinkDvoBean.reason,
linkLength = 0.0,
dataLevel = "",
linstringLength = 0.0,

View File

@ -0,0 +1,131 @@
package com.navinfo.omqs.server
import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.SystemClock
/**
* date:2023/6/18
* author:qj
* description:定时器
*/
class TimeTask<T : TimeTask.Task?>(context: Context, actionName: String, task: T) {
private var mContext: Context?
private val mActionName: String
private var mReceiver: TimeTaskReceiver? = null
private val mTask: T?
companion object {
private var mPendingIntent: PendingIntent? = null
}
init {
mContext = context
mActionName = actionName
mTask = task
initReceiver(context, actionName)
}
fun startLooperTask() {
if (null != mTask) {
mTask.exeTask()
configureAlarmManager(mTask.period())
}
}
fun stopLooperTask() {
cancelAlarmManager()
}
fun onClose() {
mContext!!.unregisterReceiver(mReceiver)
mContext = null
}
@SuppressLint("ObsoleteSdkInt")
private fun configureAlarmManager(time: Long) {
val manager = mContext!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pendIntent = pendingIntent
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
manager.setExactAndAllowWhileIdle(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time,
pendIntent
)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -> {
manager.setExact(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time,
pendIntent
)
}
else -> {
manager[AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + time] = pendIntent
}
}
}
@get:SuppressLint("UnspecifiedImmutableFlag")
private val pendingIntent: PendingIntent?
get() {
if (mPendingIntent == null) {
val requestCode = 0
val intent = Intent()
intent.action = mActionName
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
mPendingIntent = PendingIntent.getBroadcast(
mContext, requestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
}
else -> {
mPendingIntent = PendingIntent.getBroadcast(
mContext,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
}
}
return mPendingIntent
}
private fun cancelAlarmManager() {
val manager = mContext!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
manager.cancel(pendingIntent)
}
private fun initReceiver(context: Context, actionName: String) {
mReceiver = TimeTaskReceiver()
val intentFilter = IntentFilter()
intentFilter.addAction(actionName)
context.registerReceiver(mReceiver, intentFilter)
}
internal inner class TimeTaskReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
startLooperTask()
}
}
interface Task {
fun period(): Long {
// 默认时间5S
return 5000L
}
fun exeTask()
}
}

View File

@ -37,7 +37,8 @@ public class CheckPermissionsActivity extends BaseActivity {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
};
private static final int PERMISSON_REQUESTCODE = 0;
@ -53,6 +54,7 @@ public class CheckPermissionsActivity extends BaseActivity {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
BACKGROUND_LOCATION_PERMISSION
};
}

View File

@ -0,0 +1,256 @@
package com.navinfo.omqs.ui.activity.scan
import android.content.Context
import android.text.TextUtils
import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.IndoorConnectionInfoBean
import com.navinfo.omqs.bean.QRCodeBean
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.http.DefaultResponse
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.ui.activity.login.LoginStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import javax.inject.Inject
enum class QrCodeStatus {
/**
* 网络访问失败
*/
QR_CODE_STATUS_NET_FAILURE,
/**
* 成功
*/
QR_CODE_STATUS_SUCCESS,
/**
* 信息更新成功
*/
QR_CODE_STATUS_SERVER_INFO_SUCCESS,
}
@HiltViewModel
class QrCodeViewModel @Inject constructor(
private val networkService: NetworkService
) : ViewModel() {
//用户信息
val qrCodeBean: MutableLiveData<QRCodeBean> = MutableLiveData()
//是不是连接成功
val qrCodeStatus: MutableLiveData<QrCodeStatus> = MutableLiveData()
init {
qrCodeBean.value = QRCodeBean()
}
/**
* 扫一扫按钮
*/
fun connect(context: Context, ips: String) {
if (TextUtils.isEmpty(ips)) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_LONG).show()
return
}
val ipArray = ips.split(";".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
//测试代码
//final String[] ipArray = new String[]{"172.21.2.137"};
if (ipArray.isEmpty()) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_SHORT).show()
return
}
ipArray.forEach { ip ->
if (!TextUtils.isEmpty(ip)) {
viewModelScope.launch(Dispatchers.Default) {
val ipTemp: String = ip
val url = "http://$ipTemp:8080/sensor/service/keepalive"
when (val result = networkService.connectIndoorTools(url)) {
is NetResult.Success<*> -> {
if (result.data != null) {
try {
val defaultUserResponse = result.data as QRCodeBean
if (defaultUserResponse.errcode == 0) {
Constant.INDOOR_IP = ipTemp
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_SUCCESS)
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"连接室内整理工具成功。",
Toast.LENGTH_LONG
).show()
}
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${defaultUserResponse.msg}",
Toast.LENGTH_SHORT
)
.show()
}
}
} catch (e: IOException) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.exception.message}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.code}:${result.msg}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
else -> {}
}
}
}
}
}
/**
* 扫一扫按钮
*/
fun updateServerInfo(context: Context) {
if (TextUtils.isEmpty(Constant.INDOOR_IP)) {
Toast.makeText(context, "获取ip失败", Toast.LENGTH_LONG).show()
return
}
viewModelScope.launch(Dispatchers.Default) {
val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/connection"
when (val result = networkService.updateServerInfo(
url = url,
indoorConnectionInfoBean = IndoorConnectionInfoBean(
Constant.USER_ID,
Constant.USER_ID,
Constant.USER_ID,
Constant.USER_ID,
com.navinfo.collect.library.system.Constant.SERVER_ADDRESS,
Constant.USER_ID,
"Android"
)
)) {
is NetResult.Success<*> -> {
if (result.data != null) {
try {
val defaultUserResponse = result.data as QRCodeBean
if (defaultUserResponse.errcode == 0) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"信息更新成功。",
Toast.LENGTH_LONG
).show()
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_SERVER_INFO_SUCCESS)
}
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${defaultUserResponse.msg}",
Toast.LENGTH_SHORT
)
.show()
}
}
} catch (e: IOException) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.exception.message}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
"${result.code}:${result.msg}",
Toast.LENGTH_SHORT
)
.show()
}
qrCodeStatus.postValue(QrCodeStatus.QR_CODE_STATUS_NET_FAILURE)
}
else -> {}
}
}
}
override fun onCleared() {
super.onCleared()
}
}

View File

@ -0,0 +1,147 @@
package com.navinfo.omqs.ui.activity.scan
import android.annotation.SuppressLint
import android.graphics.Rect
import android.graphics.RectF
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.camera.core.ImageCapture
import androidx.camera.view.LifecycleCameraController
import androidx.databinding.DataBindingUtil
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityQrCodeBinding
import com.navinfo.omqs.ui.activity.BaseActivity
import com.navinfo.omqs.ui.listener.QRCodeAnalyser
import dagger.hilt.android.AndroidEntryPoint
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import androidx.lifecycle.Observer
import com.navinfo.omqs.ui.activity.login.LoginStatus
/**
* date:2023/6/18
* author:qj
* description:二维码扫描
*/
@AndroidEntryPoint
class QrCodeActivity : BaseActivity() {
private lateinit var binding: ActivityQrCodeBinding
private lateinit var lifecycleCameraController: LifecycleCameraController
private lateinit var cameraExecutor: ExecutorService
private val viewModel by viewModels<QrCodeViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_qr_code)
binding.qrCodeModel = viewModel
binding.lifecycleOwner = this
binding.activity = this
initView()
initController()
}
private fun initView() {
//登录校验,初始化成功
viewModel.qrCodeStatus.observe(this, qrCodeObserve)
}
/*
* 监听扫描结果
* */
private val qrCodeObserve = Observer<QrCodeStatus> {
when (it) {
QrCodeStatus.QR_CODE_STATUS_SUCCESS -> {
finish()
}
QrCodeStatus.QR_CODE_STATUS_NET_FAILURE -> {
}
QrCodeStatus.QR_CODE_STATUS_SERVER_INFO_SUCCESS -> {
}
}
}
@SuppressLint("ClickableViewAccessibility", "UnsafeOptInUsageError")
private fun initController() {
cameraExecutor = Executors.newSingleThreadExecutor()
lifecycleCameraController = LifecycleCameraController(this)
lifecycleCameraController.bindToLifecycle(this)
lifecycleCameraController.imageCaptureFlashMode = ImageCapture.FLASH_MODE_AUTO
lifecycleCameraController.setImageAnalysisAnalyzer(
cameraExecutor,
QRCodeAnalyser { barcodes, imageWidth, imageHeight ->
if (barcodes.isEmpty()) {
return@QRCodeAnalyser
}
initScale(imageWidth, imageHeight)
val list = ArrayList<RectF>()
val strList = ArrayList<String>()
barcodes.forEach { barcode ->
barcode.boundingBox?.let { rect ->
val translateRect = translateRect(rect)
list.add(translateRect)
Log.e(
"ztzt", "left${translateRect.left} +" +
" top${translateRect.top} + right${translateRect.right}" +
" + bottom${translateRect.bottom}"
)
Log.e("ztzt", "barcode.rawValue${barcode.rawValue}")
strList.add(barcode.rawValue ?: "No Value")
}
}
judgeIntent(strList)
binding.scanView.setRectList(list)
})
binding.previewView.controller = lifecycleCameraController
}
fun judgeIntent(list: ArrayList<String>) {
val sb = StringBuilder()
list.forEach {
sb.append(it)
sb.append("\n")
}
intentToResult(sb.toString())
}
private fun intentToResult(result: String) {
Log.e("qj", "QRCodeActivity === $result")
viewModel.connect(this, result)
/* val intent = Intent(this, QRCodeResultActivity::class.java)
intent.putExtra(QRCodeResultActivity.RESULT_KEY, result)
startActivity(intent)
finish()*/
}
private var scaleX = 0f
private var scaleY = 0f
private fun translateX(x: Float): Float = x * scaleX
private fun translateY(y: Float): Float = y * scaleY
//将扫描的矩形换算为当前屏幕大小
private fun translateRect(rect: Rect) = RectF(
translateX(rect.left.toFloat()),
translateY(rect.top.toFloat()),
translateX(rect.right.toFloat()),
translateY(rect.bottom.toFloat())
)
//初始化缩放比例
private fun initScale(imageWidth: Int, imageHeight: Int) {
Log.e("ztzt", "imageWidth${imageWidth} + imageHeight${imageHeight}")
scaleY = binding.scanView.height.toFloat() / imageWidth.toFloat()
scaleX = binding.scanView.width.toFloat() / imageHeight.toFloat()
Log.e("ztzt", "scaleX${scaleX} + scaleY${scaleY}")
}
}

View File

@ -0,0 +1,30 @@
package com.navinfo.omqs.ui.activity.scan
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.navinfo.omqs.databinding.ActivityResultBinding
/**
* date:2021/6/18
* author:zhangteng
* description:
*/
class QRCodeResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityResultBinding
companion object {
const val RESULT_KEY = "result_key";
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityResultBinding.inflate(layoutInflater)
setContentView(binding.root)
val intent = intent
binding.text.text = intent.getStringExtra(RESULT_KEY)
binding.button.setOnClickListener {
finish()
}
}
}

View File

@ -26,6 +26,7 @@ import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ChatMsgEntity
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.bean.SignBean
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.db.RoomAppDatabase
@ -65,7 +66,7 @@ class EvaluationResultViewModel @Inject constructor(
/**
* 问题分类 liveData[LeftAdapter]展示的数据
*/
val liveDataLeftTypeList = MutableLiveData<List<String>>()
val liveDataLeftTypeList = MutableLiveData<List<ScProblemTypeBean>>()
/**
* 问题类型 liveData [MiddleAdapter]展示的数据
@ -95,6 +96,8 @@ class EvaluationResultViewModel @Inject constructor(
var classTypeTemp: String = ""
var classCodeTemp: String = ""
init {
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
viewModelScope.launch {
@ -194,22 +197,24 @@ class EvaluationResultViewModel @Inject constructor(
list?.let {
if (list.isNotEmpty()) {
//通知页面更新
var classType = list[0]
var classType = list[0].classType
var classCode = list[0].elementCode
liveDataLeftTypeList.postValue(it)
if (bean != null) {
val classType2 = roomAppDatabase.getScProblemTypeDao()
.findClassTypeByCode(bean.renderEntity.code)
val classType2 = roomAppDatabase.getScProblemTypeDao().findClassTypeByCode(bean.renderEntity.code)
if (classType2 != null) {
classType = classType2
}
}
//如果右侧栏没数据,给个默认值
if (liveDataQsRecordBean.value!!.classType.isEmpty()) {
liveDataQsRecordBean.value!!.classType = classType
liveDataQsRecordBean.value!!.classCode = classCode
classTypeTemp = classType
classCodeTemp = classCode
} else {
classType = liveDataQsRecordBean.value!!.classType
classCode = liveDataQsRecordBean.value!!.classCode
}
getProblemList(classType)
}
@ -298,6 +303,7 @@ class EvaluationResultViewModel @Inject constructor(
*/
fun setPhenomenonMiddleBean(adapterBean: RightBean) {
liveDataQsRecordBean.value!!.classType = classTypeTemp
liveDataQsRecordBean.value!!.classCode = classCodeTemp
liveDataQsRecordBean.value!!.phenomenon = adapterBean.text
liveDataQsRecordBean.value!!.problemType = adapterBean.title
liveDataQsRecordBean.postValue(liveDataQsRecordBean.value)

View File

@ -5,12 +5,13 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ScProblemTypeBean
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
BaseRecyclerViewAdapter<String>() {
BaseRecyclerViewAdapter<ScProblemTypeBean>() {
private var selectTitle = ""
@ -24,18 +25,18 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
val title = data[position]
bd.itemId.text = title
holder.viewBinding.root.isSelected = selectTitle == title
bd.itemId.text = title.classType
holder.viewBinding.root.isSelected = selectTitle == title.classType
bd.root.setOnClickListener {
if (selectTitle != title) {
selectTitle = title
if (selectTitle != title.classType) {
selectTitle = title.classType
notifyDataSetChanged()
}
itemListener?.invoke(position, title)
itemListener?.invoke(position, title.classType)
}
}
override fun refreshData(newData: List<String>) {
override fun refreshData(newData: List<ScProblemTypeBean>) {
data = newData
notifyDataSetChanged()
}

View File

@ -1,13 +1,14 @@
package com.navinfo.omqs.ui.fragment.personalcenter
import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.blankj.utilcode.util.UriUtils
@ -21,6 +22,8 @@ import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.tools.CoroutineUtils
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.activity.scan.QrCodeActivity
import com.permissionx.guolindev.PermissionX
import dagger.hilt.android.AndroidEntryPoint
import org.oscim.core.GeoPoint
import javax.inject.Inject
@ -123,6 +126,16 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
// R.id.personal_center_menu_layer_manager -> { // 图层管理
// findNavController().navigate(R.id.QsLayerManagerFragment)
// }
/* R.id.personal_center_menu_qs_record_list -> {
findNavController().navigate(R.id.QsRecordListFragment)
}
R.id.personal_center_menu_layer_manager -> { // 图层管理
findNavController().navigate(R.id.QsLayerManagerFragment)
}*/
R.id.personal_center_menu_scan_qr_code -> {
//跳转二维码扫描界面
checkPermission()
}
}
true
}
@ -134,6 +147,11 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
fileChooser.setCallbacks(this@PersonalCenterFragment)
}
private fun intentTOQRCode() {
var intent = Intent(context, QrCodeActivity::class.java);
startActivity(intent)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
@ -147,4 +165,18 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
super.onActivityResult(requestCode, resultCode, data)
fileChooser.onActivityResult(requestCode, resultCode, data)
}
private fun checkPermission() {
PermissionX.init(this)
.permissions(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
//所有权限已经授权
Toast.makeText(context,"授权成功",Toast.LENGTH_LONG).show()
intentTOQRCode()
} else {
Toast.makeText(context, "拒绝权限: $deniedList", Toast.LENGTH_LONG).show()
}
}
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Color
import android.os.Build
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -95,18 +96,21 @@ class TaskViewModel @Inject constructor(
}
}
}
is NetResult.Error<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
.show()
}
}
is NetResult.Failure<*> -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
.show()
}
}
is NetResult.Loading -> {}
}
val realm = Realm.getDefaultInstance()
@ -139,41 +143,42 @@ class TaskViewModel @Inject constructor(
/**
* 设置当前选择的任务并高亮当前任务的所有link
*/
@RequiresApi(Build.VERSION_CODES.M)
fun setSelectTaskBean(taskBean: TaskBean) {
currentSelectTaskBean = taskBean
liveDataTaskLinks.value = taskBean.hadLinkDvoList
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mapController.lineHandler.omdbTaskLinkLayer.removeAll()
if(taskBean.hadLinkDvoList.isNotEmpty()){
mapController.lineHandler.omdbTaskLinkLayer.addLineList(taskBean.hadLinkDvoList)
var maxX = 0.0
var maxY = 0.0
var minX = 0.0
var minY = 0.0
for (item in taskBean.hadLinkDvoList) {
val geometry = GeometryTools.createGeometry(item.geometry)
if(geometry!=null){
val envelope = geometry.envelopeInternal
if (envelope.maxX > maxX) {
maxX = envelope.maxX
}
if (envelope.maxY > maxY) {
maxY = envelope.maxY
}
if (envelope.minX < minX || minX == 0.0) {
minX = envelope.minX
}
if (envelope.minY < minY || minY == 0.0) {
minY = envelope.minY
}
mapController.lineHandler.omdbTaskLinkLayer.removeAll()
if (taskBean.hadLinkDvoList.isNotEmpty()) {
mapController.lineHandler.omdbTaskLinkLayer.addLineList(taskBean.hadLinkDvoList)
var maxX = 0.0
var maxY = 0.0
var minX = 0.0
var minY = 0.0
for (item in taskBean.hadLinkDvoList) {
val geometry = GeometryTools.createGeometry(item.geometry)
if (geometry != null) {
val envelope = geometry.envelopeInternal
if (envelope.maxX > maxX) {
maxX = envelope.maxX
}
if (envelope.maxY > maxY) {
maxY = envelope.maxY
}
if (envelope.minX < minX || minX == 0.0) {
minX = envelope.minX
}
if (envelope.minY < minY || minY == 0.0) {
minY = envelope.minY
}
}
//增加异常数据判断
if(maxX!=0.0&&maxY!=0.0&&minX!=0.0&&minY!=0.0){
mapController.animationHandler.animateToBox(
maxX = maxX, maxY = maxY, minX = minX, minY = minY
)
}
}
//增加异常数据判断
if (maxX != 0.0 && maxY != 0.0 && minX != 0.0 && minY != 0.0) {
mapController.animationHandler.animateToBox(
maxX = maxX, maxY = maxY, minX = minX, minY = minY
)
}
}
}
@ -181,20 +186,20 @@ class TaskViewModel @Inject constructor(
/**
* 高亮当前选中的link
*/
@RequiresApi(Build.VERSION_CODES.M)
fun showCurrentLink(link: HadLinkDvoBean) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mapController.lineHandler.omdbTaskLinkLayer.showSelectLine(link)
val geometry = GeometryTools.createGeometry(link.geometry)
if(geometry!=null){
val envelope = geometry.envelopeInternal
mapController.animationHandler.animateToBox(
maxX = envelope.maxX,
maxY = envelope.maxY,
minX = envelope.minX,
minY = envelope.minY
)
}
mapController.lineHandler.omdbTaskLinkLayer.showSelectLine(link)
val geometry = GeometryTools.createGeometry(link.geometry)
if (geometry != null) {
val envelope = geometry.envelopeInternal
mapController.animationHandler.animateToBox(
maxX = envelope.maxX,
maxY = envelope.maxY,
minX = envelope.minX,
minY = envelope.minY
)
}
}
override fun onCleared() {

View File

@ -0,0 +1,43 @@
package com.navinfo.omqs.ui.listener
import android.annotation.SuppressLint
import android.util.Log
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import com.google.mlkit.vision.barcode.Barcode
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage
class QRCodeAnalyser(private val listener: (List<Barcode>, Int, Int) -> Unit) :
ImageAnalysis.Analyzer {
//配置当前扫码格式
private val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE,
Barcode.FORMAT_AZTEC
).build()
//获取解析器
private val detector = BarcodeScanning.getClient(options)
@SuppressLint("UnsafeExperimentalUsageError", "UnsafeOptInUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image ?: kotlin.run {
imageProxy.close()
return
}
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
detector.process(image)
.addOnSuccessListener { barCodes ->
Log.e("ztzt", "barCodes: ${barCodes.size}")
if (barCodes.size > 0) {
listener.invoke(barCodes, imageProxy.width, imageProxy.height)
//接收到结果后,就关闭解析
detector.close()
}
}
.addOnFailureListener { Log.e("ztzt", "Error: ${it.message}") }
.addOnCompleteListener { imageProxy.close() }
}
}

View File

@ -0,0 +1,88 @@
package com.navinfo.omqs.ui.widget
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import com.navinfo.omqs.R
/**
* Author:zhangteng
* description:
* date2021/6/19
*/
class ScanView(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val circlePaint = Paint() //二维码圆圈画笔
private var rectList: ArrayList<RectF>? = null //二维码数组
private var scanLine: Bitmap//横线
private var isShowLine = true//是否显示扫描线
private var animator: ObjectAnimator? = null
private var floatYFraction = 0f
set(value) {
field = value
invalidate()
}
init {
circlePaint.apply {
this.style = Paint.Style.FILL
this.color = ContextCompat.getColor(
context, android.R.color.holo_green_dark
)
}
scanLine = BitmapFactory.decodeResource(resources, R.drawable.scan_light)
getAnimator().start()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
parseResult(canvas)
if (isShowLine) {
canvas?.drawBitmap(scanLine, (width - scanLine.width) / 2f, height * floatYFraction, circlePaint)
}
}
private fun getAnimator(): ObjectAnimator {
if (animator == null) {
animator = ObjectAnimator.ofFloat(
this,
"floatYFraction",
0f,
1f
)
animator?.duration = 5000
animator?.repeatCount = -1 //-1代表无限循环
}
return animator!!
}
private fun parseResult(canvas: Canvas?) {
rectList?.let { list ->
if (list.isEmpty()) {
return
}
list.forEach {
canvas?.drawCircle(
it.left + (it.right - it.left) / 2f,
it.top + (it.bottom - it.top) / 2f,
50f,
circlePaint
)
}
}
}
fun setRectList(list: ArrayList<RectF>?) {
rectList = list
rectList?.let {
if (it.isNotEmpty()) {
isShowLine = false
getAnimator().cancel()
invalidate()
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/icon_finish_press"></item>
<item android:state_selected="true" android:drawable="@drawable/icon_finish_press"></item>
<item android:state_enabled="true" android:drawable="@drawable/icon_finish_nor"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_finish_disable"></item>
<item android:drawable="@drawable/icon_finish_nor"></item>
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/icon_forward_press"></item>
<item android:state_selected="true" android:drawable="@drawable/icon_forward_press"></item>
<item android:state_enabled="true" android:drawable="@drawable/icon_forward_nor"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_forward_disable"></item>
<item android:drawable="@drawable/icon_forward_nor"></item>
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false" android:state_enabled="true" android:drawable="@drawable/icon_no_mediaflag"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_mediaflag_disable"></item>
<item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/icon_mediaflag"></item>
<item android:drawable="@drawable/icon_no_mediaflag"></item>
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/icon_next_press"></item>
<item android:state_selected="true" android:drawable="@drawable/icon_next_press"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_next_disable"></item>
<item android:state_enabled="true" android:drawable="@drawable/icon_next_nor"></item>
<item android:drawable="@drawable/icon_next_nor"></item>
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false" android:state_enabled="true" android:drawable="@drawable/icon_play_nor"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_play_disable"></item>
<item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/icon_pause_nor"></item>
<item android:drawable="@drawable/icon_play_nor"></item>
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/icon_select_point_press"></item>
<item android:state_selected="true" android:drawable="@drawable/icon_select_point_press"></item>
<item android:state_enabled="true" android:drawable="@drawable/icon_select_point_nor"></item>
<item android:state_enabled="false" android:drawable="@drawable/icon_select_point_disable"></item>
<item android:drawable="@drawable/icon_select_point_nor"></item>
</selector>

View File

@ -130,6 +130,73 @@
android:elevation="2dp"
android:onClick="@{()->mainActivity.onClickMenu()}" />
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/main_activity_flow_indoor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/top_right_drawer_btns_mr"
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_media_flag,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next,main_activity_menu_indoor_group"
app:flow_horizontalGap="6dp"
app:flow_wrapMode="aligned"
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="@+id/main_activity_menu_indoor_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_media_flag,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next" />
<ImageButton
android:id="@+id/main_activity_snapshot_finish"
style="@style/top_right_drawer_btns_style"
android:clickable="true"
android:enabled="false"
android:focusable="true"
android:src="@drawable/map_trace_finish"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/main_activity_trace_snapshot_points"
style="@style/top_right_drawer_btns_style"
android:focusable="true"
android:src="@drawable/map_trace_select_point"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/main_activity_snapshot_media_flag"
style="@style/top_right_drawer_btns_style"
android:enabled="false"
android:focusable="true"
android:src="@drawable/map_trace_mediaflag"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/main_activity_snapshot_rewind"
style="@style/top_right_drawer_btns_style"
android:enabled="false"
android:focusable="true"
android:src="@drawable/map_trace_forward"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/main_activity_snapshot_pause"
style="@style/top_right_drawer_btns_style"
android:enabled="false"
android:focusable="true"
android:src="@drawable/map_trace_pause"
tools:ignore="DuplicateIds,MissingConstraints" />
<ImageButton
android:id="@+id/main_activity_snapshot_next"
style="@style/top_right_drawer_btns_style"
android:enabled="false"
android:focusable="true"
android:src="@drawable/map_trace_next"
tools:ignore="DuplicateIds,MissingConstraints" />
<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context=".ui.activity.scan.QRCodeActivity">
<data>
<variable
name="activity"
type="com.navinfo.omqs.ui.activity.scan.QrCodeActivity" />
<variable
name="qrCodeModel"
type="com.navinfo.omqs.ui.activity.scan.QrCodeViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Layer
android:layout_width="match_parent"
android:layout_height="match_parent"
app:constraint_referenced_ids="previewView,scanView"
tools:ignore="MissingConstraints">
</androidx.constraintlayout.helper.widget.Layer>
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.navinfo.omqs.ui.widget.ScanView
android:id="@+id/scanView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:textColor="@color/black"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="200dp" />
<Button
android:id="@+id/button"
android:text="返回"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@ -167,7 +167,7 @@
<TextView
style="@style/evaluation_fragment_title_text_style"
android:text="问题原因" />
android:text="初步分析" />
<TextView
android:id="@+id/evaluation_cause"

View File

@ -22,6 +22,10 @@
android:id="@+id/personal_center_menu_import_yuan_data"
android:icon="@drawable/ic_baseline_scatter_plot_24"
android:title="导入元数据" />
<item
android:id="@+id/personal_center_menu_scan_qr_code"
android:icon="@drawable/ic_baseline_scatter_plot_24"
android:title="扫一扫" />
<item
android:icon="@drawable/ic_baseline_sim_card_download_24"
android:title="备份数据" />

View File

@ -33,6 +33,10 @@ open class QsRecordBean @JvmOverloads constructor(
*问题分类
*/
var classType: String = "",
/**
*要素代码
*/
var classCode: String = "",
/**
* 问题类型
*/
@ -50,6 +54,7 @@ open class QsRecordBean @JvmOverloads constructor(
* 问题环节
*/
var problemLink: String = "",
/**
* 问题原因
* 根本原因RCA
@ -96,6 +101,7 @@ open class QsRecordBean @JvmOverloads constructor(
elementId = elementId,
linkId = linkId,
classType = classType,
classCode = classCode,
problemType = problemType,
phenomenon = phenomenon,
description = description,