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

 Conflicts:
	app/src/main/java/com/navinfo/omqs/Constant.kt
	app/src/main/java/com/navinfo/omqs/bean/OfflineMapCityBean.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginActivity.kt
	app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt
	app/src/main/res/layout/adapter_offline_map_city.xml
This commit is contained in:
squallzhjch
2023-04-03 10:46:26 +08:00
19 changed files with 452 additions and 43 deletions

View File

@@ -1,5 +1,7 @@
package com.navinfo.omqs
import io.realm.Realm
class Constant {
companion object {
/**
@@ -7,7 +9,9 @@ class Constant {
*/
lateinit var ROOT_PATH: String
lateinit var MAP_PATH: String
lateinit var DATA_PATH: String
lateinit var OFFLINE_MAP_PATH: String
/**
* 服务器地址
*/
@@ -20,7 +24,7 @@ class Constant {
const val message_version_right_off = "1" //立即发送
const val MESSAGE_PAGE_SIZE = 30 //消息列表一页最多数量
lateinit var realm: Realm
}
}

View File

@@ -2,7 +2,12 @@ package com.navinfo.omqs
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import io.realm.Realm
@HiltAndroidApp
class OMQSApplication : Application() {
override fun onCreate() {
super.onCreate()
Realm.init(this)
}
}

View File

@@ -1,30 +1,37 @@
package com.navinfo.omqs.bean
data class OfflineMapCityBean(
val id: String,
/**
* 文件名称
*/
val fileName: String,
/**
* 城市名称
*/
val name: String,
val url: String,
val version: Long,
var fileSize: Long,
var currentSize:Long = 0,
var status:Int = NONE
) {
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 //有新版本要更新
}
import io.realm.RealmObject
enum class StatusEnum(val status: Int) {
NONE(0), WAITING(1), LOADING(2), PAUSE(3),
ERROR(4), DONE(5), UPDATE(6)
}
open class OfflineMapCityBean{
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 = StatusEnum.NONE.status
// status的转换对象
var statusEnum:StatusEnum
get() {
return try {
StatusEnum.values().find { it.status == status }!!
} catch (e: IllegalArgumentException) {
StatusEnum.NONE
}
}
set(value) {
status = value.status
}
constructor() : super()
fun getFileSizeText(): String {
return if (fileSize < 1024.0)
"$fileSize B"

View File

@@ -0,0 +1,17 @@
package com.navinfo.omqs.bean
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
open class OfflineMapCityRealmObject(){
@PrimaryKey
var id: String = ""
var fileName: String=""
var name: String = ""
var url: String = ""
var version: Long = 0
var fileSize: Long = 0
var currentSize:Long = 0
var status:Int = 0
}

View File

@@ -0,0 +1,8 @@
package com.navinfo.omqs.data.process
/**
* 数据处理引擎,数据导入、导出及转换处理
* */
class DataEngine {
}

View File

@@ -0,0 +1,90 @@
package com.navinfo.omqs.ui
import android.content.Intent
import android.os.Bundle
import androidx.core.view.WindowCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import android.view.Menu
import android.view.MenuItem
import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.navinfo.omqs.R
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)
}
}

View File

@@ -16,9 +16,10 @@ open class PermissionsActivity : BaseActivity() {
val permissionList = mutableListOf<String>()
if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.TIRAMISU) {
//文件读写
permissionList.add(Permission.READ_MEDIA_IMAGES)
permissionList.add(Permission.READ_MEDIA_AUDIO)
permissionList.add(Permission.READ_MEDIA_VIDEO)
// permissionList.add(Permission.READ_MEDIA_IMAGES)
// permissionList.add(Permission.READ_MEDIA_AUDIO)
// permissionList.add(Permission.READ_MEDIA_VIDEO)
permissionList.add(Permission.MANAGE_EXTERNAL_STORAGE)
} else {
//文件读写
permissionList.add(Permission.WRITE_EXTERNAL_STORAGE)

View File

@@ -10,9 +10,12 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.LoginUserBean
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.*
import okio.IOException
import java.io.File
import java.math.BigInteger
enum class LoginStatus {
/**
@@ -60,6 +63,17 @@ class LoginViewModel(
loginUser.value = LoginUserBean(username = "admin", password = "123456")
}
private fun initRealm() {
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()
Constant.realm = Realm.getInstance(config)
}
/**
* 处理注册按钮
@@ -100,6 +114,8 @@ class LoginViewModel(
try {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
createRootFolder(context)
// 初始化Realm
initRealm()
} catch (e: IOException) {
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
}
@@ -122,6 +138,12 @@ class LoginViewModel(
val file = File(Constant.MAP_PATH)
if (!file.exists()) {
file.mkdirs()
Constant.DATA_PATH = Constant.ROOT_PATH + "/data/"
with(File(Constant.MAP_PATH)) {
if(!this.exists()) this.mkdirs()
}
with(File(Constant.DATA_PATH)) {
if(!this.exists()) this.mkdirs()
}
}
}

View File

@@ -1,22 +1,35 @@
package com.navinfo.omqs.ui.fragment.personalcenter
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.get
import androidx.navigation.fragment.findNavController
import com.blankj.utilcode.util.UriUtils
import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.google.android.material.snackbar.Snackbar
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
/**
* 个人中心
*/
class PersonalCenterFragment : Fragment() {
class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
private var _binding: FragmentPersonalCenterBinding? = null
private val binding get() = _binding!!
private val fileChooser by lazy { FileChooser(requireContext()) }
private val viewModel by lazy { viewModels<PersonalCenterViewModel>().value }
override fun onCreateView(
@@ -25,7 +38,6 @@ class PersonalCenterFragment : Fragment() {
): View {
_binding = FragmentPersonalCenterBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -35,13 +47,37 @@ class PersonalCenterFragment : Fragment() {
when (it.itemId) {
R.id.personal_center_menu_offline_map ->
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
R.id.personal_center_menu_import_data -> {
// 用户选中导入数据,打开文件选择器,用户选择导入的数据文件目录
fileChooser.openChooseFileDialog(object: FileChooserCallback() {
override fun onCancel(reason: String) {
}
override fun onResult(uri: Uri) {
val file = UriUtils.uri2File(uri)
// 开始导入数据
viewModel.importOmdbData(file)
}
})
}
}
true
}
fileChooser.setCallbacks(this@PersonalCenterFragment)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
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)
}
}

View File

@@ -0,0 +1,16 @@
package com.navinfo.omqs.ui.fragment.personalcenter
import androidx.lifecycle.ViewModel
import java.io.File
class PersonalCenterViewModel: ViewModel() {
fun importOmdbData(omdbFile: File) {
// 检查File是否为sqlite数据库
if (omdbFile == null || omdbFile.exists()) {
throw Exception("文件不存在")
}
if (!omdbFile.name.endsWith(".sqlite") and !omdbFile.name.endsWith("db")) {
throw Exception("文件不存在")
}
}
}