Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS
Conflicts: vtm
@ -115,6 +115,18 @@ dependencies {
|
|||||||
//kotlin反射
|
//kotlin反射
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect: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 {
|
kapt {
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
android:versionCode="3"
|
android:versionCode="3"
|
||||||
android:versionName="1.4"
|
android:versionName="1.4"
|
||||||
package="com.navinfo.omqs">
|
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" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<!-- 这个权限用于访问GPS定位-->
|
<!-- 这个权限用于访问GPS定位-->
|
||||||
@ -31,7 +36,13 @@
|
|||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<!-- 读取缓存数据 -->
|
<!-- 读取缓存数据 -->
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<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.RECORD_AUDIO" />
|
||||||
|
<!--闹钟和提醒-->
|
||||||
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||||
|
|
||||||
<!--android:largeHeap="true" 大内存 128M -->
|
<!--android:largeHeap="true" 大内存 128M -->
|
||||||
<application
|
<application
|
||||||
android:name=".OMQSApplication"
|
android:name=".OMQSApplication"
|
||||||
@ -57,12 +68,24 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.map.MainActivity"
|
android:name=".ui.activity.map.MainActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:screenOrientation="landscape"
|
android:screenOrientation="landscape"
|
||||||
android:theme="@style/Theme.OMQualityInspection" />
|
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
|
<meta-data
|
||||||
android:name="ScopedStorage"
|
android:name="ScopedStorage"
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
|
@ -52,6 +52,11 @@ class Constant {
|
|||||||
* */
|
* */
|
||||||
var LAYER_CONFIG_LIST: List<ImportConfig>? = null
|
var LAYER_CONFIG_LIST: List<ImportConfig>? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 室内整理工具IP
|
||||||
|
*/
|
||||||
|
lateinit var INDOOR_IP: String
|
||||||
|
|
||||||
const val DEBUG = true
|
const val DEBUG = true
|
||||||
|
|
||||||
var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull<Boolean>()
|
var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull<Boolean>()
|
||||||
|
@ -38,8 +38,8 @@ data class EvaluationInfo(
|
|||||||
@SerializedName("problemLink")
|
@SerializedName("problemLink")
|
||||||
val problemLink: String = "",//问题环节
|
val problemLink: String = "",//问题环节
|
||||||
|
|
||||||
@SerializedName("problemReason")
|
@SerializedName("preliminaryAnalysis")
|
||||||
val problemReason: String = "",//问题原因
|
val preliminaryAnalysis: String = "",//初步分析
|
||||||
|
|
||||||
@SerializedName("evaluatorName")
|
@SerializedName("evaluatorName")
|
||||||
val evaluatorName: String = "",//测评人名称
|
val evaluatorName: String = "",//测评人名称
|
||||||
|
@ -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",
|
||||||
|
)
|
6
app/src/main/java/com/navinfo/omqs/bean/QRCodeBean.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.navinfo.omqs.bean
|
||||||
|
|
||||||
|
data class QRCodeBean(
|
||||||
|
var errcode: Int = -1,
|
||||||
|
var msg: String = ""
|
||||||
|
)
|
@ -30,8 +30,8 @@ interface ScProblemTypeDao {
|
|||||||
/**
|
/**
|
||||||
* 获取问题分类,并去重
|
* 获取问题分类,并去重
|
||||||
*/
|
*/
|
||||||
@Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE")
|
@Query("select * from ScProblemType group by CLASS_TYPE")
|
||||||
suspend fun findClassTypeList(): List<String>?
|
suspend fun findClassTypeList(): List<ScProblemTypeBean>?
|
||||||
|
|
||||||
@Query("select DISTINCT CLASS_TYPE from ScProblemType where ELEMENT_CODE=:code")
|
@Query("select DISTINCT CLASS_TYPE from ScProblemType where ELEMENT_CODE=:code")
|
||||||
suspend fun findClassTypeByCode(code: Int): String?
|
suspend fun findClassTypeByCode(code: Int): String?
|
||||||
|
@ -2,7 +2,9 @@ package com.navinfo.omqs.http
|
|||||||
|
|
||||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||||
import com.navinfo.collect.library.data.entity.TaskBean
|
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.LoginUserBean
|
||||||
|
import com.navinfo.omqs.bean.QRCodeBean
|
||||||
import com.navinfo.omqs.bean.SysUserBean
|
import com.navinfo.omqs.bean.SysUserBean
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.Response
|
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 loginUser(loginUserBean: LoginUserBean): NetResult<DefaultResponse<SysUserBean>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接室内整理工具
|
||||||
|
*/
|
||||||
|
suspend fun connectIndoorTools(url: String): NetResult<QRCodeBean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户信息
|
||||||
|
*/
|
||||||
|
suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult<QRCodeBean>
|
||||||
}
|
}
|
@ -2,7 +2,9 @@ package com.navinfo.omqs.http
|
|||||||
|
|
||||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||||
import com.navinfo.collect.library.data.entity.TaskBean
|
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.LoginUserBean
|
||||||
|
import com.navinfo.omqs.bean.QRCodeBean
|
||||||
import com.navinfo.omqs.bean.SysUserBean
|
import com.navinfo.omqs.bean.SysUserBean
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -75,4 +77,42 @@ class NetworkServiceImpl @Inject constructor(
|
|||||||
NetResult.Error<Any>(e)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,7 +3,9 @@ package com.navinfo.omqs.http
|
|||||||
import com.navinfo.omqs.bean.EvaluationInfo
|
import com.navinfo.omqs.bean.EvaluationInfo
|
||||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||||
import com.navinfo.collect.library.data.entity.TaskBean
|
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.LoginUserBean
|
||||||
|
import com.navinfo.omqs.bean.QRCodeBean
|
||||||
import com.navinfo.omqs.bean.SysUserBean
|
import com.navinfo.omqs.bean.SysUserBean
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@ -64,6 +66,22 @@ interface RetrofitNetworkServiceAPI {
|
|||||||
@Query("evaluatorNo") evaluatorNo: String,
|
@Query("evaluatorNo") evaluatorNo: String,
|
||||||
): Response<DefaultResponse<List<TaskBean>>>
|
): 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")
|
@Headers("Content-Type: application/json")
|
||||||
@POST("/devcp/uploadSceneProblem")
|
@POST("/devcp/uploadSceneProblem")
|
||||||
suspend fun postRequest(@Body listEvaluationInfo: List<EvaluationInfo>?): Response<DefaultResponse<*>>
|
suspend fun postRequest(@Body listEvaluationInfo: List<EvaluationInfo>?): Response<DefaultResponse<*>>
|
||||||
|
@ -146,12 +146,12 @@ class TaskUploadScope(
|
|||||||
markId = hadLinkDvoBean.mesh,//"20065597"
|
markId = hadLinkDvoBean.mesh,//"20065597"
|
||||||
trackPhotoNumber = "",
|
trackPhotoNumber = "",
|
||||||
markGeometry = it.geometry,
|
markGeometry = it.geometry,
|
||||||
featureName = it.classType,
|
featureName = it.classCode,
|
||||||
problemType = problemType,
|
problemType = problemType,
|
||||||
problemPhenomenon = it.phenomenon,
|
problemPhenomenon = it.phenomenon,
|
||||||
problemDesc = it.description,
|
problemDesc = it.description,
|
||||||
problemLink = it.problemLink,
|
problemLink = it.problemLink,
|
||||||
problemReason = it.cause,
|
preliminaryAnalysis = it.cause,
|
||||||
evaluatorName = it.checkUserId,
|
evaluatorName = it.checkUserId,
|
||||||
evaluationDate = it.checkTime,
|
evaluationDate = it.checkTime,
|
||||||
evaluationWay = evaluationWay,
|
evaluationWay = evaluationWay,
|
||||||
@ -166,10 +166,17 @@ class TaskUploadScope(
|
|||||||
bodyList.add(evaluationInfo)
|
bodyList.add(evaluationInfo)
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
val linkStatus = 1
|
||||||
|
//存在原因标记未测评
|
||||||
|
if(hadLinkDvoBean.reason.isNotEmpty()){
|
||||||
|
val linkStatus = 0
|
||||||
|
}else{
|
||||||
|
val linkStatus = 1
|
||||||
|
}
|
||||||
val evaluationInfo = EvaluationInfo(
|
val evaluationInfo = EvaluationInfo(
|
||||||
evaluationTaskId = taskBean.id.toString(),
|
evaluationTaskId = taskBean.id.toString(),
|
||||||
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
|
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"
|
||||||
linkStatus = 0,
|
linkStatus = linkStatus,
|
||||||
markId = hadLinkDvoBean.mesh,//"20065597"
|
markId = hadLinkDvoBean.mesh,//"20065597"
|
||||||
trackPhotoNumber = "",
|
trackPhotoNumber = "",
|
||||||
markGeometry = "",
|
markGeometry = "",
|
||||||
@ -178,13 +185,13 @@ class TaskUploadScope(
|
|||||||
problemPhenomenon = "",
|
problemPhenomenon = "",
|
||||||
problemDesc = "",
|
problemDesc = "",
|
||||||
problemLink = "",
|
problemLink = "",
|
||||||
problemReason = "",
|
preliminaryAnalysis = "",
|
||||||
evaluatorName = "",
|
evaluatorName = "",
|
||||||
evaluationDate = "",
|
evaluationDate = "",
|
||||||
evaluationWay = 2,
|
evaluationWay = 2,
|
||||||
roadClassfcation = "",
|
roadClassfcation = "",
|
||||||
roadFunctionGrade = "",
|
roadFunctionGrade = "",
|
||||||
noEvaluationreason = "",
|
noEvaluationreason = hadLinkDvoBean.reason,
|
||||||
linkLength = 0.0,
|
linkLength = 0.0,
|
||||||
dataLevel = "",
|
dataLevel = "",
|
||||||
linstringLength = 0.0,
|
linstringLength = 0.0,
|
||||||
|
131
app/src/main/java/com/navinfo/omqs/server/TimeTask.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,8 @@ public class CheckPermissionsActivity extends BaseActivity {
|
|||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.READ_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;
|
private static final int PERMISSON_REQUESTCODE = 0;
|
||||||
@ -53,6 +54,7 @@ public class CheckPermissionsActivity extends BaseActivity {
|
|||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.RECORD_AUDIO,
|
Manifest.permission.RECORD_AUDIO,
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
BACKGROUND_LOCATION_PERMISSION
|
BACKGROUND_LOCATION_PERMISSION
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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}")
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ import com.navinfo.collect.library.utils.GeometryTools
|
|||||||
import com.navinfo.omqs.Constant
|
import com.navinfo.omqs.Constant
|
||||||
import com.navinfo.omqs.R
|
import com.navinfo.omqs.R
|
||||||
import com.navinfo.omqs.bean.ChatMsgEntity
|
import com.navinfo.omqs.bean.ChatMsgEntity
|
||||||
|
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||||
import com.navinfo.omqs.bean.SignBean
|
import com.navinfo.omqs.bean.SignBean
|
||||||
import com.navinfo.omqs.db.RealmOperateHelper
|
import com.navinfo.omqs.db.RealmOperateHelper
|
||||||
import com.navinfo.omqs.db.RoomAppDatabase
|
import com.navinfo.omqs.db.RoomAppDatabase
|
||||||
@ -65,7 +66,7 @@ class EvaluationResultViewModel @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* 问题分类 liveData,给[LeftAdapter]展示的数据
|
* 问题分类 liveData,给[LeftAdapter]展示的数据
|
||||||
*/
|
*/
|
||||||
val liveDataLeftTypeList = MutableLiveData<List<String>>()
|
val liveDataLeftTypeList = MutableLiveData<List<ScProblemTypeBean>>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 问题类型 liveData 给[MiddleAdapter]展示的数据
|
* 问题类型 liveData 给[MiddleAdapter]展示的数据
|
||||||
@ -95,6 +96,8 @@ class EvaluationResultViewModel @Inject constructor(
|
|||||||
|
|
||||||
var classTypeTemp: String = ""
|
var classTypeTemp: String = ""
|
||||||
|
|
||||||
|
var classCodeTemp: String = ""
|
||||||
|
|
||||||
init {
|
init {
|
||||||
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
|
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
@ -194,22 +197,24 @@ class EvaluationResultViewModel @Inject constructor(
|
|||||||
list?.let {
|
list?.let {
|
||||||
if (list.isNotEmpty()) {
|
if (list.isNotEmpty()) {
|
||||||
//通知页面更新
|
//通知页面更新
|
||||||
var classType = list[0]
|
var classType = list[0].classType
|
||||||
|
var classCode = list[0].elementCode
|
||||||
liveDataLeftTypeList.postValue(it)
|
liveDataLeftTypeList.postValue(it)
|
||||||
if (bean != null) {
|
if (bean != null) {
|
||||||
val classType2 = roomAppDatabase.getScProblemTypeDao()
|
val classType2 = roomAppDatabase.getScProblemTypeDao().findClassTypeByCode(bean.renderEntity.code)
|
||||||
.findClassTypeByCode(bean.renderEntity.code)
|
|
||||||
if (classType2 != null) {
|
if (classType2 != null) {
|
||||||
classType = classType2
|
classType = classType2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//如果右侧栏没数据,给个默认值
|
//如果右侧栏没数据,给个默认值
|
||||||
if (liveDataQsRecordBean.value!!.classType.isEmpty()) {
|
if (liveDataQsRecordBean.value!!.classType.isEmpty()) {
|
||||||
|
|
||||||
liveDataQsRecordBean.value!!.classType = classType
|
liveDataQsRecordBean.value!!.classType = classType
|
||||||
|
liveDataQsRecordBean.value!!.classCode = classCode
|
||||||
classTypeTemp = classType
|
classTypeTemp = classType
|
||||||
|
classCodeTemp = classCode
|
||||||
} else {
|
} else {
|
||||||
classType = liveDataQsRecordBean.value!!.classType
|
classType = liveDataQsRecordBean.value!!.classType
|
||||||
|
classCode = liveDataQsRecordBean.value!!.classCode
|
||||||
}
|
}
|
||||||
getProblemList(classType)
|
getProblemList(classType)
|
||||||
}
|
}
|
||||||
@ -298,6 +303,7 @@ class EvaluationResultViewModel @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
fun setPhenomenonMiddleBean(adapterBean: RightBean) {
|
fun setPhenomenonMiddleBean(adapterBean: RightBean) {
|
||||||
liveDataQsRecordBean.value!!.classType = classTypeTemp
|
liveDataQsRecordBean.value!!.classType = classTypeTemp
|
||||||
|
liveDataQsRecordBean.value!!.classCode = classCodeTemp
|
||||||
liveDataQsRecordBean.value!!.phenomenon = adapterBean.text
|
liveDataQsRecordBean.value!!.phenomenon = adapterBean.text
|
||||||
liveDataQsRecordBean.value!!.problemType = adapterBean.title
|
liveDataQsRecordBean.value!!.problemType = adapterBean.title
|
||||||
liveDataQsRecordBean.postValue(liveDataQsRecordBean.value)
|
liveDataQsRecordBean.postValue(liveDataQsRecordBean.value)
|
||||||
|
@ -5,12 +5,13 @@ import android.view.LayoutInflater
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import com.navinfo.omqs.R
|
import com.navinfo.omqs.R
|
||||||
|
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||||
|
|
||||||
class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
||||||
BaseRecyclerViewAdapter<String>() {
|
BaseRecyclerViewAdapter<ScProblemTypeBean>() {
|
||||||
private var selectTitle = ""
|
private var selectTitle = ""
|
||||||
|
|
||||||
|
|
||||||
@ -24,18 +25,18 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
|||||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||||
val bd = holder.viewBinding as TextItemSelectBinding
|
val bd = holder.viewBinding as TextItemSelectBinding
|
||||||
val title = data[position]
|
val title = data[position]
|
||||||
bd.itemId.text = title
|
bd.itemId.text = title.classType
|
||||||
holder.viewBinding.root.isSelected = selectTitle == title
|
holder.viewBinding.root.isSelected = selectTitle == title.classType
|
||||||
bd.root.setOnClickListener {
|
bd.root.setOnClickListener {
|
||||||
if (selectTitle != title) {
|
if (selectTitle != title.classType) {
|
||||||
selectTitle = title
|
selectTitle = title.classType
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
itemListener?.invoke(position, title)
|
itemListener?.invoke(position, title.classType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun refreshData(newData: List<String>) {
|
override fun refreshData(newData: List<ScProblemTypeBean>) {
|
||||||
data = newData
|
data = newData
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package com.navinfo.omqs.ui.fragment.personalcenter
|
package com.navinfo.omqs.ui.fragment.personalcenter
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.blankj.utilcode.util.ToastUtils
|
import com.blankj.utilcode.util.ToastUtils
|
||||||
import com.blankj.utilcode.util.UriUtils
|
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.hilt.ImportOMDBHiltFactory
|
||||||
import com.navinfo.omqs.tools.CoroutineUtils
|
import com.navinfo.omqs.tools.CoroutineUtils
|
||||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
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 dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.oscim.core.GeoPoint
|
import org.oscim.core.GeoPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -123,6 +126,16 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
|
|||||||
// R.id.personal_center_menu_layer_manager -> { // 图层管理
|
// R.id.personal_center_menu_layer_manager -> { // 图层管理
|
||||||
// findNavController().navigate(R.id.QsLayerManagerFragment)
|
// 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
|
true
|
||||||
}
|
}
|
||||||
@ -134,6 +147,11 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
|
|||||||
fileChooser.setCallbacks(this@PersonalCenterFragment)
|
fileChooser.setCallbacks(this@PersonalCenterFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun intentTOQRCode() {
|
||||||
|
var intent = Intent(context, QrCodeActivity::class.java);
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
_binding = null
|
||||||
@ -147,4 +165,18 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
fileChooser.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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
@ -95,18 +96,21 @@ class TaskViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is NetResult.Error<*> -> {
|
is NetResult.Error<*> -> {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
|
Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is NetResult.Failure<*> -> {
|
is NetResult.Failure<*> -> {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
|
Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is NetResult.Loading -> {}
|
is NetResult.Loading -> {}
|
||||||
}
|
}
|
||||||
val realm = Realm.getDefaultInstance()
|
val realm = Realm.getDefaultInstance()
|
||||||
@ -139,41 +143,42 @@ class TaskViewModel @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* 设置当前选择的任务,并高亮当前任务的所有link
|
* 设置当前选择的任务,并高亮当前任务的所有link
|
||||||
*/
|
*/
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
fun setSelectTaskBean(taskBean: TaskBean) {
|
fun setSelectTaskBean(taskBean: TaskBean) {
|
||||||
currentSelectTaskBean = taskBean
|
currentSelectTaskBean = taskBean
|
||||||
|
|
||||||
liveDataTaskLinks.value = taskBean.hadLinkDvoList
|
liveDataTaskLinks.value = taskBean.hadLinkDvoList
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
mapController.lineHandler.omdbTaskLinkLayer.removeAll()
|
mapController.lineHandler.omdbTaskLinkLayer.removeAll()
|
||||||
if(taskBean.hadLinkDvoList.isNotEmpty()){
|
if (taskBean.hadLinkDvoList.isNotEmpty()) {
|
||||||
mapController.lineHandler.omdbTaskLinkLayer.addLineList(taskBean.hadLinkDvoList)
|
mapController.lineHandler.omdbTaskLinkLayer.addLineList(taskBean.hadLinkDvoList)
|
||||||
var maxX = 0.0
|
var maxX = 0.0
|
||||||
var maxY = 0.0
|
var maxY = 0.0
|
||||||
var minX = 0.0
|
var minX = 0.0
|
||||||
var minY = 0.0
|
var minY = 0.0
|
||||||
for (item in taskBean.hadLinkDvoList) {
|
for (item in taskBean.hadLinkDvoList) {
|
||||||
val geometry = GeometryTools.createGeometry(item.geometry)
|
val geometry = GeometryTools.createGeometry(item.geometry)
|
||||||
if(geometry!=null){
|
if (geometry != null) {
|
||||||
val envelope = geometry.envelopeInternal
|
val envelope = geometry.envelopeInternal
|
||||||
if (envelope.maxX > maxX) {
|
if (envelope.maxX > maxX) {
|
||||||
maxX = envelope.maxX
|
maxX = envelope.maxX
|
||||||
}
|
}
|
||||||
if (envelope.maxY > maxY) {
|
if (envelope.maxY > maxY) {
|
||||||
maxY = envelope.maxY
|
maxY = envelope.maxY
|
||||||
}
|
}
|
||||||
if (envelope.minX < minX || minX == 0.0) {
|
if (envelope.minX < minX || minX == 0.0) {
|
||||||
minX = envelope.minX
|
minX = envelope.minX
|
||||||
}
|
}
|
||||||
if (envelope.minY < minY || minY == 0.0) {
|
if (envelope.minY < minY || minY == 0.0) {
|
||||||
minY = envelope.minY
|
minY = envelope.minY
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//增加异常数据判断
|
}
|
||||||
if(maxX!=0.0&&maxY!=0.0&&minX!=0.0&&minY!=0.0){
|
//增加异常数据判断
|
||||||
mapController.animationHandler.animateToBox(
|
if (maxX != 0.0 && maxY != 0.0 && minX != 0.0 && minY != 0.0) {
|
||||||
maxX = maxX, maxY = maxY, minX = minX, minY = minY
|
mapController.animationHandler.animateToBox(
|
||||||
)
|
maxX = maxX, maxY = maxY, minX = minX, minY = minY
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,20 +186,20 @@ class TaskViewModel @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* 高亮当前选中的link
|
* 高亮当前选中的link
|
||||||
*/
|
*/
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
fun showCurrentLink(link: HadLinkDvoBean) {
|
fun showCurrentLink(link: HadLinkDvoBean) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
mapController.lineHandler.omdbTaskLinkLayer.showSelectLine(link)
|
||||||
mapController.lineHandler.omdbTaskLinkLayer.showSelectLine(link)
|
val geometry = GeometryTools.createGeometry(link.geometry)
|
||||||
val geometry = GeometryTools.createGeometry(link.geometry)
|
if (geometry != null) {
|
||||||
if(geometry!=null){
|
val envelope = geometry.envelopeInternal
|
||||||
val envelope = geometry.envelopeInternal
|
mapController.animationHandler.animateToBox(
|
||||||
mapController.animationHandler.animateToBox(
|
maxX = envelope.maxX,
|
||||||
maxX = envelope.maxX,
|
maxY = envelope.maxY,
|
||||||
maxY = envelope.maxY,
|
minX = envelope.minX,
|
||||||
minX = envelope.minX,
|
minY = envelope.minY
|
||||||
minY = envelope.minY
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
@ -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() }
|
||||||
|
}
|
||||||
|
}
|
88
app/src/main/java/com/navinfo/omqs/ui/widget/ScanView.kt
Normal 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:
|
||||||
|
* date:2021/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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable-xhdpi/icon_finish_disable.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_finish_nor.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_finish_press.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_forward_disable.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_forward_nor.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_forward_press.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_mediaflag.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_mediaflag_disable.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_next_disable.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_next_nor.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_next_press.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_no_mediaflag.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_pause_nor.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_play_disable.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_play_nor.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_select_point_disable.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_select_point_nor.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_select_point_press.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/scan_light.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
10
app/src/main/res/drawable/map_trace_finish.xml
Normal 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>
|
9
app/src/main/res/drawable/map_trace_forward.xml
Normal 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>
|
9
app/src/main/res/drawable/map_trace_mediaflag.xml
Normal 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>
|
9
app/src/main/res/drawable/map_trace_next.xml
Normal 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>
|
9
app/src/main/res/drawable/map_trace_pause.xml
Normal 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>
|
9
app/src/main/res/drawable/map_trace_select_point.xml
Normal 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>
|
@ -130,6 +130,73 @@
|
|||||||
android:elevation="2dp"
|
android:elevation="2dp"
|
||||||
android:onClick="@{()->mainActivity.onClickMenu()}" />
|
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
|
<androidx.constraintlayout.widget.Barrier
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
47
app/src/main/res/layout/activity_qr_code.xml
Normal 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>
|
19
app/src/main/res/layout/activity_result.xml
Normal 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>
|
@ -167,7 +167,7 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/evaluation_fragment_title_text_style"
|
style="@style/evaluation_fragment_title_text_style"
|
||||||
android:text="问题原因" />
|
android:text="初步分析" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/evaluation_cause"
|
android:id="@+id/evaluation_cause"
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
android:id="@+id/personal_center_menu_import_yuan_data"
|
android:id="@+id/personal_center_menu_import_yuan_data"
|
||||||
android:icon="@drawable/ic_baseline_scatter_plot_24"
|
android:icon="@drawable/ic_baseline_scatter_plot_24"
|
||||||
android:title="导入元数据" />
|
android:title="导入元数据" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/personal_center_menu_scan_qr_code"
|
||||||
|
android:icon="@drawable/ic_baseline_scatter_plot_24"
|
||||||
|
android:title="扫一扫" />
|
||||||
<item
|
<item
|
||||||
android:icon="@drawable/ic_baseline_sim_card_download_24"
|
android:icon="@drawable/ic_baseline_sim_card_download_24"
|
||||||
android:title="备份数据" />
|
android:title="备份数据" />
|
||||||
|
@ -33,6 +33,10 @@ open class QsRecordBean @JvmOverloads constructor(
|
|||||||
*问题分类
|
*问题分类
|
||||||
*/
|
*/
|
||||||
var classType: String = "",
|
var classType: String = "",
|
||||||
|
/**
|
||||||
|
*要素代码
|
||||||
|
*/
|
||||||
|
var classCode: String = "",
|
||||||
/**
|
/**
|
||||||
* 问题类型
|
* 问题类型
|
||||||
*/
|
*/
|
||||||
@ -50,6 +54,7 @@ open class QsRecordBean @JvmOverloads constructor(
|
|||||||
* 问题环节
|
* 问题环节
|
||||||
*/
|
*/
|
||||||
var problemLink: String = "",
|
var problemLink: String = "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 问题原因
|
* 问题原因
|
||||||
* 根本原因(RCA)
|
* 根本原因(RCA)
|
||||||
@ -96,6 +101,7 @@ open class QsRecordBean @JvmOverloads constructor(
|
|||||||
elementId = elementId,
|
elementId = elementId,
|
||||||
linkId = linkId,
|
linkId = linkId,
|
||||||
classType = classType,
|
classType = classType,
|
||||||
|
classCode = classCode,
|
||||||
problemType = problemType,
|
problemType = problemType,
|
||||||
phenomenon = phenomenon,
|
phenomenon = phenomenon,
|
||||||
description = description,
|
description = description,
|
||||||
|