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:
@@ -3,8 +3,8 @@ plugins {
|
|||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
id 'kotlin-kapt'
|
id 'kotlin-kapt'
|
||||||
id 'com.google.dagger.hilt.android'
|
id 'com.google.dagger.hilt.android'
|
||||||
|
id 'realm-android'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace 'com.navinfo.omqs'
|
namespace 'com.navinfo.omqs'
|
||||||
compileSdk 33
|
compileSdk 33
|
||||||
@@ -26,8 +26,8 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '1.8'
|
||||||
@@ -50,8 +50,12 @@ dependencies {
|
|||||||
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'
|
||||||
//权限管理
|
//权限管理 https://github.com/getActivity/XXPermissions
|
||||||
implementation 'com.github.getActivity:XXPermissions:16.5'
|
implementation 'com.github.getActivity:XXPermissions:16.8'
|
||||||
|
// 文件管理 https://github.com/K1rakishou/Fuck-Storage-Access-Framework
|
||||||
|
implementation 'com.github.K1rakishou:Fuck-Storage-Access-Framework:v1.1.3'
|
||||||
|
// Android工具类库 https://blankj.com/2016/07/31/android-utils-code/
|
||||||
|
implementation 'com.blankj:utilcodex:1.30.1'
|
||||||
//依赖注入
|
//依赖注入
|
||||||
//hilt
|
//hilt
|
||||||
implementation "com.google.dagger:hilt-android:2.44"
|
implementation "com.google.dagger:hilt-android:2.44"
|
||||||
|
|||||||
@@ -34,11 +34,10 @@
|
|||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:requestLegacyExternalStorage="true"
|
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
android:theme="@style/Theme.OMQualityInspection"
|
android:theme="@style/Theme.OMQualityInspection"
|
||||||
tools:targetApi="31">
|
android:requestLegacyExternalStorage="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.login.LoginActivity"
|
android:name=".ui.activity.login.LoginActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@@ -58,6 +57,7 @@
|
|||||||
android:screenOrientation="landscape"
|
android:screenOrientation="landscape"
|
||||||
android:theme="@style/Theme.OMQualityInspection" />
|
android:theme="@style/Theme.OMQualityInspection" />
|
||||||
|
|
||||||
|
<meta-data android:name="ScopedStorage" android:value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
95
app/src/main/assets/MergeOMDB.py
Normal file
95
app/src/main/assets/MergeOMDB.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# coding:utf-8
|
||||||
|
# 合并指定目录下的omdb(sqlite)数据
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
|
# 定义遍历目录的函数
|
||||||
|
def traverse_dir(path):
|
||||||
|
fileList = list()
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for file in files:
|
||||||
|
if str(file).endswith(".omdb"):
|
||||||
|
# 文件的完整路径
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
# 处理文件,例如读取文件内容等
|
||||||
|
print(file_path)
|
||||||
|
fileList.append(file_path)
|
||||||
|
return fileList
|
||||||
|
|
||||||
|
|
||||||
|
# 打开配置文件,读取用户配置的
|
||||||
|
def openConfigJson(path):
|
||||||
|
# 读取json配置,获取要抽取的表名
|
||||||
|
with open(path, "r") as f:
|
||||||
|
configMap = json.load(f)
|
||||||
|
return configMap
|
||||||
|
|
||||||
|
|
||||||
|
# 按照tableList中指定的表名合并多个源数据库到指定目标数据库中
|
||||||
|
def mergeSqliteData(originSqliteList, destSqlite, tableList):
|
||||||
|
destConn = sqlite3.connect(destSqlite)
|
||||||
|
destCursor = destConn.cursor()
|
||||||
|
|
||||||
|
for originSqlite in originSqliteList:
|
||||||
|
originConn = sqlite3.connect(originSqlite)
|
||||||
|
originCursor = originConn.cursor()
|
||||||
|
# 从源数据库中遍历取出表list中的数据
|
||||||
|
for table in tableList:
|
||||||
|
# 检查目标数据库中是否存在指定的表
|
||||||
|
containsTable = destCursor.execute(
|
||||||
|
"SELECT sql FROM sqlite_master WHERE type='table' AND name='%s'" % (table)).fetchall()
|
||||||
|
if not containsTable or len(containsTable) <= 0:
|
||||||
|
# 复制表结构
|
||||||
|
originCursor.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='%s'" % (table))
|
||||||
|
createTableSql = originCursor.fetchone()[0]
|
||||||
|
destCursor.execute(createTableSql)
|
||||||
|
destConn.commit()
|
||||||
|
|
||||||
|
originCursor.execute("Select * From " + table)
|
||||||
|
# 获取到源数据库中该表的所有数据
|
||||||
|
originData = originCursor.fetchall()
|
||||||
|
# 获取一行数据中包含多少列,以此动态设置sql语句中的?个数
|
||||||
|
if originData and len(originData)>0:
|
||||||
|
num_cols = len(originData[0])
|
||||||
|
placeholders = ",".join(["?"] * num_cols)
|
||||||
|
for row in originData:
|
||||||
|
destCursor.execute("INSERT INTO "+table+" VALUES ({})".format(placeholders), row)
|
||||||
|
|
||||||
|
print("{}数据已导入!".format(originSqlite))
|
||||||
|
originCursor.close()
|
||||||
|
originConn.close()
|
||||||
|
destConn.commit()
|
||||||
|
destCursor.close()
|
||||||
|
destConn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
params = sys.argv[1:] # 截取参数
|
||||||
|
if params:
|
||||||
|
if not params[0]:
|
||||||
|
print("请输入要合并的omdb数据的文件夹")
|
||||||
|
raise AttributeError("请输入要合并的omdb数据的文件夹")
|
||||||
|
# 获取导出文件的表配置
|
||||||
|
jsonPath = params[0] + "/config.json"
|
||||||
|
if not os.path.exists(jsonPath):
|
||||||
|
raise AttributeError("指定目录下缺少config.json配置文件")
|
||||||
|
omdbDir = params[0]
|
||||||
|
originSqliteList = traverse_dir(omdbDir) # 获取到所有的omdb数据库的路径
|
||||||
|
|
||||||
|
tableNameList = list()
|
||||||
|
configMap = openConfigJson(jsonPath)
|
||||||
|
if configMap["tables"] and len(configMap["tables"]) > 0:
|
||||||
|
for tableName in set(configMap["tables"]):
|
||||||
|
tableNameList.append(tableName)
|
||||||
|
print(tableNameList)
|
||||||
|
else:
|
||||||
|
raise AttributeError("config.json文件中没有配置抽取数据的表名")
|
||||||
|
|
||||||
|
# 开始分别连接Sqlite数据库,按照指定表名合并数据
|
||||||
|
mergeSqliteData(originSqliteList, params[0]+"/output.sqlite", tableNameList)
|
||||||
|
else:
|
||||||
|
raise AttributeError("缺少参数:请输入要合并的omdb数据的文件夹")
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.navinfo.omqs
|
package com.navinfo.omqs
|
||||||
|
|
||||||
|
import io.realm.Realm
|
||||||
|
|
||||||
class Constant {
|
class Constant {
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
@@ -7,7 +9,9 @@ class Constant {
|
|||||||
*/
|
*/
|
||||||
lateinit var ROOT_PATH: String
|
lateinit var ROOT_PATH: String
|
||||||
lateinit var MAP_PATH: String
|
lateinit var MAP_PATH: String
|
||||||
|
lateinit var DATA_PATH: String
|
||||||
lateinit var OFFLINE_MAP_PATH: String
|
lateinit var OFFLINE_MAP_PATH: String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务器地址
|
* 服务器地址
|
||||||
*/
|
*/
|
||||||
@@ -20,7 +24,7 @@ class Constant {
|
|||||||
const val message_version_right_off = "1" //立即发送
|
const val message_version_right_off = "1" //立即发送
|
||||||
|
|
||||||
const val MESSAGE_PAGE_SIZE = 30 //消息列表一页最多数量
|
const val MESSAGE_PAGE_SIZE = 30 //消息列表一页最多数量
|
||||||
|
lateinit var realm: Realm
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,12 @@ package com.navinfo.omqs
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import io.realm.Realm
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class OMQSApplication : Application() {
|
class OMQSApplication : Application() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
Realm.init(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,37 @@
|
|||||||
package com.navinfo.omqs.bean
|
package com.navinfo.omqs.bean
|
||||||
|
|
||||||
data class OfflineMapCityBean(
|
import io.realm.RealmObject
|
||||||
val id: String,
|
|
||||||
/**
|
enum class StatusEnum(val status: Int) {
|
||||||
* 文件名称
|
NONE(0), WAITING(1), LOADING(2), PAUSE(3),
|
||||||
*/
|
ERROR(4), DONE(5), UPDATE(6)
|
||||||
val fileName: String,
|
}
|
||||||
/**
|
|
||||||
* 城市名称
|
open class OfflineMapCityBean{
|
||||||
*/
|
var id: String = ""
|
||||||
val name: String,
|
var fileName: String = ""
|
||||||
val url: String,
|
var name: String = ""
|
||||||
val version: Long,
|
var url: String = ""
|
||||||
var fileSize: Long,
|
var version: Long = 0L
|
||||||
var currentSize:Long = 0,
|
var fileSize: Long = 0L
|
||||||
var status:Int = NONE
|
var currentSize:Long = 0L
|
||||||
) {
|
var status: Int = StatusEnum.NONE.status
|
||||||
companion object Status{
|
|
||||||
const val NONE = 0 //无状态
|
// status的转换对象
|
||||||
const val WAITING = 1 //等待中
|
var statusEnum:StatusEnum
|
||||||
const val LOADING = 2 //下载中
|
get() {
|
||||||
const val PAUSE = 3 //暂停
|
return try {
|
||||||
const val ERROR = 4 //错误
|
StatusEnum.values().find { it.status == status }!!
|
||||||
const val DONE = 5 //完成
|
} catch (e: IllegalArgumentException) {
|
||||||
const val UPDATE = 6 //有新版本要更新
|
StatusEnum.NONE
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
status = value.status
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
fun getFileSizeText(): String {
|
fun getFileSizeText(): String {
|
||||||
return if (fileSize < 1024.0)
|
return if (fileSize < 1024.0)
|
||||||
"$fileSize B"
|
"$fileSize B"
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.navinfo.omqs.data.process
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据处理引擎,数据导入、导出及转换处理
|
||||||
|
* */
|
||||||
|
class DataEngine {
|
||||||
|
|
||||||
|
}
|
||||||
90
app/src/main/java/com/navinfo/omqs/ui/MainActivity.kt
Normal file
90
app/src/main/java/com/navinfo/omqs/ui/MainActivity.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,9 +16,10 @@ open class PermissionsActivity : BaseActivity() {
|
|||||||
val permissionList = mutableListOf<String>()
|
val permissionList = mutableListOf<String>()
|
||||||
if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.TIRAMISU) {
|
if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
//文件读写
|
//文件读写
|
||||||
permissionList.add(Permission.READ_MEDIA_IMAGES)
|
// permissionList.add(Permission.READ_MEDIA_IMAGES)
|
||||||
permissionList.add(Permission.READ_MEDIA_AUDIO)
|
// permissionList.add(Permission.READ_MEDIA_AUDIO)
|
||||||
permissionList.add(Permission.READ_MEDIA_VIDEO)
|
// permissionList.add(Permission.READ_MEDIA_VIDEO)
|
||||||
|
permissionList.add(Permission.MANAGE_EXTERNAL_STORAGE)
|
||||||
} else {
|
} else {
|
||||||
//文件读写
|
//文件读写
|
||||||
permissionList.add(Permission.WRITE_EXTERNAL_STORAGE)
|
permissionList.add(Permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.navinfo.omqs.Constant
|
import com.navinfo.omqs.Constant
|
||||||
import com.navinfo.omqs.bean.LoginUserBean
|
import com.navinfo.omqs.bean.LoginUserBean
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
enum class LoginStatus {
|
enum class LoginStatus {
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +63,17 @@ class LoginViewModel(
|
|||||||
loginUser.value = LoginUserBean(username = "admin", password = "123456")
|
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 {
|
try {
|
||||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
|
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT)
|
||||||
createRootFolder(context)
|
createRootFolder(context)
|
||||||
|
// 初始化Realm
|
||||||
|
initRealm()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
|
loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE)
|
||||||
}
|
}
|
||||||
@@ -122,6 +138,12 @@ class LoginViewModel(
|
|||||||
val file = File(Constant.MAP_PATH)
|
val file = File(Constant.MAP_PATH)
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file.mkdirs()
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,35 @@
|
|||||||
package com.navinfo.omqs.ui.fragment.personalcenter
|
package com.navinfo.omqs.ui.fragment.personalcenter
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
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.activity.viewModels
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.get
|
||||||
import androidx.navigation.fragment.findNavController
|
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.R
|
||||||
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
|
import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 个人中心
|
* 个人中心
|
||||||
*/
|
*/
|
||||||
class PersonalCenterFragment : Fragment() {
|
class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks {
|
||||||
|
|
||||||
private var _binding: FragmentPersonalCenterBinding? = null
|
private var _binding: FragmentPersonalCenterBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
private val fileChooser by lazy { FileChooser(requireContext()) }
|
||||||
|
private val viewModel by lazy { viewModels<PersonalCenterViewModel>().value }
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@@ -25,7 +38,6 @@ class PersonalCenterFragment : Fragment() {
|
|||||||
): View {
|
): View {
|
||||||
_binding = FragmentPersonalCenterBinding.inflate(inflater, container, false)
|
_binding = FragmentPersonalCenterBinding.inflate(inflater, container, false)
|
||||||
return binding.root
|
return binding.root
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@@ -35,13 +47,37 @@ class PersonalCenterFragment : Fragment() {
|
|||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.personal_center_menu_offline_map ->
|
R.id.personal_center_menu_offline_map ->
|
||||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
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
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileChooser.setCallbacks(this@PersonalCenterFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
_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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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("文件不存在")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#747D8C"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M9,3L5,6.99h3L8,14h2L10,6.99h3L9,3zM16,17.01L16,10h-2v7.01h-3L15,21l4,-3.99h-3z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/layout/activity_map_test.xml
Normal file
9
app/src/main/res/layout/activity_map_test.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<com.navinfo.collect.library.map.NIMapView
|
||||||
|
android:id="@+id/main_activity_map1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -11,9 +11,9 @@
|
|||||||
android:icon="@drawable/baseline_map_24"
|
android:icon="@drawable/baseline_map_24"
|
||||||
android:title="离线地图" />
|
android:title="离线地图" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/personal_center_menu_offline_map1"
|
android:id="@+id/personal_center_menu_import_data"
|
||||||
android:icon="@drawable/baseline_person_24"
|
android:icon="@drawable/ic_baseline_import_export_24"
|
||||||
android:title="menu_gallery" />
|
android:title="导入数据" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/personal_center_menu_offline_map2"
|
android:id="@+id/personal_center_menu_offline_map2"
|
||||||
android:icon="@drawable/baseline_person_24"
|
android:icon="@drawable/baseline_person_24"
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "io.realm:realm-gradle-plugin:10.10.1"
|
classpath "io.realm:realm-gradle-plugin:10.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.3.1' apply false
|
id 'com.android.application' version '7.3.1' apply false
|
||||||
id 'com.android.library' version '7.3.1' apply false
|
id 'com.android.library' version '7.3.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
|
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
|
||||||
id 'io.realm.kotlin' version '0.10.0' apply false
|
|
||||||
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.navinfo.collect.library.data.entity
|
||||||
|
|
||||||
|
import io.realm.RealmObject
|
||||||
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
|
enum class StatusEnum(val status: Int) {
|
||||||
|
NONE(0), WAITING(1), LOADING(2), PAUSE(3),
|
||||||
|
ERROR(4), DONE(5), UPDATE(6)
|
||||||
|
}
|
||||||
|
|
||||||
|
open 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 =0) : RealmObject(){
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor(){
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.navinfo.collect.library.data.entity
|
||||||
|
|
||||||
|
import io.realm.RealmModel
|
||||||
|
import io.realm.RealmObject
|
||||||
|
import io.realm.annotations.PrimaryKey
|
||||||
|
import io.realm.annotations.RealmClass
|
||||||
|
|
||||||
|
@RealmClass
|
||||||
|
open class OfflineMapCityRealmObject: RealmModel {
|
||||||
|
@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
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: String,
|
||||||
|
fileName: String,
|
||||||
|
name: String,
|
||||||
|
url: String,
|
||||||
|
version: Long,
|
||||||
|
fileSize: Long,
|
||||||
|
currentSize: Long,
|
||||||
|
status: Int
|
||||||
|
) {
|
||||||
|
this.id = id
|
||||||
|
this.fileName = fileName
|
||||||
|
this.name = name
|
||||||
|
this.url = url
|
||||||
|
this.version = version
|
||||||
|
this.fileSize = fileSize
|
||||||
|
this.currentSize = currentSize
|
||||||
|
this.status = status
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user