fix: 合并代码

This commit is contained in:
xiaoyan 2023-04-25 15:40:23 +08:00
commit 67ce6f11b9
34 changed files with 560 additions and 188 deletions

View File

@ -12,12 +12,16 @@ android {
defaultConfig { defaultConfig {
applicationId "com.navinfo.omqs" applicationId "com.navinfo.omqs"
minSdk 26 minSdk 21
targetSdk 33 targetSdk 21
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "armeabi", "mips"
}
} }
buildTypes { buildTypes {
@ -37,7 +41,18 @@ android {
viewBinding true viewBinding true
dataBinding true dataBinding true
} }
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
//ok了
lintOptions {
checkReleaseBuilds false
abortOnError false
}
} }
@ -46,7 +61,6 @@ dependencies {
implementation project(':collect-library') implementation project(':collect-library')
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
@ -72,8 +86,8 @@ dependencies {
kapt "androidx.room:room-ktx:2.5.1" kapt "androidx.room:room-ktx:2.5.1"
//excel word等文件 //excel word等文件
implementation 'org.apache.poi:poi:5.2.3' implementation 'org.apache.poi:poi:4.0.0'
implementation 'org.apache.poi:poi-ooxml:5.2.3' implementation 'org.apache.poi:poi-ooxml:4.0.0'
// spatialite文件 // spatialite文件
implementation 'com.github.sevar83:android-spatialite:2.0.1' implementation 'com.github.sevar83:android-spatialite:2.0.1'

View File

@ -16,7 +16,6 @@ class OMQSApplication : Application() {
Util.getInstance().init(applicationContext) Util.getInstance().init(applicationContext)
NetUtils.getInstance().init(this) NetUtils.getInstance().init(this)
TakePhotoManager.getInstance().init(this, 1) TakePhotoManager.getInstance().init(this, 1)
FileManager.initRootDir(this)
} }
private fun getKey(inputString: String): String { private fun getKey(inputString: String): String {

View File

@ -5,6 +5,7 @@ import com.navinfo.omqs.Constant
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass import io.realm.annotations.RealmClass
@ -55,9 +56,11 @@ open class TaskBean @JvmOverloads constructor(
/** /**
* 当前下载状态 * 当前下载状态
*/ */
var status: Int = FileDownloadStatus.NONE var status: Int = FileDownloadStatus.NONE,
) : RealmObject(){ @Ignore
fun getDownLoadUrl():String{ var message: String = ""
) : RealmObject() {
fun getDownLoadUrl(): String {
return "${Constant.SERVER_ADDRESS}devcp/download?fileStr=26" return "${Constant.SERVER_ADDRESS}devcp/download?fileStr=26"
} }
} }

View File

@ -30,13 +30,24 @@ import kotlin.streams.toList
/** /**
* 导入omdb数据的帮助类 * 导入omdb数据的帮助类
* */ * */
class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val context: Context,@Assisted("omdbFile") val omdbFile: File) { class ImportOMDBHelper @AssistedInject constructor(
@Assisted("context") val context: Context,
@Assisted("omdbFile") val omdbFile: File
) {
@Inject @Inject
lateinit var omdbHiltFactory: OMDBDataBaseHiltFactory lateinit var omdbHiltFactory: OMDBDataBaseHiltFactory
@Inject @Inject
lateinit var gson: Gson lateinit var gson: Gson
private val database by lazy { omdbHiltFactory.obtainOmdbDataBaseHelper(context, omdbFile.absolutePath, 1).writableDatabase } private val database by lazy {
private val configFile: File = File("${Constant.USER_DATA_PATH}", Constant.OMDB_CONFIG) omdbHiltFactory.obtainOmdbDataBaseHelper(
context,
omdbFile.absolutePath,
1
).writableDatabase
}
private val configFile: File =
File("${Constant.DATA_PATH}/${Constant.CURRENT_USER_ID}", Constant.OMDB_CONFIG)
/** /**
* 读取config的配置文件 * 读取config的配置文件
@ -67,8 +78,10 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
} }
}.toList() }.toList()
val cursor = database.query(table, finalColumns.toTypedArray(), "1=1", val cursor = database.query(
mutableListOf<String>().toTypedArray(), null, null, null, null) table, finalColumns.toTypedArray(), "1=1",
mutableListOf<String>().toTypedArray(), null, null, null, null
)
with(cursor) { with(cursor) {
if (moveToFirst()) { if (moveToFirst()) {
while (moveToNext()) { while (moveToNext()) {
@ -76,13 +89,17 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
for (columnIndex in 0 until columnCount) { for (columnIndex in 0 until columnCount) {
var columnName = getColumnName(columnIndex) var columnName = getColumnName(columnIndex)
if (columnName.startsWith("ST_AsText(")) { if (columnName.startsWith("ST_AsText(")) {
columnName = columnName.replace("ST_AsText(", "").substringBeforeLast(")") columnName = columnName.replace("ST_AsText(", "")
.substringBeforeLast(")")
} }
when(getType(columnIndex)) { when (getType(columnIndex)) {
FIELD_TYPE_NULL -> rowMap[columnName] = "" FIELD_TYPE_NULL -> rowMap[columnName] = ""
FIELD_TYPE_INTEGER -> rowMap[columnName] = getInt(columnIndex) FIELD_TYPE_INTEGER -> rowMap[columnName] =
FIELD_TYPE_FLOAT -> rowMap[columnName] = getFloat(columnIndex) getInt(columnIndex)
FIELD_TYPE_BLOB -> rowMap[columnName] = String(getBlob(columnIndex), Charsets.UTF_8) FIELD_TYPE_FLOAT -> rowMap[columnName] =
getFloat(columnIndex)
FIELD_TYPE_BLOB -> rowMap[columnName] =
String(getBlob(columnIndex), Charsets.UTF_8)
else -> rowMap[columnName] = getString(columnIndex) else -> rowMap[columnName] = getString(columnIndex)
} }
} }
@ -104,7 +121,7 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
suspend fun importOmdbZipFile(omdbZipFile: File): Flow<String> = withContext(Dispatchers.IO) { suspend fun importOmdbZipFile(omdbZipFile: File): Flow<String> = withContext(Dispatchers.IO) {
val importConfig = openConfigFile() val importConfig = openConfigFile()
val unZipFolder = File(omdbZipFile.parentFile, "result") val unZipFolder = File(omdbZipFile.parentFile, "result")
flow<String> { flow {
if (unZipFolder.exists()) { if (unZipFolder.exists()) {
unZipFolder.deleteRecursively() unZipFolder.deleteRecursively()
} }
@ -122,7 +139,7 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
val listResult = mutableListOf<Map<String, Any?>>() val listResult = mutableListOf<Map<String, Any?>>()
currentConfig?.let { currentConfig?.let {
val list = FileIOUtils.readFile2List(txtFile, "UTF-8") val list = FileIOUtils.readFile2List(txtFile, "UTF-8")
if (list!=null) { if (list != null) {
// 将list数据转换为map // 将list数据转换为map
for (line in list) { for (line in list) {
val map = gson.fromJson<Map<String, Any?>>(line, object:TypeToken<Map<String, Any?>>(){}.getType()) val map = gson.fromJson<Map<String, Any?>>(line, object:TypeToken<Map<String, Any?>>(){}.getType())
@ -154,10 +171,10 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
Realm.getDefaultInstance().insert(renderEntity) Realm.getDefaultInstance().insert(renderEntity)
} }
// 1个文件发送一次flow流 // 1个文件发送一次flow流
emit("${index+1}/${importConfig.tables.size}") emit("${index + 1}/${importConfig.tables.size}")
} }
Realm.getDefaultInstance().commitTransaction() Realm.getDefaultInstance().commitTransaction()
emit("finish") emit("OK")
} }
} }
@ -166,7 +183,15 @@ class ImportOMDBHelper @AssistedInject constructor(@Assisted("context") val cont
val columns = mutableListOf<String>() val columns = mutableListOf<String>()
// 查询 sqlite_master 表获取指定数据表的元数据信息 // 查询 sqlite_master 表获取指定数据表的元数据信息
val cursor = db.query("sqlite_master", arrayOf("sql"), "type='table' AND name=?", arrayOf(tableName), null, null, null) val cursor = db.query(
"sqlite_master",
arrayOf("sql"),
"type='table' AND name=?",
arrayOf(tableName),
null,
null,
null
)
// 从元数据信息中解析出列名 // 从元数据信息中解析出列名
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {

View File

@ -1,9 +1,9 @@
package com.navinfo.omqs.db package com.navinfo.omqs.db
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.omqs.bean.HadLinkDvoBean import com.navinfo.omqs.bean.HadLinkDvoBean
import com.navinfo.omqs.bean.TaskBean import com.navinfo.omqs.bean.TaskBean
import io.realm.annotations.RealmModule
@io.realm.annotations.RealmModule(classes = [TaskBean::class, HadLinkDvoBean::class]) @RealmModule(classes = [TaskBean::class, HadLinkDvoBean::class])
class MyRealmModule { class MyRealmModule {
} }

View File

@ -0,0 +1,66 @@
package com.navinfo.omqs.hilt
import android.content.Context
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.scopes.ActivityRetainedScoped
@InstallIn(ActivityRetainedComponent::class)
@Module
class ActivityModule {
/**
* 注入地图控制器在activity范围内使用单例
*/
@ActivityRetainedScoped
@Provides
fun providesMapController(): NIMapController = NIMapController()
/**
* 注入离线地图下载管理在activity范围内使用单例
*/
@ActivityRetainedScoped
@Provides
fun providesOfflineMapDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
roomAppDatabase: RoomAppDatabase,
mapController: NIMapController
): OfflineMapDownloadManager =
OfflineMapDownloadManager(networkServiceAPI, roomAppDatabase, mapController)
/**
* 注入任务下载
*/
@ActivityRetainedScoped
@Provides
fun providesTaskListDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
importFactory: ImportOMDBHiltFactory,
): TaskDownloadManager =
TaskDownloadManager(importFactory, networkServiceAPI)
/**
* 实验失败这样创建viewmodel不会在activity销毁的时候同时销毁
* 4-14:因为没有传入activity的 owner,无法检测生命周期
*/
// @ActivityRetainedScoped
// @Provides
// fun providesMainViewModel(mapController: NIMapController): MainViewModel {
// return MainViewModel(mapController)
// }
@ActivityRetainedScoped
@Provides
fun providesRealmOperateHelper(): RealmOperateHelper {
return RealmOperateHelper()
}
}

View File

@ -17,6 +17,7 @@ import dagger.Lazy
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import io.realm.Realm import io.realm.Realm
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -36,7 +37,7 @@ class GlobalModule {
@Singleton @Singleton
@Provides @Provides
fun provideApplication(application: Application): OMQSApplication { fun provideApplication(@ApplicationContext application: Application): OMQSApplication {
return application as OMQSApplication return application as OMQSApplication
} }

View File

@ -1,63 +1,21 @@
package com.navinfo.omqs.hilt package com.navinfo.omqs.hilt
import android.content.Context
import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityRetainedScoped import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.scopes.ActivityScoped
@InstallIn(ActivityRetainedComponent::class) @InstallIn(ActivityComponent::class)
@Module @Module
class MainActivityModule { class MainActivityModule {
/** /**
* 注入地图控制器在activity范围内使用单例 * 注入地图控制器在activity范围内使用单例
*/ */
@ActivityRetainedScoped @ActivityScoped
@Provides @Provides
fun providesMapController(): NIMapController = NIMapController() fun providesContext(@ActivityContext context: Context): Context = context
/**
* 注入离线地图下载管理在activity范围内使用单例
*/
@ActivityRetainedScoped
@Provides
fun providesOfflineMapDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
roomAppDatabase: RoomAppDatabase,
mapController: NIMapController
): OfflineMapDownloadManager =
OfflineMapDownloadManager(networkServiceAPI, roomAppDatabase, mapController)
/**
* 注入任务下载
*/
@ActivityRetainedScoped
@Provides
fun providesTaskListDownloadManager(
networkServiceAPI: RetrofitNetworkServiceAPI,
): TaskDownloadManager =
TaskDownloadManager(networkServiceAPI)
/**
* 实验失败这样创建viewmodel不会在activity销毁的时候同时销毁
* 4-14:因为没有传入activity的 owner,无法检测生命周期
*/
// @ActivityRetainedScoped
// @Provides
// fun providesMainViewModel(mapController: NIMapController): MainViewModel {
// return MainViewModel(mapController)
// }
@ActivityRetainedScoped
@Provides
fun providesRealmOperateHelper(): RealmOperateHelper {
return RealmOperateHelper()
}
} }

View File

@ -0,0 +1,7 @@
//package com.navinfo.omqs.hilt
//
//import javax.inject.Qualifier
//
//@Qualifier
//@Retention(AnnotationRetention.RUNTIME)
//annotation class ActivityContext

View File

@ -1,23 +1,32 @@
package com.navinfo.omqs.http.taskdownload package com.navinfo.omqs.http.taskdownload
import android.content.Context
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.navinfo.omqs.bean.TaskBean import com.navinfo.omqs.bean.TaskBean
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.hilt.OMDBDataBaseHiltFactory
import com.navinfo.omqs.http.RetrofitNetworkServiceAPI import com.navinfo.omqs.http.RetrofitNetworkServiceAPI
import dagger.hilt.android.qualifiers.ActivityContext
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
/** /**
* 管理任务数据下载 * 管理任务数据下载
*/ */
class TaskDownloadManager( class TaskDownloadManager constructor(
val importFactory: ImportOMDBHiltFactory,
val netApi: RetrofitNetworkServiceAPI, val netApi: RetrofitNetworkServiceAPI,
) { ) {
lateinit var context: Context
/** /**
* 最多同时下载数量 * 最多同时下载数量
*/ */
private val MAX_SCOPE = 3 private val MAX_SCOPE = 1
/** /**
* 存储有哪些城市需要下载的队列 * 存储有哪些城市需要下载的队列
@ -33,6 +42,9 @@ class TaskDownloadManager(
ConcurrentHashMap<Int, TaskDownloadScope>() ConcurrentHashMap<Int, TaskDownloadScope>()
} }
fun init(context: Context) {
this.context = context
}
/** /**
* 启动下载任务 * 启动下载任务
@ -92,7 +104,7 @@ class TaskDownloadManager(
fun addTask(taskBean: TaskBean) { fun addTask(taskBean: TaskBean) {
if (!scopeMap.containsKey(taskBean.id)) { if (!scopeMap.containsKey(taskBean.id)) {
scopeMap[taskBean.id] = TaskDownloadScope(this, taskBean) scopeMap[taskBean.id] = TaskDownloadScope( this, taskBean)
} }
} }

View File

@ -1,23 +1,34 @@
package com.navinfo.omqs.http.taskdownload package com.navinfo.omqs.http.taskdownload
import android.content.Context
import android.util.Log import android.util.Log
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.TaskBean import com.navinfo.omqs.bean.TaskBean
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import io.realm.Realm
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.io.RandomAccessFile import java.io.RandomAccessFile
import javax.inject.Inject
class TaskDownloadScope( class TaskDownloadScope(
private val downloadManager: TaskDownloadManager, private val downloadManager: TaskDownloadManager,
val taskBean: TaskBean, val taskBean: TaskBean,
) : ) :
CoroutineScope by CoroutineScope(Dispatchers.IO + CoroutineName("OfflineMapDownLoad")) { CoroutineScope by CoroutineScope(Dispatchers.IO + CoroutineName("OfflineMapDownLoad")) {
@Inject
lateinit var importOMDBHiltFactory: ImportOMDBHiltFactory
/** /**
*下载任务用来取消的 *下载任务用来取消的
*/ */
@ -59,7 +70,12 @@ class TaskDownloadScope(
*/ */
fun launch() { fun launch() {
downloadJob = launch() { downloadJob = launch() {
download() FileManager.checkOMDBFileInfo(taskBean)
if (taskBean.status == FileDownloadStatus.IMPORT) {
importData()
} else {
download()
}
downloadManager.launchNext(taskBean.id) downloadManager.launchNext(taskBean.id)
} }
} }
@ -76,14 +92,17 @@ class TaskDownloadScope(
* 更新任务 * 更新任务
* @param status [OfflineMapCityBean.Status] * @param status [OfflineMapCityBean.Status]
*/ */
private fun change(status: Int) { private fun change(status: Int, message: String = "") {
if (taskBean.status != status || status == FileDownloadStatus.LOADING) { if (taskBean.status != status || status == FileDownloadStatus.LOADING || status == FileDownloadStatus.IMPORTING) {
taskBean.status = status taskBean.status = status
taskBean.message = message
downloadData.postValue(taskBean) downloadData.postValue(taskBean)
launch(Dispatchers.IO) { launch {
// downloadManager.roomDatabase.getOfflineMapDao().update(taskBean) val realm = Realm.getDefaultInstance()
realm.executeTransaction {
it.copyToRealmOrUpdate(taskBean)
}
} }
} }
} }
@ -96,36 +115,75 @@ class TaskDownloadScope(
downloadData.observe(owner, ob) downloadData.observe(owner, ob)
} }
/**
* 导入数据
*/
private suspend fun importData(file: File? = null) {
try {
Log.e("jingo", "importData SSS")
change(FileDownloadStatus.IMPORTING)
var fileNew = file
?: File("${Constant.DOWNLOAD_PATH}${taskBean.evaluationTaskName}_${taskBean.dataVersion}.zip")
val importOMDBHelper: ImportOMDBHelper =
downloadManager.importFactory.obtainImportOMDBHelper(
downloadManager.context,
fileNew
)
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile).collect {
Log.e("jingo", "数据安装 $it")
if (it == "OK") {
change(FileDownloadStatus.DONE)
} else {
change(FileDownloadStatus.IMPORTING, it)
}
}
} catch (e: Exception) {
Log.e("jingo", "数据安装失败 ${e.toString()}")
change(FileDownloadStatus.ERROR)
}
Log.e("jingo", "importData EEE")
}
/** /**
* 下载文件 * 下载文件
*/ */
private suspend fun download() { private suspend fun download() {
//如果文件下载安装已经完毕
if (taskBean.status == FileDownloadStatus.DONE) {
return
}
var inputStream: InputStream? = null var inputStream: InputStream? = null
var randomAccessFile: RandomAccessFile? = null var randomAccessFile: RandomAccessFile? = null
try { try {
//创建离线地图 下载文件夹,.map文件夹的下一级 //创建离线地图 下载文件夹,.map文件夹的下一级
val fileDir = File("${Constant.DOWNLOAD_PATH}download") val fileDir = File("${Constant.DOWNLOAD_PATH}")
if (!fileDir.exists()) { if (!fileDir.exists()) {
fileDir.mkdirs() fileDir.mkdirs()
} }
val fileTemp = val fileTemp =
File("${Constant.DOWNLOAD_PATH}${taskBean.id}_${taskBean.dataVersion}") File("${Constant.DOWNLOAD_PATH}${taskBean.evaluationTaskName}_${taskBean.dataVersion}.zip")
val startPosition = taskBean.currentSize val startPosition = taskBean.currentSize
//验证断点有效性
if (startPosition < 0) throw IOException("jingo Start position less than zero") if (fileTemp.length() > 0 && taskBean.fileSize > 0 && fileTemp.length() == taskBean.fileSize) {
importData(fileTemp)
return
}
val response = downloadManager.netApi.retrofitDownLoadFile( val response = downloadManager.netApi.retrofitDownLoadFile(
start = "bytes=$startPosition-", start = "bytes=$startPosition-",
url = taskBean.getDownLoadUrl() url = taskBean.getDownLoadUrl()
) )
val responseBody = response.body() val responseBody = response.body()
change(FileDownloadStatus.LOADING)
responseBody ?: throw IOException("jingo ResponseBody is null")
responseBody ?: throw IOException("jingo ResponseBody is null")
if (startPosition == 0L) { if (startPosition == 0L) {
taskBean.fileSize = responseBody.contentLength() taskBean.fileSize = responseBody.contentLength()
Log.e("jingo", "当前文件大小 ${taskBean.fileSize}")
} }
change(FileDownloadStatus.LOADING)
//写入文件 //写入文件
randomAccessFile = RandomAccessFile(fileTemp, "rwd") randomAccessFile = RandomAccessFile(fileTemp, "rwd")
randomAccessFile.seek(startPosition) randomAccessFile.seek(startPosition)
@ -146,17 +204,14 @@ class TaskDownloadScope(
} }
} }
Log.e("jingo", "文件下载完成 ${taskBean.currentSize} == ${taskBean.fileSize}")
if (taskBean.currentSize == taskBean.fileSize) { if (taskBean.currentSize == taskBean.fileSize) {
val res = importData(fileTemp)
fileTemp.renameTo(File("${Constant.DOWNLOAD_PATH}${taskBean.evaluationTaskName}.zip"))
Log.e("jingo", "文件下载完成 修改文件 $res")
change(FileDownloadStatus.DONE)
} else { } else {
change(FileDownloadStatus.PAUSE) change(FileDownloadStatus.PAUSE)
} }
} catch (e: Throwable) { } catch (e: Throwable) {
change(FileDownloadStatus.ERROR) change(FileDownloadStatus.ERROR)
Log.e("jingo","数据下载出错 ${e.message}")
} finally { } finally {
inputStream?.close() inputStream?.close()
randomAccessFile?.close() randomAccessFile?.close()

View File

@ -16,8 +16,10 @@ class FileManager {
const val LOADING = 2 //下载中 const val LOADING = 2 //下载中
const val PAUSE = 3 //暂停 const val PAUSE = 3 //暂停
const val ERROR = 4 //错误 const val ERROR = 4 //错误
const val DONE = 5 //完成 const val IMPORT = 5 //安装
const val UPDATE = 6 //有新版本要更新 const val IMPORTING = 6 //安装中
const val UPDATE = 7 //有新版本要更新
const val DONE = 8 //完成
} }
//初始化数据文件夹 //初始化数据文件夹
@ -109,60 +111,28 @@ class FileManager {
* 检查离线地图文件 * 检查离线地图文件
*/ */
suspend fun checkOMDBFileInfo(taskBean: TaskBean) { suspend fun checkOMDBFileInfo(taskBean: TaskBean) {
if (taskBean.status == FileDownloadStatus.DONE)
return
//访问离线地图文件夹 //访问离线地图文件夹
val fileDir = File("${Constant.DOWNLOAD_PATH}") val fileDir = File("${Constant.DOWNLOAD_PATH}")
//如果连本地文件夹还没有,就不用修改任何数据了 //如果连本地文件夹还没有,就不用修改任何数据了
if (!fileDir.exists()) { if (!fileDir.exists()) {
return return
} }
//访问离线地图临时下载文件夹
val fileTempDir = File(Constant.DOWNLOAD_PATH)
//是否有一份.map文件了
var mapFile: File? = null
//文件夹里文件挨个访问 //文件夹里文件挨个访问
for (item in fileDir.listFiles()) { for (item in fileDir.listFiles()) {
//先找到对应的省市文件例如540000_西藏自治区_20230401195018.map",以id开头 //先找到对应的省市文件例如540000_西藏自治区_20230401195018.map",以id开头
if (item.isFile && item.name.startsWith("${taskBean.id}_")) { if (item.isFile && item.name == "${taskBean.evaluationTaskName}_${taskBean.dataVersion}.zip") {
//如果本地文件与从网络获取到版本号一致,表示这个文件已经下载完毕,不用处理了 taskBean.currentSize = item.length()
if (item.name == "${taskBean.id}_${taskBean.dataVersion}") { if (taskBean.fileSize > 0 && taskBean.fileSize == item.length()) {
taskBean.status = FileDownloadStatus.DONE taskBean.status = FileDownloadStatus.IMPORT
return } else {
} taskBean.status = FileDownloadStatus.PAUSE
//文件存在,版本号不对应,留给下面流程处理
mapFile = item
break
}
}
//临时下载文件夹
if (fileTempDir.exists()) {
for (item in fileTempDir.listFiles()) {
//先找到对应的省市文件例如540000_20230401195018",以id开头
if (item.isFile && item.name.startsWith("${taskBean.id}_")) {
//如果本地文件与从网络获取到版本号一致,表示这个文件已经在下载列表中
if (item.name == "${taskBean.id}_${taskBean.dataVersion}") {
//如果这个临时文件的大小和下载大小是一致的,说明已经下载完了,但是在下载环节没有更名移动成功,需要重命名和移动文件夹
if (item.length() == taskBean.fileSize) {
//移动更名文件后删除旧数据,修改状态
if (item.renameTo(File("${Constant.OFFLINE_MAP_PATH}${taskBean.evaluationTaskName}.zip"))) {
//删除旧版本数据
mapFile?.delete()
taskBean.status = FileDownloadStatus.DONE
return
}
} else { // 临时文件大小和目标不一致,说明下载了一半
taskBean.status = FileDownloadStatus.PAUSE
taskBean.currentSize = item.length()
return
}
} else { //虽然省市id开头一致但是版本号不一致说明之前版本下载了一部分现在要更新了原来下载的文件直接删除
taskBean.status = FileDownloadStatus.UPDATE
item.delete()
return
}
break
} }
return
} }
} }
taskBean.status = FileDownloadStatus.NONE
} }
} }
} }

View File

@ -0,0 +1,204 @@
/**
*
*/
package com.navinfo.omqs.ui.activity;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* 继承了Activity实现Android6.0的运行时权限检测
* 需要进行运行时权限检测的Activity可以继承这个类
*/
public class CheckPermissionsActivity extends BaseActivity {
//是否需要检测后台定位权限设置为true时如果用户没有给予后台定位权限会弹窗提示
private boolean needCheckBackLocation = false;
//如果设置了target > 28需要增加这个权限否则不会弹出"始终允许"这个选择框
private static String BACKGROUND_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
};
private static final int PERMISSON_REQUESTCODE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
BACKGROUND_LOCATION_PERMISSION
};
}
}
/**
* 判断是否需要检测防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
}
/**
*
* @param permissions
*
*/
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class,
int.class});
method.invoke(this, array, PERMISSON_REQUESTCODE);
}
}
} catch (Throwable e) {
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
*
*/
private List<String> findDeniedPermissions(String[] permissions) {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23){
try {
for (String perm : permissions) {
Method checkSelfMethod = getClass().getMethod("checkSelfPermission", String.class);
Method shouldShowRequestPermissionRationaleMethod = getClass().getMethod("shouldShowRequestPermissionRationale",
String.class);
if ((Integer)checkSelfMethod.invoke(this, perm) != PackageManager.PERMISSION_GRANTED
|| (Boolean)shouldShowRequestPermissionRationaleMethod.invoke(this, perm)) {
if(!needCheckBackLocation
&& BACKGROUND_LOCATION_PERMISSION.equals(perm)) {
continue;
}
needRequestPermissonList.add(perm);
}
}
} catch (Throwable e) {
}
}
return needRequestPermissonList;
}
/**
* 检测是否所有的权限都已经授权
*
*/
private boolean verifyPermissions(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
/**
* 显示提示信息
*
*/
private void showMissingPermissionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("当前应用缺少必要权限。\\n\\n请点击\\\"设置\\\"-\\\"权限\\\"-打开所需权限。");
// 拒绝, 退出应用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAppSettings();
}
});
builder.setCancelable(false);
builder.show();
}
/**
* 启动应用的设置
*
*/
private void startAppSettings() {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}

View File

@ -33,7 +33,7 @@ open abstract class PermissionsActivity : BaseActivity() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
// permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION) // permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION)
} }
XXPermissions.with(this) /* XXPermissions.with(this)
// 申请单个权限 // 申请单个权限
.permission(permissionList) .permission(permissionList)
// 设置权限请求拦截器(局部设置) // 设置权限请求拦截器(局部设置)
@ -73,7 +73,7 @@ open abstract class PermissionsActivity : BaseActivity() {
onPermissionsDenied() onPermissionsDenied()
} }
} }
}) })*/
} }
/** /**

View File

@ -11,6 +11,7 @@ import androidx.lifecycle.Observer
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityLoginBinding import com.navinfo.omqs.databinding.ActivityLoginBinding
import com.navinfo.omqs.ui.activity.CheckPermissionsActivity
import com.navinfo.omqs.ui.activity.PermissionsActivity import com.navinfo.omqs.ui.activity.PermissionsActivity
import com.navinfo.omqs.ui.activity.map.MainActivity import com.navinfo.omqs.ui.activity.map.MainActivity
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -20,7 +21,7 @@ import dagger.hilt.android.AndroidEntryPoint
*/ */
@AndroidEntryPoint @AndroidEntryPoint
class LoginActivity : PermissionsActivity() { class LoginActivity : CheckPermissionsActivity() {
private lateinit var binding: ActivityLoginBinding private lateinit var binding: ActivityLoginBinding
private val viewModel by viewModels<LoginViewModel>() private val viewModel by viewModels<LoginViewModel>()
@ -97,15 +98,6 @@ class LoginActivity : PermissionsActivity() {
} }
} }
//进应用根本不调用,待查
override fun onPermissionsGranted() {
Log.e("jingo", "调用了吗")
}
override fun onPermissionsDenied() {
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
} }

View File

@ -10,6 +10,7 @@ import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ResourceUtils import com.blankj.utilcode.util.ResourceUtils
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.LoginUserBean import com.navinfo.omqs.bean.LoginUserBean
import com.navinfo.omqs.db.MyRealmModule
import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.http.NetworkService
@ -170,7 +171,7 @@ class LoginViewModel @Inject constructor(
.directory(userFolder) .directory(userFolder)
.name("OMQS.realm") .name("OMQS.realm")
.encryptionKey(password) .encryptionKey(password)
// .modules(Realm.getDefaultModule(), MyRealmModule()) .modules(Realm.getDefaultModule(), MyRealmModule())
.schemaVersion(1) .schemaVersion(1)
.build() .build()
Realm.setDefaultConfiguration(config) Realm.setDefaultConfiguration(config)

View File

@ -4,10 +4,8 @@ import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.ToastUtils
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener import com.navinfo.collect.library.map.handler.NiLocationListener
import com.navinfo.omqs.Constant import com.navinfo.omqs.Constant
@ -34,10 +32,10 @@ class MainActivity : BaseActivity() {
@Inject @Inject
lateinit var offlineMapDownloadManager: OfflineMapDownloadManager lateinit var offlineMapDownloadManager: OfflineMapDownloadManager
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main) binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//初始化地图 //初始化地图
mapController.init( mapController.init(

View File

@ -3,38 +3,24 @@ package com.navinfo.omqs.ui.fragment.personalcenter
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.util.Log
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 androidx.fragment.app.Fragment
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.UriUtils import com.blankj.utilcode.util.UriUtils
import com.github.k1rakishou.fsaf.FileChooser import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.navinfo.collect.library.data.RealmUtils
import com.navinfo.collect.library.data.entity.OMDBEntity
import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
import com.navinfo.omqs.db.ImportOMDBHelper 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.activity.BaseActivity
import com.navinfo.omqs.ui.fragment.BaseFragment import com.navinfo.omqs.ui.fragment.BaseFragment
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.realm.Realm
import io.realm.RealmDictionary
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.oscim.core.GeoPoint import org.oscim.core.GeoPoint
import java.io.File
import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
/** /**

View File

@ -28,6 +28,7 @@ class QsRecordListAdapter(
private val context: Context private val context: Context
) : BaseRecyclerViewAdapter<QsRecordBean>() { ) : BaseRecyclerViewAdapter<QsRecordBean>() {
private var itemClickListener: IKotlinItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding = val viewBinding =
@ -46,6 +47,10 @@ class QsRecordListAdapter(
val qsRecordBean = data[position] val qsRecordBean = data[position]
//tag 方便onclick里拿到数据 //tag 方便onclick里拿到数据
holder.tag = qsRecordBean.id.toString() holder.tag = qsRecordBean.id.toString()
// 点击事件
holder.itemView.setOnClickListener {
itemClickListener!!.onItemClickListener(position)
}
changeViews(binding, qsRecordBean) changeViews(binding, qsRecordBean)
} }
@ -59,6 +64,16 @@ class QsRecordListAdapter(
override fun getItemViewRes(position: Int): Int { override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_qs_record_list return R.layout.adapter_qs_record_list
} }
// 提供set方法
fun setOnKotlinItemClickListener(itemClickListener: IKotlinItemClickListener) {
this.itemClickListener = itemClickListener
}
//自定义接口
interface IKotlinItemClickListener {
fun onItemClickListener(position: Int)
}
} }

View File

@ -5,13 +5,17 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView.VERTICAL import androidx.recyclerview.widget.RecyclerView.VERTICAL
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentQsRecordListBinding import com.navinfo.omqs.databinding.FragmentQsRecordListBinding
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.fragment.BaseFragment import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.tasklist.QsRecordListAdapter import com.navinfo.omqs.ui.fragment.tasklist.QsRecordListAdapter
import com.navinfo.omqs.ui.other.BaseToast.makeText
import com.navinfo.omqs.ui.widget.RecycleViewDivider import com.navinfo.omqs.ui.widget.RecycleViewDivider
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.apache.poi.xwpf.usermodel.VerticalAlign import org.apache.poi.xwpf.usermodel.VerticalAlign
@ -51,6 +55,18 @@ class QsRecordListFragment : BaseFragment(){
itemDecoration.setDrawable(resources.getDrawable(R.drawable.separator)) itemDecoration.setDrawable(resources.getDrawable(R.drawable.separator))
binding.qsRecyclerview.addItemDecoration(itemDecoration) binding.qsRecyclerview.addItemDecoration(itemDecoration)
viewModel.getList(requireContext()) viewModel.getList(requireContext())
// itemClick
adapter!!.setOnKotlinItemClickListener(object : QsRecordListAdapter.IKotlinItemClickListener {
override fun onItemClickListener(position: Int) {
viewModel.onItemClickListener(activity as MainActivity,position)
findNavController().popBackStack()
}
})
}
override fun onResume() {
super.onResume()
viewModel.getList(requireContext())
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -1,11 +1,16 @@
package com.navinfo.omqs.ui.fragment.qsrecordlist package com.navinfo.omqs.ui.fragment.qsrecordlist
import android.content.Context import android.content.Context
import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.QsRecordBean import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.omqs.R
import com.navinfo.omqs.ui.activity.map.MainActivity
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm import io.realm.Realm
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -27,4 +32,11 @@ class QsRecordListViewModel @Inject constructor(
} }
} }
fun onItemClickListener(activity: MainActivity, position :Int){
val naviController = activity.findNavController(R.id.main_activity_right_fragment)
val bundle = Bundle()
bundle.putString("QsId", liveDataQSList.value?.get(position)?.id)
naviController.navigate(R.id.EvaluationResultFragment, bundle)
ToastUtils.showLong(liveDataQSList.value?.get(position)?.classType)
}
} }

View File

@ -13,6 +13,8 @@ import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
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
import java.io.File
import javax.inject.Inject
/** /**
* 离线地图城市列表 RecyclerView 适配器 * 离线地图城市列表 RecyclerView 适配器
@ -31,7 +33,7 @@ class TaskListAdapter(
if (it.tag != null) { if (it.tag != null) {
val taskBean = data[it.tag as Int] val taskBean = data[it.tag as Int]
when (taskBean.status) { when (taskBean.status) {
FileDownloadStatus.NONE, FileDownloadStatus.UPDATE, FileDownloadStatus.PAUSE, FileDownloadStatus.ERROR -> { FileDownloadStatus.NONE, FileDownloadStatus.UPDATE, FileDownloadStatus.PAUSE, FileDownloadStatus.IMPORT, FileDownloadStatus.ERROR -> {
Log.e("jingo", "开始下载 ${taskBean.status}") Log.e("jingo", "开始下载 ${taskBean.status}")
downloadManager.start(taskBean.id) downloadManager.start(taskBean.id)
} }
@ -125,6 +127,29 @@ class TaskListAdapter(
View.INVISIBLE View.INVISIBLE
binding.taskDownloadBtn.text = "更新" binding.taskDownloadBtn.text = "更新"
} }
FileDownloadStatus.IMPORTING -> {
if (binding.taskProgress.visibility != View.VISIBLE) binding.taskProgress.visibility =
View.VISIBLE
binding.taskDownloadBtn.text = "安装中"
val split = taskBean.message.split("/")
if (split.size == 2) {
try {
val index = split[0].toInt()
val count = split[1].toInt()
binding.taskProgress.progress =
index * 100 / count
} catch (e: Exception) {
Log.e("jingo", "更新进度条 $e")
}
} else {
binding.taskProgress.progress = 0
}
}
FileDownloadStatus.IMPORT -> {
if (binding.taskProgress.visibility != View.VISIBLE) binding.taskProgress.visibility =
View.INVISIBLE
binding.taskDownloadBtn.text = "安装"
}
} }
} }

View File

@ -30,6 +30,7 @@ class TaskListFragment : BaseFragment(){
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
downloadManager.init(requireContext())
_binding = FragmentTaskListBinding.inflate(inflater, container, false) _binding = FragmentTaskListBinding.inflate(inflater, container, false)
return binding.root return binding.root

View File

@ -27,12 +27,28 @@ class TaskListViewModel @Inject constructor(
fun getTaskList(context: Context) { fun getTaskList(context: Context) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
Log.e("jingo","realm hashCOde ${realm.hashCode()}") Log.e("jingo", "realm hashCOde ${realm.hashCode()}")
var taskList: List<TaskBean> = mutableListOf()
when (val result = networkService.getTaskList("02911")) { when (val result = networkService.getTaskList("02911")) {
is NetResult.Success -> { is NetResult.Success -> {
if (result.data != null) { if (result.data != null) {
realm.executeTransaction { realm.executeTransaction {
realm.copyToRealmOrUpdate(result.data.obj) result.data.obj?.let { list ->
for (task in list) {
val item = realm.where(TaskBean::class.java).equalTo(
"id", task.id
).findFirst()
if (item != null) {
task.fileSize = item.fileSize
Log.e("jingo", "当前文件大小 ${task.fileSize}")
task.status = item.status
task.currentSize = item.currentSize
}
realm.copyToRealmOrUpdate(task)
}
}
val objects = realm.where(TaskBean::class.java).findAll()
taskList = realm.copyFromRealm(objects)
} }
} }
} }
@ -51,9 +67,8 @@ class TaskListViewModel @Inject constructor(
is NetResult.Loading -> {} is NetResult.Loading -> {}
else -> {} else -> {}
} }
val objects = realm.where(TaskBean::class.java).findAll()
val taskList = realm.copyFromRealm(objects) for (item in taskList) {
for(item in taskList){
FileManager.checkOMDBFileInfo(item) FileManager.checkOMDBFileInfo(item)
} }
liveDataTaskList.postValue(taskList) liveDataTaskList.postValue(taskList)

View File

@ -8,6 +8,7 @@
android:paddingLeft="10dp" android:paddingLeft="10dp"
android:paddingTop="5dp" android:paddingTop="5dp"
android:paddingRight="10dp" android:paddingRight="10dp"
android:paddingBottom="5dp"
tools:context="com.navinfo.omqs.ui.fragment.tasklist.TaskListAdapter"> tools:context="com.navinfo.omqs.ui.fragment.tasklist.TaskListAdapter">
<TextView <TextView

View File

@ -28,9 +28,7 @@ android {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
} }
} }
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
} }
buildTypes { buildTypes {
@ -60,7 +58,6 @@ dependencies {
api fileTree(dir: 'libs', include: ['*.jar', '*.aar']) api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
api files('libs/BaiduLBS_Android.jar') api files('libs/BaiduLBS_Android.jar')
//
api 'androidx.core:core-ktx:1.9.0' api 'androidx.core:core-ktx:1.9.0'
api 'androidx.appcompat:appcompat:1.6.1' api 'androidx.appcompat:appcompat:1.6.1'
api 'com.google.android.material:material:1.8.0' api 'com.google.android.material:material:1.8.0'

View File

@ -4,7 +4,6 @@ import com.navinfo.collect.library.utils.GeometryToolsKt
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmSet import io.realm.RealmSet
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
/** /**

View File

@ -75,7 +75,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//可选默认gcj02设置返回的定位结果坐标系如果配合百度地图使用建议设置为bd09ll; //可选默认gcj02设置返回的定位结果坐标系如果配合百度地图使用建议设置为bd09ll;
locationOption.setCoorType("gcj02") locationOption.setCoorType("gcj02")
//可选默认0即仅定位一次设置发起连续定位请求的间隔需要大于等于1000ms才是有效的 //可选默认0即仅定位一次设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
locationOption.setScanSpan(1000) locationOption.setScanSpan(1200)
//可选,设置是否需要地址信息,默认不需要 //可选,设置是否需要地址信息,默认不需要
locationOption.setIsNeedAddress(false) locationOption.setIsNeedAddress(false)
//可选,设置是否需要地址描述 //可选,设置是否需要地址描述
@ -97,11 +97,11 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//可选默认false设置定位时是否需要海拔信息默认不需要除基础定位版本都可用 //可选默认false设置定位时是否需要海拔信息默认不需要除基础定位版本都可用
locationOption.setIsNeedAltitude(true) locationOption.setIsNeedAltitude(true)
//设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者该模式下开发者无需再关心定位间隔是多少定位SDK本身发现位置变化就会及时回调给开发者 //设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者该模式下开发者无需再关心定位间隔是多少定位SDK本身发现位置变化就会及时回调给开发者
// locationOption.setOpenAutoNotifyMode() locationOption.setOpenAutoNotifyMode()
//设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者 //设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者
locationOption.setOpenAutoNotifyMode( /* locationOption.setOpenAutoNotifyMode(
5, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT 5, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT
) )*/
//需将配置好的LocationClientOption对象通过setLocOption方法传递给LocationClient对象使用 //需将配置好的LocationClientOption对象通过setLocOption方法传递给LocationClient对象使用
locationClient.locOption = locationOption locationClient.locOption = locationOption
} catch (e: Throwable) { } catch (e: Throwable) {