增加质检结果展示页面
This commit is contained in:
@@ -5,6 +5,7 @@ import android.util.Log
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
@@ -12,7 +13,17 @@ import java.io.File
|
||||
@HiltAndroidApp
|
||||
class OMQSApplication : Application() {
|
||||
override fun onCreate() {
|
||||
FileManager.initRootDir(this)
|
||||
super.onCreate()
|
||||
FileManager.initRootDir(this)
|
||||
Realm.init(this)
|
||||
val password = "password".encodeToByteArray().copyInto(ByteArray(64))
|
||||
// 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}")
|
||||
val config = RealmConfiguration.Builder()
|
||||
.directory(File(Constant.DATA_PATH))
|
||||
.name("HDData")
|
||||
// .encryptionKey(password)
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
}
|
||||
}
|
||||
6
app/src/main/java/com/navinfo/omqs/bean/BaseBean.kt
Normal file
6
app/src/main/java/com/navinfo/omqs/bean/BaseBean.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
open class BaseBean : Serializable, Cloneable {
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
|
||||
@Entity(tableName = "OfflineMapCity")
|
||||
@Parcelize
|
||||
data class OfflineMapCityBean @JvmOverloads constructor(
|
||||
@PrimaryKey
|
||||
var id: String = "",
|
||||
var fileName: String = "",
|
||||
var name: String = "",
|
||||
var url: String = "",
|
||||
var version: Long = 0L,
|
||||
var fileSize: Long = 0L,
|
||||
var currentSize: Long = 0L,
|
||||
var status: Int = NONE
|
||||
) : Parcelable {
|
||||
|
||||
companion object Status {
|
||||
const val NONE = 0 //无状态
|
||||
const val WAITING = 1 //等待中
|
||||
const val LOADING = 2 //下载中
|
||||
const val PAUSE = 3 //暂停
|
||||
const val ERROR = 4 //错误
|
||||
const val DONE = 5 //完成
|
||||
const val UPDATE = 6 //有新版本要更新
|
||||
}
|
||||
|
||||
// // status的转换对象
|
||||
// var statusEnum: StatusEnum
|
||||
// get() {
|
||||
// return try {
|
||||
// StatusEnum.values().find { it.status == status }!!
|
||||
// } catch (e: IllegalArgumentException) {
|
||||
// StatusEnum.NONE
|
||||
// }
|
||||
// }
|
||||
// set(value) {
|
||||
// status = value.status
|
||||
// }
|
||||
|
||||
fun getFileSizeText(): String {
|
||||
return if (fileSize < 1024.0)
|
||||
"$fileSize B"
|
||||
else if (fileSize < 1048576.0)
|
||||
"%.2f K".format(fileSize / 1024.0)
|
||||
else if (fileSize < 1073741824.0)
|
||||
"%.2f M".format(fileSize / 1048576.0)
|
||||
else
|
||||
"%.2f M".format(fileSize / 1073741824.0)
|
||||
}
|
||||
|
||||
}
|
||||
115
app/src/main/java/com/navinfo/omqs/bean/QsRecord.kt
Normal file
115
app/src/main/java/com/navinfo/omqs/bean/QsRecord.kt
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
|
||||
/**
|
||||
* @author zhjch
|
||||
* @version V1.0
|
||||
* @ClassName: Rd_qcRecord
|
||||
* @Date 2016/1/12
|
||||
* @Description: ${TODO}(质检对象)
|
||||
*/
|
||||
open class QsRecord @JvmOverloads constructor(
|
||||
/**
|
||||
* id 主键
|
||||
*
|
||||
*/
|
||||
@PrimaryKey var id: String = "",
|
||||
/**
|
||||
* linkPid 绑定的道路ID
|
||||
*/
|
||||
var linkPid: String = "",
|
||||
/**
|
||||
*问题分类
|
||||
*/
|
||||
var classType: String = "",
|
||||
/**
|
||||
* 问题类型
|
||||
*/
|
||||
var type: String = "",
|
||||
|
||||
/**
|
||||
* 问题现象
|
||||
*/
|
||||
var phenomenon: String = "",
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
var description: String = "",
|
||||
/**
|
||||
* 设置initial_cause
|
||||
* @param initial_cause
|
||||
* initial_cause
|
||||
*/
|
||||
// var initial_cause: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取root_cause
|
||||
// * @return root_cause
|
||||
// */
|
||||
// /**
|
||||
// * 设置root_cause
|
||||
// * @param root_cause
|
||||
// * root_cause
|
||||
// */
|
||||
////根本原因(RCA)
|
||||
// var root_cause: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取check_userid
|
||||
// * @return check_userid
|
||||
// */
|
||||
// /**
|
||||
// * 设置check_userid
|
||||
// * @param check_userid
|
||||
// * check_userid
|
||||
// */
|
||||
////质检员
|
||||
// var check_userid: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取check_time
|
||||
// * @return check_time
|
||||
// */
|
||||
// /**
|
||||
// * 设置check_time
|
||||
// * @param check_time
|
||||
// * check_time
|
||||
// */
|
||||
////质检日期
|
||||
// var check_time: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取confirm_userid
|
||||
// * @return confirm_userid
|
||||
// */
|
||||
// /**
|
||||
// * 设置confirm_userid
|
||||
// * @param confirm_userid
|
||||
// * confirm_userid
|
||||
// */
|
||||
////确认人
|
||||
// var confirm_userid: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取t_lifecycle
|
||||
// * @return t_lifecycle
|
||||
// */
|
||||
// /**
|
||||
// * 设置t_lifecycle
|
||||
// * @param t_lifecycle
|
||||
// * t_lifecycle
|
||||
// */
|
||||
////状态 0 无; 1 删除;2 更新;3 新增;
|
||||
// var t_lifecycle = 0
|
||||
// /**
|
||||
// * 获取t_status
|
||||
// * @return t_status
|
||||
// */
|
||||
// /**
|
||||
// * 设置t_status
|
||||
// * @param t_status
|
||||
// * t_status
|
||||
// */
|
||||
////问题记录提交状态 0 未提交;1 已提交;
|
||||
// var t_status = 0
|
||||
) : RealmObject(
|
||||
|
||||
)
|
||||
30
app/src/main/java/com/navinfo/omqs/bean/ScProblemTypeBean.kt
Normal file
30
app/src/main/java/com/navinfo/omqs/bean/ScProblemTypeBean.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity(tableName = "ScProblemType")
|
||||
@Parcelize
|
||||
data class ScProblemTypeBean(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0,
|
||||
/**
|
||||
* 问题分类
|
||||
*/
|
||||
@ColumnInfo("CLASS_TYPE")
|
||||
var classType: String = "",
|
||||
/**
|
||||
* 问题类型
|
||||
*/
|
||||
@ColumnInfo("TYPE")
|
||||
var problemType: String = "",
|
||||
/**
|
||||
* 问题现象
|
||||
*/
|
||||
@ColumnInfo("PHENOMENON")
|
||||
var phenomenon: String = ""
|
||||
|
||||
) : Parcelable
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity(tableName = "ScRootCauseAnalysis")
|
||||
@Parcelize
|
||||
data class ScRootCauseAnalysisBean(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0,
|
||||
/**
|
||||
* 问题环节
|
||||
*/
|
||||
@ColumnInfo("PROBLEM_LINK")
|
||||
var problemLink: String = "",
|
||||
/**
|
||||
* 问题原因
|
||||
*/
|
||||
@ColumnInfo("PROBLEM_CAUSE")
|
||||
var problemCause: String = "",
|
||||
) : Parcelable
|
||||
21
app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
Normal file
21
app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.navinfo.omqs.db
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
|
||||
import com.navinfo.omqs.db.dao.OfflineMapDao
|
||||
import com.navinfo.omqs.db.dao.ScProblemTypeDao
|
||||
import com.navinfo.omqs.db.dao.ScRootCauseAnalysisDao
|
||||
|
||||
@Database(
|
||||
entities = [OfflineMapCityBean::class, ScProblemTypeBean::class, ScRootCauseAnalysisBean::class],
|
||||
version = 1,
|
||||
exportSchema = false
|
||||
)
|
||||
abstract class RoomAppDatabase : RoomDatabase() {
|
||||
abstract fun getOfflineMapDao(): OfflineMapDao
|
||||
abstract fun getScProblemTypeDao(): ScProblemTypeDao
|
||||
abstract fun getScRootCauseAnalysisDao(): ScRootCauseAnalysisDao
|
||||
}
|
||||
23
app/src/main/java/com/navinfo/omqs/db/dao/OfflineMapDao.kt
Normal file
23
app/src/main/java/com/navinfo/omqs/db/dao/OfflineMapDao.kt
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.navinfo.omqs.db.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
|
||||
@Dao
|
||||
interface OfflineMapDao {
|
||||
|
||||
@Insert
|
||||
suspend fun insert(message: OfflineMapCityBean): Long
|
||||
|
||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun update(message: OfflineMapCityBean)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertOrUpdate(list: List<OfflineMapCityBean>)
|
||||
|
||||
@Query("select * from OfflineMapCity order by id")
|
||||
suspend fun getOfflineMapList(): List<OfflineMapCityBean>
|
||||
|
||||
@Query("select * from OfflineMapCity where status != 0 order by id")
|
||||
suspend fun getOfflineMapListWithOutNone(): List<OfflineMapCityBean>
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.navinfo.omqs.db.dao
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase.getDatabase
|
||||
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||
|
||||
|
||||
@Dao
|
||||
interface ScProblemTypeDao {
|
||||
// @Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
// suspend fun insert(bean: ScProblemTypeBean): Long
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertList(list: List<ScProblemTypeBean>)
|
||||
|
||||
|
||||
@Query("delete from ScProblemType")
|
||||
suspend fun deleteAll()
|
||||
|
||||
/**
|
||||
* 更新整个数据库表,由于没有
|
||||
*/
|
||||
@Transaction
|
||||
suspend fun insertOrUpdateList(list: List<ScProblemTypeBean>) {
|
||||
//先删除
|
||||
deleteAll()
|
||||
//后插入
|
||||
insertList(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取问题分类,并去重
|
||||
*/
|
||||
@Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE")
|
||||
suspend fun findClassTypeList(): List<String>?
|
||||
|
||||
/**
|
||||
* 获取问题类型,并去重
|
||||
*/
|
||||
@Query("select DISTINCT TYPE from ScProblemType where CLASS_TYPE=:type order by TYPE")
|
||||
suspend fun findProblemTypeList(type: String): List<String>
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Query("select PHENOMENON from ScProblemType where CLASS_TYPE=:classType and TYPE=:type order by PHENOMENON")
|
||||
suspend fun getPhenomenonList(classType: String, type: String): List<String>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.navinfo.omqs.db.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
|
||||
|
||||
|
||||
@Dao
|
||||
interface ScRootCauseAnalysisDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertList(list: List<ScRootCauseAnalysisBean>)
|
||||
|
||||
|
||||
@Query("delete from ScRootCauseAnalysis")
|
||||
suspend fun deleteAll()
|
||||
|
||||
@Transaction
|
||||
suspend fun insertOrUpdateList(list: List<ScRootCauseAnalysisBean>) {
|
||||
//先删除
|
||||
deleteAll()
|
||||
//后插入
|
||||
insertList(list)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.navinfo.omqs.hilt
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.room.Room
|
||||
import com.google.gson.Gson
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.OMQSApplication
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
|
||||
import com.navinfo.omqs.tools.RealmCoroutineScope
|
||||
import com.tencent.wcdb.database.SQLiteCipherSpec
|
||||
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory
|
||||
import dagger.Lazy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
@@ -95,12 +99,41 @@ class GlobalModule {
|
||||
return retrofit.create(RetrofitNetworkServiceAPI::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* realm 注册
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRealmService(context: Application): RealmCoroutineScope {
|
||||
return RealmCoroutineScope(context)
|
||||
@Provides
|
||||
fun provideDatabase(context: Application): RoomAppDatabase {
|
||||
val DB_PASSWORD = "123456";
|
||||
val cipherSpec = SQLiteCipherSpec()
|
||||
.setPageSize(1024)
|
||||
.setSQLCipherVersion(3)
|
||||
val factory = WCDBOpenHelperFactory()
|
||||
// .passphrase(DB_PASSWORD.toByteArray()) // passphrase to the database, remove this line for plain-text
|
||||
.cipherSpec(cipherSpec) // cipher to use, remove for default settings
|
||||
.writeAheadLoggingEnabled(true) // enable WAL mode, remove if not needed
|
||||
.asyncCheckpointEnabled(true); // enable asynchronous checkpoint, remove if not needed
|
||||
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
RoomAppDatabase::class.java,
|
||||
"${Constant.DATA_PATH}/omqs.db"
|
||||
)
|
||||
|
||||
// [WCDB] Specify open helper to use WCDB database implementation instead
|
||||
// of the Android framework.
|
||||
.openHelperFactory(factory)
|
||||
|
||||
// Wipes and rebuilds instead of migrating if no Migration object.
|
||||
// Migration is not part of this codelab.
|
||||
// .fallbackToDestructiveMigration().addCallback(sRoomDatabaseCallback)
|
||||
.build();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * realm 注册
|
||||
// */
|
||||
// @Provides
|
||||
// @Singleton
|
||||
// fun provideRealmService(context: Application): RealmCoroutineScope {
|
||||
// return RealmCoroutineScope(context)
|
||||
// }
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.navinfo.omqs.hilt
|
||||
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
|
||||
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
|
||||
import com.navinfo.omqs.tools.RealmCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -28,9 +28,10 @@ class MainActivityModule {
|
||||
@Provides
|
||||
fun providesOfflineMapDownloadManager(
|
||||
networkServiceAPI: RetrofitNetworkServiceAPI,
|
||||
realmManager: RealmCoroutineScope
|
||||
roomAppDatabase: RoomAppDatabase,
|
||||
mapController: NIMapController
|
||||
): OfflineMapDownloadManager =
|
||||
OfflineMapDownloadManager(networkServiceAPI, realmManager)
|
||||
OfflineMapDownloadManager(networkServiceAPI, roomAppDatabase, mapController)
|
||||
|
||||
/**
|
||||
* 实验失败,这样创建,viewmodel不会在activity销毁的时候同时销毁
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.navinfo.omqs.http
|
||||
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
|
||||
@@ -2,16 +2,19 @@ package com.navinfo.omqs.http.offlinemapdownload
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
|
||||
import com.navinfo.omqs.tools.RealmCoroutineScope
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
* 管理离线地图下载
|
||||
*/
|
||||
class OfflineMapDownloadManager(
|
||||
val netApi: RetrofitNetworkServiceAPI, val realmManager: RealmCoroutineScope
|
||||
val netApi: RetrofitNetworkServiceAPI,
|
||||
val roomDatabase: RoomAppDatabase,
|
||||
val mapController: NIMapController
|
||||
) {
|
||||
/**
|
||||
* 最多同时下载数量
|
||||
|
||||
@@ -4,8 +4,8 @@ import android.util.Log
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@@ -32,8 +32,8 @@ class OfflineMapDownloadScope(
|
||||
/**
|
||||
* 管理观察者,同时只有一个就行了
|
||||
*/
|
||||
// private var observer: Observer<OfflineMapCityBean>? = null
|
||||
private var lifecycleOwner: LifecycleOwner? = null
|
||||
private val observer = Observer<Any> {}
|
||||
// private var lifecycleOwner: LifecycleOwner? = null
|
||||
|
||||
/**
|
||||
*通知UI更新
|
||||
@@ -89,10 +89,10 @@ class OfflineMapDownloadScope(
|
||||
if (cityBean.status != status || status == OfflineMapCityBean.LOADING) {
|
||||
cityBean.status = status
|
||||
downloadData.postValue(cityBean)
|
||||
|
||||
downloadManager.realmManager.launch {
|
||||
downloadManager.realmManager.insertOrUpdate(cityBean)
|
||||
launch(Dispatchers.IO) {
|
||||
downloadManager.roomDatabase.getOfflineMapDao().update(cityBean)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class OfflineMapDownloadScope(
|
||||
*/
|
||||
fun observer(owner: LifecycleOwner, ob: Observer<OfflineMapCityBean>) {
|
||||
removeObserver()
|
||||
this.lifecycleOwner = owner
|
||||
// this.lifecycleOwner = owner
|
||||
downloadData.observe(owner, ob)
|
||||
}
|
||||
|
||||
@@ -156,6 +156,9 @@ class OfflineMapDownloadScope(
|
||||
fileTemp.renameTo(File("${Constant.OFFLINE_MAP_PATH}${cityBean.fileName}"))
|
||||
Log.e("jingo", "文件下载完成 修改文件 $res")
|
||||
change(OfflineMapCityBean.DONE)
|
||||
withContext(Dispatchers.Main) {
|
||||
downloadManager.mapController.layerManagerHandler.loadBaseMap()
|
||||
}
|
||||
} else {
|
||||
change(OfflineMapCityBean.PAUSE)
|
||||
}
|
||||
@@ -168,9 +171,10 @@ class OfflineMapDownloadScope(
|
||||
}
|
||||
|
||||
fun removeObserver() {
|
||||
lifecycleOwner?.let {
|
||||
downloadData.removeObservers(it)
|
||||
null
|
||||
}
|
||||
downloadData.observeForever(observer)
|
||||
// lifecycleOwner?.let {
|
||||
downloadData.removeObserver(observer)
|
||||
// null
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.navinfo.omqs.tools
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import java.io.File
|
||||
|
||||
class FileManager {
|
||||
|
||||
@@ -1,57 +1,47 @@
|
||||
package com.navinfo.omqs.tools
|
||||
|
||||
import android.app.Application
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.Constant
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmModel
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.newSingleThreadContext
|
||||
import java.io.File
|
||||
|
||||
class RealmCoroutineScope(context: Application) :
|
||||
CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) {
|
||||
lateinit var realm: Realm
|
||||
|
||||
init {
|
||||
launch {
|
||||
Realm.init(context)
|
||||
val password = "password".encodeToByteArray().copyInto(ByteArray(64))
|
||||
// 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}")
|
||||
val config = RealmConfiguration.Builder()
|
||||
.directory(File(Constant.DATA_PATH))
|
||||
.name("HDData")
|
||||
// .encryptionKey(password)
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
realm = Realm.getDefaultInstance()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getOfflineCityList(): List<OfflineMapCityBean> {
|
||||
var list: List<OfflineMapCityBean> = mutableListOf()
|
||||
realm.executeTransaction {
|
||||
val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
|
||||
list = realm.copyFromRealm(objects)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
suspend fun insertOrUpdate(objects: Collection<RealmModel?>?) {
|
||||
realm.executeTransaction {
|
||||
realm.insertOrUpdate(objects)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun insertOrUpdate(realmModel: RealmModel?) {
|
||||
realm.executeTransaction {
|
||||
realm.insertOrUpdate(realmModel)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//package com.navinfo.omqs.tools
|
||||
//
|
||||
//import android.app.Application
|
||||
//import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
//import com.navinfo.omqs.Constant
|
||||
//import io.realm.Realm
|
||||
//import io.realm.RealmConfiguration
|
||||
//import io.realm.RealmModel
|
||||
//import io.realm.Sort
|
||||
//import io.realm.kotlin.where
|
||||
//import kotlinx.coroutines.CoroutineScope
|
||||
//import kotlinx.coroutines.launch
|
||||
//import kotlinx.coroutines.newSingleThreadContext
|
||||
//import java.io.File
|
||||
//
|
||||
//class RealmCoroutineScope(context: Application) :
|
||||
// CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) {
|
||||
// lateinit var realm: Realm
|
||||
//
|
||||
// init {
|
||||
// launch {
|
||||
// realm = Realm.getDefaultInstance()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// suspend fun getOfflineCityList(): List<OfflineMapCityBean> {
|
||||
// var list: List<OfflineMapCityBean> = mutableListOf()
|
||||
// realm.executeTransaction {
|
||||
// val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
|
||||
// list = realm.copyFromRealm(objects)
|
||||
// }
|
||||
// return list
|
||||
// }
|
||||
//
|
||||
// suspend fun insertOrUpdate(objects: Collection<RealmModel?>?) {
|
||||
// realm.executeTransaction {
|
||||
// realm.insertOrUpdate(objects)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// suspend fun insertOrUpdate(realmModel: RealmModel?) {
|
||||
// realm.executeTransaction {
|
||||
// realm.insertOrUpdate(realmModel)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -1,84 +0,0 @@
|
||||
package com.navinfo.omqs.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import com.github.k1rakishou.fsaf.FileChooser
|
||||
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
|
||||
import com.navinfo.omqs.databinding.ActivityMainBinding
|
||||
import com.navinfo.omqs.ui.activity.PermissionsActivity
|
||||
|
||||
class MainActivity : PermissionsActivity(), FSAFActivityCallbacks {
|
||||
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private val fileChooser by lazy { FileChooser(this@MainActivity) }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// val navController = findNavController(R.id.nav_host_fragment_content_main)
|
||||
// appBarConfiguration = AppBarConfiguration(navController.graph)
|
||||
// setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
|
||||
fileChooser.setCallbacks(this@MainActivity)
|
||||
// binding.fab.setOnClickListener { view ->
|
||||
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
||||
// .setAnchorView(R.id.fab)
|
||||
// .setAction("Action", null).show()
|
||||
// // 开始数据导入功能
|
||||
// fileChooser.openChooseFileDialog(object: FileChooserCallback() {
|
||||
// override fun onCancel(reason: String) {
|
||||
// }
|
||||
//
|
||||
// override fun onResult(uri: Uri) {
|
||||
// val file = UriUtils.uri2File(uri)
|
||||
// Snackbar.make(view, "文件大小为:${file.length()}", Snackbar.LENGTH_LONG)
|
||||
// .show()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted() {
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied() {
|
||||
}
|
||||
|
||||
// override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
// // Inflate the menu; this adds items to the action bar if it is present.
|
||||
// menuInflater.inflate(R.menu.menu_main, menu)
|
||||
// return true
|
||||
// }
|
||||
|
||||
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
// // Handle action bar item clicks here. The action bar will
|
||||
// // automatically handle clicks on the Home/Up button, so long
|
||||
// // as you specify a parent activity in AndroidManifest.xml.
|
||||
// return when (item.itemId) {
|
||||
// R.id.action_settings -> true
|
||||
// else -> super.onOptionsItemSelected(item)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onSupportNavigateUp(): Boolean {
|
||||
// val navController = findNavController(R.id.nav_host_fragment_content_main)
|
||||
// return navController.navigateUp(appBarConfiguration)
|
||||
// || super.onSupportNavigateUp()
|
||||
// }
|
||||
|
||||
override fun fsafStartActivityForResult(intent: Intent, requestCode: Int) {
|
||||
startActivityForResult(intent, requestCode)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
fileChooser.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.omqs.bean.LoginUserBean
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.http.NetResult
|
||||
import com.navinfo.omqs.http.NetworkService
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import com.navinfo.omqs.tools.RealmCoroutineScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
import okio.IOException
|
||||
@@ -57,7 +57,7 @@ enum class LoginStatus {
|
||||
@HiltViewModel
|
||||
class LoginViewModel @Inject constructor(
|
||||
private val networkService: NetworkService,
|
||||
private val realmManager: RealmCoroutineScope
|
||||
private val roomAppDatabase: RoomAppDatabase
|
||||
) : ViewModel() {
|
||||
//用户信息
|
||||
val loginUser: MutableLiveData<LoginUserBean> = MutableLiveData()
|
||||
@@ -126,9 +126,7 @@ class LoginViewModel @Inject constructor(
|
||||
for (cityBean in result.data) {
|
||||
FileManager.checkOfflineMapFileInfo(cityBean)
|
||||
}
|
||||
realmManager.launch {
|
||||
realmManager.insertOrUpdate(result.data)
|
||||
}
|
||||
roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data)
|
||||
}
|
||||
}
|
||||
is NetResult.Error -> {
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.activity.viewModels
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.findNavController
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.R
|
||||
@@ -28,6 +29,7 @@ class MainActivity : BaseActivity() {
|
||||
//注入地图控制器
|
||||
@Inject
|
||||
lateinit var mapController: NIMapController
|
||||
|
||||
@Inject
|
||||
lateinit var offlineMapDownloadManager: OfflineMapDownloadManager
|
||||
|
||||
@@ -39,9 +41,9 @@ class MainActivity : BaseActivity() {
|
||||
//初始化地图
|
||||
mapController.init(
|
||||
this,
|
||||
binding.mapView.mainActivityMap,
|
||||
binding.mainActivityMap,
|
||||
null,
|
||||
Constant.ROOT_PATH + "/map/"
|
||||
Constant.MAP_PATH
|
||||
)
|
||||
//关联生命周期
|
||||
binding.lifecycleOwner = this
|
||||
@@ -83,4 +85,11 @@ class MainActivity : BaseActivity() {
|
||||
binding.mainActivityDrawer.open()
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击录音按钮
|
||||
*/
|
||||
fun voiceOnclick() {
|
||||
val naviController = findNavController(R.id.main_activity_right_fragment)
|
||||
naviController.navigate(R.id.EvaluationResultFragment)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.navinfo.omqs.ui.fragment.empty
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.navinfo.omqs.databinding.FragmentEmptyBinding
|
||||
|
||||
class EmptyFragment :Fragment(){
|
||||
private var _binding: FragmentEmptyBinding? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
// private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentEmptyBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
class EvaluationResultAdapter(activity: FragmentActivity, val fragmentList: List<Fragment>) :
|
||||
FragmentStateAdapter(activity) {
|
||||
override fun getItemCount(): Int {
|
||||
return fragmentList.size
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return fragmentList[position]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class EvaluationResultFragment : Fragment() {
|
||||
private var _binding: FragmentEvaluationResultBinding? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value }
|
||||
private var phenomenonFragmentAdapter: EvaluationResultAdapter? = null
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentEvaluationResultBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
//返回按钮
|
||||
binding.evaluationBar.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
//监听数据变化
|
||||
viewModel.classTypeListLiveData.observe(viewLifecycleOwner) {
|
||||
if (it == null || it.isEmpty()) {
|
||||
Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
binding.evaluationClassType.adapter =
|
||||
ArrayAdapter(requireContext(), R.layout.text_item_select, it)
|
||||
}
|
||||
}
|
||||
//选择问题分类的回调
|
||||
binding.evaluationClassType.onItemSelectedListener =
|
||||
object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>?, view: View?, position: Int, id: Long
|
||||
) {
|
||||
viewModel.getProblemTypeList(position)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
/**
|
||||
* 监听联动选择的内容
|
||||
*/
|
||||
viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) {
|
||||
binding.evaluationClassTabLayout.let { tabLayout ->
|
||||
tabLayout.removeAllTabs()
|
||||
val fragmentList = mutableListOf<Fragment>()
|
||||
for (item in it) {
|
||||
val tab = tabLayout.newTab()
|
||||
tab.text = item
|
||||
tabLayout.addTab(tab)
|
||||
fragmentList.add(PhenomenonFragment(viewModel.currentClassType,item))
|
||||
}
|
||||
phenomenonFragmentAdapter =
|
||||
activity?.let { a -> EvaluationResultAdapter(a, fragmentList) }
|
||||
binding.evaluationViewpager.adapter = phenomenonFragmentAdapter
|
||||
|
||||
TabLayoutMediator(
|
||||
binding.evaluationClassTabLayout,
|
||||
binding.evaluationViewpager
|
||||
) { tab, position ->
|
||||
tab.text = it[position]
|
||||
}.attach()
|
||||
updateHeight(0)
|
||||
}
|
||||
|
||||
}
|
||||
//获取数据
|
||||
viewModel.getClassTypeList()
|
||||
binding.evaluationViewpager.registerOnPageChangeCallback(object :
|
||||
ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
updateHeight(position)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private fun updateHeight(position: Int) {
|
||||
phenomenonFragmentAdapter?.let {
|
||||
if (it.fragmentList.size > position) {
|
||||
val fragment: Fragment = it.fragmentList[position]
|
||||
if (fragment.view != null) {
|
||||
val viewWidth = View.MeasureSpec.makeMeasureSpec(
|
||||
fragment.requireView().width, View.MeasureSpec.EXACTLY
|
||||
)
|
||||
val viewHeight =
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
fragment.requireView().measure(viewWidth, viewHeight)
|
||||
binding.evaluationViewpager.let { viewpager ->
|
||||
if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) {
|
||||
//必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效...
|
||||
val layoutParams: ViewGroup.LayoutParams =
|
||||
viewpager.layoutParams
|
||||
layoutParams.height = fragment.requireView().measuredHeight
|
||||
viewpager.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.Dispatcher
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class EvaluationResultViewModel @Inject constructor(
|
||||
private val roomAppDatabase: RoomAppDatabase,
|
||||
) : ViewModel() {
|
||||
init {
|
||||
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}")
|
||||
}
|
||||
|
||||
/**
|
||||
* 问题分类 liveData
|
||||
*/
|
||||
|
||||
val classTypeListLiveData = MutableLiveData<List<String>?>()
|
||||
|
||||
/**
|
||||
* 问题类型 liveData
|
||||
*/
|
||||
|
||||
val problemTypeListLiveData = MutableLiveData<List<String>>()
|
||||
|
||||
var currentClassType: String = ""
|
||||
|
||||
/**
|
||||
* 查询数据库,获取问题分类
|
||||
*/
|
||||
fun getClassTypeList() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val list = roomAppDatabase.getScProblemTypeDao().findClassTypeList()
|
||||
classTypeListLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询问题类型
|
||||
*/
|
||||
fun getProblemTypeList(index: Int) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
classTypeListLiveData.value?.let {
|
||||
if (index < it.size) {
|
||||
currentClassType = it[index]
|
||||
val list =
|
||||
roomAppDatabase.getScProblemTypeDao().findProblemTypeList(currentClassType)
|
||||
problemTypeListLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getPhenomenonList() {
|
||||
viewModelScope.launch (Dispatchers.IO){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class PhenomenonAdapter() : BaseRecyclerViewAdapter<String>() {
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.text_item_select
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
val viewBinding =
|
||||
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return BaseViewHolder(viewBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
(holder.viewBinding as TextItemSelectBinding).itemId.text = data[position]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.navinfo.omqs.databinding.FragmentPhenomenonBinding
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PhenomenonFragment(private val classType: String, private val title: String) :
|
||||
Fragment() {
|
||||
@Inject
|
||||
lateinit var roomAppDatabase: RoomAppDatabase
|
||||
private var _binding: FragmentPhenomenonBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentPhenomenonBinding.inflate(inflater, container, false)
|
||||
Log.e("jingo", "PhenomenonFragment onCreateView ${hashCode()}")
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.phenomenonRecyclerview.setHasFixedSize(true)
|
||||
binding.phenomenonRecyclerview.layoutManager = LinearLayoutManager(context)
|
||||
val adapter = PhenomenonAdapter()
|
||||
binding.phenomenonRecyclerview.adapter = adapter
|
||||
lifecycleScope.launch {
|
||||
Log.e("jingo", "$classType $title ")
|
||||
val list = roomAppDatabase.getScProblemTypeDao().getPhenomenonList(classType, title)
|
||||
Log.e("jingo", "${list.toString()}")
|
||||
adapter.refreshData(list)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
Log.e("jingo", "PhenomenonFragment onDestroyView ${hashCode()}")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import dagger.hilt.EntryPoint
|
||||
|
||||
/**
|
||||
* 离线地图主页面,viewpage适配器
|
||||
|
||||
@@ -6,9 +6,9 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Observer
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
@@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||
*使用 LiveData 的 observeForever 然后在 ViewHolder 销毁前手动调用 removeObserver
|
||||
*使用 LifecycleRegistry 给 ViewHolder 分发生命周期(这里使用了这个)
|
||||
*/
|
||||
class OfflineMapCityListAdapter @Inject constructor(
|
||||
class OfflineMapCityListAdapter(
|
||||
private val downloadManager: OfflineMapDownloadManager, private val context: Context
|
||||
) : BaseRecyclerViewAdapter<OfflineMapCityBean>() {
|
||||
|
||||
@@ -126,7 +126,7 @@ class OfflineMapCityListAdapter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.adapter_offline_map_city
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,10 @@ import android.content.Context
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.collect.library.data.entity.OfflineMapCityBean
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import com.navinfo.omqs.tools.RealmCoroutineScope
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.realm.Realm
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
@@ -22,6 +18,7 @@ import javax.inject.Inject
|
||||
@HiltViewModel
|
||||
class OfflineMapCityListViewModel @Inject constructor(
|
||||
@ApplicationContext val context: Context,
|
||||
private val roomDatabase: RoomAppDatabase
|
||||
) : ViewModel() {
|
||||
|
||||
val cityListLiveData = MutableLiveData<List<OfflineMapCityBean>>()
|
||||
@@ -31,13 +28,14 @@ class OfflineMapCityListViewModel @Inject constructor(
|
||||
*/
|
||||
fun getCityList() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val realm = Realm.getDefaultInstance()
|
||||
val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
|
||||
val list = realm.copyFromRealm(objects)
|
||||
realm.close()
|
||||
for (item in list) {
|
||||
FileManager.checkOfflineMapFileInfo(item)
|
||||
}
|
||||
// val realm = Realm.getDefaultInstance()
|
||||
// val objects = realm.where<OfflineMapCityBean>().findAll().sort("id", Sort.ASCENDING)
|
||||
// val list = realm.copyFromRealm(objects)
|
||||
// realm.close()
|
||||
// for (item in list) {
|
||||
// FileManager.checkOfflineMapFileInfo(item)
|
||||
// }
|
||||
val list = roomDatabase.getOfflineMapDao().getOfflineMapList()
|
||||
cityListLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* 离线地图
|
||||
* 离线地图总页面
|
||||
*/
|
||||
class OfflineMapFragment : Fragment() {
|
||||
|
||||
|
||||
@@ -6,16 +6,33 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapBinding
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.navinfo.omqs.databinding.FragmentOfflineMapStateListBinding
|
||||
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
/**
|
||||
* 离线地图管理页面
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class OfflineMapStateListFragment : Fragment() {
|
||||
@Inject
|
||||
lateinit var downloadManager: OfflineMapDownloadManager
|
||||
private var _binding: FragmentOfflineMapStateListBinding? = null
|
||||
|
||||
private val viewModel by viewModels<OfflineMapStateListViewModel>()
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val adapter: OfflineMapCityListAdapter by lazy {
|
||||
OfflineMapCityListAdapter(
|
||||
downloadManager,
|
||||
requireContext()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -27,11 +44,24 @@ class OfflineMapStateListFragment : Fragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val layoutManager = LinearLayoutManager(context)
|
||||
//// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能
|
||||
binding.offlineMapCityStateListRecyclerview.setHasFixedSize(true)
|
||||
binding.offlineMapCityStateListRecyclerview.layoutManager = layoutManager
|
||||
binding.offlineMapCityStateListRecyclerview.adapter = adapter
|
||||
viewModel.cityListLiveData.observe(viewLifecycleOwner) {
|
||||
adapter.refreshData(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.getCityList()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.bean.OfflineMapCityBean
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 离线地图城市列表viewModel
|
||||
*/
|
||||
@HiltViewModel
|
||||
class OfflineMapStateListViewModel @Inject constructor(
|
||||
@ApplicationContext val context: Context,
|
||||
private val roomDatabase: RoomAppDatabase
|
||||
) : ViewModel() {
|
||||
|
||||
val cityListLiveData = MutableLiveData<List<OfflineMapCityBean>>()
|
||||
|
||||
/**
|
||||
* 去获取正在下载或 已经下载的离线地图列表
|
||||
*/
|
||||
fun getCityList() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val list = roomDatabase.getOfflineMapDao().getOfflineMapListWithOutNone()
|
||||
if (cityListLiveData.value != null) {
|
||||
if (cityListLiveData.value!!.size != list.size)
|
||||
cityListLiveData.postValue(list)
|
||||
}else{
|
||||
cityListLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.navinfo.omqs.ui.fragment.offlinemap
|
||||
|
||||
import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class OfflineMapViewHolder(dataBinding: AdapterOfflineMapCityBinding) : BaseViewHolder(dataBinding) {
|
||||
init{
|
||||
dataBinding.offlineMapDownloadBtn
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,12 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
|
||||
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
/**
|
||||
* 个人中心
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
|
||||
|
||||
private var _binding: FragmentPersonalCenterBinding? = null
|
||||
@@ -54,6 +56,18 @@ class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
|
||||
}
|
||||
})
|
||||
}
|
||||
R.id.personal_center_menu_import_yuan_data->{
|
||||
// 用户选中导入数据,打开文件选择器,用户选择导入的数据文件目录
|
||||
fileChooser.openChooseFileDialog(object: FileChooserCallback() {
|
||||
override fun onCancel(reason: String) {
|
||||
}
|
||||
|
||||
override fun onResult(uri: Uri) {
|
||||
viewModel.importScProblemData(uri)
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@@ -1,16 +1,89 @@
|
||||
package com.navinfo.omqs.ui.fragment.personalcenter
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.blankj.utilcode.util.UriUtils
|
||||
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||
import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.apache.poi.ss.usermodel.Cell
|
||||
import org.apache.poi.ss.usermodel.Row
|
||||
import org.apache.poi.ss.usermodel.Sheet
|
||||
import org.apache.poi.ss.usermodel.WorkbookFactory
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
class PersonalCenterViewModel: ViewModel() {
|
||||
@HiltViewModel
|
||||
class PersonalCenterViewModel @Inject constructor(
|
||||
private val roomAppDatabase: RoomAppDatabase
|
||||
) : ViewModel() {
|
||||
fun importOmdbData(omdbFile: File) {
|
||||
// 检查File是否为sqlite数据库
|
||||
if (omdbFile == null || omdbFile.exists()) {
|
||||
if (omdbFile == null || !omdbFile.exists()) {
|
||||
throw Exception("文件不存在")
|
||||
}
|
||||
if (!omdbFile.name.endsWith(".sqlite") and !omdbFile.name.endsWith("db")) {
|
||||
throw Exception("文件不存在")
|
||||
}
|
||||
}
|
||||
|
||||
fun importScProblemData(uri: Uri) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val file = UriUtils.uri2File(uri)
|
||||
val inputStream: InputStream =
|
||||
FileInputStream(file) //getAssets().open("sample.xlsx")
|
||||
val workbook = WorkbookFactory.create(inputStream)
|
||||
//获取所有sheet
|
||||
val sheet1 = workbook.getSheet("SC_PROBLEM_TYPE")
|
||||
sheet1?.let {
|
||||
val rowCount: Int = it.physicalNumberOfRows // 获取行数
|
||||
val list = mutableListOf<ScProblemTypeBean>()
|
||||
for (i in 1 until rowCount) {
|
||||
val row: Row = it.getRow(i) // 获取行
|
||||
val cellCount: Int = row.physicalNumberOfCells // 获取列数
|
||||
if (cellCount == 3) {
|
||||
val bean = ScProblemTypeBean()
|
||||
bean.classType = row.getCell(0).stringCellValue
|
||||
bean.problemType = row.getCell(1).stringCellValue
|
||||
bean.phenomenon = row.getCell(2).stringCellValue
|
||||
list.add(bean)
|
||||
Log.e("jingo", bean.toString())
|
||||
}
|
||||
}
|
||||
roomAppDatabase.getScProblemTypeDao().insertOrUpdateList(list)
|
||||
}
|
||||
val sheet2 = workbook.getSheet("SC_ROOT_CAUSE_ANALYSIS")
|
||||
sheet2?.let {
|
||||
val rowCount: Int = it.physicalNumberOfRows // 获取行数
|
||||
val list = mutableListOf<ScRootCauseAnalysisBean>()
|
||||
for (i in 1 until rowCount) {
|
||||
val row: Row = it.getRow(i) // 获取行
|
||||
val cellCount: Int = row.physicalNumberOfCells // 获取列数
|
||||
if (cellCount == 2) {
|
||||
val bean = ScRootCauseAnalysisBean()
|
||||
bean.problemLink = row.getCell(0).stringCellValue
|
||||
bean.problemCause = row.getCell(1).stringCellValue
|
||||
list.add(bean)
|
||||
Log.e("jingo", bean.toString())
|
||||
}
|
||||
}
|
||||
roomAppDatabase.getScRootCauseAnalysisDao().insertOrUpdateList(list)
|
||||
}
|
||||
workbook.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
Log.e("jingo", e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.view.View.OnClickListener
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.navinfo.omqs.R
|
||||
|
||||
/**
|
||||
* RecyclerView 适配器基础类
|
||||
@@ -26,6 +27,11 @@ abstract class BaseRecyclerViewAdapter<T>(var data: List<T> = listOf()) :
|
||||
// )
|
||||
// }
|
||||
|
||||
abstract fun getItemViewRes(position: Int): Int
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return getItemViewRes(position)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return data.size
|
||||
|
||||
Reference in New Issue
Block a user